-
-
Notifications
You must be signed in to change notification settings - Fork 105
NW|26-JUI-SDC|Ahmad Hmedan|Sprint 5 |Prep exercises #639
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 1 commit
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,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) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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()) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| 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 main() -> None: | ||
| name: str = input("Name: ") | ||
| age: int = int(input("Age: ")) | ||
|
|
||
| print("""choose an operating system: | ||
| 1.Ubuntu | ||
| 2,Arch Linux | ||
| 3.macOs""") | ||
| choice: int = int(input("Enter Your choice: ")) | ||
| os_map: dict[int, OperatingSystem] = { | ||
| 1: OperatingSystem.UBUNTU, | ||
| 2: OperatingSystem.ARCH, | ||
| 3: OperatingSystem.MACOS, | ||
| } | ||
|
|
||
| preferred_operating_system: OperatingSystem = os_map[choice] | ||
|
|
||
| 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 | ||
| ) | ||
| if person1.preferred_operating_system != most_available_os: | ||
| print("Are you willing to accept ", most_available_os.value, "instead") | ||
|
Contributor
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. If you have a question like this, what is the user expected to do? Is there some way for them to answer the question / change the outcome of the program?
Author
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. Thank you for the feedback, You're right_ the original version asked the question and do not let the user to respond, so it couldn't affect the program's behaviour. I have updated the code so the user can answer Y/N, If they accept the program will assigns them a laptop with the most available OS; otherwise, it keeps their original choice or exit if there is no suitable laptops is available |
||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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(). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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()) |
|
Contributor
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. Good explanations |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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}") |
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.
Is there any input validation here? What is the UX like if something goes wrong?
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.
Thanks for the feedback. I added a loop to validate the user's input. If the user enters an invalid choice, the program displays a message telling them they must enter a number between 1 and 3, then keeps asking until they enter a valid option. I think this provides a better user experience than letting the program continue with invalid input.