-
-
Notifications
You must be signed in to change notification settings - Fork 42
WestMidlands| SDC-NOV-2025| SARA TAHIR | Sprint 5 | Feature/Prep #282
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
eb5b9e2
d937285
7dbbd28
882b78f
6771d14
4e2e07e
77ca2f6
6f00188
2dc539b
2eb49e9
a5faf8b
cfa95d6
7f31e92
842c004
dfc29a8
af120e7
b5b4a6f
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,18 @@ | ||
| 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)) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| from datetime import date | ||
| from dataclasses import dataclass | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| birth_day: date | ||
| preferred_operating_system: str | ||
|
|
||
| def age(self)-> int: #returns age in years | ||
| today = date.today() | ||
| years = today.year - self.birth_day.year | ||
| if(today.month, today.day) < (self.birth_day.month, self.birth_day.day): | ||
| years -= 1 | ||
| return years | ||
|
|
||
| def is_adult(self): | ||
| return self.age() >= 18 | ||
|
|
||
|
|
||
| p1 = Person("Sara", date(1996, 10, 28), "macOS") | ||
| print(p1) | ||
|
|
||
| p2 = Person("Sara", date(1996, 10, 28), "macOS") | ||
| print(p1 == p2) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| def double(n): | ||
| return n*2 | ||
| num = double("22") | ||
| print(num) | ||
|
|
||
| #my prediction is that it would return 2222. As python will treat 22 as a string being a strongly typed language. | ||
| #if it was javascript * operator would have forced numeric converion and 22 string would have become 22 int and 44 would | ||
| #have been returned | ||
| # when I run the file it returns 2222 as expected. | ||
|
|
||
| # 2nd exercise- original function : | ||
| def double(number): | ||
| return number * 3 | ||
|
|
||
| print(double(10)) # returns "30" | ||
|
|
||
| #so we either change the name of the function to triple or multiply number with 2 rather than 3 | ||
| def triple(number): | ||
| return number * 3 | ||
|
|
||
| print(triple(10)) # returns "30" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| from dataclasses import dataclass | ||
| from enum import Enum | ||
| from typing import List | ||
| import sys | ||
|
|
||
|
|
||
| class OperatingSystem(Enum): | ||
| MACOS = "macOS" | ||
| ARCH = "Arch Linux" | ||
| UBUNTU = "Ubuntu" | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age: int | ||
| preferred_os: OperatingSystem | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class Laptop: | ||
| id: int | ||
| manufacturer: str | ||
| model: str | ||
| screen_size_in_inches: float | ||
| operating_system: OperatingSystem | ||
|
|
||
| #library of 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), | ||
| ] | ||
|
|
||
| def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]: | ||
| possible_laptops = [] | ||
| for laptop in laptops: | ||
| if laptop.operating_system == person.preferred_os: | ||
| possible_laptops.append(laptop) | ||
| return possible_laptops # returns an array of possible laptops for the person | ||
|
|
||
| #accept userinput | ||
| name = input("Enter your name: ").strip() | ||
| age_str = input("Enter your age: ").strip() #input always returns a str, we need to convert this to an integer | ||
| os_str = input("Enter your preferred operating system: ").strip() | ||
| # Validate age | ||
| try: | ||
| age = int(age_str) | ||
| except ValueError: | ||
| print("Error: Age must be a number.", file= sys.stderr) | ||
|
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. Nice! Liking the use of stderr here. |
||
| sys.exit(1) | ||
|
|
||
| # Validate OS | ||
| try: | ||
| preferred_os = OperatingSystem(os_str) | ||
| except ValueError: | ||
| print("Error: Invalid operating system.", file=sys.stderr) | ||
| sys.exit(1) | ||
|
|
||
| #Create a person after validation | ||
| person = Person(name = name, age = age, preferred_os =preferred_os) | ||
| #finding laptops for this person | ||
| possible = find_possible_laptops(laptops, person) | ||
| print(f"The laptop library has {len(possible)} with {preferred_os.value}.") | ||
|
|
||
| # Start with an empty dictionary | ||
| os_counts: dict[OperatingSystem, int] = {} | ||
|
|
||
| for laptop in laptops: | ||
| os = laptop.operating_system | ||
| # If we've seen this OS before, add 1, otherwise start at 1 | ||
| if os in os_counts: | ||
| os_counts[os] += 1 | ||
| else: | ||
| os_counts[os] = 1 | ||
|
|
||
| best_os = None | ||
| best_count = -1 | ||
|
|
||
| # Loop through each (key, value) pair | ||
| for pair in os_counts.items(): | ||
| os = pair[0] # the key (operating system) | ||
| count = pair[1] # the value (number of laptops) | ||
|
|
||
| # Check if this count is bigger than the best so far | ||
| if count > best_count: | ||
| best_os = os | ||
| best_count = count | ||
|
|
||
| print("Best OS:", best_os, "with", best_count, "laptops") | ||
| if best_os != preferred_os: | ||
| print(f"If you’re willing to accept {best_os.value}, " | ||
| f"you’re more likely to get a laptop since there are {best_count} available.") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| from dataclasses import dataclass | ||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age : int | ||
| children: list["Person"] #nside the Person class- the Person-type doesnt exist, so we add "" to person, | ||
|
|
||
|
|
||
|
|
||
| Muhib = Person(name="Muhib",age= 7, children=[]) | ||
| Muiz = Person(name="Muiz",age= 4,children=[]) | ||
|
|
||
| Sara = Person(name="Sara",age= 31, children=[Muhib, Muiz]) | ||
|
|
||
| def print_family_tree(person: Person, indent: int = 0) -> None: | ||
| print(" " * indent + f"{person.name} ({person.age})") #indent(int)represents how many spaces to put before the person’s name when printing. | ||
| for child in person.children: | ||
| print_family_tree(child, indent + 2) | ||
|
|
||
| print_family_tree(Sara) | ||
|
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. This is all good. If you want (and only if you want) a stretch objective, make it cope with children who have children and print out a proper tree (so children, grandchildren, great-grandchildren increasingly indented). Definitely an optional task
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. I did it and It introduced me to the concept of recursion. I have never come across them before and really tried understanding it throught the family tree example. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| class Parent: | ||
| """Represents a person with a first and last name.""" | ||
| 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 the full name as 'First Last'.""" | ||
| return f"{self.first_name} {self.last_name}" | ||
|
|
||
|
|
||
| class Child(Parent): | ||
| """Represents a person who can change last names, tracking previous ones.""" | ||
| def __init__(self, first_name: str, last_name: str): | ||
| """Initialize a Child with a first and last name, plus a list of previous last names.""" | ||
| super().__init__(first_name, last_name) | ||
| self.previous_last_names: list[str] = [] | ||
|
|
||
| def change_last_name(self, last_name) -> None: | ||
| """Change the last name and record the previous one.""" | ||
| self.previous_last_names.append(self.last_name) | ||
| self.last_name = last_name | ||
|
|
||
| def get_full_name(self) -> str: | ||
| """Return the full name, with suffix showing original last name if changed.""" | ||
| suffix = "" | ||
| 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()) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| from datetime import date | ||
| class Person: | ||
| def __init__(self, name: str, birth_day: date): | ||
| self.name = name | ||
| self.birth_day = birth_day | ||
|
|
||
| def age(self)-> int: #returns age in years | ||
| today = date.today() | ||
| years = today.year - self.birth_day.year | ||
| if(today.month, today.day) < (self.birth_day.month, self.birth_day.day): | ||
| years -= 1 | ||
| return years | ||
|
|
||
| def is_adult(self): | ||
| return self.age() >= 18 | ||
|
|
||
| def __str__(self) -> str: | ||
| return f"{self.name}, born {self.birth_day}, age {self.age()}" | ||
|
|
||
| p1 = Person("Sara", date(1996, 10, 28)) | ||
| print(p1.is_adult()) # True | ||
|
|
||
| p2 = Person("Muhib", date(2018, 6, 22)) | ||
| print(p2.is_adult()) # False |
| 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 = [] | ||
| 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}") | ||
SaraTahir28 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
|
|
||
| from typing import Dict | ||
| def open_account(balances: Dict[str,int], name:str, amount:int)->None: #dic type str and int--- returns none/figured after running --strict flag with mypy | ||
| #Adding a new account | ||
| balances[name] = amount | ||
|
|
||
| def sum_balances(accounts:Dict[str,int])-> int: #takes type dic[str, int}returns 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: #type int returns type str | ||
| #formatting pence as a string | ||
| sign = "-" if total_pence < 0 else "" | ||
| total_pence = abs(total_pence) | ||
|
|
||
| if total_pence < 100: | ||
|
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. What happens if the account has a negative balance?
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. The function didn’t explicitly handle negative balances. I’ve now updated it so negative values are formatted consistently by applying the minus sign to the final £/p output. |
||
| return f"{sign}{total_pence}p" | ||
| pounds =(total_pence // 100) #floordivision always returns an int | ||
| pence = total_pence % 100 | ||
| return f"{sign}£{pounds}.{pence:02d}" | ||
|
|
||
| balances:Dict[str,int] = { #dic type {str:int} | ||
| "Sima": 700, | ||
| "Linn": 545, | ||
| "Georg": 831, | ||
| } | ||
|
|
||
| open_account(balances,"Tobi", 913) # correct passing of the argumenst to functions with balances. | ||
| open_account(balances,"Olya", 713) | ||
|
|
||
| total_pence = sum_balances(balances) #returntype int | ||
| total_string = format_pence_as_string(total_pence) #returntype str and wrong function name | ||
|
|
||
| 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.
Technically Python is "duck typed" not "strongly typed" - worth googling the difference.
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.
Very interesting the answer that i got is that Python is a strongly typed, dynamically typed language that uses duck typing. I have understood how it can behave in both ways as types can be check at runtime and that behavior matters more than the declared type