diff --git a/Perp-exercises/Generics6.1.py b/Perp-exercises/Generics6.1.py new file mode 100644 index 000000000..6e7f9b3b7 --- /dev/null +++ b/Perp-exercises/Generics6.1.py @@ -0,0 +1,23 @@ +from dataclasses import dataclass + + +@dataclass(frozen=True) +class Person: + name: str + age: int + children: list["Person"] + + +fatma = Person(name="Fatma", age=22, children=[]) +aisha = Person(name="Aisha", age=17, children=[]) + +imran = Person(name="Imran", age=44, 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) diff --git a/Perp-exercises/class-exercise3.1.py b/Perp-exercises/class-exercise3.1.py new file mode 100644 index 000000000..122bda47f --- /dev/null +++ b/Perp-exercises/class-exercise3.1.py @@ -0,0 +1,25 @@ +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 is_student(person: Person) -> bool: + return person.student diff --git a/Perp-exercises/dataclase-5.1.py b/Perp-exercises/dataclase-5.1.py new file mode 100644 index 000000000..0b78dc9ac --- /dev/null +++ b/Perp-exercises/dataclase-5.1.py @@ -0,0 +1,27 @@ +from datetime import date +from dataclasses import dataclass + + +@dataclass(frozen=True) +class Person: + + name: str + date_of_birth: date + preferred_operating_system: str + + def age(self) -> int: + current: date = date.today() + age: int = current.year - self.date_of_birth.year + if (current.month, current.day) < ( + self.date_of_birth.month, + self.date_of_birth.day, + ): + age -= 1 + return age + + def is_adult(self) -> bool: + return self.age() >= 18 + + +imran = Person("Imran", date(2022, 10, 16), "Ubuntu") +print(imran.is_adult()) diff --git a/Perp-exercises/enum8.1.py b/Perp-exercises/enum8.1.py new file mode 100644 index 000000000..d9f6f7755 --- /dev/null +++ b/Perp-exercises/enum8.1.py @@ -0,0 +1,157 @@ +from enum import Enum +from typing import List +from dataclasses import dataclass + + +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + + +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: int + operating_system: OperatingSystem + + +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_system: OperatingSystem + + +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 group_laptops_by_operating_system( + laptops: List[Laptop], +) -> dict[OperatingSystem, List[Laptop]]: + available_laptops: dict[OperatingSystem, List[Laptop]] = { + OperatingSystem.UBUNTU: [], + OperatingSystem.ARCH: [], + OperatingSystem.MACOS: [], + } + for laptop in laptops: + available_laptops[laptop.operating_system].append(laptop) + + return available_laptops + + +def how_many_match( + person: Person, available_laptops: dict[OperatingSystem, List[Laptop]] +) -> int: + return len(available_laptops[person.preferred_operating_system]) + + +def most_available_operating_system( + available_laptops: dict[OperatingSystem, List[Laptop]], +) -> OperatingSystem: + if not available_laptops: + raise ValueError("No operating systems available") + max_len: int = -1 + most_available: OperatingSystem + for key, val in available_laptops.items(): + if len(val) > max_len: + max_len = len(val) + most_available = key + + return most_available + + +def read_operating_system() -> OperatingSystem: + print("""choose an operating system: + 1.Ubuntu + 2,Arch Linux + 3.macOs""") + + while True: + try: + choice = int(input("Enter Your choice[1-3]: ")) + if 1 <= choice <= 3: + break + except ValueError: + print("please enter a valid number.") + + os_map: dict[int, OperatingSystem] = { + 1: OperatingSystem.UBUNTU, + 2: OperatingSystem.ARCH, + 3: OperatingSystem.MACOS, + } + return os_map[choice] +def read_valid_number(message:str)->int: + + while True: + try: + num = int(input(message)) + return num + except ValueError: + print("Please enter a valid number.") + + +def main() -> None: + name: str = input("Name: ") + age: int = read_valid_number("Age: ") + preferred_operating_system: OperatingSystem = read_operating_system() + person1: Person = Person(name, age, preferred_operating_system) + + laptops_by_operating_system = group_laptops_by_operating_system(laptops) + matching_laptop_count: int = how_many_match(person1, laptops_by_operating_system) + print("We have", matching_laptop_count, "matches") + + most_available_os: OperatingSystem = most_available_operating_system( + laptops_by_operating_system + ) + choice: OperatingSystem = person1.preferred_operating_system + if person1.preferred_operating_system != most_available_os: + confirm = input( + "Are you willing to accept " f"{most_available_os.value} instead? Y/N: " + ) + if confirm.lower() == "y": + choice = most_available_os + + if not choice: + print("No laptops are available for that operating system.") + return + rented_laptops: list[Laptop] = [] + + rented_out: Laptop = laptops_by_operating_system[choice].pop() + rented_laptops.append(rented_out) + + + +if __name__ == "__main__": + main() diff --git a/Perp-exercises/exercises1-1.py b/Perp-exercises/exercises1-1.py new file mode 100644 index 000000000..5d19c64f2 --- /dev/null +++ b/Perp-exercises/exercises1-1.py @@ -0,0 +1,6 @@ +# Predict what double("22") will do. Then run the code and check. +# Did it do what you expected? Why did it return the value it did? + +# answer +# I predict that will return undefined or raise an error. However, it returned "2222" +# because double function repeats the string twice diff --git a/Perp-exercises/exercises1-2.py b/Perp-exercises/exercises1-2.py new file mode 100644 index 000000000..e69de29bb diff --git a/Perp-exercises/inheritance9.1.py b/Perp-exercises/inheritance9.1.py new file mode 100644 index 000000000..d4718be83 --- /dev/null +++ b/Perp-exercises/inheritance9.1.py @@ -0,0 +1,59 @@ +class Parent: # Implement a class called Parent + def __init__( + self, first_name: str, last_name: str + ): # Constructor that initializes the object's attributes. + self.first_name = first_name # Create the 'first_name' attribute and assign the constructor argument to it + self.last_name = last_name + + def get_name(self) -> str: # Return the person's first name. + return f"{self.first_name} {self.last_name}" + + +class Child(Parent): # Implement a class called Child that inherit the class Parent + def __init__( + self, first_name: str, last_name: str + ): # Constructor for derived class + super().__init__( + first_name, last_name + ) # call the parent class to initialize inherited attributes. + self.previous_last_names = [] # Create a list to store Previous last names + + def change_last_name( + self, last_name: str + ) -> None: # implement a function that take one parameter (the new name) + self.previous_last_names.append( + self.last_name + ) # and store the last name before setting a new value + self.last_name = last_name + + def get_full_name( + self, + ) -> ( + str + ): # declare a var and return full name with "nee "and fist name that assign when the object where declare + 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" +) # declare an object of Child class and give two arguments as firstname and last name +print(person1.get_name()) # print full name (Elizaveta Alekseeva) +print( + person1.get_full_name() +) # print full name (Elizaveta Alekseeva) we did not change the last name yet +person1.change_last_name( + "Tyurina" +) # store the last name in pervious_last_name list then set a new value for last name "Tyurina" +print(person1.get_name()) # #print full name (Elizaveta Tyurina) +print(person1.get_full_name()) # print Elizaveta Tyurina (née Alekseeva) +person2 = Parent( + "Elizaveta", "Alekseeva" +) # declare an object of Parent class and give two arguments as firstname and last name +print(person2.get_name()) # print full name (Elizaveta Alekseeva) +# print(person2.get_full_name()) # Error: Parent does not define get_full_name(). +# person2.change_last_name("Tyurina") ## Error: Parent does not define change_last_name(). +print(person2.get_name()) # print full name (Elizaveta Alekseeva) +# print(person2.get_full_name()) # Error: Parent does not define get_full_name(). diff --git a/Perp-exercises/method4.2.py b/Perp-exercises/method4.2.py new file mode 100644 index 000000000..314eb09bc --- /dev/null +++ b/Perp-exercises/method4.2.py @@ -0,0 +1,25 @@ +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 age(self) -> int: + current: date = date.today() + age: int = current.year - self.date_of_birth.year + if (current.month, current.day) < ( + self.date_of_birth.month, + self.date_of_birth.day, + ): + age -= 1 + return age + + def is_adult(self) -> bool: + return self.age() >= 18 + + +imran = Person("Imran", date(2022, 10, 16), "Ubuntu") +print(imran.is_adult()) diff --git a/Perp-exercises/method_exercise4.1.py b/Perp-exercises/method_exercise4.1.py new file mode 100644 index 000000000..020f4d77f --- /dev/null +++ b/Perp-exercises/method_exercise4.1.py @@ -0,0 +1,5 @@ +# Think of the advantages of using methods instead of free functions. Write them down in your notebook. +# Polymorphism – Derived classes can override methods to provide different behavior. +# Encapsulation – Methods operate on the object's data (self), keeping data and behavior together. +# Inheritance – Methods are inherited by derived classes, reducing code duplication. +# Direct access to object state – Methods can access the object's attributes and other methods through self. diff --git a/Perp-exercises/mypy-exercise2.py b/Perp-exercises/mypy-exercise2.py new file mode 100644 index 000000000..2f92d7ae2 --- /dev/null +++ b/Perp-exercises/mypy-exercise2.py @@ -0,0 +1,34 @@ +def open_account(balances: dict[str, int], name: str, amount: int) -> None: + balances[name] = amount + + +def sum_balances(accounts: dict[str, int]) -> 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: + 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}")