LIACS >Kristian Rietveld >Courses >Programmeermethoden NA, Najaar 2017
headerimg

Banner image by Sebastian Niedlich on Flickr, CC BY-NC-SA 2.0

Programmeermethoden NA 2017
Eerste programmeeropgave: Wortels

De eerste programmeeropgave van het vak Programmeermethoden NA in het najaar van 2017 heet Wortels. Deze opdracht is de Python-versie van de C++ opdracht die wordt gemaakt bij het C++ college Programmeermethoden.

De meest recente versie van deze opdracht (met eventuele aanvullingen en verbeteringen) is altijd te vinden op: http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna2017/opdr1.html. Dit is versie 6sep2017.

Het programma dat voor deze opgave moet worden geschreven probeert te bepalen of iemand geschikt is voor een studie aan de universiteit: er is immers geen loting. Daartoe moeten enkele vragen beantwoord worden; zo moet de kandidaat weten op welke dag hij/zij geboren is. En als je denkt dat x2-1=0 één oplossing in de reële getallen heeft, is een beta-studie misschien niet verstandig.

Om te beginnen moet de gebruiker zijn/haar geboortejaar als geheel getal invoeren, en daarna de geboortemaand, ook als geheel getal. Vervolgens voert hij/zij de geboortedag in, wederom als geheel getal. Het programma berekent dan de leeftijd van de gebruiker op de peildatum (zie hieronder), zowel in aantal jaren als in maanden (bijvoorbeeld: 10 jaar en 3 maanden; 123 maanden); beide worden op het beeldscherm getoond. De leeftijd in maanden wordt op dezelfde manier bepaald als die in jaren, hoeveel maanden zijn er verstreken sinds de geboorte? Merk op dat als je op de 31ste geboren bent, wordt je iedere maand een maand ouder, maar je bent niet zo vaak "maandig" — dat ben je namelijk alleen op iedere 31ste. Jarige en maandige gebruikers worden gefeliciteerd. Aangenomen mag worden dat het programma op de peildatum 25 september 2017 draait (definieër de variabelen boven in het programma; liefhebbers (klik hier voor een voorbeeld) mogen met datetime.date de echte huidige dag opvragen en gebruiken). Let op: het programma moet in principe ook op andere peildata vanaf heden tot 2100 correct werken! Test dit dan ook!

Gebruikers jonger dan 10 jaar (de 10-de verjaardag nog niet gevierd) of ouder dan 100 jaar (dus 101-ste verjaardag aan het vieren of reeds gevierd) worden meteen geweigerd. Er wordt gekeken naar de leeftijd in volledige jaren; 100 jaar en 10 maanden telt dus als 100 jaar oud. Als uit het geboortejaar, respectievelijk maand, direct al duidelijk is dat het met de leeftijd niets gaat worden, moeten de vragen naar maand en/of dag niet worden gesteld; de gebruiker wordt zo snel mogelijk geweigerd en het programma stopt meteen in zulke gevallen. Maar soms biedt pas de dag uitsluitsel!

Nu moet de gebruiker zijn/haar geboortedag (zondag, maandag, ..., zaterdag) weten. Het antwoord moet met één letter (de eerste letter van de dag; geen cijfer dus) worden gegeven, bijvoorbeeld w voor woensdag. In het geval van d/z wordt nog om de tweede letter gevraagd.
Daarna wordt de eigenlijke geboortedag berekend om het antwoord van de gebruiker te controleren. Als deze fout is, wordt men meteen "verwijderd", en stopt het programma. Het resultaat van deze berekening hoeft dus niet geprint te worden (maar kan wel handig zijn bij het testen)!
Het is niet de bedoeling om methoden uit de time en datetime modules te gebruiken om deze dag uit te rekenen. Het programma moet een berekening bevatten om deze dag te bepalen! Gebruik bijvoorbeeld dat 1 januari 1901 op een dinsdag viel. Gebruik niet het Doomsday algoritme (zie ook hier). Voor de periode 1901–2099 geldt dat een jaar een schrikkeljaar is precies dan als het jaartal door 4 deelbaar is.

De echte test bestaat uit enkele vragen. Mensen van 30 jaar of ouder worden bij iedere vraag met "u" aangesproken, jongeren met "je/jij". Dit hoeft dus nog niet te worden gedaan bij de vragen omtrent de geboortedatum en geboortedag. Splits de Python-code in het programma niet onnodig vaak!

Er wordt gekeken of de aanstaande student de abc-formule beheerst. Wiskundig inzicht is namelijk vereist voor een beta-studie. Mocht dat niet zo zijn, wordt er getest hoe het met de kunst- of literatuurkennis staat.

Een kwadratische vergelijking heeft 0, 1 of 2 reële oplossingen, die we kunnen vinden met behulp van de abc-formule. Het programma genereert een willekeurige kwadratische vergelijking van de vorm a x2 + b x + c = 0 en toont deze "netjes" op het scherm (de exponent mag er uit zien als x^2). Hierbij geldt dat a, b en c gehele getallen zijn (in absolute waarde maximaal 1000000), waarbij a groter dan 0 is. De student wordt gevraagd hoeveel reële oplossingen zij/hij denkt dat deze vergelijking heeft: 0, 1 of 2.
In alle gevallen worden de oplossingen van de vergelijking (als die er zijn) op het scherm afgedrukt, dus ook als de gebruiker het antwoord fout heeft. En let op: dit is dus niet alleen hoeveel unieke oplossingen er zijn, maar ook de oplossingen zelf! Liefhebbers mogen met complexe getallen werken.

Is het antwoord goed, dan wordt de kandidaat tot een exacte studie toegelaten, en stopt het programma. Anders wordt een meerkeuzevraag (Aa/Bb/Cc/Dd) over kunst of literatuur gesteld, die uitsluitsel biedt over de toelating tot een alpha-studie. Als het daar ook mis gaat, is men helaas niet geschikt voor een universitaire studie. Gebruikers tot en met 30 jaar krijgen hier een andere vraag dan de oudere gebruikers — maar bij beiden is "hetzelfde" antwoord, bijvoorbeeld steeds B, goed. Zorg ervoor dat zowel hoofdletters als kleine letters als antwoorden worden geaccepteerd.

Voor a, b en c moeten variabelen van type int worden gebruikt. Voor het fabriceren van willekeurige gehele getallen moet gebruik worden gemaakt van de random-generator module in Python. Gebruik bijvoorbeeld x = random.randint(0, 199) om een "willekeurig" getal tussen 0 en 199 (grenzen inbegrepen) in de variabele x te krijgen. Zet bovenaan het programma import random om de random-generator te importeren en eenmalig te initialiseren (dit gebeurt met de huidige tijd van de dag). Voor worteltrekken kan y = math.sqrt(x) worden gebruikt; hiervoor moet bovenaan het programma import math worden geplaatst.

Opmerkingen

Als de gebruiker een niet bestaande maand invoert, bijvoorbeeld −8, of een jaartal als 4242 (in de toekomst dus), stopt het programma met de mededeling dat dit niet kan (gebruik sys.exit(1) en zet bovenaan het programma import sys). Evenzo voor een niet bestaande dag, bijvoorbeeld 31 april of 42 december. We nemen aan dat de gebruiker zo vriendelijk is verder geen fouten te maken bij het invoeren van gegevens: hij/zij voert niet al te gekke getallen of letters in, etcetera. Vanzelfsprekend worden hem/haar wel duidelijke vragen gepresenteerd.

Elk programma moet bij het "runnen" aan het begin op het beeldscherm laten zien wie de makers zijn, wat hun jaar van aankomst, studierichting en studentnummer is, welke opgave het is, wat de gebruiker te wachten en te doen staat, de datum waarop het programma gemaakt is, enzovoorts. Dit noemen we het infoblokje en deze informatie is bestemd voor de gebruikers van het programma. Probeer dit er netjes uit te laten zien. Maak geen al te complexe kaders eromheen; gebruik liefst alleen de eerste 128 gewone ASCII karakters.
Bovenaan het programma (in de Python-code dus) dient commentaar over het programma te staan, special bestemd voor andere programmeurs (en nakijkers). Bijvoorbeeld kort wat het programma doet, de datum waarop het programma voor het laatst is gewijzigd, welke interpreterversie gebruikt is en het besturingssysteem waarop het programma is getest; gebruikers van het programma vinden dat niet interessant.
Denk aan het gebruik van lege regels, inspringen, commentaar, enzovoorts. Lees ook eens over richtlijnen bij het maken van programmeeropgaven, en bestudeer de huisregels. Er hoeft geen gebruik van functies, lijsten, het while- en for-statement gemaakt te worden. Alleen de module random mag en moet gebruikt worden — en eventueel sys en datetime om de echte huidige dag op te vragen. Ruwe indicatie voor de lengte van het Python-programma inclusief commentaar, witregels, infoblokje: 200 tot 300 regels.

Uiterste inleverdatum: maandag(!) 25 september 2017, 13:00 uur.
Manier van inleveren (één exemplaar per koppel, dat — ter herinnering — uit twee personen bestaat):

  1. Digitaal zowel de Python-code (.py-bestand) als het verslag (in PDF-formaat) inleveren via BlackBoard. Onder "Content / Course Documents" vind je een onderdeel "Opdracht 1". Geef de bestanden bij voorkeur de namen XXXXXXX-YYYYYYY-opdr1.py en XXXXXXX-YYYYYYY-opdr1.pdf met op de plekken van XXXXXXX en YYYYYYY de studentnummers van de makers ingevuld. De laatst voor de deadline ingeleverde versie wordt nagekeken.
  2. En ook een papieren versie van het verslag (inclusief de Python-code) deponeren in de speciaal daarvoor bestemde doos "Programmeermethoden NA (Python)" in de postkamer van Informatica, kamer 156 van het Snellius-gebouw.
    Overal duidelijk datum en namen van de twee makers vermelden, in het bijzonder als commentaar in de eerste regels van de Python-code. Lees bij het derde werkcollege hoe het verslag eruit moet zien. Zijn spaties/tabs goed verwerkt?
Te gebruiken interpreter: Python 2.7. Het programma moet in principe zowel op een Linux-machine, als onder Mac en Windows draaien. Normering: (consequente) layout 2; commentaar 2; infoblokje 1; verslag 1; werking 4.