Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
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



@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?



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?

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)}