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
28 changes: 28 additions & 0 deletions sprint5/Exercise1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
def open_account(balances: dict[str,int], name: str, amount: int) -> None:
balances[name] = amount

def sum_balances(accounts: dict[str, int]) -> int:
for name, pence in accounts.items():
print(f"{name} had balance {pence}")
return sum(accounts.values())

def format_pence_as_string(total_pence: int) -> str:
if total_pence < 100:
return f"{total_pence}p"
pounds = 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)
total_string = format_pence_as_string(total_pence)

print(f"The bank accounts total {total_string}")
22 changes: 22 additions & 0 deletions sprint5/Exercise2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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.age)
print(imran.preferred_operating_system)


eliza = Person("Eliza", 34, "Arch Linux")
print(eliza.name)

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

print(is_adult(imran))

def get_address(person: Person) -> str: #this returns an error
return person.address
38 changes: 38 additions & 0 deletions sprint5/Inheritance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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("1",person1.get_name()) # It should print "Elizaveta Alekseeva"
print("2",person1.get_full_name()) # It should print "Elizaveta Alekseeva"
person1.change_last_name("Tyurina") # Changes the last name to "Tyurina"
print("3",person1.get_name())# It should print "Elizaveta Alekseeva" # I was wrong here because the child's last_name has been changed to "Tyurina".
print("4",person1.get_full_name())# I thought it would print "Elizaveta Alekseeva (née Tyurina)"
# I was wrong here again because I misunderstood how last_name and previous_last_names work.

person2 = Parent("Elizaveta", "Alekseeva")
print("5",person2.get_name()) # It should print "Elizaveta Alekseeva"
print("6",person2.get_full_name()) # Returns an error because Parent doesn't have a get_full_name() method.
person2.change_last_name("Tyurina") # Returns an error because Parent doesn't have a change_last_name() method.
print("7",person2.get_name()) # It should print "Elizaveta Alekseeva"
print(person2.get_full_name()) # returns an error again because Parent doesn't have a get_full_name() method.
29 changes: 29 additions & 0 deletions sprint5/Methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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(2000, 5, 10),
"Ubuntu"
)

print(imran.is_adult())
32 changes: 32 additions & 0 deletions sprint5/dataclasses-example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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


imran = Person(
"Imran",
date(2000, 5, 10),
"Ubuntu"
)

print(imran)
print(imran.is_adult())
84 changes: 84 additions & 0 deletions sprint5/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from dataclasses import dataclass
from enum import Enum
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



laptops = [
Laptop(1, "Dell", "XPS", 13, OperatingSystem.ARCH),
Laptop(2, "Dell", "XPS", 15, OperatingSystem.UBUNTU),
Laptop(3, "Dell", "XPS", 15, OperatingSystem.UBUNTU),
Laptop(4, "Apple", "MacBook", 13, OperatingSystem.MACOS),
]


name = input("What is your name? ")

try:
age = int(input("What is your age? "))
except ValueError:
print("Age must be a number.", file=sys.stderr)
sys.exit(1)


try:
operating_system = input("What operating system do you prefer? ")
preferred_operating_system = OperatingSystem(operating_system)
except ValueError:
print("That is not a valid operating system.", file=sys.stderr)
sys.exit(1)


person = Person(
name,
age,
preferred_operating_system
)

number_of_laptops = 0

for laptop in laptops:
if laptop.operating_system == person.preferred_operating_system:
number_of_laptops += 1


print(
f"There are {number_of_laptops} "
f"{person.preferred_operating_system.value} laptops available."
)

for operating_system in OperatingSystem:
number_available = 0

for laptop in laptops:
if laptop.operating_system == operating_system:
number_available += 1

if number_available > number_of_laptops:
print(
f"You are more likely to get a laptop if you "
f"are willing to use {operating_system.value}."
)

20 changes: 20 additions & 0 deletions sprint5/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=10, children=[])
aisha = Person(name="Aisha", age=5 ,children=[])

imran = Person(name="Imran", age=40, 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 sprint5/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", "Arch Linux"]),
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"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A type here. Could raise ValueError.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Khantdotcom, for reviewing my code. Can you explain how it can cause a ValueError, please? I assume you are pointing to "ubuntu", which is lowercase here. In this case, I don't see any error being thrown, except that it will miss the laptop with ID 3 as a possibility. I think that's also why we use enums in the next exercise to fix this issue.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you are completely right, @BoshraM! That was a slip on my part.

I meant to type "typo" rather than "type," and you are entirely correct that it won't raise a ValueError. Standard Python will just evaluate the string comparison to False, leading to a silent logic bug where Laptop ID 3 is missed, just as you described.

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}")