diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ee425719 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +.venv/ + + + + + + + + + + + + + + + diff --git a/dataclass.py b/dataclass.py new file mode 100644 index 00000000..c55f83d9 --- /dev/null +++ b/dataclass.py @@ -0,0 +1,22 @@ +# This code defines a Person with a name, date of birth, and favorite operating system. +# It also checks if the person is 18 years old or older. + +from dataclasses import dataclass +from datetime import date + +@dataclass(frozen=True) # Makes the object read-only after creation +class Person: + name: str + date_of_birth: date + preferred_operating_system: str + + def is_adult(self) -> bool: + today = date.today() # Get today's date + age = today.year - self.date_of_birth.year # Calculate age + if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): + age -= 1 # Subtract 1 if birthday hasn't happened yet this year + return age >= 18 # True if age is 18 or more + +imran = Person("Imran", date(2010, 6, 10), "Ubuntu") # Create a person +print(imran) # Show person info +print(imran.is_adult()) # Check if Imran is an adult \ No newline at end of file diff --git a/enums.py b/enums.py new file mode 100644 index 00000000..72c05482 --- /dev/null +++ b/enums.py @@ -0,0 +1,83 @@ +# This program asks the user for their name, age, and favorite operating system. +# It then shows laptops that match the person's OS preference. +# If another OS has more laptops available, it gives a suggestion. + +from dataclasses import dataclass +from enum import Enum +from typing import List +import sys + +# Define supported operating systems +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + + @staticmethod + def from_string(value: str): + for os in OperatingSystem: + if os.value.lower() == value.strip().lower(): + return os + raise ValueError(f"Sorry, we don't support that operating system: {value}") + +# Person has a name, age, and favorite operating system +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_system: OperatingSystem + +# Laptop has details including operating system +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: OperatingSystem + +# Find laptops that match the person's preferred OS +def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]: + return [laptop for laptop in laptops if laptop.operating_system == person.preferred_operating_system] + +# Create a list of available 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), + Laptop(id=5, manufacturer="Apple", model="macBook Pro", screen_size_in_inches=15, operating_system=OperatingSystem.MACOS), +] + +try: + name = input("What's your name? ").strip() + + age_input = input("How old are you? ").strip() + if not age_input.isdigit(): + raise ValueError("Age must be a number.") + age = int(age_input) + + os_input = input("Which operating system do you like? (Ubuntu, Arch Linux, macOS): ").strip() + preferred_os = OperatingSystem.from_string(os_input) + + # Create the person object from user input + person = Person(name=name, age=age, preferred_operating_system=preferred_os) + +except ValueError as e: + print(f"{e}", file=sys.stderr) + sys.exit(1) # Exit if input is not valid + +# Find matching laptops +matching = find_possible_laptops(laptops, person) +print(f"\nHi {person.name}, we have {len(matching)} laptop(s) with {preferred_os.value}.") + +# Count how many laptops there are for each OS +os_counts = {os: 0 for os in OperatingSystem} +for laptop in laptops: + os_counts[laptop.operating_system] += 1 + +# Suggest other OS if more laptops are available with it +most_available_os = max(os_counts, key=os_counts.get) +if most_available_os != preferred_os and os_counts[most_available_os] > len(matching): + print(f"We have more laptops with {most_available_os.value}.") + print(f"If you're okay with using {most_available_os.value}, you might get one faster.") diff --git a/generic.py b/generic.py new file mode 100644 index 00000000..d6561e2b --- /dev/null +++ b/generic.py @@ -0,0 +1,26 @@ +# This program creates a person with children and prints a simple family tree. + +from dataclasses import dataclass +from typing import List + +# Define a Person with a name, age, and a list of children (who are also Person objects) +@dataclass(frozen=True) +class Person: + name: str + age: int + children: List["Person"] # List of other Person objects + +# Create children +fatma = Person(name="Fatma", age=5, children=[]) +aisha = Person(name="Aisha", age=7, children=[]) + +# Create parent with children +imran = Person(name="Imran", age=35, children=[fatma, aisha]) + +# Print person's name and their children +def print_family_tree(person: Person) -> None: + print(person.name) + for child in person.children: + print(f"- {child.name} ({child.age})") # Print each child's name and age + +print_family_tree(imran) # Show family tree starting from Imran diff --git a/inheritance.py b/inheritance.py new file mode 100644 index 00000000..0901662c --- /dev/null +++ b/inheritance.py @@ -0,0 +1,45 @@ +# This program shows inheritance: a Child class that extends Parent and adds extra features. + +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) # Use Parent's init + self.previous_last_names = [] # Track old 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}" + + +# Create a Child object and test name changes +person1 = Child("Elizaveta", "Alekseeva") +print(person1.get_name()) # Elizaveta Alekseeva +print(person1.get_full_name()) # Elizaveta Alekseeva +person1.change_last_name("Tyurina") +print(person1.get_name()) # Elizaveta Tyurina +print(person1.get_full_name()) # Elizaveta Tyurina (née Alekseeva) + +# Create a Parent object +person2 = Parent("Elizaveta", "Alekseeva") +print(person2.get_name()) # Works: method exists + +# The following lines will cause errors because Parent doesn't have those methods +# print(person2.get_full_name()) # Error: Parent has no get_full_name() +# person2.change_last_name("Tyurina") # Error: Parent has no change_last_name() +# print(person2.get_full_name()) # Error again + +# To fix the errors above, you'd need to check the object type before calling those methods diff --git a/method.py b/method.py new file mode 100644 index 00000000..9112dd7c --- /dev/null +++ b/method.py @@ -0,0 +1,24 @@ +# This program defines a person with name, birthdate, and favorite OS, +# then checks if the person is an adult (18 or older). + +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() # Get today's date + age = today.year - self.date_of_birth.year # Find age by year difference + + # If birthday hasn't come yet this year, subtract 1 from age + if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): + age -= 1 + + return age >= 18 # Return True if 18 or older + +# Create a person named Imran with birthday June 10, 2010 +imran = Person("Imran", date(2010, 6, 10), "Ubuntu") +print(imran.is_adult()) # Check if Imran is an adult (True/False) diff --git a/objectclass.py b/objectclass.py new file mode 100644 index 00000000..8c5f2a9a --- /dev/null +++ b/objectclass.py @@ -0,0 +1,14 @@ +# This program defines a Person with name and age, +# and includes a function to check if they are an adult. + +class Person: + def __init__(self, name: str, age: int): + self.name = name + self.age = age # hair_color is NOT defined here + +def is_adult(person: Person) -> bool: + return person.age >= 18 # Returns True if age is 18 or more + +# This function will cause an error because 'hair_color' doesn't exist +def print_hair_color(person: Person) -> None: + print(person.hair_color) # AttributeError if hair_color not added diff --git a/refactoring.py b/refactoring.py new file mode 100644 index 00000000..231cc95e --- /dev/null +++ b/refactoring.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", "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}") diff --git a/typecheck.py b/typecheck.py new file mode 100644 index 00000000..fb1ddd11 --- /dev/null +++ b/typecheck.py @@ -0,0 +1,32 @@ +from typing import Dict + +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}") + total += pence + return total + +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}")