Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
20 changes: 20 additions & 0 deletions Sprint5/classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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)

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

print(is_adult(imran))

def works_at(person: Person) -> str:

Choose a reason for hiding this comment

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

Not sure what works_at is doing here?

return person.jobcompany
25 changes: 25 additions & 0 deletions Sprint5/data-class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from datetime import date
from dataclasses import dataclass

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

def age(self)-> int: #returns age in years
today = date.today()
years = today.year - self.birth_day.year
if(today.month, today.day) < (self.birth_day.month, self.birth_day.day):
years -= 1
return years

def is_adult(self):
return self.age() >= 18


p1 = Person("Sara", date(1996, 10, 28), "macOS")
print(p1)

p2 = Person("Sara", date(1996, 10, 28), "macOS")
print(p1 == p2)
21 changes: 21 additions & 0 deletions Sprint5/double.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
def double(n):
return n*2
num = double("22")
print(num)

#my prediction is that it would return 2222. As python will treat 22 as a string being a strongly typed language.

Choose a reason for hiding this comment

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

Technically Python is "duck typed" not "strongly typed" - worth googling the difference.

#if it was javascript * operator would have forced numeric converion and 22 string would have become 22 int and 44 would
#have been returned
# when I run the file it returns 2222 as expected.

# 2nd exercise- original function :
def double(number):
return number * 3

print(double(10)) # returns "30"

#so we either change the name of the function to triple or multiply number with 2 rather than 3
def triple(number):
return number * 3

print(triple(10)) # returns "30"
93 changes: 93 additions & 0 deletions Sprint5/e-num.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
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_os: OperatingSystem


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

#library of 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),
]

def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]:
possible_laptops = []
for laptop in laptops:
if laptop.operating_system == person.preferred_os:
possible_laptops.append(laptop)
return possible_laptops # returns an array of possible laptops for the person

#accept userinput
name = input("Enter your name: ").strip()
age_str = input("Enter your age: ").strip() #input always returns a str, we need to convert this to an integer
os_str = input("Enter your preferred operating system: ").strip()
# Validate age
try:
age = int(age_str)
except ValueError:
print("Error: Age must be a number.", file= sys.stderr)

Choose a reason for hiding this comment

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

Nice! Liking the use of stderr here.

sys.exit(1)

# Validate OS
try:
preferred_os = OperatingSystem(os_str)
except ValueError:
print("Error: Invalid operating system.", file=sys.stderr)
sys.exit(1)

#Create a person after validation
person = Person(name = name, age = age, preferred_os =preferred_os)
#finding laptops for this person
possible = find_possible_laptops(laptops, person)
print(f"The laptop library has {len(possible)} with {preferred_os.value}.")

# Start with an empty dictionary
os_counts: dict[OperatingSystem, int] = {}

for laptop in laptops:
os = laptop.operating_system
# If we've seen this OS before, add 1, otherwise start at 1
if os in os_counts:
os_counts[os] += 1
else:
os_counts[os] = 1

best_os = None
best_count = -1

# Loop through each (key, value) pair
for pair in os_counts.items():
os = pair[0] # the key (operating system)
count = pair[1] # the value (number of laptops)

# Check if this count is bigger than the best so far
if count > best_count:
best_os = os
best_count = count

print("Best OS:", best_os, "with", best_count, "laptops")
if best_os != preferred_os:
print(f"If you’re willing to accept {best_os.value}, "
f"you’re more likely to get a laptop since there are {best_count} available.")
21 changes: 21 additions & 0 deletions Sprint5/generics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from dataclasses import dataclass

@dataclass(frozen=True)
class Person:
name: str
age : int
children: list["Person"] #nside the Person class- the Person-type doesnt exist, so we add "" to person,



Muhib = Person(name="Muhib",age= 7, children=[])
Muiz = Person(name="Muiz",age= 4,children=[])

Sara = Person(name="Sara",age= 31, children=[Muhib, Muiz])

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

print_family_tree(Sara)

Choose a reason for hiding this comment

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

This is all good. If you want (and only if you want) a stretch objective, make it cope with children who have children and print out a proper tree (so children, grandchildren, great-grandchildren increasingly indented). Definitely an optional task

40 changes: 40 additions & 0 deletions Sprint5/lastexer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Parent:
"""Represents a person with a first and last name."""
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 the full name as 'First Last'."""
return f"{self.first_name} {self.last_name}"


class Child(Parent):
"""Represents a person who can change last names, tracking previous ones."""
def __init__(self, first_name: str, last_name: str):
"""Initialize a Child with a first and last name, plus a list of previous last names."""
super().__init__(first_name, last_name)
self.previous_last_names: list[str] = []

def change_last_name(self, last_name) -> None:
"""Change the last name and record the previous one."""
self.previous_last_names.append(self.last_name)
self.last_name = last_name

def get_full_name(self) -> str:
"""Return the full name, with suffix showing original last name if changed."""
suffix = ""
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())
24 changes: 24 additions & 0 deletions Sprint5/methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from datetime import date
class Person:
def __init__(self, name: str, birth_day: date):
self.name = name
self.birth_day = birth_day

def age(self)-> int: #returns age in years
today = date.today()
years = today.year - self.birth_day.year
if(today.month, today.day) < (self.birth_day.month, self.birth_day.day):
years -= 1
return years

def is_adult(self):
return self.age() >= 18

def __str__(self) -> str:
return f"{self.name}, born {self.birth_day}, age {self.age()}"

p1 = Person("Sara", date(1996, 10, 28))
print(p1.is_adult()) # True

p2 = Person("Muhib", date(2018, 6, 22))
print(p2.is_adult()) # False
42 changes: 42 additions & 0 deletions Sprint5/refactor.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}")

Choose a reason for hiding this comment

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

All good!

34 changes: 34 additions & 0 deletions Sprint5/type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

from typing import Dict
def open_account(balances: Dict[str,int], name:str, amount:int)->None: #dic type str and int--- returns none/figured after running --strict flag with mypy
#Adding a new account
balances[name] = amount

def sum_balances(accounts:Dict[str,int])-> int: #takes type dic[str, int}returns int
total = int = 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: #type int returns type str
#formatting pence as a string
if total_pence < 100:

Choose a reason for hiding this comment

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

What happens if the account has a negative balance?

return f"{total_pence}p"
pounds =(total_pence // 100) #floordivision always returns an int
pence = total_pence % 100
return f"£{pounds}.{pence:02d}"

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

open_account(balances,"Tobi", 913) # correct passing of the argumenst to functions with balances.
open_account(balances,"Olya", 713)

total_pence = sum_balances(balances) #returntype int
total_string = format_pence_as_string(total_pence) #returntype str and wrong function name

print(f"The bank accounts total {total_string}")