Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions laptop Allocation/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python-envs.pythonProjects": []
}
87 changes: 87 additions & 0 deletions laptop Allocation/laptop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from dataclasses import dataclass
from enum import Enum
from typing import Dict, List
import sys
import numpy as np #to build and mnaiplate our sadness grid
from scipy.optimize import linear_sum_assignment #to find optimal laptop allocaation to minimize sadness across all users

class OperatingSystem(Enum):
MACOS = "macOS"
ARCH = "Arch Linux"
UBUNTU = "Ubuntu"

@dataclass(frozen=True)
class Person:
name: str
age: int
# Sorted in order of preference, most preferred is first.
preferred_operating_systems: List[OperatingSystem]


@dataclass(frozen=True)
class Laptop:
id: int
manufacturer: str
model: str
screen_size_in_inches: float
operating_system: OperatingSystem

#library of laptops
laptop = [
Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU),
Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
Laptop(id=5, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
Laptop(id=6, manufacturer="Dell", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH),
Laptop(id=7, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
Laptop(id=8, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS),
]
# Preset dataset of people
people = [
Person(name="Sara", age=31, preferred_operating_systems=[OperatingSystem.ARCH,OperatingSystem.UBUNTU]),
Person(name="Shabs", age=40, preferred_operating_systems=[OperatingSystem.ARCH,OperatingSystem.MACOS,OperatingSystem.UBUNTU]),
Person(name="Jawad", age= 36, preferred_operating_systems=[OperatingSystem.MACOS,OperatingSystem.UBUNTU,OperatingSystem.ARCH]),
Person(name="Mike", age=35, preferred_operating_systems=[OperatingSystem.MACOS,OperatingSystem.ARCH]),
Person(name="Mawra", age=28, preferred_operating_systems=[OperatingSystem.MACOS]),
Person(name="Fatma", age= 22, preferred_operating_systems=[OperatingSystem.UBUNTU,OperatingSystem.ARCH]),
Person(name="Muhib", age= 19, preferred_operating_systems=[OperatingSystem.MACOS,OperatingSystem.UBUNTU]),

]

def sadness(person: Person, laptop: Laptop) -> int:
if laptop.operating_system == person.preferred_operating_systems[0]:
return 0
elif len(person.preferred_operating_systems) > 1 and laptop.operating_system == person.preferred_operating_systems[1]:
return 1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coding the 0,1,2 feels clunky here. If you're explicitly saying that if it's not in the top 3 it's terrible, then that's one thing. But this code looks like a failure to use index to get the ranking of the laptop. Either explicitly have a "maximum rank for any happiness" (as you appear to have here, but don't say) or use and index (making sure it copes with not found correctly)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have Updated the sadness function , its no longer hard‑coded. The score is now calculated using the index of the laptop’s operating system within the person’s preference tuple. Anything outside the top three ranks is treated as a poor match and returns the TERRIBLE_SADNESS .

elif len(person.preferred_operating_systems) > 2 and laptop.operating_system == person.preferred_operating_systems[2]:
return 2
else:
return 100

#I have chose to use Hungarian Algorithm Approach to solve the problem.

def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
n_people = len(people) #length of people []
n_laptops = len(laptops) #length of laptops []
if n_laptops < n_people:
raise ValueError("Not enough laptops to allocate one to each person.")
sadness_matrix = np.zeros((n_people, n_laptops), dtype= int) #npzero mean each cell in 2d grid is a zero and dtype is datatype int so it int 0
for i, person in enumerate(people): #enumerate gives us both index position and the item itself from the list
for j, laptop in enumerate(laptops):
sadness_matrix[i,j] = sadness(person, laptop) #this matrix represents complete laptop allocation
# Hungarian algorithm to run on our sadness matrix
row_indices, col_indices = linear_sum_assignment(sadness_matrix) #which person which laptop
# Map people to laptops
allocation = {}
for i, j in zip(row_indices, col_indices):#it pairs up results (person indices and laptop indices). The loop then uses those pairs to build the final allocation dictionary
allocation[people[i].name] = laptops[j]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've declared the function as Dict[Person,Laptop] but are return Dict[str,Laptop]. I'm guessing you actually want the former?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I did and I fixed it.The discussion around the os behaving as a tuple in our saturday session was helpful here for me

return allocation


def print_allocation(allocation: Dict[Person, Laptop]):
for name, lap in allocation.items():
print(f"{name} gets Laptop {lap.id} ({lap.operating_system.value})")

allocation = allocate_laptops(people, laptop)
print_allocation(allocation)
Loading