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: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
testoutput.txt
.venv/
__pycache__/
1 change: 1 addition & 0 deletions prep-exercise/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.venv/
30 changes: 30 additions & 0 deletions prep-exercise/account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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: dict[str, int] = {
"Sima": 700,
"Linn": 545,
"Georg": 831,
}

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

total_pence = sum_balances(balances)
total_string = format_pence_as_string(total_pence)

print(f"The bank accounts total {total_string}")
41 changes: 41 additions & 0 deletions prep-exercise/inheritance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class Parent:
def __init__(self, first_name: str, last_name: str):
self.first_name = first_name
self.last_name = last_name

def get_name(self) -> str:
return f"{self.first_name} {self.last_name}"


class Child(Parent):
def __init__(self, first_name: str, last_name: str):
super().__init__(first_name, last_name)
self.previous_last_names = []

def change_last_name(self, last_name) -> None:
self.previous_last_names.append(self.last_name)
self.last_name = last_name

def get_full_name(self) -> str:
suffix = ""
if len(self.previous_last_names) > 0:
suffix = f" (née {self.previous_last_names[0]})"
return f"{self.first_name} {self.last_name}{suffix}"

person1 = Child("Elizaveta", "Alekseeva")
print(person1.get_name())
print(person1.get_full_name())
person1.change_last_name("Tyurina")
print(person1.get_name())
print(person1.get_full_name())

person2 = Parent("Elizaveta", "Alekseeva")
print(person2.get_name())
# print(person2.get_full_name())
# person2.change_last_name("Tyurina")
print(person2.get_name())
# print(person2.get_full_name())

# person2 is a Parent. Parent only defines get_name().
# It does not define get_full_name() or change_last_name(),
# so calling those methods causes an AttributeError.
111 changes: 111 additions & 0 deletions prep-exercise/laptop-library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
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


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


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,),
]

name = input("Name: ")
age_input = input("Age: ")
os_input = input("Preferred operating system: ")

try:
age = int(age_input)
except ValueError:
print("Age must be a number", file=sys.stderr)
sys.exit(1)

try:
preferred_os = OperatingSystem(os_input)
except ValueError:
print(
"Operating system must be one of: macOS, Arch Linux, Ubuntu",
file=sys.stderr,
)
sys.exit(1)

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

possible_laptops = find_possible_laptops(laptops, person)

print(
f"we have {len(possible_laptops)} laptop(s) with "
f"{person.preferred_operating_system.value}."
)

ubuntu_count = 0
arch_count = 0
macos_count = 0


for laptop in laptops:
if laptop.operating_system == OperatingSystem.UBUNTU:
ubuntu_count += 1
elif laptop.operating_system == OperatingSystem.ARCH:
arch_count += 1
elif laptop.operating_system == OperatingSystem.MACOS:
macos_count += 1


preferred_count = len(possible_laptops)

best_os = OperatingSystem.UBUNTU
best_count = ubuntu_count

if arch_count > best_count:
best_os = OperatingSystem.ARCH
best_count = arch_count

if macos_count > best_count:
best_os = OperatingSystem.MACOS
best_count = macos_count


if best_count > preferred_count:
print(
f"If you're willing to accept {best_os.value}, "
f"you're more likely to get a laptop because "
f"we have {best_count} available."
)


11 changes: 11 additions & 0 deletions prep-exercise/mypy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
def double(number):
return number * 3

print(double(10))


# when checked with mypy --strict it pointed to two errors
# first missing annotation on line 1
# secondly in line 4 call to untyped function in typed context.
# but it did not notice that in we are putting *3
# so mypy is good for helping us to check the types.
14 changes: 14 additions & 0 deletions prep-exercise/persone-dataclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from dataclasses import dataclass
from datetime import date

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

imran = Person("Imran", date(2004, 4, 15), "Ubuntu") # We can call this constructor - @dataclass generated it for us.
print(imran)

imran2 = Person("Imran", date(2004, 4, 15), "Ubuntu")
print(imran == imran2) # Prints True
21 changes: 21 additions & 0 deletions prep-exercise/persone-date.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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):
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(2004, 4, 15), "Ubuntu")
print(imran.is_adult())
48 changes: 48 additions & 0 deletions prep-exercise/persone-enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from dataclasses import dataclass
from enum import Enum
from typing import List

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


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


people = [
Person(name="Imran", age=22, preferred_operating_system=OperatingSystem.UBUNTU),
Person(name="Eliza", age=34, preferred_operating_system=OperatingSystem.ARCH),
]

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),
]

for person in people:
possible_laptops = find_possible_laptops(laptops, person)
print(f"Possible laptops for {person.name}: {possible_laptops}")
20 changes: 20 additions & 0 deletions prep-exercise/persone-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
age: int
children: List["Person"]

fatma = Person(name="Fatma", age=5, children=[])
aisha = Person(name="Aisha", age=8, 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 prep-exercise/persone-type-guided-ref.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_system: List[str]


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


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


people = [
Person(name="Imran", age=22, preferred_operating_system=["Ubuntu"]),
Person(name="Eliza", age=34, preferred_operating_system=["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}")
25 changes: 25 additions & 0 deletions prep-exercise/persone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class Person:
def __init__(self, name: str, age: int, address:str, preferred_operating_system: str):
self.name = name
self.age = age
self.address = address
self.preferred_operating_system = preferred_operating_system

imran = Person("Imran", 22, "London", "Ubuntu")
print(imran.name)
print(imran.address) # person.py error: "Person" has no attribute "address" [attr-defined]

eliza = Person("Eliza", 34, "London", "Arch Linux")
print(eliza.name)
print(eliza.address) # person.py error: "Person" has no attribute "address" [attr-defined]

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

print(is_adult(imran))


# Because there is no address attribute in the Person class
# mypy does not accept line 9 and line 13
# so we have to add self.address = address and define the type on def.
# then I add the address to person details.
Loading