Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d40d30e
create a dir & README.md file for the new "Implement Laptop Allocatio…
HassanOHOsman Dec 8, 2025
5856dd0
create a .py file too hold the script
HassanOHOsman Dec 8, 2025
a7f4634
add given code
HassanOHOsman Dec 8, 2025
3b84ade
function to allocate laptop for each person
HassanOHOsman Dec 8, 2025
8366a7a
importing from itertools module
HassanOHOsman Dec 8, 2025
78ff572
create a helper function to handle the sadness level logic
HassanOHOsman Dec 8, 2025
18106de
remove helper function psudo code
HassanOHOsman Dec 8, 2025
2405f09
add a return type to helper function
HassanOHOsman Dec 8, 2025
fc69d05
expoloring all scenarios to find the least possible sadness level option
HassanOHOsman Dec 8, 2025
9ffb839
compute sadness level for each scenario
HassanOHOsman Dec 8, 2025
658bbdb
add if condition to find if we're at the best scenario leading to low…
HassanOHOsman Dec 8, 2025
73156dd
adding Dict as import from typing module
HassanOHOsman Dec 8, 2025
f599d9b
convert best_scenario_Assignment to a dictionary {perspn:laptop}
HassanOHOsman Dec 8, 2025
f39df4a
fix buggy code by replacing scenarios with permutations
HassanOHOsman Dec 8, 2025
b6e2e46
Renamed list "preferred_operating_systems" with a plural name for bet…
HassanOHOsman Jan 16, 2026
12da74e
remove the exception handling with a simple if condition to avoid com…
HassanOHOsman Jan 16, 2026
7fc8382
change logic by implementing break once a scenario is already worse t…
HassanOHOsman Jan 16, 2026
cc37f86
Replace current laptop allocation with Hungarian algorithm
HassanOHOsman Jan 18, 2026
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
42 changes: 42 additions & 0 deletions implement-laptop-allocation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
In the prep, there was an exercise around finding possible laptops for a group of people.

Choose a reason for hiding this comment

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

Including the problem statement as a readme really helps me as a reviewer, so I don't have to go and find it. Thanks!


Your exercise is to extend this to actually allocate laptops to the people.

Given these class definitions:

from dataclasses import dataclass
from enum import Enum
from typing import List

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_system: List[OperatingSystem]


@dataclass(frozen=True)
class Laptop:
id: int
manufacturer: str
model: str
screen_size_in_inches: float
operating_system: OperatingSystem
Write a function with this signature:

def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
Every person should be allocated exactly one laptop.

If we define "sadness" as the number of places down in someone's ranking the operating system the ended up with (i.e. if your preferences were [UBUNTU, ARCH, MACOS] and you were allocated a MACOS machine your sadness would be 2), we want to minimise the total sadness of all people. If we allocate someone a laptop with an operating system not in their preferred list, treat them as having a sadness of 100.

Maximum time in hours
3

How to submit
Submit a PR to this repo containing your function (and any supporting code).
113 changes: 113 additions & 0 deletions implement-laptop-allocation/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
from dataclasses import dataclass
from enum import Enum
from typing import List, Dict

from scipy.optimize import linear_sum_assignment



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


def sadness(person: Person, laptop: Laptop) ->int:
if laptop.operating_system in person.preferred_operating_systems:
return person.preferred_operating_systems.index(laptop.operating_system)
return 100

Choose a reason for hiding this comment

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

I like the way you have separated this into a separate function, that's good. However it's bad practice to use exceptions in "normal" code execution, as they are very expensive in terms of processing time. They're great for error handling and have particular strengths there. On the next Saturday session, whether it's me or someone else, ask whoever's running it to talk about when using exceptions is a good or a bad idea, it would be a good discussion for the wider group to take part in.

How would you implement this function without try/except?

Copy link
Author

Choose a reason for hiding this comment

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

A simple if condition could have handled this.



def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:

if len(people) != len(laptops):
raise ValueError("Number of individuals and laptops must be equal")

cost_matrix = [
[sadness(person, laptop) for laptop in laptops]
for person in people
]

person_indices, laptop_indices = linear_sum_assignment(cost_matrix)

return {people[p_idx]: laptops[l_idx]
for p_idx, l_idx in zip(person_indices, laptop_indices)

}





if __name__ == "__main__":
people = [
Person(
name="Alice",
age=30,
preferred_operating_systems=[
OperatingSystem.MACOS,
OperatingSystem.UBUNTU,
],
),
Person(
name="Bob",
age=25,
preferred_operating_systems=[
OperatingSystem.UBUNTU,
OperatingSystem.MACOS,
],
),
Person(
name="Carol",
age=28,
preferred_operating_systems=[
OperatingSystem.ARCH,
OperatingSystem.MACOS,
],
),
]

laptops = [
Laptop(
id=1,
manufacturer="Apple",
model="MacBook Air",
screen_size_in_inches=13.3,
operating_system=OperatingSystem.MACOS,
),
Laptop(
id=2,
manufacturer="Dell",
model="XPS",
screen_size_in_inches=13.0,
operating_system=OperatingSystem.UBUNTU,
),
Laptop(
id=3,
manufacturer="Lenovo",
model="ThinkPad",
screen_size_in_inches=14.0,
operating_system=OperatingSystem.ARCH,
),
]

allocation = allocate_laptops(people, laptops)

for person, laptop in allocation.items():
print(f"{person.name} → {laptop.model} ({laptop.operating_system.value})")