Skip to content

Commit 12a76f1

Browse files
committed
allocation task
1 parent 4350f48 commit 12a76f1

1 file changed

Lines changed: 191 additions & 0 deletions

File tree

laptop_allocation.py

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
from dataclasses import dataclass, field
2+
from enum import Enum
3+
from typing import Dict, List
4+
5+
class OperatingSystem(Enum):
6+
MACOS = "macOS"
7+
ARCH = "Arch Linux"
8+
UBUNTU = "Ubuntu"
9+
10+
@dataclass(frozen=True)
11+
class Person:
12+
name: str
13+
age: int
14+
# Sorted in order of preference, most preferred is first.
15+
preferred_operating_system: List[OperatingSystem]
16+
17+
def __hash__(self):
18+
return hash((self.name, self.age))
19+
20+
21+
@dataclass(frozen=True)
22+
class Laptop:
23+
id: int
24+
manufacturer: str
25+
model: str
26+
screen_size_in_inches: float
27+
operating_system: OperatingSystem
28+
29+
def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
30+
if len(people) > len(laptops):
31+
raise Exception("Sorry, there are not enough laptops.")
32+
alloc_dict = {}
33+
# people with fewer options choose first, because they potentially can generate most sadness
34+
people.sort(key=lambda person: len(person.preferred_operating_system))
35+
for person in people:
36+
for laptop in laptops:
37+
is_match = False
38+
# if it a last chance to get a laptop, it used anyway
39+
if laptops.index(laptop) == len(laptops) - 1:
40+
alloc_dict[person] = laptop
41+
break
42+
for sys in person.preferred_operating_system:
43+
if sys == laptop.operating_system:
44+
alloc_dict[person] = laptop
45+
laptops.pop(laptops.index(laptop))
46+
is_match = True
47+
break
48+
if is_match:
49+
break
50+
return alloc_dict
51+
52+
def calcSadness(person: Person, laptop: Laptop) -> int:
53+
sadness = 0
54+
is_sys_matched = False
55+
for i in range(len(person.preferred_operating_system)):
56+
if person.preferred_operating_system[i] == laptop.operating_system:
57+
is_sys_matched = True
58+
sadness += i
59+
break
60+
if not is_sys_matched:
61+
sadness = 100
62+
return sadness
63+
64+
def print_allocation(alloc_dict: Dict[Person, Laptop]) -> None:
65+
for person in alloc_dict.keys():
66+
print(f"{person.name} gets: {alloc_dict[person].model} with {alloc_dict[person].operating_system.name}.")
67+
68+
def main() -> None:
69+
people_five = [
70+
Person(name="Alice", age=28,
71+
preferred_operating_system=[OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
72+
Person(name="Bob", age=34,
73+
preferred_operating_system=[OperatingSystem.ARCH]),
74+
Person(name="Charlie", age=22,
75+
preferred_operating_system=[OperatingSystem.ARCH, OperatingSystem.UBUNTU, OperatingSystem.MACOS]),
76+
Person( name="Dana", age=41,
77+
preferred_operating_system=[OperatingSystem.MACOS]),
78+
Person(name="Eli", age=25,
79+
preferred_operating_system=[OperatingSystem.ARCH, OperatingSystem.MACOS])
80+
]
81+
laptops_five = [
82+
Laptop(id=1, manufacturer="Apple", model="MacBook Pro 14", screen_size_in_inches=14.2, operating_system=OperatingSystem.MACOS),
83+
Laptop(id=2, manufacturer="Framework", model="Laptop 13", screen_size_in_inches=13.5, operating_system=OperatingSystem.ARCH),
84+
Laptop(id=3, manufacturer="Dell", model="XPS 13 Developer Edition", screen_size_in_inches=13.4, operating_system=OperatingSystem.UBUNTU),
85+
Laptop(id=4, manufacturer="Apple", model="MacBook Air", screen_size_in_inches=13.6, operating_system=OperatingSystem.MACOS),
86+
Laptop(id=5, manufacturer="Lenovo", model="ThinkPad X1 Carbon", screen_size_in_inches=14.0, operating_system=OperatingSystem.ARCH)
87+
]
88+
people_ten = [
89+
Person(name="Alice", age=28,
90+
preferred_operating_system=[OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
91+
Person(name="Bob", age=34,
92+
preferred_operating_system=[OperatingSystem.ARCH]),
93+
Person(name="Charlie", age=22,
94+
preferred_operating_system=[OperatingSystem.ARCH, OperatingSystem.UBUNTU, OperatingSystem.MACOS]),
95+
Person( name="Dana", age=41,
96+
preferred_operating_system=[OperatingSystem.MACOS]),
97+
Person(name="Eli", age=25,
98+
preferred_operating_system=[OperatingSystem.ARCH, OperatingSystem.MACOS]),
99+
Person(name="Fiona", age=30,
100+
preferred_operating_system=[OperatingSystem.UBUNTU, OperatingSystem.ARCH]),
101+
Person(name="George", age=27,
102+
preferred_operating_system=[OperatingSystem.MACOS, OperatingSystem.ARCH]),
103+
Person(name="Hannah", age=29,
104+
preferred_operating_system=[OperatingSystem.ARCH]),
105+
Person(name="Ian", age=38,
106+
preferred_operating_system=[OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
107+
Person(name="Julia", age=24,
108+
preferred_operating_system=[OperatingSystem.ARCH, OperatingSystem.UBUNTU])
109+
]
110+
laptops_ten = [
111+
Laptop(id=1, manufacturer="Apple", model="MacBook Pro 14", screen_size_in_inches=14.2, operating_system=OperatingSystem.MACOS),
112+
Laptop(id=2, manufacturer="Framework", model="Laptop 13", screen_size_in_inches=13.5, operating_system=OperatingSystem.ARCH),
113+
Laptop(id=3, manufacturer="Dell", model="XPS 13 Developer Edition", screen_size_in_inches=13.4, operating_system=OperatingSystem.UBUNTU),
114+
Laptop(id=4, manufacturer="Apple", model="MacBook Air", screen_size_in_inches=13.6, operating_system=OperatingSystem.MACOS),
115+
Laptop(id=5, manufacturer="Lenovo", model="ThinkPad X1 Carbon", screen_size_in_inches=14.0, operating_system=OperatingSystem.ARCH),
116+
Laptop(id=6, manufacturer="System76", model="Lemur Pro", screen_size_in_inches=14.1, operating_system=OperatingSystem.UBUNTU),
117+
Laptop(id=7, manufacturer="Apple", model="MacBook Pro 16", screen_size_in_inches=16.2, operating_system=OperatingSystem.MACOS),
118+
Laptop(id=8, manufacturer="Razer", model="Blade 14", screen_size_in_inches=14.0, operating_system=OperatingSystem.ARCH),
119+
Laptop(id=9, manufacturer="HP", model="Dev One", screen_size_in_inches=14.0, operating_system=OperatingSystem.UBUNTU),
120+
Laptop(id=10, manufacturer="ASUS", model="ROG Zephyrus G14", screen_size_in_inches=14.0, operating_system=OperatingSystem.ARCH)
121+
]
122+
laptops_twenty = [
123+
Laptop(1, "Apple", "MacBook Pro 14", 14.2, OperatingSystem.MACOS),
124+
Laptop(2, "Framework", "Laptop 13", 13.5, OperatingSystem.ARCH),
125+
Laptop(3, "Dell", "XPS 13", 13.4, OperatingSystem.UBUNTU),
126+
Laptop(4, "Apple", "MacBook Air M3", 13.6, OperatingSystem.MACOS),
127+
Laptop(5, "Lenovo", "ThinkPad X1 Carbon", 14.0, OperatingSystem.ARCH),
128+
Laptop(6, "System76", "Lemur Pro", 14.1, OperatingSystem.UBUNTU),
129+
Laptop(7, "Apple", "MacBook Pro 16", 16.2, OperatingSystem.MACOS),
130+
Laptop(8, "Razer", "Blade 14", 14.0, OperatingSystem.ARCH),
131+
Laptop(9, "HP", "Dev One", 14.0, OperatingSystem.UBUNTU),
132+
Laptop(10, "ASUS", "ROG Zephyrus G14", 14.0, OperatingSystem.ARCH),
133+
Laptop(11, "Apple", "MacBook Air M2", 15.3, OperatingSystem.MACOS),
134+
Laptop(12, "Star Labs", "StarBook", 14.0, OperatingSystem.ARCH),
135+
Laptop(13, "Lenovo", "ThinkPad P16", 16.0, OperatingSystem.UBUNTU),
136+
Laptop(14, "Microsoft", "Surface Laptop (Linux Mod)", 13.5, OperatingSystem.ARCH),
137+
Laptop(15, "Apple", "MacBook Pro 13", 13.3, OperatingSystem.MACOS),
138+
Laptop(16, "Framework", "Laptop 16", 16.0, OperatingSystem.ARCH),
139+
Laptop(17, "Dell", "Precision 5570", 15.6, OperatingSystem.UBUNTU),
140+
Laptop(18, "System76", "Pangolin", 15.6, OperatingSystem.UBUNTU),
141+
Laptop(19, "Apple", "MacBook Air", 13.3, OperatingSystem.MACOS),
142+
Laptop(20, "Tuxedo", "InfinityBook Pro", 14.0, OperatingSystem.ARCH)
143+
]
144+
people_twenty = [
145+
Person("Alice", 25, [OperatingSystem.ARCH]),
146+
Person("Bob", 32, [OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
147+
Person("Charlie", 19, [OperatingSystem.ARCH, OperatingSystem.UBUNTU]),
148+
Person("Diana", 45, [OperatingSystem.MACOS]),
149+
Person("Edward", 28, [OperatingSystem.ARCH, OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
150+
Person("Fiona", 31, [OperatingSystem.UBUNTU, OperatingSystem.ARCH]),
151+
Person("George", 27, [OperatingSystem.ARCH]),
152+
Person("Hannah", 22, [OperatingSystem.MACOS, OperatingSystem.ARCH]),
153+
Person("Ian", 35, [OperatingSystem.MACOS]),
154+
Person("Julia", 29, [OperatingSystem.ARCH, OperatingSystem.MACOS]),
155+
Person("Kevin", 24, [OperatingSystem.ARCH]),
156+
Person("Laura", 33, [OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
157+
Person("Mason", 26, [OperatingSystem.ARCH, OperatingSystem.UBUNTU, OperatingSystem.MACOS]),
158+
Person("Nora", 40, [OperatingSystem.MACOS]),
159+
Person("Oliver", 21, [OperatingSystem.ARCH]),
160+
Person("Paige", 30, [OperatingSystem.UBUNTU]),
161+
Person("Quinn", 23, [OperatingSystem.ARCH, OperatingSystem.MACOS]),
162+
Person("Riley", 38, [OperatingSystem.MACOS, OperatingSystem.UBUNTU]),
163+
Person("Sam", 25, [OperatingSystem.ARCH]),
164+
Person("Tina", 29, [OperatingSystem.MACOS, OperatingSystem.ARCH])
165+
]
166+
# inside allocation function .pop() function is used when laptop selected -
167+
# so copy of original list is passed to avoid mutation
168+
result_dict_5 = allocate_laptops(people=people_five, laptops=laptops_five.copy())
169+
result_dict_10 = allocate_laptops(people=people_ten, laptops=laptops_ten.copy())
170+
result_dict_20 = allocate_laptops(people=people_twenty, laptops=laptops_twenty.copy())
171+
print("####################################result for 5 people and 5 laptops#####################################")
172+
print_allocation(alloc_dict=result_dict_5)
173+
sadness_5 = 0
174+
for person in result_dict_5.keys():
175+
sadness_5 += calcSadness(person, result_dict_5[person])
176+
print(f"Total sadness: {sadness_5}")
177+
print("###################################result for 10 people and 10 laptops####################################")
178+
print_allocation(alloc_dict=result_dict_10)
179+
sadness_10 = 0
180+
for person in result_dict_10.keys():
181+
sadness_10 += calcSadness(person, result_dict_10[person])
182+
print(f"Total sadness: {sadness_10}")
183+
print("###################################result for 20 people and 20 laptops####################################")
184+
print_allocation(alloc_dict=result_dict_20)
185+
sadness_20 = 0
186+
for person in result_dict_20.keys():
187+
sadness_20 += calcSadness(person, result_dict_20[person])
188+
print(f"Total sadness: {sadness_20}")
189+
190+
if __name__ == "__main__":
191+
main()

0 commit comments

Comments
 (0)