ooad1-4 Exercise 3: A Rule Multiplicity Cannot Say ===================================================== Constraint, in words: "At any time, a bike has at most one repair job whose status is 'in progress'. A bike may have any number of finished jobs." ex3.py (Python 3.14): import unittest from dataclasses import dataclass, field @dataclass class RepairJob: bike: "Bike" status: str = "in progress" # in progress | finished @dataclass class Bike: description: str jobs: list[RepairJob] = field(default_factory=list) # Bike "1" -- "0..*" RepairJob def open_job(self) -> RepairJob: """The rule the diagram cannot show: at most ONE job in progress per bike.""" in_progress = [j for j in self.jobs if j.status == "in progress"] if in_progress: raise ValueError("this bike already has a job in progress") job = RepairJob(self) self.jobs.append(job) return job class Rule(unittest.TestCase): def test_many_jobs_over_time(self): bike = Bike("red road bike") for _ in range(3): bike.open_job().status = "finished" self.assertEqual(len(bike.jobs), 3) # 0..* is satisfied def test_but_only_one_in_progress(self): bike = Bike("red road bike") bike.open_job() with self.assertRaises(ValueError): bike.open_job() def test_a_finished_job_frees_the_bike(self): bike = Bike("red road bike") bike.open_job().status = "finished" bike.open_job() # allowed if __name__ == "__main__": unittest.main(verbosity=2) Run with: py ex3.py Output: test_a_finished_job_frees_the_bike (__main__.Rule.test_a_finished_job_frees_the_bike) ... ok test_but_only_one_in_progress (__main__.Rule.test_but_only_one_in_progress) ... ok test_many_jobs_over_time (__main__.Rule.test_many_jobs_over_time) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK WHY THIS WORKS AS AN ANSWER --------------------------- The diagram says Bike 1 -- 0..* RepairJob, which the first test satisfies (three jobs over time). The constraint is about status at a moment, which no multiplicity can express, so it is stated in words next to the model and enforced where jobs are opened. The second and third tests are the two sides of the rule: refused while one is in progress, allowed again once it is finished.