De Duitse fysicus Jörg Pretz van de universiteit van Aken ontwierp een binaire klok met 15 lampen die in de vorm van een driehoek worden gerangschikt.
Deze klok moet op de volgende manier gelezen worden:
De klok hierboven geeft dus het volgende tijdstip aan: \[ 6\ \textrm{uur} + (2 \times 2\ \textrm{uur}) + (2 \times 30\ \textrm{minuten}) + (3 \times 1\ \textrm{minuut}) = 11\!:\!03 \] Het feit dat de lampen een rode kleur hebben, geeft aan dat het namiddag is, ofwel 23:03 op een 24-uursklok. Om 11:03 in de voormiddag zouden dezelfde lampen aan staan, maar ze zouden dan een groene kleur hebben. Hieronder staan nog enkele voorbeelden:
De tijdsduur die aan elke lamp wordt toegekend, is gelijk aan de totale tijdsduur van alle lampen samen op de rij eronder mocht er aan die rij een extra lamp toegevoegd worden. Op elke rij lichten de lampen van links naar rechts op, waardoor een rij met $$n$$ lampen in totaal $$n + 1$$ verschillende toestanden kan weergeven (van alle lampen uit tot alle lampen aan). Het aantal verschillende toestanden dat kan weergegeven worden door een driehoekige rangschikking van lampen met $$n$$ lampen op de onderste rij is dan \[ (n + 1) \times ((n - 1) + 1) \times ((n - 2) + 1) \times \cdots \times (1 + 1) = (n + 1)! \] Het is met andere woorden de faculteit van een natuurlijk getal, en door een gelukkig toeval is het aantal minuten in 12 uur zo een faculteit ($$12 \times 60 = 720 = 6!$$). In zijn artikel zegt Jörg Pretz hierover het volgende:
Het hele concept van de klok werkt dus enkel en alleen maar omdat onze tijdsrekening gebaseerd is op een zestigdelig stelsel dat teruggaat op de Babyloniërs, en niet op een tiendelig stelsel zoals voorgesteld ten tijde van de Franse Revolutie.
Er zit echter een klein foutje in het ontwerp van de klok: als alle lampen uit staan, dan zegt de klok niet of het middernacht (00:00) of twaalf uur 's middags (12:00) is. Technisch gezien beschouwen we 00:00 als de eerste minuut van de voormiddag (nul lampen groen opgelicht op elke rij) en 12:00 als de eerste minuut van de namiddag (nul lampen rood opgelicht op elke rij).
Definieer een klasse Klok die toelaat om driehoekige klokken voor te stellen in Python. Deze klasse moet minstens de volgende methoden ondersteunen:
Een initialisatiemethode waaraan twee natuurlijke getallen moeten doorgegeven worden die respectievelijk het aantal uren $$u$$ ($$0 \leq u < 24$$) en het aantal minuten $$m$$ ($$0 \leq m < 60$$) op een 24-uursklok aangeven. Als de argumenten geen integers zijn die binnen de opgegeven grenzen liggen, dan moet er een AssertionError opgeworpen worden met de boodschap ongeldig tijdstip.
Een methode verzetUren met een optionele parameter waaraan een getal $$u \in \mathbb{Z}$$ kan doorgegeven worden (standaardwaarde: 1). De methode moet de tijd die wordt aangeduid door de klok het gegeven aantal uren $$u$$ vooruit (als $$u > 0$$) of achteruit (als $$u < 0$$) zetten. Hierbij moet rekening gehouden worden met het feit dat op een 24-uursklok 23 uur gevolgd wordt door 0 uur, en dus ook dat 0 uur voorafgegaan wordt door 23 uur. De methode moet een referentie teruggeven naar het object waarop de methode werd aangeroepen.
Een methode verzetMinuten met een optionele parameter waaraan een getal $$m \in \mathbb{Z}$$ kan doorgegeven worden (standaardwaarde: 1). De methode moet de tijd die wordt aangeduid door de klok het gegeven aantal minuten $$m$$ vooruit (als $$m > 0$$) of achteruit (als $$m < 0$$) zetten. Hierbij moet eventueel naar een volgend/vorig uur gesprongen worden, en moet rekening gehouden worden met het feit dat op een 24-uursklok 23:59 gevolgd wordt door 00:00, en dus ook dat 00:00 voorafgegaan wordt door 23:59. De methode moet een referentie teruggeven naar het object waarop de methode werd aangeroepen.
Een methode lampen waaraan geen argumenten kunnen doorgegeven worden. De methode moet een tuple met twee elementen teruggeven: i) een tuple met vijf natuurlijke getallen die aangeven hoeveel lampen aan staan op elke rij van de driehoekige klok (opgelijst van boven naar onder) en ii) één enkel karakter dat de kleur van de lampen aangeeft: G voor groen of R voor rood.
Een methode __repr__ die een stringvoorstelling van het object teruggeeft. Deze string moet een Python statement bevatten dat aangeeft hoe een object van de klasse Klok moet aangemaakt worden dat is ingesteld op dezelfde tijd die momenteel wordt aangeduid door het object waarop de methode wordt aangeroepen. Bekijk onderstaand voorbeeld om te zien hoe deze stringvoorstelling er precies moet uitzien.
Een methode __str__ die een stringvoorstelling van het object teruggeeft. Deze string moet een grafische voorstelling van de driehoekige klok weergeven. Daarbij wordt elke rij van de klok op een afzonderlijke regel weergegeven. De lampen op een rij worden voorgesteld door één enkel karakter: G voor een lamp die aan staat in de voormiddag, R voor een lamp die aan staat in de namiddag en een punt (.) voor een lamp die uit staat. De karakters van de lampen op dezelfde rij worden telkens van elkaar gescheiden door één enkele spatie, en er worden spaties toegevoegd aan het begin van de regel (behalve de laatste) om een driehoekige voorstelling te bekomen. Er staan nooit spaties op het einde van een regel. Bekijk onderstaand voorbeeld om te zien hoe deze stringvoorstelling er precies moet uitzien.
>>> klok = Klok(11, 3)
>>> klok.lampen()
((1, 2, 2, 0, 3), 'G')
>>> klok
Klok(11, 3)
>>> print(klok)
G
G G
G G .
. . . .
G G G . .
>>> klok.verzetUren()
Klok(12, 3)
>>> klok.lampen()
((0, 0, 0, 0, 3), 'R')
>>> klok.verzetUren(11)
Klok(23, 3)
>>> klok.lampen()
((1, 2, 2, 0, 3), 'R')
>>> print(klok)
R
R R
R R .
. . . .
R R R . .
>>> klok.verzetMinuten()
Klok(23, 4)
>>> klok.lampen()
((1, 2, 2, 0, 4), 'R')
>>> klok.verzetMinuten(42)
Klok(23, 46)
>>> klok.lampen()
((1, 2, 3, 2, 4), 'R')
>>> print(klok)
R
R R
R R R
R R . .
R R R R .
>>> klok.verzetMinuten(13)
Klok(23, 59)
>>> klok.lampen()
((1, 2, 3, 4, 5), 'R')
>>> print(klok)
R
R R
R R R
R R R R
R R R R R
>>> klok.verzetMinuten()
Klok(0, 0)
>>> klok.lampen()
((0, 0, 0, 0, 0), 'G')
>>> print(klok)
.
. .
. . .
. . . .
. . . . .
>>> klok.verzetUren(10).verzetMinuten(17)
Klok(10, 17)
>>> klok.lampen()
((1, 2, 0, 2, 5), 'G')
>>> print(klok)
G
G G
. . .
G G . .
G G G G G
>>> Klok(42, 42)
Traceback (most recent call last):
AssertionError: ongeldig tijdstip
Speel gerust een beetje met onderstaande interactieve voorstelling van de driehoekige klok.