Card 07/ 08
Practice: Totalling Headcount in an Organisation Chart
Departments hold teams and people; count everyone under one department.
An organisation chart is a natural Composite, and this exercise asks you to build one and compute through it. Engineering has a head, Hal, and two teams. Platform has Eli, Fay and Gus. Product has Chen and Dee, and a Design group with Ana and Ben.
- Name the leaf and the composite.
- Write
PersonandGroupwith a sharedheadcount()method. - What does
headcount()return for Product, and for Engineering? - Where would a rule such as "count contractors as half" belong?
Show a solution
from abc import ABC, abstractmethod
class Unit(ABC):
@abstractmethod
def headcount(self) -> int: ...
class Person(Unit):
def __init__(self, name: str) -> None:
self.name = name
def headcount(self) -> int:
return 1
class Group(Unit):
def __init__(self, name: str, members: list[Unit]) -> None:
self.name = name
self._members = members
def headcount(self) -> int:
return sum(member.headcount() for member in self._members)
design = Group("Design", [Person("Ana"), Person("Ben")])
product = Group("Product", [Person("Chen"), Person("Dee"), design])
platform = Group("Platform", [Person("Eli"), Person("Fay"), Person("Gus")])
engineering = Group("Engineering", [Person("Hal"), platform, product])
for group in (design, product, platform, engineering):
print(f"{group.name}: {group.headcount()}")Design: 2
Product: 4
Platform: 3
Engineering: 8Person is the leaf and Group is the composite. Product returns 4: Chen, Dee, and the two people in Design. Engineering returns 8: Hal, the three in Platform and the four in Product. A common wrong answer for Engineering is 3, the count of its direct members, which is what a loop over _members without recursion would give.
The contractor rule belongs on the leaf: a Contractor leaf returning 0.5, or a field on Person. Group stays unchanged, because it sums whatever its members return.
← → move through sections and cards