Een combinatieslot is een soort slot waarbij gebruikgemaakt wordt van een reeks getallen om het slot te openen en te sluiten. De getallenreeks kan ingevoerd worden door middel van een reeks onafhankelijk roterende schijven waarin getallen gestanst zijn. Deze schijven sturen rechtstreeks het blokkeringsmechanisme aan, volgens het principe omschreven aan de hand van onderstaande illustraties.
Schrijf een klasse Combinatieslot waarmee objecten kunnen geïnstantieerd worden die een combinatieslot met $$s \in \mathbb{N}_0$$ schijven voorstellen. Elke schijf is gemarkeerd met de opeenvolgende getallen 0, 1, …, $$m$$. Er is juist één combinatie waarop de schijven moeten ingesteld worden om het slot te kunnen openen. De objecten van de klasse Combinatieslot moeten minstens de volgende methoden ondersteunen:
Een initialisatiemethode waaraan een reeks (een lijst of een tuple) natuurlijke getallen moet doorgegeven worden. Deze getallen geven de juiste combinatie aan waarmee het slot kan geopend worden. Het aantal getallen $$s \in \mathbb{N}_0$$ in de reeks correspondeert met het aantal schijven van het combinatieslot. Initieel staat elke schijf van het slot ingesteld op de waarde nul. De initialisatiemethode heeft ook nog een tweede optionele parameter maxwaarde waarmee het grootste getal $$m \in \mathbb{N}_0$$ kan opgegeven worden waarmee de schijven gemarkeerd zijn (standaardwaarde: 9). Het slot moet minstens één schijf hebben, en elk getal van de juiste combinatie moet in het interval [0, $$m$$] gelegen zijn. Indien dit niet het geval is, dan moet de initialisatiemethode een AssertionError opwerpen met de boodschap ongeldige combinatie.
Een methode __repr__ die een stringvoorstelling van het object moet teruggeven in het formaat Combinatieslot(t, maxwaarde=m), waarbij t een tuple is dat de reeks natuurlijke getallen bevat die de juiste combinatie vormen om het slot te openen, en m het grootste getal is waarmee de schijven gemarkeerd zijn.
Een methode __str__ die een stringvoorstelling van het object moet teruggeven. Deze stringvoorstelling bestaat uit de reeks getallen waarop de schijven momenteel ingesteld zijn, van elkaar gescheiden door koppeltekens.
Een methode roteer waarmee één of meer schijven over een gegeven aantal posities kunnen gedraaid worden. Aan deze methode moeten twee argumenten doorgegeven worden: i) de schijven die moeten gedraaid worden, en ii) het aantal posities waarover de schijven moeten gedraaid worden. Schijven worden steeds naar een grotere waarde gedraaid, waarbij na het getal $$m$$ doorgedraaid wordt naar nul. Om aan te geven welke schijven moeten gedraaid worden, worden de schijven van links naar rechts oplopend genummerd vanaf nul. Indien er slechts één schijf moet gedraaid worden, dan wordt het nummer van die schijf (integer) als eerste argument doorgegeven. Indien er meerdere schijven moeten gedraaid worden, dan wordt een collectie (een lijst, tuple of verzameling) met de nummers van de schijven als eerste argument doorgegeven. Indien aan de methode roteer het nummer van een onbestaande schijf wordt doorgegeven, dan moet een AssertionError opgeworpen worden met de boodschap ongeldige schijf. In dat geval mag ook geen enkele van de opgegeven schijven gedraaid worden.
Een methode open die een Booleaanse waarde moet teruggeven, die aangeeft of de schijven al dan niet op de juiste combinatie ingesteld staan waarmee het slot kan geopend worden.
>>> slot = Combinatieslot((9, 2, 4))
>>> slot
Combinatieslot((9, 2, 4), maxwaarde=9)
>>> print(slot)
0-0-0
>>> slot.open()
False
>>> slot.roteer(1, 2)
>>> print(slot)
0-2-0
>>> slot.roteer(2, 5)
>>> print(slot)
0-2-5
>>> slot.open()
False
>>> slot.roteer([2, 0], 9)
>>> print(slot)
9-2-4
>>> slot.open()
True
>>> slot = Combinatieslot([14, 13, 2, 7, 6], maxwaarde=16)
>>> slot
Combinatieslot((14, 13, 2, 7, 6), maxwaarde=16)
>>> print(slot)
0-0-0-0-0
>>> slot.roteer([0, 2, 4], 6)
>>> print(slot)
6-0-6-0-6
>>> slot.roteer([1, 3, 5], 13)
Traceback (most recent call last):
AssertionError: ongeldige schijf
>>> print(slot)
6-0-6-0-6
>>> slot.roteer([1, 3, 2], 13)
>>> print(slot)
6-13-2-13-6
>>> slot.roteer([0, 3], 8)
>>> print(slot)
14-13-2-4-6
>>> slot.open()
False
>>> slot.roteer(3, 3)
>>> print(slot)
14-13-2-7-6
>>> slot.open()
True
>>> slot = Combinatieslot([1, 2, 3, 4, 5], maxwaarde=4)
Traceback (most recent call last):
AssertionError: ongeldige combinatie
>>> slot = Combinatieslot([])
Traceback (most recent call last):
AssertionError: ongeldige combinatie