Skip to content
Open
Show file tree
Hide file tree
Changes from 14 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).
56 changes: 56 additions & 0 deletions implement-laptop-allocation/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from dataclasses import dataclass
from enum import Enum
from typing import List, Dict
from itertools import permutations


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]

Choose a reason for hiding this comment

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

As a general naming tip, if you have something which is a list or an array, give it a plural name. So preferred_operating_systems in this case. Helps the reader understand the use of the code

Copy link
Author

Choose a reason for hiding this comment

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

Done!



@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:
try:
return person.preferred_operating_system.index(laptop.operating_system)
except ValueError:
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]:

best_scenario_assignment = None
best_total_sadness = float("inf")

for scenario in permutations(laptops):

Choose a reason for hiding this comment

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

Wow! OK, if you've got 5 laptops you're looking at 120 possibilities here, that's manageable.
If you've got 10, you're looking at nearly 4 million possibilities. Hey, it's a computer, it will cope.
How many possibilities are you enumerating if you've got 20 laptops?

How else could you do this?

Copy link
Author

Choose a reason for hiding this comment

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

I've used a method with "break" to avoid unnecessary checking if total_sadness is already greater than the best_total_sadness

total_sadness = 0

#find the sadness level for each scenario
for person, laptop in zip(people, scenario):
total_sadness += sadness(person, laptop)

#Check if this is the best scenario so far
if total_sadness < best_total_sadness:
best_total_sadness = total_sadness
best_scenario_assignment = scenario

# Convert best_scenario_assignment into Dict[Person, Laptop]
return {person: laptop for person, laptop in zip(people, best_scenario_assignment)}