-
-
Notifications
You must be signed in to change notification settings - Fork 42
London | SDC-Nov-2025| Ikenna Agulobi | Sprint 5| Prep exercise python #312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
97b8bfb
35d41f0
365c6c0
df16e92
de541ce
a65cd79
ddd8aff
87966be
2e3050b
e524c39
611c259
664b191
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # ========== exercise 1 ================================== | ||
| # 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? | ||
|
|
||
| def half(value): | ||
| return value / 2 | ||
|
|
||
| def double(value): | ||
| return value * 2 | ||
|
|
||
| def second(value): | ||
| return value[1] | ||
|
|
||
| print(double("22")) | ||
|
|
||
| # My prediction was that double("22") would print 44. | ||
| # After running the code, I realized it prints "2222" because | ||
| # multiplying a string by an integer in Python repeats the string. | ||
| # | ||
| # What I have learned is that in Python, the * operator behaves | ||
| # differently depending on the data type. For example: | ||
| # - with integers, it performs mathematical multiplication | ||
| # - with strings, it performs string repetition |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # ================= exercise =============================== | ||
| # Read the code and write down what the bug is. How would you fix it? | ||
|
|
||
| def double(number): | ||
| return number * 3 | ||
|
|
||
| print(double(10)) | ||
|
|
||
| # The bug in the code is that the function is named double(), but it multiplies | ||
| # the number by 3 instead of 2. This makes the function behavior inconsistent | ||
| # with its name. | ||
|
|
||
| # To fix this, either: | ||
| # - we need to change the function to return number * 2, or | ||
| # - rename the function to triple() if multiplying by 3 is the intended behavior. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
|
|
||
| def open_account(balances, name, amount): | ||
| balances[name] = amount | ||
|
|
||
| def sum_balances(accounts): | ||
| total = 0 | ||
| for name, pence in accounts.items(): | ||
| print(f"{name} had balance {pence}") | ||
| total += int(pence) | ||
| return total | ||
|
|
||
| def format_pence_as_string(total_pence): | ||
| if total_pence < 100: | ||
| return f"{total_pence}p" | ||
| pounds = int(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}") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| class Person: | ||
| def __init__(self, name: str, age: int, preferred_operating_system: str, address: str): | ||
| self.name = name | ||
| self.age = age | ||
| self.preferred_operating_system = preferred_operating_system | ||
| self.address = address | ||
|
|
||
| imran = Person("Imran", 22, "Ubuntu", "London street") | ||
| print(imran.name) | ||
| print(imran.address) | ||
|
|
||
| eliza = Person("Eliza", 34, "Arch Linux", "Hatfield town") | ||
| print(eliza.name) | ||
| print(eliza.address) | ||
|
|
||
| # ====function to check if imran is an adult=========== | ||
| def is_adult(person: Person) -> bool: | ||
| return person.age >= 18 | ||
|
|
||
| print(is_adult(imran)) | ||
|
|
||
|
|
||
| def address(person: Person) -> str: | ||
| return person.city #city property does not exist | ||
|
|
||
| print(address(imran)) |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you describe the difference and any dis/advantage of using a class method vs a function? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # exercise | ||
| # Change the Person class to take a date of birth (using the standard library’s datetime.date class) and store it in a field instead of age. | ||
| # Update the is_adult method to act the same as before. | ||
|
|
||
|
|
||
| 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): | ||
| today = date.today() | ||
| age = today.year - self.date_of_birth.year | ||
|
|
||
| if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): | ||
| age = age - 1 | ||
|
|
||
| return age >= 18 | ||
|
|
||
| imran = Person("Imran", date(2005, 5, 12), "Ubuntu") | ||
| print(imran.is_adult()) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # ✍️exercise | ||
| # Write a Person class using @datatype which uses a datetime.date for date of birth, rather than an int for age. | ||
| # Re-add the is_adult method to it. | ||
|
|
||
| from dataclasses import dataclass | ||
| from datetime import date | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| date_of_birth: date | ||
| preferred_operating_system: str | ||
|
|
||
|
|
||
| def is_adult(self): | ||
| today = date.today() | ||
| age = today.year - self.date_of_birth.year | ||
|
|
||
| if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): | ||
| age = age - 1 | ||
|
|
||
| return age >= 18 | ||
|
|
||
| imran = Person("Imran", date(2000,5,12), "Ubuntu") | ||
| print(imran) | ||
|
|
||
| imran2 = Person("Imran",date(2000,5,12), "Ubuntu") | ||
| print(imran == imran2) # Prints True |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| from dataclasses import dataclass | ||
| from typing import List | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age: int | ||
| children: List["Person"] | ||
|
|
||
| fatma = Person(name="Fatma", age= 22, children=[]) | ||
| aisha = Person(name="Aisha", age =21, children=[]) | ||
|
|
||
| imran = Person(name="Imran", age = 33, children=[fatma, aisha]) | ||
|
|
||
| def print_family_tree(person: Person) -> None: | ||
| print(person.name) | ||
| for child in person.children: | ||
| print(f"- {child.name} ({child.age})") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this print grandchildren recursively? |
||
|
|
||
| print_family_tree(imran) | ||
| 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: List[Laptop] = [] | ||
| 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}") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| from dataclasses import dataclass | ||
| from enum import Enum | ||
| from typing import List, Dict | ||
| import sys | ||
|
|
||
| class OperatingSystem(Enum): | ||
| MACOS = "macOS" | ||
| ARCH = "Arch Linux" | ||
| UBUNTU = "Ubuntu" | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age: int | ||
| preferred_operating_system: OperatingSystem | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class Laptop: | ||
| id: int | ||
| manufacturer: str | ||
| model: str | ||
| screen_size_in_inches: float | ||
| operating_system: OperatingSystem | ||
|
|
||
| # =====define parse age====== | ||
| def parse_age(raw: str) -> int: | ||
| try: | ||
| age= int(raw) | ||
| except ValueError: | ||
| print("Error: age must be asn integer.", file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| if age <= 0: | ||
| print("Error: age must be a positive integer.", file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| return age | ||
|
|
||
| # =====define parse operating system====== | ||
| def parse_operating_system(raw: str) -> OperatingSystem: | ||
| normalized = raw.strip().lower() | ||
|
|
||
| aliases = { | ||
| "macos": OperatingSystem.MACOS, | ||
| "mac": OperatingSystem.MACOS, | ||
| "arch": OperatingSystem.ARCH, | ||
| "arch linux": OperatingSystem.ARCH, | ||
| "ubuntu": OperatingSystem.UBUNTU, | ||
| } | ||
|
|
||
| if normalized not in aliases: | ||
| valid = ", ".join(sorted(aliases.keys())) | ||
| print(f"Error: invalid operating system. Try one of: {valid}", file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| return aliases[normalized] | ||
|
|
||
|
|
||
| # =======count laptops by os============ | ||
| def count_laptops_by_os(laptops: List[Laptop]) -> Dict[OperatingSystem, int]: | ||
| counts: Dict[OperatingSystem, int] = {os: 0 for os in OperatingSystem} | ||
| for laptop in laptops: | ||
| counts[laptop.operating_system] +=1 | ||
| return counts | ||
|
|
||
|
|
||
| # ======define main ================ | ||
| def main() -> None: | ||
| laptops = [ | ||
| Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13.0, operating_system=OperatingSystem.ARCH), | ||
| Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15.0, operating_system=OperatingSystem.UBUNTU), | ||
| Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15.0, operating_system=OperatingSystem.UBUNTU), | ||
| Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13.0, operating_system=OperatingSystem.MACOS), | ||
| ] | ||
|
|
||
| name = input("Enter your name: ").strip() | ||
| if not name: | ||
| print("Error: name cannot be empty.", file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| age = parse_age(input("Enter your age: ")) | ||
| preferred_os = parse_operating_system(input("preferred OS(Ubuntu / Arch / macOS): ")) | ||
|
|
||
| person = Person(name=name, age=age, preferred_operating_system=preferred_os) | ||
|
|
||
| counts = count_laptops_by_os(laptops) | ||
| preferred_count = counts[person.preferred_operating_system] | ||
|
|
||
| print(f"\nHi {person.name} (age {person.age})") | ||
| print(f"Laptops available with {person.preferred_operating_system.value}: {preferred_count}") | ||
|
|
||
| # Find the OS with maximum availability | ||
| best_os = max(counts, key=lambda os:counts[os]) | ||
| best_count = counts[best_os] | ||
|
|
||
| if best_os != person.preferred_operating_system and best_count > preferred_count: | ||
| print( | ||
| f"If you are willing to accept {best_os.value} instead," | ||
| f"You're more likely to get a laptop. {best_count} available)." | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you have an extra bracket here you dont need |
||
| ) | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # play computer game with the code below and predict what you expect each line will do. Then run the code and check your prediction (If any lines cause errors, you may need to comment them out to check later lines). | ||
|
|
||
| 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: list[str] = [] | ||
|
|
||
| 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()) #works because get_name is inherited from Parent. | ||
| print(person1.get_full_name()) # get_full_name() works, exist in child. | ||
| person1.change_last_name("Tyurina") #change_last_name("Tyurina") works, exist in child.. | ||
| print(person1.get_name()) # works because it comes from Parent.get_name. | ||
| print(person1.get_full_name())# works because it comes from Parent.get_name. | ||
|
|
||
|
|
||
| person2 = Parent("Elizaveta", "Alekseeva") | ||
| print(person2.get_name()) # works because it is in the Parent class. | ||
| print(person1.get_full_name()) | ||
| # print(person2.get_full_name()) # crashes the program as get_full_name is defined only in child | ||
| # person2.change_last_name("Tyurina") # crashes the program as change_last_name is defined only in child not in parent | ||
| print(person2.get_name()) | ||
| # print(person2.get_full_name()) #get_full_name is defined only in child not in parent | ||
|
|
||
|
|
||
| # ===============What I learned from playing computer game with above code. | ||
|
|
||
| # 1. Objects can only call methods they actually have inside them. | ||
| # - Creating a parent object does not automatically give the child its behavior | ||
|
|
||
| # ===================================================================== | ||
| #2. Inheritance is "is-a", not "might-be" i.e | ||
| # A child is a parent(here the child can inherit freely from the father.) | ||
| # A parent is NOT a child(i.e a parent does not inherit from the child) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has this file passed the mypy type checker?