Skip to content

Commit 0e56f0b

Browse files
committed
laptop task function
1 parent b5089a2 commit 0e56f0b

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

laptop task/laptop.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
from dataclasses import dataclass
2+
from enum import Enum
3+
from typing import List, Dict
4+
import sys
5+
6+
class OperatingSystem(Enum):
7+
MACOS = "macOS"
8+
ARCH = "Arch Linux"
9+
UBUNTU = "Ubuntu"
10+
11+
12+
@dataclass(frozen=True)
13+
class Person:
14+
name: str
15+
age: int
16+
# Sorted in order of preference, most preferred is first.
17+
preferred_operating_system: List[OperatingSystem]
18+
19+
20+
@dataclass(frozen=True)
21+
class Laptop:
22+
id: int
23+
manufacturer: str
24+
model: str
25+
screen_size_in_inches: float
26+
operating_system: OperatingSystem
27+
28+
29+
#add new person with preferences
30+
def create_a_new_person() -> Person:
31+
add_name = input("What is your name? \n").title()
32+
if not add_name or add_name == "" or len(add_name) > 50:
33+
print("Enter a valid name.", file=sys.stderr)
34+
sys.exit(1)
35+
36+
add_age = int(input("What is your age? \n"))
37+
if add_age < 0 or add_age > 100:
38+
print("Enter a valid age.", file=sys.stderr)
39+
sys.exit(1)
40+
41+
#get strings to rank
42+
print("Select your 3 favourite operating systems. Type 'macOS', 'Arch Linux' or 'Ubuntu'.")
43+
os1_str = input("What is your fav os?: \n")
44+
os2_str = input("What is your second fav os?: \n")
45+
os3_str = input("What is your third fav os?: \n")
46+
47+
#chamnge here to enums by using constructor from enums os
48+
# choice1 = OperatingSystem(os1_str)
49+
# choice2 = OperatingSystem(os2_str)
50+
# choice3 = OperatingSystem(os3_str)
51+
# user_oss_ranked_as_enums = [choice1, choice2, choice3]
52+
# or shorter
53+
#here i have strings converted to enums so can compare
54+
user_oss_ranked_as_enums = [
55+
OperatingSystem(os1_str),
56+
OperatingSystem(os2_str),
57+
OperatingSystem(os3_str)
58+
]
59+
60+
# grab by value of enum str not whole obj like compared in logic[0]
61+
print(
62+
f"Hi {add_name}, your choices were saved and your favourite os is {user_oss_ranked_as_enums[0].value}")
63+
64+
return Person(name=add_name, age=add_age, preferred_operating_system=user_oss_ranked_as_enums)
65+
66+
67+
laptops = [
68+
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
69+
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
70+
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
71+
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
72+
]
73+
74+
#here i need to refactor i was changing logic from coursework
75+
#return laptop obj and happiness value
76+
def link_laptops_and_happiness(laptops: List[Laptop], person: Person):
77+
78+
for laptop in laptops:
79+
#to comapre to if selected fav sanes 0 = first choice
80+
if laptop.operating_system == person.preferred_operating_system[0]:
81+
return laptop, 0
82+
83+
for laptop in laptops:
84+
if laptop.operating_system == person.preferred_operating_system[1]:
85+
return laptop, 1
86+
87+
for laptop in laptops:
88+
if laptop.operating_system == person.preferred_operating_system[2]:
89+
return laptop, 2
90+
91+
#in case laptop not on list
92+
non_existent_laptop = Laptop(
93+
id=100,
94+
manufacturer="Does not exist",
95+
model="no laptop",
96+
screen_size_in_inches=0.0,
97+
operating_system=OperatingSystem.MACOS
98+
)
99+
return non_existent_laptop, 100
100+
101+
#this is to sort people
102+
def compare_count_of_choices_and_os(person: Person, available_laptops: List[Laptop]) -> int:
103+
#from enum for fav
104+
fav = person.preferred_operating_system[0]
105+
106+
count_of_available = 0
107+
for laptop in available_laptops:
108+
if laptop.operating_system == fav:
109+
count_of_available += 1
110+
111+
return count_of_available
112+
113+
114+
def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
115+
print(f"Welcome to the laptop allocator")
116+
117+
#store final
118+
students_with_laptops_assigned = {}
119+
available_laptops = list(laptops)
120+
121+
#minimise unhappiness so ones with least available laptops go first
122+
people.sort(key=lambda p: compare_count_of_choices_and_os(p, available_laptops))
123+
124+
for person_being_checked in people:
125+
126+
laptop, sadness = link_laptops_and_happiness(available_laptops, person_being_checked)
127+
#non listed os
128+
if laptop.id !=100:
129+
students_with_laptops_assigned[person_being_checked] = laptop
130+
#remove from available to allocate
131+
available_laptops.remove(laptop)
132+
print(f"Allocated {laptop.model} to {person_being_checked.name} with a sadness score of {sadness}.")
133+
else:
134+
#if no laptop on list give them popped one
135+
remaining = available_laptops.pop(0)
136+
students_with_laptops_assigned[person_being_checked] = remaining
137+
print(f"Allocated non-matching {remaining.model} to {person_being_checked.name} with a sadness score of 100)")
138+
139+
return students_with_laptops_assigned
140+
141+
142+
143+
def main():
144+
# add people
145+
people = []
146+
for i in range(4):
147+
people.append(create_a_new_person())
148+
149+
final_dict = allocate_laptops(people, laptops)
150+
151+
print("All people have been assigned laptops.")
152+
153+
main()

0 commit comments

Comments
 (0)