|
| 1 | + |
| 2 | +# EXERCISE 1: |
| 3 | +# Write a program which: |
| 4 | + |
| 5 | +# Already has a list of Laptops that a library has to lend out. |
| 6 | +# Accepts user input to create a new Person - it should use the input function to read a person’s name, age, and preferred operating system. |
| 7 | +# Tells the user how many laptops the library has that have that operating system. |
| 8 | +# If there is an operating system that has more laptops available, tells the user that if they’re willing to accept that operating system they’re more likely to get a laptop. |
| 9 | +# You should convert the age and preferred operating system input from the user into more constrained types as quickly as possible, and should output errors to stderr and terminate the program with a non-zero exit code if the user input bad values. |
| 10 | + |
| 11 | +# SOLUTION: |
| 12 | + |
| 13 | +import sys |
| 14 | +from dataclasses import dataclass |
| 15 | +from enum import Enum |
| 16 | +from typing import List |
| 17 | + |
| 18 | +class OperatingSystem(Enum): |
| 19 | + MACOS = "macOS" |
| 20 | + ARCH = "Arch Linux" |
| 21 | + UBUNTU = "Ubuntu" |
| 22 | + |
| 23 | +@dataclass(frozen=True) |
| 24 | +class Person: |
| 25 | + name: str |
| 26 | + age: int |
| 27 | + preferred_operating_system: OperatingSystem |
| 28 | + |
| 29 | +@dataclass(frozen=True) |
| 30 | +class Laptop: |
| 31 | + id: int |
| 32 | + manufacturer: str |
| 33 | + model: str |
| 34 | + screen_size_in_inches: float |
| 35 | + operating_system: OperatingSystem |
| 36 | + |
| 37 | +# Predefined laptops |
| 38 | +laptops = [ |
| 39 | + Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH), |
| 40 | + Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU), |
| 41 | + Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU), |
| 42 | + Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS), |
| 43 | +] |
| 44 | + |
| 45 | +def count_laptops_by_os(laptops: List[Laptop]) -> dict: |
| 46 | + os_count = {os: 0 for os in OperatingSystem} |
| 47 | + for laptop in laptops: |
| 48 | + os_count[laptop.operating_system] += 1 |
| 49 | + return os_count |
| 50 | + |
| 51 | +def main(): |
| 52 | + # --- Input name --- |
| 53 | + name = input("Enter your name: ").strip() |
| 54 | + if not name: |
| 55 | + print("Error: Name cannot be empty.", file=sys.stderr) |
| 56 | + sys.exit(1) |
| 57 | + |
| 58 | + # --- Input age --- |
| 59 | + age_input = input("Enter your age: ").strip() |
| 60 | + try: |
| 61 | + age = int(age_input) |
| 62 | + if age <= 0: |
| 63 | + raise ValueError() |
| 64 | + except ValueError: |
| 65 | + print("Error: Age must be a positive integer.", file=sys.stderr) |
| 66 | + sys.exit(1) |
| 67 | + |
| 68 | + # --- Input preferred OS --- |
| 69 | + print("Choose preferred operating system:") |
| 70 | + for os in OperatingSystem: |
| 71 | + print(f"- {os.value}") |
| 72 | + os_input = input("Enter OS: ").strip() |
| 73 | + |
| 74 | + try: |
| 75 | + preferred_os = OperatingSystem(os_input) |
| 76 | + except ValueError: |
| 77 | + print("Error: Invalid operating system.", file=sys.stderr) |
| 78 | + sys.exit(1) |
| 79 | + |
| 80 | + # --- Create Person --- |
| 81 | + new_person = Person(name=name, age=age, preferred_operating_system=preferred_os) |
| 82 | + |
| 83 | + # --- Count laptops by OS --- |
| 84 | + os_count = count_laptops_by_os(laptops) |
| 85 | + |
| 86 | + # --- Show count for user's preferred OS --- |
| 87 | + count_for_user_os = os_count.get(new_person.preferred_operating_system, 0) |
| 88 | + print(f"There are {count_for_user_os} laptops available with {new_person.preferred_operating_system.value}.") |
| 89 | + |
| 90 | + # --- Find the OS with most laptops --- |
| 91 | + max_os = max(os_count, key=os_count.get) |
| 92 | + max_count = os_count[max_os] |
| 93 | + |
| 94 | + # Suggest alternative if more laptops are available |
| 95 | + if max_os != new_person.preferred_operating_system and max_count > count_for_user_os: |
| 96 | + print(f"Tip: There are more laptops available with {max_os.value} ({max_count} laptops). " |
| 97 | + f"If you're willing to accept that OS, you're more likely to get a laptop.") |
| 98 | + |
| 99 | +if __name__ == "__main__": |
| 100 | + main() |
0 commit comments