generated from CodeYourFuture/Module-Template
-
-
Notifications
You must be signed in to change notification settings - Fork 21
London | 25-SDC-July | Mikiyas Gebremichael | Sprint 4 | Prep exercises #35
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
Open
Mikiyas-STP
wants to merge
13
commits into
CodeYourFuture:main
Choose a base branch
from
Mikiyas-STP:prep_exercises
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
d51f5d4
exercise 1
Mikiyas-STP 591f7d2
exercisetwo type annotation
Mikiyas-STP 8ab46a1
checking with mypy
Mikiyas-STP ad93aba
exercise4 free function vs methods
Mikiyas-STP e2ff6e9
methods
Mikiyas-STP 959803f
exercise5 using @dataclass. Dataclasses simplify the creation of “v…
Mikiyas-STP c1fa81a
the exercise
Mikiyas-STP 037482f
using generic, frozen with data class
Mikiyas-STP 2cac78b
nonrefactored version of the exercise
Mikiyas-STP f6e0e57
refactored and fixes on types
Mikiyas-STP 0fc053a
matching preferences
Mikiyas-STP 9b4bfad
enums and type safe data classes
Mikiyas-STP f113cf1
last exeercise
Mikiyas-STP File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| def double(value): | ||
| return value * 2 | ||
|
|
||
| print(double("22")) | ||
| #Predict what double("22") will do | ||
|
|
||
| #Answer | ||
| #"2222" because "22" will be treated as a string and then the program just duplicates it and return 2222 with a string value | ||
|
|
||
| def double(number): | ||
| return number * 3 | ||
|
|
||
| print(double(10)) | ||
|
|
||
| #find the bug | ||
| #answer | ||
| #This is a logic error instead of giving the double it returns the triple of the number | ||
| #we can improve it by changing 3 by 2 since it doesnt have any type error |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| 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}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| 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) | ||
|
|
||
| #imran.address and eliza.address is not valid attribute | ||
| #error: "Person" has no attribute "address" | ||
|
|
||
|
|
||
| def is_adult(person: Person) -> bool: | ||
| return person.age >= 18 | ||
|
|
||
| print(is_adult(imran)) | ||
| #ok | ||
|
|
||
| def get_city(person: Person) -> str: | ||
| return person.city | ||
| #person has no attribute city. | ||
|
|
||
| #to run mypy mypy ./***.py | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| 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 | ||
|
|
||
| def is_adult(self): | ||
| return self.age >= 18 | ||
|
|
||
| imran = Person("Imran", 22, "Ubuntu") | ||
| print(imran.is_adult()) | ||
|
|
||
| #✍️exercise | ||
| #Think of the advantages of using methods instead of free functions. Write them down in your notebook. | ||
|
|
||
|
|
||
| #answer | ||
| #Reusability | ||
| #Polymorphism – Different subclasses can override the same method name with different behaviour. | ||
|
|
||
|
|
||
| #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. | ||
| 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() | ||
| age = today.year - self.date_of_birth.year | ||
| if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): | ||
| age -= 1 | ||
| return age >= 18 | ||
| #example | ||
| imra = Person("Imra", date(2003, 7, 14), "Ubuntu") | ||
| eliz = Person("Eliz", date(1991, 3, 25), "Arch Linux") | ||
|
|
||
| print(imra.is_adult()) | ||
| print(eliz.is_adult()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| 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) -> bool: | ||
| 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): #if bd havent occured even once this year -1 | ||
| age -= 1 | ||
| return age >= 18 | ||
|
|
||
| #example | ||
| imran = Person("Imran", date(2003, 7, 14), "Ubuntu") | ||
| eliza = Person("Eliza", date(1991, 3, 25), "Arch Linux") | ||
| print(imran) | ||
| print(imran.is_adult()) | ||
| print(eliza.is_adult()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| from dataclasses import dataclass | ||
| from typing import List | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age: int | ||
|
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 solve this in a way that it always prints the current age, rather than hard-coding a specific age? |
||
| children: List["Person"] | ||
|
|
||
| fatma = Person(name="Fatma", age=8, children=[]) | ||
| aisha = Person(name="Aisha", age=6, children=[]) | ||
|
|
||
| imran = Person(name="Imran", age=35, 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) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| 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]: | ||
| # create a set of lowercase preferred names for faster membership checks | ||
| prefs_lower = {os.lower() for os in person.preferred_operating_systems} #turn the string in to lowercase and it stores is on our set called prefs_lower | ||
| possible_laptops: List[Laptop] = [] | ||
| for laptop in laptops: | ||
| if laptop.operating_system.lower() in prefs_lower: | ||
| 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}") | ||
| # now ubuntu and Ubuntu is the same match | ||
| # by basically checking if the lower case version of our text is there we declare it is the same thing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| from dataclasses import dataclass | ||
| from enum import Enum | ||
| from typing import List | ||
| from collections import Counter | ||
| import sys | ||
|
|
||
| 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: float | ||
| operating_system: OperatingSystem | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age: int | ||
| preferred_operating_system: OperatingSystem | ||
|
|
||
| #library’s laptops | ||
| laptops = [ | ||
| Laptop(1, "Dell", "XPS 13", 13, OperatingSystem.ARCH), | ||
| Laptop(2, "Dell", "XPS 15", 15, OperatingSystem.UBUNTU), | ||
| Laptop(3, "Lenovo", "ThinkPad", 14, OperatingSystem.UBUNTU), | ||
| Laptop(4, "Apple", "MacBook Air", 13, OperatingSystem.MACOS), | ||
| ] | ||
| #user input | ||
| name = input("Enter your name: ").strip() | ||
| try: | ||
| age = int(input("Enter your age: ").strip()) | ||
| except ValueError: | ||
| print("Error Age must be a number ", file=sys.stderr) | ||
| sys.exit(1) | ||
| os_input = input("Enter your preferred operating system (macOS / Arch Linux / Ubuntu): ").strip() | ||
| try: | ||
| preferred_os = OperatingSystem(os_input) | ||
| except ValueError: | ||
| print(f"Error '{os_input}' is not a valid operating system.", file=sys.stderr) | ||
| print("Valid options are:", [os.value for os in OperatingSystem], file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| #Processing | ||
| person = Person(name=name, age=age, preferred_operating_system=preferred_os) | ||
| matching_laptops = [l for l in laptops if l.operating_system == person.preferred_operating_system] | ||
|
|
||
| print(f"\n library has {len(matching_laptops)} laptop/s with {preferred_os.value}") | ||
|
|
||
| #suggest an alternative if better availability | ||
| os_counts = Counter([l.operating_system for l in laptops]) | ||
| most_common_os, most_common_count = os_counts.most_common(1)[0] | ||
|
|
||
| if most_common_os != preferred_os and most_common_count > len(matching_laptops): | ||
| print(f"💡 There are more laptops with {most_common_os.value}.") | ||
| print(f"If you’re willing to use {most_common_os.value}, you’re more likely to get one.") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| 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 = [] | ||
|
|
||
| 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()) | ||
| 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()) | ||
| #print(person2.get_full_name()) | ||
| #person2.change_last_name("Tyurina") | ||
| print(person2.get_name()) | ||
| #print(person2.get_full_name()) | ||
|
|
||
|
|
||
| #without commenting the three lines the output was like thiss | ||
| #Elizaveta Alekseeva | ||
| #Elizaveta Alekseeva | ||
| #Elizaveta Tyurina | ||
| #Elizaveta Alekseeva | ||
| #Elizaveta Tyurina (née Alekseeva) | ||
| #Traceback (most recent call last): | ||
| # File "/Users/Module-Decomposition/prep_exercises/exercise9inheritance.py", line 34, in <module> | ||
| # print(person2.get_full_name()) | ||
| #AttributeError: 'Parent' object has no attribute 'get_full_name' | ||
|
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 explain what this error means? |
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Could you suggest a change that would fix this error?