Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
node_modules
testoutput.txt
.venv
__pycache__
.mypy_cache
50 changes: 50 additions & 0 deletions sprint-5-prep/1-use-types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Exercise-1

# Predict what double("22") will do.
# Then run the code and check. Did it do what you expected?
# Why did it return the value it did?

def double(value):
return value * 2

#Answer
#I guess it'll return 2222. That's because any value in quotes is a string,
# and when strings are multiplied, they repeat the characters.

def double(value):
return value * 2

print("double is:", double("22")) #double is: 2222

# Yes, It returned 2222 as I predicted.
# Python's operator "*" when used with a string and a number, repeats this string as "number" times,
# and it didn't convert the string "22" into number 22.


#Exercise-2

def double(number):
return number * 3

print(double(10))


#Read the above code and write down what the bug is. How would you fix it?

# Answer
# There are two way to fix it:
# 1. Change *3 to *2.

def double(number):
return number * 2

print(double(10))

# or

# 2. Rename the function to "triple" if we want multiply by 3 - it keeps the logic correct.

def triple(number):
return number * 3

print(triple(10))
31 changes: 31 additions & 0 deletions sprint-5-prep/2-type-checking-mypy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Dict

def open_account(balances: Dict[str, int], name: str, amount: int)-> None:
balances[name] = amount

def sum_balances(accounts: Dict[str, int])-> int:
total = 0
for name, pence in accounts.items():
print(f"{name} had balance {pence}")
total += pence
return total

def format_pence_as_string(total_pence: int)-> str:
if total_pence < 100:
return f"{total_pence}p"
pounds = int(total_pence / 100)
pence = total_pence % 100
return f"£{pounds}.{pence:02d}"

balances = {
"Sima": 700,
"Linn": 545,
"Georg": 831,
}

open_account(balances, "Tobi", 913)
open_account(balances, "Olya", 713)

total_pence = sum_balances(balances)

print(f"The bank accounts total {total_string}")
24 changes: 24 additions & 0 deletions sprint-5-prep/3-classes-and-objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class Person:
def __init__(self, name: str, age: int, preferred_operating_system: str):
self.name = name
self.age = age
self.preferred_operating_system = preferred_operating_system

imran = Person("Imran", 22, "Ubuntu")
print(imran.name)
#print(imran.address)
#error: Person class has no attribute "address"

eliza = Person("Eliza", 34, "Arch Linux")
print(eliza.name)
#print(eliza.address)
#the same error: Person class has no attribute "address"

def is_adult(person: Person) -> bool:
return person.age >= 18

print(is_adult(imran))

def get_phone(person: Person) -> str:
return person.phone_number
# After running mypy this method also causes an error, because Person class has no attribute "phone_number"
44 changes: 44 additions & 0 deletions sprint-5-prep/4-methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Exercises-1
# Think of the advantages of using methods instead of free functions.
# Write them down in your notebook.

# 1. Organisation: all Person-related logic lives inside the Person class.

# 2. Encapsulation: we only have to update the method once,
# for example if we change "age" to "date_of_birth" inside the class.
# With free functions, we'd have to update every function that touches person.age across the whole codebase.

# 3. Simple search: if we type "imran." our editor shows everything Person can do.
# With free functions, we have to remember they exist.

# 4. Clear ownership: "person.is_adult()" is definitely about a person,
# but with "is_adult(x)" we don't know what it's about.

# 5. Easier to catch errors with mypy, because all methods related to the class are in one place.


# Exercises-2
# Change the Person class to take a date of birth (using the standard library’s datetime.date class)
# and store it in a field instead of age.
#
# Update the is_adult method to act the same as before.

from datetime import date

class Person:
def __init__(self, name: str, date_of_birth: date, preferred_operating_system: str):
self.name = name
self.date_of_birth = date_of_birth
self.preferred_operating_system = preferred_operating_system

def is_adult(self) -> bool:
today = date.today()
age = today.year - self.date_of_birth.year

if(today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day):
age -= 1

return age >= 18

imran = Person("Imran", date(2003, 6, 20), "Ubuntu")
print(imran.is_adult())
22 changes: 22 additions & 0 deletions sprint-5-prep/5-dataclasses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from dataclasses import dataclass
from datetime import date

@dataclass(frozen=True)
class Person:
name: str
date_of_birth: date
preferred_operating_system: str

def is_adult(self) -> bool:
today = date.today()

age = today.year - self.date_of_birth.year
if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day):
age -= 1
return age >= 18


zoi = Person("Zoi", date(2003, 3, 23), "Ubuntu")

print("zoi:", zoi)
print("zoi.is_adult():", zoi.is_adult())
20 changes: 20 additions & 0 deletions sprint-5-prep/6-generics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from dataclasses import dataclass
from typing import List

@dataclass(frozen=True)
class Person:
name: str
children: list["Person"]
age: int

fatma = Person(name="Fatma", age=9, children=[])
aisha = Person(name="Aisha", age=5, children=[])

imran = Person(name="Imran", age=35, children=[fatma, aisha])

def print_family_tree(person: Person) -> None:
print(person.name)
for child in person.children:
print(f"- {child.name} ({child.age})")

print_family_tree(imran)
42 changes: 42 additions & 0 deletions sprint-5-prep/7-type-guided-refactorings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from dataclasses import dataclass
from typing import List

@dataclass(frozen=True)
class Person:
name: str
age: int
preferred_operating_systems: List[str]


@dataclass(frozen=True)
class Laptop:
id: int
manufacturer: str
model: str
screen_size_in_inches: float
operating_system: str


def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]:
possible_laptops = []
for laptop in laptops:
if laptop.operating_system in person.preferred_operating_systems:
possible_laptops.append(laptop)
return possible_laptops


people = [
Person(name="Imran", age=22, preferred_operating_systems=["Ubuntu"]),
Person(name="Eliza", age=34, preferred_operating_systems=["Arch Linux"]),
]

laptops = [
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system="Arch Linux"),
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="Ubuntu"),
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="ubuntu"),
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system="macOS"),
]

for person in people:
possible_laptops = find_possible_laptops(laptops, person)
print(f"Possible laptops for {person.name}: {possible_laptops}")
79 changes: 79 additions & 0 deletions sprint-5-prep/8-enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from dataclasses import dataclass
from enum import Enum
from typing import List
import sys

class OperatingSystem(Enum):
MACOS = "macOS"
ARCH = "Arch Linux"
UBUNTU = "Ubuntu"

@dataclass(frozen=True)
class Person:
name: str
age: int
preferred_operating_system: OperatingSystem

@dataclass(frozen=True)
class Laptop:
id: int
manufacturer: str
model: str
screen_size_in_inches: float
operating_system: OperatingSystem

os_input_name = input("Your name is: ")

os_input_age = input("Your age is: ")
try:
age = int(os_input_age)
except ValueError:
print(f"Error: '{os_input_age}' is not a valid age", file=sys.stderr)
sys.exit(1)

os_input_preferred_os = input("Preferred operating system is: ")
try:
preferred_operating_system = OperatingSystem(os_input_preferred_os)
except ValueError:
print(f"Error: '{os_input_preferred_os}' is not a valid operating system", file=sys.stderr)
sys.exit(1)

person = Person(name = os_input_name, age=age, preferred_operating_system=preferred_operating_system)

laptops = [
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
Laptop(id=5, manufacturer="Apple", model="macBook", screen_size_in_inches=14, operating_system=OperatingSystem.MACOS),
Laptop(id=6, manufacturer="Apple", model="macBook", screen_size_in_inches=15, operating_system=OperatingSystem.MACOS),
]

def find_specific_os(laptops: List[Laptop], preferred_os: OperatingSystem) -> List[Laptop]:
possible_laptops = []

for laptop in laptops:
if (laptop.operating_system == preferred_os):
possible_laptops.append(laptop)

possible_laptops_amount = len(possible_laptops)

print(f"The amount of possible laptops with preferred operating system is", possible_laptops_amount)

return possible_laptops

result = find_specific_os(laptops, preferred_operating_system)

counts_laptop_per_os: dict[OperatingSystem, int] = {}

for laptop in laptops:
os = laptop.operating_system
if os in counts_laptop_per_os:
counts_laptop_per_os[os] += 1
else:
counts_laptop_per_os[os] = 1

top_os = max(counts_laptop_per_os, key=lambda os: counts_laptop_per_os[os])

if top_os != preferred_operating_system:
print(f"If you're willing to use {top_os.value}, you're more likely to get a laptop ({counts_laptop_per_os[top_os]} available)")
Loading
Loading