diff --git a/Sprint5/classes.py b/Sprint5/classes.py new file mode 100644 index 00000000..6df932c7 --- /dev/null +++ b/Sprint5/classes.py @@ -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: + return person.jobcompany \ No newline at end of file diff --git a/Sprint5/data-class.py b/Sprint5/data-class.py new file mode 100644 index 00000000..0d125ff7 --- /dev/null +++ b/Sprint5/data-class.py @@ -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) \ No newline at end of file diff --git a/Sprint5/double.py b/Sprint5/double.py new file mode 100644 index 00000000..f6f5ec6b --- /dev/null +++ b/Sprint5/double.py @@ -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. +#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" \ No newline at end of file diff --git a/Sprint5/e-num.py b/Sprint5/e-num.py new file mode 100644 index 00000000..19bccf8d --- /dev/null +++ b/Sprint5/e-num.py @@ -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) + 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.") \ No newline at end of file diff --git a/Sprint5/generics.py b/Sprint5/generics.py new file mode 100644 index 00000000..71fd4c46 --- /dev/null +++ b/Sprint5/generics.py @@ -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) \ No newline at end of file diff --git a/Sprint5/lastexer.py b/Sprint5/lastexer.py new file mode 100644 index 00000000..2c3e6bb3 --- /dev/null +++ b/Sprint5/lastexer.py @@ -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()) diff --git a/Sprint5/methods.py b/Sprint5/methods.py new file mode 100644 index 00000000..13963c24 --- /dev/null +++ b/Sprint5/methods.py @@ -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 \ No newline at end of file diff --git a/Sprint5/refactor.py b/Sprint5/refactor.py new file mode 100644 index 00000000..c2d34ef5 --- /dev/null +++ b/Sprint5/refactor.py @@ -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}") \ No newline at end of file diff --git a/Sprint5/type.py b/Sprint5/type.py new file mode 100644 index 00000000..9340cf25 --- /dev/null +++ b/Sprint5/type.py @@ -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: + 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}") \ No newline at end of file