Skip to content

Commit 6f60796

Browse files
Complete exercises for Module Tools/Sprint 5/Prep - step 8 'enums'
1 parent 61c0a09 commit 6f60796

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

prep-exercises/h_enums.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import sys
2+
from dataclasses import dataclass
3+
from enum import Enum
4+
from typing import List
5+
from collections import Counter
6+
7+
class OperatingSystem(Enum):
8+
MACOS = "macOS"
9+
ARCH = "Arch Linux"
10+
UBUNTU = "Ubuntu"
11+
12+
@dataclass(frozen=True)
13+
class Person:
14+
name: str
15+
age: int
16+
preferred_operating_systems: OperatingSystem
17+
18+
19+
@dataclass(frozen=True)
20+
class Laptop:
21+
id: int
22+
manufacturer: str
23+
model: str
24+
screen_size_in_inches: float
25+
operating_system: OperatingSystem
26+
27+
def find_possible_laptops(available_laptops: List[Laptop], current_person: Person) -> List[Laptop]:
28+
return [
29+
laptop for laptop in available_laptops
30+
if laptop.operating_system == current_person.preferred_operating_systems
31+
]
32+
33+
laptops = [
34+
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
35+
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
36+
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
37+
Laptop(id=4, manufacturer="Apple", model="MacBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
38+
Laptop(id=5, manufacturer="Apple", model="MacBook Air", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
39+
Laptop(id=6, manufacturer="Lenovo", model="ThinkPad", screen_size_in_inches=14, operating_system=OperatingSystem.ARCH),
40+
Laptop(id=7, manufacturer="Asus", model="ZenBook", screen_size_in_inches=13, operating_system=OperatingSystem.UBUNTU),
41+
Laptop(id=8, manufacturer="HP", model="Spectre", screen_size_in_inches=14, operating_system=OperatingSystem.MACOS),
42+
Laptop(id=9, manufacturer="Apple", model="MacBook Pro", screen_size_in_inches=16, operating_system=OperatingSystem.MACOS),
43+
]
44+
45+
# ------------------------
46+
# Exercise 1
47+
# ------------------------
48+
# Write a program which:
49+
# - Already has a list of Laptops that a library has to lend out.
50+
# - Accepts user input to create a new Person - it should use the input function to read a person’s name, age,
51+
# and preferred operating system.
52+
# - Tells the user how many laptops the library has that have that operating system.
53+
# - If there is an operating system that has more laptops available, tells the user that if they’re willing
54+
# to accept that operating system they’re more likely to get a laptop.
55+
# You should convert the age and preferred operating system input from the user into more constrained types as quickly
56+
# as possible, and should output errors to stderr and terminate the program with a non-zero exit code if the
57+
# user input bad values.
58+
59+
def user_prompt() -> Person:
60+
try:
61+
name = str(input("Please enter your first name: "))
62+
if not name.isalpha():
63+
raise ValueError("Name must contain only alphabetic characters.")
64+
65+
age = int(input("Please enter your age: "))
66+
if age <= 0:
67+
raise ValueError("Age must be positive.")
68+
69+
# define valid OS options
70+
valid_os = [os.value for os in OperatingSystem]
71+
72+
# dynamically display the os options
73+
preferred_os = input(f"Please enter correct operating system name, either {', '.join(valid_os)}: ").strip()
74+
75+
# validate the OS
76+
if preferred_os not in valid_os:
77+
raise ValueError("Invalid operating system.")
78+
79+
# convert to enum
80+
preferred_os_enum = OperatingSystem(preferred_os)
81+
82+
return Person(name=name, age=age, preferred_operating_systems=preferred_os_enum)
83+
84+
# throw an error and exit for invalid age and os input
85+
except ValueError as error:
86+
print(f"Invalid input: {error}", file=sys.stderr)
87+
sys.exit(1)
88+
89+
90+
91+
def main() -> None:
92+
93+
user_details = user_prompt()
94+
95+
matching_laptops = find_possible_laptops(laptops, user_details)
96+
97+
# get the counts of the laptops for an OS e.g. os_counts = {OperatingSystem.MACOS: 4,OperatingSystem.ARCH: 2,OperatingSystem.UBUNTU: 3}
98+
os_counts = Counter(laptop.operating_system for laptop in laptops)
99+
100+
print(f"{user_details.name}, there are {len(matching_laptops)} laptops available with your preferred operating system ({user_details.preferred_operating_systems.value}).")
101+
102+
if matching_laptops:
103+
print("Matching laptops:")
104+
for laptop in matching_laptops:
105+
print(f"- {laptop.manufacturer} {laptop.model} ({laptop.screen_size_in_inches}\" screen)")
106+
else:
107+
print("No laptops available with your preferred operating system.")
108+
109+
# get the count of laptops for users preferred OS
110+
user_os_count = os_counts[user_details.preferred_operating_systems]
111+
112+
# find the OSes with more laptops available
113+
alternative_os = [(os, count) for os, count in os_counts.items() if count > user_os_count]
114+
115+
if alternative_os:
116+
print("However, there are more laptops available with the following operating systems:")
117+
for os, count in alternative_os:
118+
print(f"- {os.value}: {count} laptops")
119+
print("If you consider one of these options, you will have a greater chance of getting a laptop.")
120+
else:
121+
print("Your preferred operating system has the most laptops available.")
122+
123+
if __name__ == "__main__":
124+
main()

0 commit comments

Comments
 (0)