Skip to content

Commit 84d03a0

Browse files
Implement initial laptop allocation logic and user input handling
1 parent f593c90 commit 84d03a0

1 file changed

Lines changed: 82 additions & 3 deletions

File tree

implement-laptop-allocation/laptop_allocaton.py

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import sys
12
from dataclasses import dataclass
23
from enum import Enum
3-
from typing import List
4+
from typing import List, Dict
45

56
class OperatingSystem(Enum):
67
MACOS = "macOS"
@@ -12,7 +13,7 @@ class Person:
1213
name: str
1314
age: int
1415
# Sorted in order of preference, most preferred is first.
15-
preferred_operating_system: List[OperatingSystem]
16+
preferred_operating_systems: List[OperatingSystem]
1617

1718

1819
@dataclass(frozen=True)
@@ -23,5 +24,83 @@ class Laptop:
2324
screen_size_in_inches: float
2425
operating_system: OperatingSystem
2526

27+
# In the prep, there was an exercise around finding possible laptops for a group of people.
2628

27-
def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
29+
# Your exercise is to extend this to actually allocate laptops to the people.
30+
# Every person should be allocated exactly one laptop.
31+
32+
# If we define “sadness” as the number of places down in someone’s ranking the operating system the ended
33+
# up with (i.e. if your preferences were [UBUNTU, ARCH, MACOS] and you were allocated a MACOS
34+
# machine your sadness would be 2), we want to minimise the total sadness of all people.
35+
# If we allocate someone a laptop with an operating system not in their preferred list,
36+
# treat them as having a sadness of 100.
37+
38+
laptops_list: List[Laptop] = [
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+
Laptop(id=5, manufacturer="Apple", model="MacBook Air", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
44+
Laptop(id=6, manufacturer="Lenovo", model="ThinkPad", screen_size_in_inches=14, operating_system=OperatingSystem.ARCH),
45+
Laptop(id=7, manufacturer="Asus", model="ZenBook", screen_size_in_inches=13, operating_system=OperatingSystem.UBUNTU),
46+
Laptop(id=8, manufacturer="HP", model="Spectre", screen_size_in_inches=14, operating_system=OperatingSystem.MACOS),
47+
Laptop(id=9, manufacturer="Apple", model="MacBook Pro", screen_size_in_inches=16, operating_system=OperatingSystem.MACOS),
48+
]
49+
50+
people: List[Person] = [
51+
Person(name="Imran", age=18, preferred_operating_systems=[OperatingSystem.UBUNTU, OperatingSystem.ARCH]),
52+
Person(name="Eliza", age=34, preferred_operating_systems=[OperatingSystem.ARCH, OperatingSystem.MACOS]),
53+
Person(name="Luke", age=26, preferred_operating_systems=[OperatingSystem.MACOS, OperatingSystem.UBUNTU, OperatingSystem.ARCH]),
54+
Person(name="Abby", age=30, preferred_operating_systems=[OperatingSystem.MACOS]),
55+
Person(name="Ger", age=51, preferred_operating_systems=[OperatingSystem.UBUNTU, OperatingSystem.MACOS]),
56+
]
57+
58+
def user_prompt() -> Person:
59+
try:
60+
# strip() whitespace before processing (no need for str type here as input always returns a string)
61+
name = input("Please enter your first name: ").strip()
62+
if not name.isalpha():
63+
raise ValueError("Name must contain only alphabetic characters.")
64+
65+
# strip() before converting to integer
66+
age = int(input("Please enter your age: ").strip())
67+
minimum_age = 18
68+
if age < minimum_age:
69+
raise ValueError("Age must be 18 or over.")
70+
71+
72+
# define valid OS options
73+
valid_os = [os.value for os in OperatingSystem]
74+
75+
# prompt the user to enter OS preferences in order of preference (no need for str type here)
76+
preferred_os = input(f"Please enter your preferred operating systems in order of preference, separated by commas (e.g., {', '.join(valid_os)}): ").strip()
77+
78+
# split and validate the OS
79+
preferred_os_list = [os.strip() for os in preferred_os.split(",")]
80+
preferred_os_enum = []
81+
for os_name in preferred_os_list:
82+
if os_name not in valid_os:
83+
raise ValueError(f"Invalid operating system: {os_name}")
84+
# convert to enum
85+
preferred_os_enum.append(OperatingSystem(os_name))
86+
87+
return Person(name=name, age=age, preferred_operating_systems=preferred_os_enum)
88+
89+
# throw an error and exit for invalid age and os input
90+
except ValueError as error:
91+
print(f"Invalid input: {error}", file=sys.stderr)
92+
sys.exit(1)
93+
94+
95+
def find_possible_laptops(available_laptops: List[Laptop], current_person: Person) -> List[Laptop]:
96+
return [
97+
laptop for laptop in available_laptops
98+
if laptop.operating_system in current_person.preferred_operating_systems
99+
]
100+
101+
# allocated sequentially, in a first come first served order
102+
def allocate_laptops_sequentially(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
103+
"""
104+
Allocate laptops to people sequentially based on the order in the people list.
105+
This approach respects the 'wait your turn' principle.
106+
"""

0 commit comments

Comments
 (0)