Onze maan vertoont zogenaamde schijngestalten, wat wil zeggen dat ze zich gedurende haar omloop rond de aarde in verschillende gedaanten laat zien. Dit fenomeen wordt veroorzaakt door het feit dat de maan vanuit een andere richting door de zon wordt bestraald dan de richting waarin ze wordt waargenomen. Hierdoor lijkt het alsof de terminator (dit is de scheidingslijn van licht en donker) zich over de oppervlakte van de maan verplaatst, waardoor de maan te zien is als een sikkelvormig of rond lichaam. De periode waarin de maan rond de aarde draait wordt over het algemeen onderverdeeld in acht maanfasen: nieuwe maan, jonge maansikkel, eerste kwartier, wassende maan, volle maan, afnemende maan, laatste kwartier en asgrauwe maan. Als je voor een gegeven datum kunt bepalen hoeveel dagen er zijn verstreken sinds de laatste nieuwe maan, dan kan je de corresponderende maanfase bepalen door te kijken in welke achtste deel van de periode van de maanrotatie dit aantal dagen valt (zie onderstaande figuur).

maanfasen
Benamingen van de schijngestalten van de maan, zoals die worden toegepast op het Noordelijk halfrond.

De maan draait in een baan om de aarde met een periode $$p=29.530588853$$ dagen. Als we weten dat er een nieuwe maan voorkwam op 6 januari 2000, dan kunnen we op basis van onderstaande formule het aantal dagen sinds de laatste nieuwe maan bepalen. We noteren dit aantal dagen als $$d_n$$. \[ d_n = d_r - p * \left\lfloor\frac{d_r}{p}\right\rfloor \] Hierbij stelt $$d_r$$ het aantal dagen voor sinds de referentiedatum van 6 januari 2000, en stelt de operator $$\lfloor x\rfloor$$ het geheel deel van het reëel getal $$x$$ voor. Stel dat we bijvoorbeeld de maanfase willen bepalen voor de datum 28/01/2010. Er zijn op deze datum reeds 3675 dagen verstreken sinds 6 januari 2000, waardoor in dit geval $$d_n=13,21$$. Aangezien de waarde van $$d_n$$ in het vierde deel van de achtdelige onderverdeling van de maanperiode valt, correspondeert deze datum dus met de maanfase wassende maan.

Opgave

Schrijf een functie

maanfase([dag][, maand][, jaar])

die de fase van de maan teruggeeft die correspondeert met een opgegeven datum. Aan deze functie moeten de dag, de maand en het jaar van de opgegeven datum als drie afzonderlijke integerargumenten doorgegeven worden. Alle parameters van de functie zijn optioneel, en krijgen als standaardwaarde de dag, de maand en het jaar van vandaag mee. Hierbij moet de datum van vandaag dynamisch bepaald worden, en niet vast ingesteld op bijvoorbeeld de dag waarop je de functie hebt geïmplementeerd. Indien de functie bijvoorbeeld wordt aangeroepen met argumenten die corresponderen met de datum 28 januari 2010, dan moet de string wassende maan als waarde teruggegeven worden. Probeer het aantal en de uitdrukking van de voorwaarden die moeten getest worden om het resultaat van de functie te bepalen zo beknopt mogelijk te houden.

Hint: Bestudeer de module datetime die meegeleverd wordt met The Python Standard Library1. Bekijk in het bijzonder wat je allemaal kan doen met date objecten — die datums voorstellen — en timedelta objecten — die tijdsintervallen voorstellen. Onderstaande demo kan je waarschijnlijk al een deel op weg helpen.

>>> from datetime import date
>>> vandaag = date.today()
>>> type(vandaag)
<type 'datetime.date'>
>>> vandaag.year, vandaag.month, vandaag.day
(2011, 11, 18)
>>> geboortedatum = date(1975, 12, 5)
>>> aantal_dagen = vandaag - geboortedatum
>>> type(aantal_dagen)
<type 'datetime.timedelta'>
>>> aantal_dagen.days
13132
>>> 'Ik ben vandaag {} dagen oud'.format(aantal_dagen.days)
'Ik ben vandaag 13132 dagen oud'

Voorbeeld

>>> from datetime import date
>>> vandaag = date.today()
>>> print(vandaag)
2011-11-02
>>> maanfase(vandaag.day, vandaag.month, vandaag.year)
'jonge maansikkel'
>>> maanfase(2, 11, 2011)
'jonge maansikkel'
>>> maanfase(dag=2, maand=11, jaar=2011)
'jonge maansikkel'
>>> maanfase(jaar=2011, maand=11, dag=2)
'jonge maansikkel'
>>> maanfase(maand=11, dag=2, jaar=2011)
'jonge maansikkel'
>>> maanfase(2, jaar=2011, maand=11)
'jonge maansikkel'
>>> maanfase(maand=8)
'nieuwe maan'
>>> maanfase(maand=2)
'asgrauwe maan'
>>> maanfase(jaar=2020)
'volle maan'
>>> maanfase(28, 1, 2009)
'nieuwe maan'
>>> maanfase(28, 1, 2010)
'wassende maan'
>>> maanfase(28, 1, 2011)
'laatste kwartier'