Skip to content
Closed
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
5 changes: 5 additions & 0 deletions Sprint5/Limits of type checking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def double(number):
return number * 3
print(double(10))

#this code runs perfectly.
13 changes: 13 additions & 0 deletions Sprint5/class&objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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)

eliza = Person("Eliza", 34, "Arch Linux")
print(eliza.name)
print(eliza.address)
26 changes: 26 additions & 0 deletions Sprint5/dataclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from dataclasses import dataclass
from datetime import date

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

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

birthday_has_passed = (today.month, today.day) >= (self.birth_date.month, self.birth_date.day)

if not birthday_has_passed:
age -= 1

return age >= 18

imran1 = Person("Imran", date(2000, 5, 20), "Ubuntu")
imran2 = Person("Imran", date(2000, 5, 20), "Ubuntu")

print(imran1)
print(f"Are they equal? {imran1 == imran2}")
print(f"Is Imran an adult? {imran1.is_adult()}")
65 changes: 65 additions & 0 deletions Sprint5/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import sys
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 Laptop:
id: int
operating_system: OperatingSystem

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

laptops = [
Laptop(id=1, operating_system=OperatingSystem.ARCH),
Laptop(id=2, operating_system=OperatingSystem.UBUNTU),
Laptop(id=3, operating_system=OperatingSystem.UBUNTU),
Laptop(id=4, operating_system=OperatingSystem.MACOS),
Laptop(id=5, operating_system=OperatingSystem.UBUNTU),
]

def get_user_person() -> Person:
name = input("Enter your name: ")

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

os_input = input("Enter preferred OS (macOS, Arch Linux, Ubuntu): ")
try:
pref_os = OperatingSystem(os_input)
except ValueError:
print(f"Error: '{os_input}' is not a valid operating system.", file=sys.stderr)
sys.exit(1)
return Person(name=name, age=age, preferred_operating_system=pref_os)

def main():
user = get_user_person()
counts = {os: 0 for os in OperatingSystem}
for laptop in laptops:
counts[laptop.operating_system] += 1

user_pref = user.preferred_operating_system
pref_count = counts[user_pref]
print(f"There are {pref_count} laptops available with {user_pref.value}.")

best_os = max(counts, key=counts.get)
max_count = counts[best_os]

if max_count > pref_count:
print(f"Note: If you are willing to use {best_os.value}, we have {max_count} available. "
"You're more likely to get one!")

if __name__ == "__main__":
main()
23 changes: 23 additions & 0 deletions Sprint5/generics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from dataclasses import dataclass
from typing import List

@dataclass(frozen=True)
class Person:
name: str
age: int # Added the missing field
children: List["Person"]

# Inventing ages for the family members
fatma = Person(name="Fatma", age=8, children=[])
aisha = Person(name="Aisha", age=10, children=[])

# Imran needs an age as well, and now includes his 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:
# This line now works because 'age' exists in the Person class
print(f"- {child.name} ({child.age})")

print_family_tree(imran)
40 changes: 40 additions & 0 deletions Sprint5/inheritance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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())

# The Child can access everything the Parent has because it inherits from it.
# The parent has no attribute of the Child.
24 changes: 24 additions & 0 deletions Sprint5/methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# The advantage of using methods instead of free functions.
# 1. Encapsulation & Organization: methods group behavior directly with the data it operates on the object.
# 2. State management: methods have direct access to 'self'.
# 3. Readibility.

from datetime import date

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

def is_adult(self) -> bool:
today = date.today()
age = today.year - self.birth_date.year
birthday_has_passed: bool = (today.month, today.day) >= (self.birth_date.month, self.birth_date.day)

if not birthday_has_passed:
age -= 1
return age >= 18

imran = Person("Imran", date(2000, 5, 20), "Ubuntu")
print(f"Is Imran an adult? {imran.is_adult()}")
40 changes: 40 additions & 0 deletions Sprint5/mypy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from typing import Dict

# Added Type Annotations
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}")
# If 'pence' isn't an int, this will fail or cause issues later
total += pence
return total

def format_pence_as_string(total_pence: int) -> str:
if total_pence < 100:
return f"{total_pence}p"
# Use // for floor division to ensure 'pounds' is an int
pounds = total_pence // 100
pence = total_pence % 100
return f"£{pounds}.{pence:02d}"

balances: Dict[str, int] = {
"Sima": 700,
"Linn": 545,
"Georg": 831,
}

# BUGS FIXED HERE:
# Changed 9.13 (float) to 913 (int)
# Changed "£7.13" (str) to 713 (int)
open_account(balances, "Tobi", 913)
open_account(balances, "Olya", 713)

total_pence = sum_balances(balances)

# BUG FIXED HERE: Corrected the function name call
total_string = format_pence_as_string(total_pence)

print(f"The bank accounts total {total_string}")
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"),
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}")
Loading