NETWERKEN en OBJECTORIËNTATIE

Maat: px
Weergave met pagina beginnen:

Download "NETWERKEN en OBJECTORIËNTATIE"

Transcriptie

1 FACULTEIT INDUSTRIELE INGENIEURSWETENSCHAPPEN! CAMPUS DE NAYER! NETWERKEN en OBJECTORIËNTATIE Deel 2: Objectoriëntatie in Python Joost Vennekens

2

3 Inhoudsopgave 1 Objecten en klassen Een beetje geschiedenis Objecten Klassen Constructoren Magische methodes Wijzigen van attributen Voorbeelden De klasse Drank De klasse Rechthoek De klasse Cirkel Een blik achter de schermen Samenwerkende objecten Een object als argument Een object als resultaat Associaties tussen klassen Lijsten en objecten Objecten met lijsten Lijsten van objecten Objecten met lijsten van objecten Voorbeelden Punten en veelhoeken Cocktails en dranken Overerving Het overschrijven van methodes Overervingshiërarchieën Methodes uit een superklasse oproepen Voorbeelden Vierkanten

4 4 Varia Python als server-side scripting taal Methodes met default argumenten Vergelijken van objecten Nog meer vergelijkingen Uitzonderingen Uitzonderingen opwerpen Uitzonderingen afhandelen Herwerking van het voorbeeld Statische methodes Nog een blik achter de schermen De volledige klasse Cirkel Private variabelen Eigenschappen (Properties) A Practicum opgaves 77 A.1 Setup A.2 Vogelpik A.3 De eerste objectjes A.4 Punten, ruimtes en ballen A.5 Tijd voor actie A.6 Muren A.7 Krachten

5 Objecten en klassen Een beetje geschiedenis Als 1 programmeur op 1 dag 100 lijnen Python code kan schrijven, hoeveel lijnen code schrijft hij dan op 10 dagen? Of, hoeveel code schrijft een team van 10 programmeurs dan op 1 dag? Het is vooral voor IT managers verleidelijk om op deze vragen het antwoord 1000 te geven. De praktijk wijst echter uit dat echte antwoord veel minder is. De verklaring daarvoor ligt in het feit dat lijnen code niet onafhankelijk zijn van elkaar. Als de ene lijn een toekenning x = x * 2 doet, en een paar lijnen erna volgt een test op de waarde van x: i f x > 5: print "wat veel!" dan is de eerste lijn code duidelijk relevant voor de tweede lijn. Met andere woorden, om te kunnen begrijpen wat de tweede lijn juist doet, moeten we ons bewust zijn van het bestaan van de eerste lijn. Een programma van 200 regels is daarom niet gewoon maar dubbel zo complex als een programma van 100 regels, maar veel méér: elke lijn van de 200 regels kan immers potentieel relevant zijn voor elke andere lijn. Er zijn dus mogelijke interacties tussen lijnen code, die allemaal relevant kunnen zijn voor de programmeur, ten opzichte van mogelijke interacties in het kortere programma. De complexiteit van een programma hoe moeilijk het is om dit programma te begrijpen stijgt dus veel sneller dan het aantal lijnen code. Programmeertalen hebben sinds de begindagen van de computer een grote ontwikkeling doorgemaakt. Deze evoluties kunnen best begrepen worden als een voortdurende zoektocht naar manieren om dit fenomeen tegen te gaan. Globaal gesproken is het de bedoeling om grote programma s zoveel mogelijk uiteen te trekken in kleinere stukjes. Als we ons programma van 200 lijnen code kunnen opdelen in twee 5

6 stukken van elk 100 lijnen én we kunnen dit zodanig doen dat we er zeker van zijn dat geen enkele lijn code uit het ene deel relevant is voor het andere deel, dan blijven en slechts mogelijke interacties over, wat een pak minder is dan Maar hoe kunnen we dat nu verwezenlijken? In het begin zocht men vooral zijn heil in het opsplitsen van de grote taak die een programma moest vervullen in kleinere deeltaken. Dit heeft geleid tot het invoeren van functies. De hoop hierbij was dat men een programma zou kunnen begrijpen door al zijn functies te begrijpen, en dat men elke functie afzonderlijk zou kunnen begrijpen. Men dacht, met andere woorden, dat enkel maar lijnen code binnen dezelfde functie relevant zouden zijn voor elkaar, zodat het zou volstaan om een programma op te splitsen in functies die klein genoeg zijn. Als we onze 200 lijnen code opsplitsen in 10 functies van 20 lijnen, dan zijn er maar mogelijke interacties, wat een grootte-orde minder is dan de oorspronkelijke : eureka! Helaas bleek al snel dat dit in de praktijk toch niet zo goed werkte. De reden hiervoor ligt zelfs nogal voor de hand: als we ons programma gaan opsplitsen in deeltaken, dan moeten we deze deeltaken natuurlijk na elkaar uitvoeren. Maar dat betekent dat de invoer van taak 2 natuurlijk de uitvoer van taak 1 zal zijn! En de invoer van taak 20 is de uitvoer van taak 19, wiens invoer de uitvoer van taak 18 was, wiens invoer de uitvoer was van taak 17, wiens invoer.... We zien al snel dat een taak helemaal niet onafhankelijk is van de taken die ervoor kwamen, maar dat ze hier juist heel erg van afhangt. Dit betekent ook dat als we in taak 1 een aanpassing doen, deze aanpassing mogelijk een effect kan hebben op taak 2, en dus ook op taak 3, en dus ook op.... Als we een regel veranderen in taak 1, dan zouden we dus eigenlijk alle andere regels code uit taken 2 t/m 20 terug moeten gaan bekijken, om te zien of we ze ook niet moeten aanpassen. Dat is duidelijk niet wat we willen. In het begin van de jaren 90 is men dan op zoek gegaan naar een alternatief. Merk op dat men hier dus niet gewoon maar op zoek was naar een nieuwe programmeertaal, maar naar een nieuw wereldbeeld. Er was nood aan een andere manier van kijken: een programma moest niet langer gezien worden als een verzameling van taken die konden worden opgesplitst in deeltaken, maar als... iets anders? De grote doorbraak die er dan gekomen is, is dat men beseft heeft dat een oud concept, bedacht door academici in de jaren 60, eigenlijk perfect het antwoord op deze vraag kon geven. Het concept was dat van objectgericht programmeren, en het antwoord is simpelweg: beschouw een programma niet langer als een verzameling van (deel-)taken, maar als een verzameling van samenwerkende objecten. Hoewel dit antwoord dus al bestaat sinds de jaren 60, heeft het tot de jaren 90 geduurd voor men eindelijk de bijhorende vraag bedacht heeft, namelijk: hoe kunnen we onze programma s zodanig structureren dat zoveel mogelijk 6

7 regels code onafhankelijk zijn van elkaar? 1.2 Objecten Om echt te kunnen begrijpen hoe het objectgerichte wereldbeeld ertoe kan leiden dat programma s beter (dwz. met meer onafhankelijkheden) gestructureerd worden, is het nodig om eerst wat dieper in te gaan op de betekenis die de term object in deze context heeft. We doen dit door even versneld de geschiedenis van het programmeren door te maken, aan de hand van een eenvoudig voorbeeld. Een cocktail bestaat uit een aantal ingrediënten die in een specifieke verhouding door elkaar gemengd moeten worden. Een vodka-orange bestaat bijvoorbeeld voor een derde uit vodka, en voor de rest uit fruitsap. Dit betekent dat om een glas van 25cl te vullen met vodka-orange, er 8,3cl vodka nodig is en 16,7cl fruitsap. En als we bijvoorbeeld al 10cl vodka hebben ingeschonken, is er nog 20cl fruitsap nodig. Dergelijke berekeningen worden natuurlijk des te uitdagender, naarmate er meer vodka-oranges geconsumeerd worden. Laten we daarom een computerprogramma maken dat ons kan helpen. verhouding = 1.0 / 3.0 cocktail def vodkavoorcocktail ( cocktail ) : return verhouding * cocktail def fruitsapvoorcocktail ( cocktail ) : return (1 verhouding ) * cocktail # aandeel vodka per eenheid def vodkavoorfruitsap ( fruitsap ) : return fruitsap * ( verhouding / (1 verhouding ) ) def fruitsapvoorvodka ( vodka ) : return vodka * ( ( 1 verhouding ) / verhouding ) Deze functies gebruiken we dan natuurlijk als volgt: >>> vodkavoorcocktail(25) >>> fruitsapvoorvodka(10) In traditionele terminologie hebben we hier gebruik gemaakt van een datastructuur, waarin we de gegevens die we nodig hebben kunnen bijhouden, en daarbij horen een aantal functies, die op basis van deze datastructuur de gewenste uitvoer produceren. Natuurlijk is onze datastructuur hier heel eenvoudig, aangezien hij enkel maar bestaat uit 7

8 de waarde 1/3. Zelfs voor zo n eenvoudige datastructuur zijn er echter tal van alternatieven te bedenken. Bijvoorbeeld, we hadden in plaats van de hoeveelheid vodka per eenheid cocktail, ook de verhouding tussen de hoeveelheid fruitsap en de hoeveelheid vodka kunnen gebruiken. verhouding = 2.0 # eenheden fruitsap per eenheid vodka def vodkavoorfruitsap2 ( fruitsap ) : return fruitsap / verhouding def fruitsapvoorvodka2 ( vodka ) : return verhouding * vodka def vodkavoorcocktail2 ( cocktail ) : return cocktail / ( verhouding + 1) def fruitsapvoorcocktail2 ( cocktail ) : vodka = vodkavoorcocktail2 ( cocktail ) return fruitsapvoorvodka2 ( vodka ) Deze functies berekenen natuurlijk net dezelfde resultaten als voorheen: >>> vodkavoorcocktail2(25) >>> fruitsapvoorvodka2(10) 20.0 Hier zien we een eenvoudige illustratie van een belangrijk fenomeen: als we de voorstelling van onze data veranderen, dan moeten we ook alle functies veranderen die deze data gebruiken. Wat zou er gebeuren als we dit zouden vergeten? Dan zouden we bijvoorbeeld per ongeluk onze oude definitie van de functie fruitsapvoorvodka(vodka) samen kunnen gebruiken met onze nieuwe datavoorstelling verhouding = 2.0. Het is duidelijk dat dit een fout resultaat zal opleveren, en een cocktail die veel te licht is. Historisch weetje: In 1999 verloor de NASA $ toen de Mars Climate Orbiter missie mislukte. De oorzaak van het feit dat deze satelliet opbrandde in de atmosfeer van Mars, zonder ook maar één zinvol resultaat te produceren, was een software-fout: de ene functie dacht dat een bepaald getalletje een waarde in Newton voorstelde, terwijl de andere dacht dat dit een waarde in Pond was. Of het nu gaat om ontploffende satellieten of cocktails die niet straf genoeg zijn, de les is dezelfde: het is gevaarlijk om een datastructuur los te zien van de functies die hem moeten gebruiken. Deze les is meteen de belangrijkste motivatie voor objectgericht programmeren. 8

9 Laat ons, voor we verder gaan, eerst eens een meer realistische versie van ons programma bekijken. Het is natuurlijk een beetje belachelijk dat we code geschreven hebben die enkel maar werkt voor vodka-oranges. Met een kleine beetje extra moeite, zouden we code kunnen schrijven die werkt voor alle cocktails. Hiervoor zullen we natuurlijk onze datastructuur iets ingewikkelder moeten maken, en onze functies daaraan aanpassen. # ingredienten per eenheid cocktail vodkaorange = { vodka : 0.33, fruitsap : 0. 67} def ingredientpercocktail ( cocktail, hoeveelheid, ingredient ) : return hoeveelheid * cocktail [ ingredient ] def ingredientperingredient ( cocktail, hoeveelheid, gegeven, gezocht ) : return hoeveelheid * ( cocktail [ gezocht ]/ cocktail [ gegeven ] ) Als we nu bijvoorbeeld willen weten hoeveel vodka er nodig is voor 20cl fruitsap, doen we: >>> ingredientperingredient(vodkaorange, 20, fruitsap, vodka ) We gebruiken nu als datastructuur een woordenboek (dictionary) en hebben twee functies geschreven die gebruik maken van deze datastructuur. Hier is nu eens een idee: aangezien we toch net besloten hebben dat de functies die een datastructuur gebruiken onafscheidelijk met deze datastructuur verbonden zijn, waarom steken we die functies dan niet gewoon bij in dat woordenboek? In Python kan dit immers perfect: we kunnen met een functie alles doen wat we met bijvoorbeeld een getal of een string kunnen doen. Iets als dit kan bijvoorbeeld perfect: def dubbel ( x ) : return x * 2 print dubbel ( 3 ) functie = dubbel print functie ( 3 ) De toekenning in de voorlaatste lijn geeft de functie dubbel in wezen gewoon een tweede naam, die we zoals de laatste lijn laat zien daarna eveneens kunnen gebruiken om de functie op te roepen. We kunnen dus even goed onze functie nemen en deze bij in de gegevensstructuur van onze cocktail plaatsen. 9

10 def ingredientpercocktail ( cocktail, hoeveelheid, ingredient ) : return hoeveelheid * cocktail [ ingredient ] def ingredientperingredient ( cocktail, hoeveelheid, gegeven, gezocht ) : verhouding = cocktail [ gezocht ] / cocktail [ gegeven ] return hoeveelheid * verhouding vodkaorange = { vodka : 0.33, fruitsap : 0.67, ipc : ingredientpercocktail, ipi : ingredientperingredient } Eender welke bewerking we met onze vodkaorange willen doen, kunnen we nu voor elkaar krijgen door enkel maar naar dit woordenboek te kijken. Het berekenen van een hoeveelheid fruitsap per hoeveelheid vodka, kan nu bijvoorbeeld zo: vodkaorange [ ipi ] ( vodkaorange, 20, fruitsap, vodka ) Hier komen dus zowel de functie die we toepassen als de data waarop we ze toepassen uit hetzelfde woordenboek. Een groot voordeel van deze aanpak is dat gelijk welke datastructuur we nu kiezen om onze gegevens in voor te stellen, we altijd de juiste functies erbij zullen hebben. Veronderstel bijvoorbeeld dat we, in plaats van te zeggen dat een Bloody Mary voor 0.25 uit vodka bestaat en voor 0.75 uit tomatensap (zoals we hierboven deden voor onze vodka-orange), liever zeggen dat hij één deel vodka moet bevatten per 3 delen tomatensap. bloodymary = { vodka : 1. 0, tomatensap : 3. 0} Bij deze voorstelling horen nu natuurlijk andere functies dan bij onze vodka-orange, namelijk: def ingredientpercocktail2 ( cocktail, hoeveelheid, ingredient ) : som = 0 for drank in cocktail : som += cocktail [ drank ] return hoeveelheid * cocktail [ ingredient ] / som (De functie ingredientperingredient mag dezelfde blijven, aangezien de som daar in zowel teller als noemer zou staan.) Deze functie kunnen we nu ook bij in onze bloodymary steken. bloodymary [ ipi ] = ingredientperingredient bloodymary [ ipc ] = ingredientpercocktail2 Nu lopen we dus nooit het risico dat we ons zullen vergissen tussen ingredientpercocktail en ingredientpercocktail2! 10

11 (Opmerking voor de aandachtige lezer: Moest je bovenstaande code effectief proberen uit te voeren, zou je merken dat er nog een fout in dit programma zit. Het is instructief om eens na te denken over hoe we deze fout in het algemeen zouden kunnen vermijden.) Er is nog een tweede voordeel, dat mooi geïllustreerd wordt door volgend fragmentje, dat berekent hoeveel vodka we nodig hebben voor 25cl Vodka-orange en 25cl Bloody Mary samen. cocktails = [ vodkaorange, bloodymary ] vodkanodig = 0 for c in cocktails : vodkanodig += c [ ipc ] ( c, 25, vodka ) Hoewel dat aan dit fragmentje helemaal niet te zien is, zal er hier voor onze twee verschillende cocktails een verschillende functie worden opgeroepen. Bovendien zal dit ook telkens de juiste functie zijn! Het feit dat de twee cocktails achter de schermen een verschillende voorstelling voor hun gegevens gebruiken is nu vanuit het oogpunt van bovenstaand fragmentje niet meer relevant. We hebben hier dus een mooie onafhankelijkheid tussen verschillende delen van onze code kunnen realiseren. Deze manier van werken is nu de essentie van het objectgeöriënteerd programmeren. Met de term object bedoelt men immers niet meer of niet minder dan een gegevensstructuur waar alle functies die nodig zijn om deze gegevensstructuur te manipuleren bij inzitten. Samengevat: een gegevensstructuur wéét iets, een functie kán iets, en een object weet niet alleen iets, maar kan daar ook iets mee. Het voornaamste voordeel van de objectgeöriënteerde manier van werken is encapsulatie. Dit betekent dat, zolang we de gegevens die in een object vervat zitten enkel maar manipuleren door middel van de functies die in het object zitten, we helemaal niet hoeven te weten hoe dit object deze gegevens juist voorstelt. Al deze details zitten immers netjes ingekapseld in het object. Hierdoor kunnen we ook op elk moment de gegevensvoorstelling veranderen bijvoorbeeld van onze vodkaorange voorstelling naar de bloodymary zonder dat we aan de rest van ons programma iets hoeven te veranderen. De essentie van objectgeöriënteerd programmeren zit hem dus in de functies die bij in het object zitten. Aangezien dit concept van een functie die bij in een object zit zodanig belangrijk is, heeft men daar dan ook maar meteen een woord voor verzonnen: dit noemt men een methode. object = gegevens + gedrag Een methode is een functie in een object 1.3 Klassen In de vorige sectie hebben we de essentie van objectgericht programmeren uit de doeken gedaan, zonder daarvoor iets meer over 11

12 Python te zien dan er in de cursus van het 1 e jaar reeds besproken werd. Python is echter een objectgerichte programmeertaal, wat betekent dat deze taal een aantal speciale voorzieningen zogenaamde syntactische suiker aanbiedt om programmeren op de objectgerichte manier aangenamer te maken. Een eerste ding dat al meteen opvalt als we onze cocktailbar verder willen uitbreiden, is dat we nogal veel repetitief tikwerk moeten doen. bloodymary = { vodka : 0.34, tomatensap : 0.66, ipc : ingredientpercocktail, ipi : ingredientperingredient } vodkaorange = { vodka : 0.34, fruitsap : 0.66, ipc : ingredientpercocktail, ipi : ingredientperingredient } gintonic = { gin : 0.34, tonic : 0.66, ipc : ingredientpercocktail, ipi : ingredientperingredient } Al deze cocktail-objects hebben immers dezelfde methodes. Aangezien luiheid een grote deugd is voor een programmeur, zouden we liever gewoon één keer zeggen dat alle cocktail-objectjes deze methodes moeten hebben, in plaats van dit elke keer opnieuw te moeten tikken. Hiervoor bestaat het concept van een klasse: een klasse is een verzameling van objecten die allemaal dezelfde methodes hebben. In het geval van ons voorbeeld, gaan we dus een klasse Cocktail invoeren, de methodes ingredientpercocktail en ingredientperingredient koppelen aan deze klasse, en tot slot zeggen dat bloodymary, vodkaorange en gintonic allemaal Cocktails zijn. Dit gaat als volgt: class Cocktail : def ingredientpercocktail ( cocktail, hoeveelheid, ingredient ) : pass # <- Hier komt nog een berekening def ingredientperingredient ( cocktail, hoeveelheid, gegeven, gezocht ) : pass # <- Hier komt nog een berekening gintonic = Cocktail ( ) bloodymary = Cocktail ( ) vodkaorange = Cocktail ( ) 12

13 Met het sleutelwoord class definiëren we dus een klasse met een bepaalde naam, waarbij we dan alle methodes van deze klasse opsommen. Nadien kunnen we de naam van deze klasse gebruiken als een functie die een nieuw objectje aanmaakt, dat tot deze bepaalde klasse behoort. We zeggen dan ook wel dat dit object een instantiatie van deze klasse is. Het netto-effect is dus dat aan elk object dat door middel van de uitdrukking Cocktail() wordt aangemaakt, de twee methodes worden toegevoegd die in de declaratie van deze klasse zijn opgenomen. In de voorgaan sectie hebben we een woordenboek gebruikt om een object voor te stellen. In Python zijn echte objecten (dwz. objecten die zijn aangemaakt op basis van een class) een klein beetje verschillend van woordenboeken. Daar waar we in een woordenboek volgende notatie gebruiken om aan een nieuw sleutel-waarde paar toe te voegen: woordenboek [ sleutel ] = waarde doen we dat met een object als volgt: object. sleutel = waarde Ook hier is een beetje terminologie voor: we noemen sleutel in dit geval een attribuut van het object. Nadat we dus bovenstaande Cocktails hebben aangemaakt, kunnen we er als volgt ingrediënten aan toevoegen: gintonic. gin = 0.34 gintonic. tonic = 0.66 Nu heeft het object gintonic dus twee methodes (namelijk de methodes ingredientpercocktail en ingredientperingredient van zijn klasse) en twee attributen (gin en tonic). De notatie om methodes en attributen van een object aan te spreken is trouwens identiek dezelfde, alleen zijn er natuurlijk ook haakjes en argumenten nodig om een methode op te roepen. gintonic. ingredientpercocktail ( argumenten ) Zonder de haakjes en argumenten, zouden we de methode niet oproepen, maar krijgen we gewoon deze methode zelf terug, zoals te zien is in de Python interpreter: >>> gintonic.ingredientpercocktail <bound method Cocktail.ingredientPerCocktail of < main.cocktail instance at 0x50da08>> Laten we nu deze methode ook eens implementeren. In de vorige sectie hadden we deze functie: def ingredientpercocktail ( cocktail, hoeveelheid, ingredient ) : return hoeveelheid * cocktail [ ingredient ] De gegevens in een object heten attributen 13

14 Nu we van de cocktail een object gemaakt hebben in plaats van een woordenboek, moeten we deze functie natuurlijk aanpassen. Het idee is dat we eigenlijk dit zouden willen doen: def ingredientpercocktail ( cocktail, hoeveelheid, ingredient ) : return hoeveelheid * cocktail. ingredient Maar dit zal helaas niet werken! Deze code zal immers op zoek gaan naar een (niet-bestaand) attribuut ingredient van het object gintonic. Terwijl we eigenlijk willen dat als we deze functie oproepen met als laatste argument bv. de string gin, dat dan het attribuut cocktail.gin gezocht zou worden. Gelukkig kent Python speciaal voor dit probleem een functie getattr(object,naam), waarvan het tweede argument een string moet zijn. Met andere woorden, als we getattr(gintonic, gin ) doen, dan zal het attribuut gintonic.gin worden opgehaald. Hiermee wordt de definitie van onze klasse dan: class Cocktail : def ingredientpercocktail ( z e l f, hoeveelheid, ingredient ) : return hoeveelheid * getattr ( z e l f, ingredient ) Het eerste argument van een methode is zelf def ingredientperingredient ( z e l f, hoeveelheid, gegeven, gezocht ) : verhouding = getattr ( z e l f, gezocht ) /getattr ( z e l f, gegeven ) return hoeveelheid * verhouding We hebben nu ook nog een tweede, kleine wijziging gedaan tov. onze vorige code. We hebben het eerste argument van onze methodes hernoemd naar zelf. In Python is het eerste argument van een methode altijd het object waarbij de methode hoort. De conventie is om dit argument altijd deze naam te geven (of self in Engelstalige code). We zouden verwachten dat we deze methode nu als volgt kunnen oproepen: gintonic. ingredientpercocktail ( gintonic, 20, gin ) Dit is echter niet helemaal juist. In werkelijkheid is het namelijk nog net iets eenvoudiger. Het eerste argument van deze methode-oproep zal immers toch altijd hetzelfde zijn als het object waarin de methode zelf zit. Meer nog, het feit dat de methode gegevens manipuleert die in haar eigen object zitten is net de essentie van objectgericht programmeren! Daarom zal Python dit eerste argument impliciet achter de schermen zelf doorgeven, zonder dat wij dit zelf hoeven te doen gintonic. ingredientpercocktail ( 20, gin ) 14

15 wordt egeven impliciet Hoewel er dus in de definitie van deze methode drie argumenten waren, moeten we er bij de oproep van deze methode slechts twee zelf expliciet doorgeven. Het ontbrekende argument is het object waarop de methode wordt opgeroepen (gintonic, in dit geval), dat als impliciet eerste argument wordt doorgegeven. 1.4 Constructoren We hebben tot dusver de ingrediënten van onze cocktails gewoon voorgesteld door een string ( gin, vodka,... ). Als we in ons programma meer moeten weten over een drank dan enkel maar zijn naam, dan zal deze voorstelling ontoereikend zijn en hebben we nood aan een gegevensstructuur waarin we al de relevante informatie over een drank kunnen bijhouden. Hiervoor kunnen we natuurlijk ook weer objecten gaan gebruiken. We hebben dan een klasse nodig, die we hier Drank gaan noemen. Het is vaak nuttig om, vooraleer we effectief Python code gaan schrijven, even kort samen te vatten wat wij juist van plan zijn, door de attributen en methodes van de klasse op te lijsten. We doen dit in de vorm van een info-kaartje, dat er zo uitziet: Klasse Drank Attr. naam : string alcoholpercentage : R prijs : R Meth. Op dit ogenblik, zijn we dus niet van plan om methodes te voorzien in onze Drank-objecten. Dit betekent dat we eigenlijk evengoed een woordenboek zouden kunnen gebruiken om deze gegevens in voor te stellen, als een object. Er zijn twee goede redenen om toch voor een object te kiezen. Ten eerste is het verwarrend om in hetzelfde programma sommige gegevens voor te stellen door een object en sommige door een woordenboek; in een objectgericht programma kiezen we dus best zoveel mogelijk voor objecten. Ten tweede zou het altijd nog kunnen dat we later alsnog methodes blijken nodig te hebben. Als we van in het begin voor objecten gekozen hebben, is dit een veel eenvoudigere operatie, dan wanneer we een woordenboek zouden moeten gaan omvormen tot een object. Wegens het gebrek aan methodes, krijgen we dus een klasse definitie die leeg is. class Drank: pass Deze lege klasse dient vooral om ons nu alvast een plaats te geven waar we later als we het programma verder gaan uitbreiden eventuele 15

16 methodes van de klasse Drank kunnen gaan toevoegen. Het feit dat de definitie van deze klasse leeg is, belet ons natuurlijk niet om objecten hiervan aan te maken. gin = Drank ( ) gin.naam = gin gin. alcoholpercentage = 0.15 gin. p r i j s = 12 vodka = Drank ( ) vodka.naam = vodka vodka. alcoholprecentage = 0.40 vodka. p r i j s = 20 We zien hier opnieuw een hoop tikwerk opduiken, met bovendien het risico op moeilijk te vinden fouten. Zo staat er in het voorbeeld hierboven een tikfout, die op dit moment nog ongemerkt voorbij zal gaan, maar ongetwijfeld later voor problemen gaat zal zorgen als we het alcoholpercentage van onze dranken willen raadplegen. Beter is het dus om een methode te definiëren die de verschillende attributen van een Drank invult. class Drank: def vulattributenin ( z e l f, naam, perc, p r i j s ) : z e l f.naam = naam z e l f. alcoholpercentage = perc z e l f. p r i j s = p r i j s gin = Drank ( ) gin. vulattributenin ( gin, 0.15, 12) vodka = Drank ( ) vodka. vulattributenin ( vodka, 0.40, 20) In dit voorbeeld zien we dat we, telkens als we een Drank aanmaken, we als eerste werk de initializatie-functie vulattributenin hierop gaan oproepen. Dit zal bovendien in heel ons programma waarschijnlijk altijd zo zijn. Python laat ons toe om ons programma nog wat compacter te maken door deze twee stappen het aanmaken van een object en het initializeren ervan in één instructie uit te voeren. Het enige dat we hiervoor moeten doen, is onze initializatie-methode een speciale naam geven: init. De naam van deze functie bestaat dus uit het woordje init (als afkorting van initializatie), voorafgegaan en gevolgd door telkens twee underscores _. De reden voor de underscores is dat Python deze notatie gebruikt voor dingen die op één of andere manier speciaal zijn, in de zin dat Python zelf er achter de rug van de programmeur dingen mee zal 16

17 doen. Deze notatie oogt een beetje vreemd, maar dat is eigenlijk precies de bedoeling: de underscores dienen als een waarschuwing voor mensen die de code zouden lezen zonder de speciale functie te kennen. Als ze de underscores zien, dan weten ze dat deze functie iets speciaals doet, en dat ze best eens de Python documentatie erop zouden naslaan om te weten te komen wat dit speciale juist is. Deze speciale functies worden ook wel magische functies genoemd, omdat ze een effect kunnen hebben op het gedrag van een programma in delen die er op het eerste zicht helemaal niets mee te maken hebben. class Drank: def i n i t ( z e l f, naam, perc, p r i j s ) : z e l f.naam = naam z e l f. alcoholpercentage = perc z e l f. p r i j s = p r i j s gin = Drank ( gin, 0.15, 12) vodka = Drank ( vodka, 0.40, 20) Als we in onze definitie van onze klasse een methode voorzien met de naam init, dan zal Python dus voor ons een functie definiëren met volgende eigenschappen: de naam van de functie is dezelfde als de naam van de klasse; het aantal argumenten van de functie is hetzelfde als het aantal argumenten van de init methode. Wat deze functie zal doen is: 1. Eerst maakt de functie een nieuw object aan van de klasse, en koppelt hieraan alle methodes die bij de klasse horen; 2. Daarna roept de functie de initializatie-methode init van deze klasse op op het object dat ze net heeft aangemaakt, met als argumenten de argumenten die ze zelf gekregen heeft; 3. Tot slot geeft deze functie het nieuw aangemaakte en geïnitializeerde object terug als haar resultaat. Deze functie wordt de constructor van de klasse genoemd. (Opmerking terzijde: Sommige objectgerichte programmeertalen bieden de mogelijkheid aan om per klasse meerdere constructoren te voorzien, die bijvoorbeeld objecten initializeren op basis van verschillende parameters. In Python is dit niet mogelijk, aangezien het gedrag van de constructor volledig bepaald wordt door hetgeen er in de init -methode staat, en er maar één methode met deze naam in 17

18 elke klasse kan zijn. Wel is het mogelijk om sommige argumenten van deze methode een default waarde mee te geven, waarmee een deel van de functionaliteit waarvoor het hebben van meerdere constructors in andere programmeertalen gebruikt wordt, toch gerealizeerd kan worden.) 1.5 Magische methodes Naast init zijn er in Python nog een hele hoop andere speciale functies en methodes. Een greep uit het gamma. Python biedt een aantal functies aan die objecten van één datatype omzetten naar een ander datatype. Bijvoorbeeld: >>> int(5.4) 5 >>> float(3) 3.0 >>> str(4) 4 >>> int( 7 ) 7 >>> float( 7 ) 7.0 Al deze functies werken door achter de schermen een corresponderende magische methode op te roepen, die dezelfde naam heeft maar dan aangevuld met de nodige underscores. Door in onze eigen klassen deze methodes te implementeren, kunnen we dus bepalen hoe onze eigen objecten zullen worden omgezet naar andere datatypes: class Drank: def i n i t ( z e l f, naam, perc, p r i j s ) : z e l f.naam = naam z e l f. alcoholpercentage = perc z e l f. p r i j s = p r i j s def str ( z e l f ) : return z e l f.naam + ( + str ( z e l f. alcoholpercentage ) + %) def f l o a t ( z e l f ) : return z e l f. alcoholpercentage Laten we dit eens uitproberen: >>> d = Drank( pils, 0.4, 2) 18

19 >>> str(d) pils (0.4%) >>> float(d) >>> int(d) Traceback (most recent call last): File "<stdin>", line 1, in? AttributeError: Drank instance has no attribute int In bovenstaande klasse is het waarschijnlijk niet nodig om een methode float te hebben. Er zijn immers weinig situaties te bedenken waarin we op het idee zouden komen om een drank als een kommagetal te gebruiken. De methode str lijkt daarentegen wel zinvol. Telkens als we een drank zouden willen afprinten, moeten we deze immers transformeren naar een string. Sterker nog: als we een drank meegeven aan een print opdracht, dan zal Python achter de schermen deze conversie uitvoeren. Normaalgezien krijgen we iets als dit te zien, als we een Drank-object proberen af te printen: >>> print Drank( pils, 0.4, 2) < main.drank instance at 0x50e9b8> Nu we echter een str methode gedefiniëerd hebben in de klasse Drank, ziet het resultaat er anders uit: >>> print Drank( pils, 0.4, 2) pils (0.4%) Van de verschillende conversie-methodes die hierboven werden aangehaald, is str dan ook veruit de meest gebruikte. Tot slot nog een laatste beetje magie. In de interactieve Python shell, kan je het commando help gebruiken om meer informatie in te winnen over ingebouwde objecten, klassen, functies of methodes. Bijvoorbeeld: >>> help(str)... Return a nice string representation of the object. If the argument is a string, the return value is the same object.... Bij de definitie van een nieuwe klasse, kan je als eerste instructie een string opgeven, en deze zal dan afgebeeld worden als gebruikers om hulp vragen over deze klasse. Deze string wordt per conventie tussen driedubbele aanhalingstekens geplaatst, ook als hij op één lijn past, en wordt de docstring van de klasse genoemd. 19

20 class WatDoetDit : """ Een klasse die het gebruik van een docstring illustreert. """ pass >>> help(watdoetdit) Help on class WatDoetDit in module main : class WatDoetDit Een klasse die het gebruik van een docstring illustreert. 1.6 Wijzigen van attributen De attributen van een object komen altijd tot stand tijdens zijn initializatie. Het is natuurlijk mogelijk om achteraf de waarde van deze attributen nog te gaan wijzigen. Als we bijvoorbeeld plots 2,5 e korting krijgen op gin, dan kan dit als volgt verwerkt worden: class Drank: def i n i t ( z e l f, naam, perc, p r i j s ) : z e l f.naam = naam z e l f. alcoholpercentage = perc z e l f. p r i j s = p r i j s... # Nog wat andere methodes gin = Drank ( gin, 0.35, 10) gin. p r i j s = gin. p r i j s 2.5 Hierbij wordt de waarde van attribuut prijs van het object gin dus aangepast van buiten deze klasse. Een alternatief is dat we de klasse Drank een extra methode geven, waarmee we deze aanpassing binnen de klasse doen. class Drank: def i n i t ( z e l f, naam, perc, p r i j s ) : z e l f.naam = naam z e l f. alcoholpercentage = perc z e l f. p r i j s = p r i j s... # Nog wat andere methodes 20

21 def krijgkorting ( z e l f, bedrag ) : z e l f. p r i j s = z e l f. p r i j s bedrag gin = Drank ( gin, 0.35, 10) gin. krijgkorting ( 2. 5 ) Aangezien het de bedoeling van objectgericht programmeren is dat klassen zoveel mogelijk hun eigen gegevens inkapselen, is de tweede optie vaak de beste. 1.7 Voorbeelden Tot slot van dit hoofdstuk, nog een aantal voorbeelden van volledige klassen De klasse Drank Het info-kaartje van onze klasse Drank is intussen dit geworden: Klasse Drank Attr. naam : string alcoholpercentage : R prijs : R Meth. init (zelf, naam, perc, prijs) str (zelf) En de bijhorende Python code is dan: class Drank: """ Objecten van deze klasse stellen een drank voor met: """ - een naam, - een alcoholpercentage, - een prijs (in euro per liter). def i n i t ( z e l f, naam, perc, p r i j s ) : z e l f.naam = naam z e l f. alcoholpercentage = perc z e l f. p r i j s = p r i j s def str ( z e l f ) : return z e l f.naam + ( + str ( z e l f. alcoholpercentage ) + %) 21

22 1.7.2 De klasse Rechthoek Volgende klasse laat ons toe om rechthoeken voor te stellen, af te printen, en hun oppervlakte en omtrek te berekenen. Klasse Rechthoek Attr. hoogte : R breedte : R Meth. oppervlakte(zelf) : R omtrek(zelf) : R class Rechthoek : """ Objecten van deze klasse stellen een meetkundige rechthoek voor met een hoogte en breedte. """ def i n i t ( z e l f, b, h) : z e l f. breedte = b z e l f. hoogte = h def str ( z e l f ) : return "Rechthoek van " + str ( z e l f. breedte ) + "x" + str ( z e l f. hoogte ) def oppervlakte ( z e l f ) : return z e l f. breedte * z e l f. hoogte def omtrek ( z e l f ) : return 2 * ( z e l f. breedte + z e l f. hoogte ) Deze klasse gebruiken we dan bijvoorbeeld zo: >>> r = Rechthoek(2,3) >>> print r Rechthoek van 2x3 >>> r.oppervlakte() 6 >>> r.omtrek() De klasse Cirkel Andere meetkundige vormen kunnen natuurlijk op een gelijkaardige manier worden voorgesteld. Voor een cirkel hebben we het getal π nodig, dat we kunnen aanspreken als math.pi, nadat we eerst deze module math geïmporteerd hebben. 22

23 Klasse Cirkel Attr. straal : R Meth. oppervlakte(zelf) : R omtrek(zelf) : R class Cirkel : def i n i t ( z e l f, straal ) : z e l f. straal = straal def str ( z e l f ) : return "Cirkel met straal " + str ( z e l f. straal ) def omtrek ( z e l f ) : import math return z e l f. straal * 2 * math. pi def oppervlakte ( z e l f ) : import math return z e l f. straal * (math. pi ** 2) 1.8* Een blik achter de schermen Veel programmeertalen hebben de filosofie dat ze programmeurs tegen zichzelf of tegen hun collega s moeten beschermen. Python heeft deze filosofie niet. Dit is natuurlijk slecht nieuws voor programmeurs die deze bescherming nodig hebben, maar goed nieuws voor de anderen. We hebben eerder gezien dat er een grote gelijkenis bestaat tussen attributen van een object en sleutel-waarde paren in een woordenboek. Dit hoeft geen verwondering te wekken, want achter de schermen worden de attributen van een object gewoon in een woordenboek gestoken. Dit magische woordenboek heeft de naam dict en is zelf een attribuut van het object. >>> d = Drank( pils, 0.04, 2) >>> d. dict { naam : pils, alcoholpercentage : 0.04, prijs : 2} Elk object behoort, zoals je weet, tot een bepaalde klasse. Deze klasse wordt bijgehouden in het attribuut class. >>> d. class <class main.drank at 0x505b40> Op basis van de inleiding van dit hoofdstuk, had je misschien verwacht dat de methodes van de klasse Drank bij in het woordenboek 23

24 d. dict zouden zitten. Dit is echter niet het geval. De reden hiervoor is gewoon zuinigheid: aangezien alle objecten van de klasse toch dezelfde methodes delen, hoeven ze die niet allemaal afzonderlijk bij te houden. Het is voldoende als gewoon de klasse d. class de methodes bijhoudt. Dit doet ze in haar eigen dict, waar we o.a. ook de docstring van de klasse terugvinden. >>> d. class. dict { module : main, doc : Objecten van deze klasse stellen een drank voor met:\n\n - een naam,\n - een alcoholpercentage, \n - een prijs (in euro per liter). \n, str : <function str at 0x50a230>, init : <function init at 0x50a630>} 24

25 Samenwerkende objecten 2 In het vorige hoofdstuk hebben we enkel maar naar geïsoleerde klassen en objecten gekeken. In een echt programma zullen verschillende klassen normaalgezien moeten samenwerken. Er zijn drie manieren waarop één klasse een andere kan gebruiken: Een klasse kan een methode hebben, waarin een object van een andere klasse als argument voorkomt; Een klasse kan een methode hebben, die een object van een andere klasse teruggeeft; Een klasse kan een attribuut hebben waarin ze een object van een andere klasse bijhoudt. Er is duidelijk verschil tussen de eerste twee mogelijkheden en de derde, namelijk de duurtijd van de samenwerking. In de eerste twee gevallen is dit een tijdelijke samenwerking, waarbij de ene klasse de andere enkel maar nodig heeft tijdens één enkel methode oproep. Het laatste geval, daarentegen, beschrijft een duurzame binding tussen twee objecten, die mogelijk hun hele levensduur lang meegaat. Dit fenomeen wordt ook wel een associatie tussen de twee klassen genoemd. Associatie = contract van onbepaalde duur 2.1 Een object als argument In Secties en introduceerden we een klasse Cirkel en een klasse Rechthoek. Laat ons nu de klasse Cirkel uitbreiden met een methode die kan nagaan of de cirkel in een gegeven Rechthoek past. class Cirkel : #... de klasse zoals voorheen def pastin ( z e l f, rechthoek ) : 25

26 return ( z e l f. straal <= rechthoek. hoogte and z e l f. straal <= rechthoek. breedte ) Een voorbeeldje van het gebruik van deze methode: >>> cirkel = Cirkel(5) >>> rh = Rechthoek(6,7) >>> cirkel.pastin(rh) True Een object dat als argument wordt meegegeven, gedraagt zich zoals een woordenboek of een lijst, in die zin dat als er in de methode wijzigingen gebeuren aan een attribuut van dit object, deze wijzigingen ook buiten de methode zichtbaar zullen zijn. Laat ons dit illustreren met een methode die een rechthoek inkrimpt totdat hij in een cirkel past. class Cirkel : #... de klasse zoals voorheen def maakingesloten ( z e l f, rechthoek ) : i f rechthoek. hoogte > z e l f. straal : rechthoek. hoogte = z e l f. straal i f rechthoek. breedte > z e l f. straal : rechthoek. breedte = z e l f. straal >>> cirkel = Cirkel(5) >>> rh = Rechthoek(3,7) >>> print rh Rechthoek van 3x7 >>> cirkel.maakingesloten(rh) >>> print rh Rechthoek van 3x5 2.2 Een object als resultaat Als we in bovenstaand voorbeeld nog andere plannen hebben met onze originele rechthoek rh, dan kan het lastig zijn dat we deze nu net in place veranderd hebben. Een alternatief is om in onze methode een nieuwe Rechthoek aan te maken, en deze terug te geven als resultaat. De oorspronkelijke rechthoek kan dan onveranderd blijven. Vergelijk onderstaande code met de versie uit de vorige sectie: class Cirkel : #... de klasse zoals voorheen 26

27 def maakingesloten ( z e l f, rechthoek ) : i f rechthoek. breedte > z e l f. straal : nieuwebreedte = z e l f. straal else : nieuwebreedte = rechthoek. breedte i f rechthoek. hoogte > z e l f. straal : nieuwehoogte = z e l f. straal else : nieuwehoogte = rechthoek. hoogte return Rechthoek ( nieuwebreedte, nieuwehoogte ) Het gebruik van deze methode moet dan natuurlijk ook anders: >>> cirkel = Cirkel(5) >>> rh = rechthoek(3,7) >>> rh2 = cirkel.maakingesloten(rh) >>> print rh Rechthoek van 3x7 >>> print rh2 Rechthoek van 3x5 Welk van beide stijlen te verkiezen valt, is vaak een kwestie van persoonlijke smaak. In de Python gemeenschap, is men vaak nogal gewonnen voor een functionele stijl van programmeren, waarin functies en methodes zich gedragen zoals wiskundige functies. Dit betekent dat, net zoals een wiskundige functie f, een methode wel een resultaat y = f(x) zal berekenen, maar geen veranderingen zal aanbrengen aan x. Aanhangers van deze programmeerstijl zouden dus waarschijnlijk onze tweede variant van de methode maakingesloten verkiezen. De achterliggende motivatie is dezelfde als altijd: ze geloven dat er op deze manier gemakkelijker onafhankelijkheden tussen verschillende stukken code gerealiseerd kunnen worden, wat uiteindelijk aanleiding zou moeten geven tot programma s die gemakkelijker te ontwikkelen en te onderhouden zijn. 2.3 Associaties tussen klassen Een associatie tussen twee klassen betekent dat elk object van de ene klasse een attribuut heeft waarin een object van de andere klasse wordt bijgehouden. Om dit te illustreren verlaten we even onze rechthoeken en cirkels voor een belangrijkere toepassing, namelijk het bijhouden van onze drankvoorraad. We zagen in het vorige hoofdstuk (Sectie 1.7.1) al een klasse Drank, waarmee we kunnen bijhouden welke dranken we in voorraad hebben. Dit breiden we nu zodanig uit, dat we ook kunnen bijhouden hoeveel er van een bepaalde drank in voorraad is. Hiervoor introduceren we volgende klasse: 27

28 Klasse Fles Attr. drank : Drank inhoud (in cl) : N Meth. haaluit(zelf, hoeveelheid) voegtoe(zelf, hoeveelheid) waarde(zelf) : R Elk object van de klasse Fles heeft dus een attribuut waarin het een object van de klasse Drank gaat bijhouden. Er is dus, maw., een associatie tussen Fles en Drank. Vaak is het inzichtelijker om in plaats van bovenstaand info-kaartje een zogenaamd klassendiagramma te tekenen. Hierop worden associates aanduid met een pijl tussen de twee klassen in kwestie. Deze pijl vertrekt bij de klasse die het attribuut heeft waarmee deze associatie wordt voorgesteld, en dit attribuut wordt dan niet meer opgenomen in diens lijst met attributen. Eventueel kan de naam van het attribuut wel nog vermeld worden als label bij de pijl. Om het geheel overzichtelijk te houden, wordt er vaak ook voor gekozen om de methodes of zelfs de attributen van een klasse niet te vermelden. Fles inhoud : N drank Drank naam alcoholpercentage prijs : string : R : R class Fles : def i n i t ( z e l f, drank, inhoud ) : z e l f. drank = drank z e l f. inhoud = inhoud def haaluit ( z e l f, hoeveelheid ) : z e l f. inhoud = z e l f. inhoud hoeveelheid def voegtoe ( z e l f, hoeveelheid ) : z e l f. inhoud = z e l f. inhoud + hoeveelheid def waarde ( z e l f ) : prijspercl = z e l f. drank. p r i j s / return z e l f. inhoud * prijspercl De interessantste methode is hier de laatste, waarin een Fles object zijn eigen inhoud moet combineren met de prijs van zijn drank om zijn eigen waarde te bepalen. De deling door 100 is nodig omdat de klasse Drank zijn prijs bijhoudt in e/l, terwijl de inhoud van een Fles 28

29 in cl wordt bijgehouden. Op zich kan dit riskant zijn (denk aan de ontplofte Mars Observator): als we later zouden besluiten om de prijs van een Drank ook in e/cl te zetten, moeten we eraan denken om de deling door 100 weg te halen, of anders krijgen we natuurlijk foute resultaten. Het is in dit geval waarschijnlijk veiliger om voor een andere strategie te kiezen, waarbij het doen van berekeningen met het attribuut drank.prijs zoveel mogelijk in de klasse Drank gebeurt. class Fles :... def waarde ( z e l f ) : return z e l f. drank. prijspercl ( ) * z e l f. inhoud class Drank:... def prijspercl ( z e l f ) : return z e l f. p r i j s / Lijsten en objecten Ook in onze eigen objecten kunnen we vaak op nuttige wijze gebruik maken van de functionaliteit van Pythons ingebouwde lijsten. In de cursus van het eerste jaar, heb je gezien hoe je met deze lijsten moet omgaan. Een kort voorbeeldje ter herinnering: >>> lijst = [1,2,3] >>> print lijst [1, 2, 3] >>> lijst.append(4) >>> print lijst [1, 2, 3, 4] >>> for element in lijst:... print element >>> print lijst[1] 2 >>> for i in range(len(lijst)):... print i, "->", lijst[i] 29

30 > 1 1 -> 2 2 -> 3 3 -> 4 Herinner je bij de uitvoer van het laatste commando ook dat de index van een lijst altijd begint te tellen vanaf 0; het element dat bij index 1 hoort, is dus niet het eerste, maar wel het tweede element van de lijst Objecten met lijsten Een lijst kan net zoals bijvoorbeeld een getal, een string of een object gebruikt worden als een attribuut van een object. Als een object zo n attribuut heeft, zal het vaak methodes aanbieden waarmee elementen kunnen worden toegevoegd aan en/of weggehaald uit de lijst. Als de constructor van zo n object al geen lijst meekrijgt als argument, dan zal hier typisch een nieuwe, lege lijst worden aangemaakt. Het volgende voorbeeld toont een klasse waarmee een rij van getallen kan worden bijgehouden om hiervan het gemiddelde te berekenen. class GetallenRij : def i n i t ( z e l f ) : z e l f. r i j = [ ] def voegtoe ( z e l f, getal ) : z e l f. r i j. append ( getal ) def str ( z e l f ) : return str ( z e l f. r i j ) def som( z e l f ) : som = 0 for getal in z e l f. r i j : som += getal return som def gemiddelde ( z e l f ) : som = z e l f.som ( ) return f l o a t (som) / len ( z e l f. r i j ) # ^^^^^ anders krijgen we een gehele deling Deze klasse kunnen we dan bijvoorbeeld als volgt gebruiken. >>> rij = GetallenRij() >>> rij.voegtoe(3) >>> rij.voegtoe(6) 30

31 >>> rij.voegtoe(7) >>> print rij [3, 6, 7] >>> rij.gemiddelde() Lijsten van objecten Naast waardes van een primitief type, zoals getallen of strings, kunnen ook objecten in een lijst gestoken worden. Zo zal onderstaande code een lijst van twee objecten maken, en daar dan nadien nog een geheel getal en een derde object aan toevoegen. gin = Drank (... ) p i l s = Drank (... ) wijn = Drank (... ) f1 = Fles ( gin,50) f2 = Fles ( pils,25) f3 = Fles ( wijn,75) l i j s t = [ f1, f2 ] l i j s t. append ( 4 ) l i j s t. append ( f3 ) De lijst die door deze code geproduceerd wordt, ziet er als volgt uit: >>> print lijst [< main.fles instance at 0x50d580>, < main.fles instance at 0x50d5a8>, 4, < main.fles instance at 0x50d5d0>] Een grafische voorstelling hiervan is te zien in Figuur 2.1. Het belangrijkste punt hiervan, is dat lijst[0] dus eigenlijk gewoon een andere naam is voor hetzelfde object dat ook al de naam f1 heeft. Het effect hiervan zien we bijvoorbeeld in volgende interactie: >>> print f1.inhoud 50 >>> lijst[0].inhoud = 25 >>> print f1.inhoud Objecten met lijsten van objecten Als we objecten in een lijst kunnen steken, is het natuurlijk ook mogelijk om zo n lijst van objecten te gebruiken als een attribuut van een andere object. Op deze manier kunnen we, met andere woorden, een associatie tot stand brengen van een object van één klasse met een verzameling van objecten van een andere klasse. Hiervan kunnen we 31

32 lijst 4 Fles drank gin inhoud 50 Fles drank pils inhoud 25 Fles drank wijn inhoud 75 f1 f2 f3 Figuur 2.1: Een grafische voorstelling van het resultaat van de code lijst = [f1,f2,4,f3]. bijvoorbeeld gebruik maken om gegevens over een DrankVoorraad bij te houden, door middel van een lijst van flessen waaruit deze voorraad bestaat. Klasse DrankVoorraad Attr. flessen : lijst<fles> Meth. waarde(zelf) : R Met de notatie lijst<fles> bedoelen we een lijst met daarin een aantal Fles objecten. In een klassendiagramma, kunnen we zo n lijst aanduiden met een sterretje, zoals te zien in Figuur 2.2. Veel van het gedrag dat een object van een klasse zoals DrankVoorraad zal aanbieden, wordt typisch gerealizeerd door middel van een iteratie over de Fles-objecten die in zijn lijst zitten. Bijvoorbeeld de methode om de volledige waarde van een drankkast te berekenen, gegeven de waarde van de individuele flessen, valt op deze manier te implementeren. class DrankVoorraad : def i n i t ( z e l f ) : z e l f. flessen = [ ] def voegtoe ( z e l f, f l e s ) : z e l f. flessen. append ( f l e s ) def waarde ( z e l f ) : 32

33 DrankVoorraad waarde(zelf) : R flessen Fles inhoud : N waarde(zelf) : R voegtoe(zelf, hoeveelheid) haaluit(zelf, hoeveelheid) drank Drank naam alcoholpercentage prijs : string : R : R Figuur 2.2: Een klassendiagramma waarbij een drankvoorraad uit een verzameling flessen bestaat. resultaat = 0 for f in z e l f. flessen : resultaat += f. waarde ( ) return resultaat Laten we even stilstaan bij het resultaat dat deze methode berekent. Als de drankvoorraad n flessen {f 1,..., f n } bevat, waarbij V i de inhoud is van fles i en p i de prijs van de drank d i die in fles f i zit, dan berekent deze methode volgende som w: w = V i p i. 1 i n De methode waarde uit de klasse DrankVoorraad berekent heel deze som, gebruikmakend van de gelijknamige methode uit de klasse Fles, die één term ervan berekent. Sommige getalletjes leggen dus een hele weg af, voordat ze uiteindelijk in deze som belanden: Drank Fles DrankVoorraad p 1 d 1 f 1 V 1 p 1 i V i p i d n p n f n V n p n 33

NETWERKEN en OBJECTORIËNTATIE

NETWERKEN en OBJECTORIËNTATIE FACULTEIT INDUSTRIELE INGENIEURSWETENSCHAPPEN! CAMPUS DE NAYER! NETWERKEN en OBJECTORIËNTATIE Deel 2: Objectoriëntatie in Python Joost Vennekens Inhoudsopgave 1 Objecten en klassen 5 1.1 Een beetje geschiedenis.....................

Nadere informatie

Objectgericht Programmeren. (in Python)

Objectgericht Programmeren. (in Python) Objectgericht Programmeren (in Python) Motivatie Programmeren is moeilijk Waarom? Complexiteit 100 200 300 400 500 kloc (1000 lijnen code) g1 = raw_input("eerste getal?") g2 = raw_input("tweede getal?")

Nadere informatie

N&O: Objectgericht Programmeren. (in Python)

N&O: Objectgericht Programmeren. (in Python) N&O: Objectgericht Programmeren (in Python) N&O Twee aparte onderwerpen Internet en websites (50%) Programmeren in Python (50%) Komen samen in dynamische websites Webpagina als user interface voor Python

Nadere informatie

Datatypes Een datatype is de sort van van een waarde van een variabele, veel gebruikte datatypes zijn: String, int, Bool, char en double.

Datatypes Een datatype is de sort van van een waarde van een variabele, veel gebruikte datatypes zijn: String, int, Bool, char en double. Algemeen C# Variabele Een variabele is een willekeurige waarde die word opgeslagen. Een variabele heeft altijd een datetype ( De soort waarde die een variabele bevat). Datatypes Een datatype is de sort

Nadere informatie

Het relaas van de beginnende programmeur. Het hoe en waarom van de assistent

Het relaas van de beginnende programmeur. Het hoe en waarom van de assistent Het relaas van de beginnende programmeur Het hoe en waarom van de assistent 1. Help, mijn code doet niks... Mogelijke oplossingen: Heb je op run geduwd (groene pijltje)? Zolang je niet op 'run' duwt, kent

Nadere informatie

Maak automatisch een geschikte configuratie van een softwaresysteem;

Maak automatisch een geschikte configuratie van een softwaresysteem; Joost Vennekens joost.vennekens@kuleuven.be Technologiecampus De Nayer We zijn geïnteresseerd in het oplossen van combinatorische problemen, zoals bijvoorbeeld: Bereken een lessenrooster die aan een aantal

Nadere informatie

Programmeermethoden NA. Week 5: Functies (vervolg)

Programmeermethoden NA. Week 5: Functies (vervolg) Programmeermethoden NA Week 5: Functies (vervolg) Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna/ Bij ons leer je de wereld kennen 1 Functies Vorige week bekeken we functies: def

Nadere informatie

OEFENINGEN PYTHON REEKS 1

OEFENINGEN PYTHON REEKS 1 Vraag 1: Expressies & Types OEFENINGEN PYTHON REEKS 1 Python maakt gebruik van enkele vaak voorkomende (data)types. Zo zijn er integers die behoren tot de gehele getallen (VB: 3), zijn er float s die behoren

Nadere informatie

Objectgericht programmeren 1.

Objectgericht programmeren 1. Objectgericht programmeren 1 joost.vennekens@kuleuven.be http://www.cs.kuleuven.be/~joost/dn Objectgericht ontwerpen 35% Objectgericht ontwerpen 65% OP1 Informatiesystemen 50% Databanken 50% OP1 Evaluatie

Nadere informatie

OEFENINGEN PYTHON REEKS 1

OEFENINGEN PYTHON REEKS 1 OEFENINGEN PYTHON REEKS 1 Vraag 1: Python als een eenvoudige rekenmachine Python maakt gebruik van enkele vaak voorkomende (data)types. Zo zijn er integers die behoren tot de gehele getallen (VB: 3) en

Nadere informatie

Variabelen en statements in ActionScript

Variabelen en statements in ActionScript Ontwikkelen van Apps voor ios en Android Variabelen en statements in ActionScript 6.1 Inleiding Als we het in de informatica over variabelen hebben, bedoelen we een stukje in het geheugen van de computer

Nadere informatie

Programmeermethoden NA. Week 5: Functies (vervolg)

Programmeermethoden NA. Week 5: Functies (vervolg) Programmeermethoden NA Week 5: Functies (vervolg) Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna2016/ Functies Vorige week bekeken we functies: def bereken(a, x): return a * (x

Nadere informatie

[15] Variabelen in functies (of: een woordje over scope)

[15] Variabelen in functies (of: een woordje over scope) [15] Variabelen in functies (of: een woordje over scope) In de vorige leerfiche hebben we geleerd over functies. We leerden dat functies parameters hebben en dat ze return-waarden kunnen teruggeven aan

Nadere informatie

Programmeren (1) Examen NAAM:

Programmeren (1) Examen NAAM: Schrijf al je antwoorden op deze vragenbladen (op de plaats die daarvoor is voorzien) en geef zowel klad als net af. Bij heel wat vragen moet je zelf Java-code schrijven. Hou dit kort en bondig. Je hoeft

Nadere informatie

Vakgroep CW KAHO Sint-Lieven

Vakgroep CW KAHO Sint-Lieven Vakgroep CW KAHO Sint-Lieven Objecten Programmeren voor de Sport: Een inleiding tot JAVA objecten Wetenschapsweek 20 November 2012 Tony Wauters en Tim Vermeulen tony.wauters@kahosl.be en tim.vermeulen@kahosl.be

Nadere informatie

Inleiding Programmeren 2

Inleiding Programmeren 2 Inleiding Programmeren 2 Gertjan van Noord 11 december 2017 Zelle hoofdstuk 10 Stof Overzicht - theorie 1. Zelle hoofdstuk 4 en 5 2. Zelle hoofdstuk 7 en 8, recursie, Brookshear hoofdstuk 5 3. Zelle hoofdstuk

Nadere informatie

[14] Functies. Volg mee via 14_Functies-1.py. We beginnen met een eenvoudig voorbeeldje:

[14] Functies. Volg mee via 14_Functies-1.py. We beginnen met een eenvoudig voorbeeldje: [14] Functies Een goede programmeur doet altijd zijn best om zoveel mogelijk aan hergebruik van code te doen. Je probeert in je programma code te gebruiken die iemand anders heeft gemaakt, of code die

Nadere informatie

Inleiding Programmeren 2

Inleiding Programmeren 2 Inleiding Programmeren 2 Gertjan van Noord, Leonie Bosveld 12 december 2016 Zelle hoofdstuk 10 Stof Overzicht - theorie 1. Zelle hoofdstuk 4 en 5 2. Zelle hoofdstuk 7 en 8, recursie, Brookshear hoofdstuk

Nadere informatie

Programmeermethoden NA

Programmeermethoden NA Programmeermethoden NA Week 6: Lijsten Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna/ Bij ons leer je de wereld kennen 1 Getal opbouwen Stel je leest losse karakters (waaronder

Nadere informatie

Een spoedcursus python

Een spoedcursus python Een spoedcursus python Zoals je in de titel misschien al gezien hebt, geven wij een spoedcursus Python. Door deze cursus leer je alle basics, zoals het rekenen met Python en het gebruik van strings. Het

Nadere informatie

Programmeermethoden NA. Week 6: Lijsten

Programmeermethoden NA. Week 6: Lijsten Programmeermethoden NA Week 6: Lijsten Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna2016/ Getal opbouwen Stel je leest losse karakters (waaronder cijfers) en je moet daar een getal

Nadere informatie

BEGINNER JAVA Inhoudsopgave

BEGINNER JAVA Inhoudsopgave Inhoudsopgave 6 Configuratie Hallo wereld! Praten met de gebruiker Munt opgooien Voorwaarden Lussen......6 Configuratie Met deze Sushi kaarten ga je een simpel spel maken met één van de meest populaire

Nadere informatie

VAN HET PROGRAMMEREN. Inleiding

VAN HET PROGRAMMEREN. Inleiding OVERZICHT VAN HET PROGRAMMEREN Inleiding Als je leert programmeren lijkt het nogal overweldigend om die eerste stappen te doorworstelen. Er zijn dan ook heel wat programmeertalen (Java, Ruby, Python, Perl,

Nadere informatie

Beginselen van programmeren Practicum 1 (Doolhof) : Oplossing

Beginselen van programmeren Practicum 1 (Doolhof) : Oplossing Beginselen van programmeren Practicum 1 (Doolhof) : Oplossing Introductie In dit document geven we een mogelijke oplossing voor het eerste practicum. Deze oplossing gebruikt verschillende klassen en overerving,

Nadere informatie

4 ASP.NET MVC. 4.1 Controllers

4 ASP.NET MVC. 4.1 Controllers 4 ASP.NET MVC ASP.NET is het.net raamwerk voor het bouwen van webapplicaties. De MVC variant hiervan is speciaal ontworpen voor het bouwen van dergelijke applicaties volgens het Model-View-Controller paradigma.

Nadere informatie

OEFENINGEN PYTHON REEKS 1

OEFENINGEN PYTHON REEKS 1 Vraag 1: Expressies & Types OEFENINGEN PYTHON REEKS 1 Python maakt gebruik van enkele vaak voorkomende (data)types. Zo zijn er integers die behoren tot de gehele getallen (VB: 3), zijn er float s die behoren

Nadere informatie

HOE TEKEN IK EEN OMGEVINGSMODEL

HOE TEKEN IK EEN OMGEVINGSMODEL HOE TEKEN IK EEN OMGEVINGSMODEL MATTIAS DE WAEL 1. Inleiding Om de allereenvoudigste Scheme expressies te begrijpen volstaat het substitutiemodel. Het substitutiemodel verondersteld het bestaan van een

Nadere informatie

Je gaat leren programmeren en een spel bouwen met de programmeertaal Python. Websites zoals YouTube en Instagram zijn gebouwd met Python.

Je gaat leren programmeren en een spel bouwen met de programmeertaal Python. Websites zoals YouTube en Instagram zijn gebouwd met Python. 1 Je gaat leren programmeren en een spel bouwen met de programmeertaal Python. Websites zoals YouTube en Instagram zijn gebouwd met Python. Voordat je leert programmeren, moet je jouw pc zo instellen dat

Nadere informatie

Zoemzinnen. Algemene info. Functies met een variabel aantal argumenten

Zoemzinnen. Algemene info. Functies met een variabel aantal argumenten Zoemzinnen Functies met een variabel aantal argumenten Bij het definiëren van een functie leg je in principe vast hoeveel argumenten er aan de functie moeten doorgegeven worden. Dit aantal correspondeert

Nadere informatie

[13] Rondjes draaien (loops)

[13] Rondjes draaien (loops) [13] Rondjes draaien (loops) Met de if else uit de leerfiche [11] hebben we leren werken met één van de belangrijkste programmeerstructuren in Python. Bijna even belangrijk zijn de verschillende mogelijkheden

Nadere informatie

Inleiding Programmeren 2

Inleiding Programmeren 2 Inleiding Programmeren 2 Gertjan van Noord November 26, 2018 Stof week 3 nogmaals Zelle hoofdstuk 8 en recursie Brookshear hoofdstuk 5: Algoritmes Datastructuren: tuples Een geheel andere manier om te

Nadere informatie

INHOUDSOPGAVE. Over de auteur, de illustrator en de technische redacteuren 13

INHOUDSOPGAVE. Over de auteur, de illustrator en de technische redacteuren 13 INHOUDSOPGAVE Over de auteur, de illustrator en de technische redacteuren 13 Dankwoord 14 Inleiding 15 Waarom Python?... 16 Hoe je code leert schrijven... 16 Voor wie is dit boek... 17 Wat staat er in

Nadere informatie

Overerving & Polymorfisme

Overerving & Polymorfisme Overerving & Polymorfisme Overerving Sommige klassen zijn speciaal geval van andere klasse Docent is een speciaal geval van werknemer, dwz. elke docent is ook werknemer Functionaliteit van docent = functionaliteit

Nadere informatie

Arrays. Complexe datastructuren. Waarom arrays. Geen stijlvol programma:

Arrays. Complexe datastructuren. Waarom arrays. Geen stijlvol programma: Geen stijlvol programma: Complexe datastructuren Arrays vijf verschillende variabelen voor iets dat als één rij getallen bestempeld wordt; onbruikbaar wanneer het over meer getallen (bijvoorbeeld ) gaat.

Nadere informatie

Modelleren en Programmeren

Modelleren en Programmeren Modelleren en Programmeren Jeroen Bransen 11 december 2015 Ingebouwde datastructuren Meer boomstructuren Access specifiers Gebruikersinvoer Codestijl Packages SAT-solver Ingebouwde datastructuren Ingebouwde

Nadere informatie

II. ZELFGEDEFINIEERDE FUNCTIES

II. ZELFGEDEFINIEERDE FUNCTIES II. ZELFGEDEFINIEERDE FUNCTIES In Excel bestaat reeds een uitgebreide reeks van functies zoals SOM, GEMIDDELDE, AFRONDEN, NU enz. Het is de bedoeling om functies aan deze lijst toe te voegen door in Visual

Nadere informatie

Les 3. Gebruik in volledige programma Default argumenten Vergelijken van objecten

Les 3. Gebruik in volledige programma Default argumenten Vergelijken van objecten Les 3 Gebruik in volledige programma Default argumenten Vergelijken van objecten Een Python programma def foo( ):... def bar( ):... def baz( ):... def main():... main() Een Python programma class Drank:...

Nadere informatie

VAN HET PROGRAMMEREN. Inleiding. Het spiraalmodel. De programmeertaal. vervolgens de berekening van het totale bedrag, incl. BTW:

VAN HET PROGRAMMEREN. Inleiding. Het spiraalmodel. De programmeertaal. vervolgens de berekening van het totale bedrag, incl. BTW: OVERZICHT VAN HET PROGRAMMEREN Inleiding Als je leert programmeren lijkt het nogal overweldigend om die eerste stappen te doorworstelen. Er zijn dan ook heel wat programmeertalen (Java, Ruby, Python, Perl,

Nadere informatie

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12

1 Delers 1. 3 Grootste gemene deler en kleinste gemene veelvoud 12 Katern 2 Getaltheorie Inhoudsopgave 1 Delers 1 2 Deelbaarheid door 2, 3, 5, 9 en 11 6 3 Grootste gemene deler en kleinste gemene veelvoud 12 1 Delers In Katern 1 heb je geleerd wat een deler van een getal

Nadere informatie

Visual Basic.NET. Visual Basic.NET. M. den Besten 0.3 VB. NET

Visual Basic.NET. Visual Basic.NET. M. den Besten 0.3 VB. NET Visual Basic.NET M. den Besten 0.3 VB. NET Inhoud Voorwoord Deel 1 Visual Basic.NET 1.1 Inleiding...13 1.2 De programmeertaal Visual Basic.NET...14 1.3 Microsoft Visual Basic 2010 Express Edition...15

Nadere informatie

Python. Vraag 1: Expressies en types. Vraag 1 b: Types -Ingebouwde functies- Vraag 1 a 3/10/14

Python. Vraag 1: Expressies en types. Vraag 1 b: Types -Ingebouwde functies- Vraag 1 a 3/10/14 Python Vraag 1: Expressies en types Integrated Development Environment (IDE): Ø Wing 101 (gratis te downloaden op www.wingware.com) Oefeningen in de shell >> noemen we de prompt Python commando s = expressies

Nadere informatie

Een eenvoudig algoritme om permutaties te genereren

Een eenvoudig algoritme om permutaties te genereren Een eenvoudig algoritme om permutaties te genereren Daniel von Asmuth Inleiding Er zijn in de vakliteratuur verschillende manieren beschreven om alle permutaties van een verzameling te generen. De methoden

Nadere informatie

10 Meer over functies

10 Meer over functies 10 Meer over functies In hoofdstuk 5 hebben we functies uitgebreid bestudeerd. In dit hoofdstuk bekijken we drie andere aspecten van functies: recursieve functies dat wil zeggen, functies die zichzelf

Nadere informatie

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk.

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk. HOOFDSTUK 3 3.1 Stapsgewijs programmeren In de vorige hoofdstukken zijn programmeertalen beschreven die imperatief zijn. is het stapsgewijs in code omschrijven wat een programma moet doen, net als een

Nadere informatie

OEFENINGEN PYTHON REEKS 5

OEFENINGEN PYTHON REEKS 5 Vraag 1: Interpoleren (vervolg) OEFENINGEN PYTHON REEKS 5 Bouw verder op je code van Reeks 3, vraag 4. Voeg vier constanten toe aan je code: X0 = 280, Y0 = 0, Z0 = 50 en SIZE = 8. a) Teken een kubus met

Nadere informatie

Uitleg van de Hough transformatie

Uitleg van de Hough transformatie Uitleg van de Hough transformatie Maarten M. Fokkinga, Joeri van Ruth Database groep, Fac. EWI, Universiteit Twente Versie van 17 mei 2005, 10:59 De Hough transformatie is een wiskundige techniek om een

Nadere informatie

Informatica. Deel II: les 1. Java versus Python. Jan Lemeire Informatica deel II februari mei 2014. Parallel Systems: Introduction

Informatica. Deel II: les 1. Java versus Python. Jan Lemeire Informatica deel II februari mei 2014. Parallel Systems: Introduction Informatica Deel II: les 1 Java versus Python Jan Lemeire Informatica deel II februari mei 2014 Parallel Systems: Introduction Arabidopsis (zandraket) Arabidopsis (zandraket) MMIQQA Multimodal Microscopic

Nadere informatie

Computervaardigheden. Universiteit Antwerpen. Computervaardigheden en Programmatie. Grafieken en Rapporten 1. Inhoud. Wat is scripting?

Computervaardigheden. Universiteit Antwerpen. Computervaardigheden en Programmatie. Grafieken en Rapporten 1. Inhoud. Wat is scripting? Inhoud Computervaardigheden Hoofdstuk 4 Scripting (Let op: dit is enkel voor studenten Biologie.) Dit hoofdstuk bekijkt heel kort de basis van scripting. - Opstellen van functies. - Conditionele code.

Nadere informatie

Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur

Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, 13.00-15.00 uur 1. De situatie die ontstaat door class A : B C D; kan beschreven worden door (a) B is een A (b)

Nadere informatie

start -> id (k (f c s) (g s c)) -> k (f c s) (g s c) -> f c s -> s c

start -> id (k (f c s) (g s c)) -> k (f c s) (g s c) -> f c s -> s c Een Minimaal Formalisme om te Programmeren We hebben gezien dat Turing machines beschouwd kunnen worden als universele computers. D.w.z. dat iedere berekening met natuurlijke getallen die met een computer

Nadere informatie

MINICURSUS PHP. Op dit lesmateriaal is een Creative Commons licentie van toepassing Sebastiaan Franken en Rosalie de Klerk Bambara

MINICURSUS PHP. Op dit lesmateriaal is een Creative Commons licentie van toepassing Sebastiaan Franken en Rosalie de Klerk Bambara MINICURSUS PHP Op dit lesmateriaal is een Creative Commons licentie van toepassing. 2017-2018 Sebastiaan Franken en Rosalie de Klerk Bambara PHP Cursus Deze cursus is om de eerste stappen in de wereld

Nadere informatie

PYTHON REEKS 2: FUNCTIES. Mathias Polfliet

PYTHON REEKS 2: FUNCTIES. Mathias Polfliet PYTHON REEKS 2: FUNCTIES Mathias Polfliet mpolflie@etrovub.be TERUG NAAR PYTHON BASICS VRAAG 1: VOLUME BOL Het volume van een bol met straal r is 4 3 πr3 π Wat is het volume in cm³ van een bol met straal

Nadere informatie

[8] De ene 1 is de andere niet

[8] De ene 1 is de andere niet [8] De ene 1 is de andere niet Volg mee via 08_Types.py In de volgende leerfiche gaan we rekenen met Python. Dat kan je in een programma doen, maar dat kan je ook gewoon vanuit het Shell-venster doen.

Nadere informatie

Omschrijf bij ieder onderdeel van de methode de betekenis ervan. Java kent twee groepen van klassen die een GUI kunnen maken: awt en swing.

Omschrijf bij ieder onderdeel van de methode de betekenis ervan. Java kent twee groepen van klassen die een GUI kunnen maken: awt en swing. irkel (met Jpanel) ij de onderstaande opdracht behoort het bestand Panels: JPanels_1.java (map Panel) in de map irkel. pplicaties in Java hebben altijd een publieke klasse waarin een methode main voorkomt.

Nadere informatie

Programmeren: Visual Basic

Programmeren: Visual Basic PETERSTUYVESANT COLLEGE INFORMATICA 2009-2010 Programmeren: Visual Basic Document Afbaking 01. VERSCHILLENDE PROGRAMMEERTALEN 02. PROGRAMMEER PAKKETTEN 03. GUI 03.1 GUI ELEMENTEN 03.2 GUI EIGENSCHAPPEN

Nadere informatie

Toets Programmeren, 2YP05 op donderdag 13 november 2008, 09:00-12:00

Toets Programmeren, 2YP05 op donderdag 13 november 2008, 09:00-12:00 Toets Programmeren, 2YP05 op donderdag 13 november 2008, 09:00-12:00 TU/e Technische Universiteit Eindhoven Faculteit Wiskunde en Informatica (Na de toets gecorrigeerde versie) PROBLEEM: Sleutels Lees

Nadere informatie

Javascript oefenblad 1

Javascript oefenblad 1 Leer de basis van Javascript. Javascript oefenblad 1 Niels van Velzen Javascript oefenblad 1 Pagina 2 Inleiding Javascript is niet altijd even makkelijk. Vooral aan het begin is het even wennen hoe de

Nadere informatie

Dynamiek met VO-Script

Dynamiek met VO-Script Dynamiek met VO-Script Door Bert Dingemans DLA Ontwerp & Software bert@dla-architect.nl Inleiding Op de SDGN nieuwsgroep voor Visual Objects ontstond laatst een draad van berichten over de nieuwe libraries

Nadere informatie

Niet-numerieke data-types

Niet-numerieke data-types Intern wordt een karakter voorgesteld als een rij van acht bits, Niet-numerieke data-types string de letter a 01100001 0110 0001 0x61 97 Bij interpretatie van de inhoud van een byte als een geheel getal,

Nadere informatie

Algemeen. Rorschachtest. Algemene info

Algemeen. Rorschachtest. Algemene info Algemeen Als Python de volgende regel moet lezen uit een tekstbestand, dan wordt er gelezen tot en met de eerstvolgende newline ('\n') of tot het einde van het bestand. Het laatste karakter van de regel

Nadere informatie

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren HOOFDSTUK 3 3.1 Stapsgewijs programmeren De programmeertalen die tot nu toe genoemd zijn, zijn imperatieve of procedurele programmeertalen. is het stapsgewijs in code omschrijven wat een programma moet

Nadere informatie

Een gelinkte lijst in C#

Een gelinkte lijst in C# Een gelinkte lijst in C# In deze tutorial ga demonstreren hoe je een gelinkte lijst kan opstellen in C#. We gaan een klasse schrijven, die een gelijkaardige functionaliteit heeft als een ArrayList, namelijk

Nadere informatie

Labo 2 Programmeren II

Labo 2 Programmeren II Labo 2 Programmeren II L. Schoofs K. van Assche Gebruik Visual Studio 2005 om een programma te ontwikkelen dat eenvoudige grafieken tekent. Deze opgave heb je vorig academiejaar reeds in Java geïmplementeerd.

Nadere informatie

Cursus MSW-Logo. Def. Recursie: recursie is het oproepen van dezelfde functie of procedure binnen de functie of procedure

Cursus MSW-Logo. Def. Recursie: recursie is het oproepen van dezelfde functie of procedure binnen de functie of procedure Hfdst 1: De schildpadwereld Recursie Cursus MSW-Logo Def. Recursie: recursie is het oproepen van dezelfde functie of procedure binnen de functie of procedure Regelmatige vierhoeken Voorbeeld in Logo: TO

Nadere informatie

Getallen 1 is een computerprogramma voor het aanleren van de basis rekenvaardigheden (getalbegrip).

Getallen 1 is een computerprogramma voor het aanleren van de basis rekenvaardigheden (getalbegrip). Getallen 1 Getallen 1 is een computerprogramma voor het aanleren van de basis rekenvaardigheden (getalbegrip). Doelgroep Rekenen en Wiskunde Getallen 1 Getallen 1 is geschikt voor groep 7 en 8 van de basisschool

Nadere informatie

Modulewijzer InfPbs00DT

Modulewijzer InfPbs00DT Modulewijzer InfPbs00DT W. Oele 0 juli 008 Inhoudsopgave Inleiding 3 Waarom wiskunde? 3. Efficiëntie van computerprogramma s............... 3. 3D-engines en vectoranalyse................... 3.3 Bewijsvoering

Nadere informatie

van PSD naar JavaScript

van PSD naar JavaScript 2015 van PSD naar JavaScript F. Vonk versie 2 19-9-2015 inhoudsopgave 1. inleiding... - 2-2. ontwikkelomgeving... - 3-3. programmeerconcepten... - 4 - statement... - 4 - sequentie... - 4 - variabele en

Nadere informatie

Objectgeoriënteerd programmeren in Java 1

Objectgeoriënteerd programmeren in Java 1 Objectgeoriënteerd programmeren in Java 1 CPP Javaprogrammeur Bijeenkomst 3 Leereenheden 7, 8, 9 De Java API Java bevat een grote bibliotheek standaardklassen: de Java API Voorbeelden java.lang basisklassen

Nadere informatie

Numerieke aspecten van de vergelijking van Cantor. Opgedragen aan Th. J. Dekker. H. W. Lenstra, Jr.

Numerieke aspecten van de vergelijking van Cantor. Opgedragen aan Th. J. Dekker. H. W. Lenstra, Jr. Numerieke aspecten van de vergelijking van Cantor Opgedragen aan Th. J. Dekker H. W. Lenstra, Jr. Uit de lineaire algebra is bekend dat het aantal oplossingen van een systeem lineaire vergelijkingen gelijk

Nadere informatie

Een inleiding in de Unified Modeling Language 79

Een inleiding in de Unified Modeling Language 79 Een inleiding in de Unified Modeling Language 79 2. Het objectdiagram Soms hebben we behoefte om in de plaats van een klasse een instantie van deze klasse weer te geven. Figuur 3.22. toont als voorbeeld

Nadere informatie

Abstracte klassen & Interfaces

Abstracte klassen & Interfaces Abstracte klassen & Interfaces Overerving public class Vierhoek {... Vierhoek public class Rechthoek extends Vierhoek {... public class Ruit extends Vierhoek {... Rechthoek Ruit Elke rechthoek is een vierhoek.

Nadere informatie

Instructie voor Docenten. Hoofdstuk 13 OMTREK EN OPPERVLAKTE

Instructie voor Docenten. Hoofdstuk 13 OMTREK EN OPPERVLAKTE Instructie voor Docenten Hoofdstuk 13 OMTREK EN OPPERVLAKTE Instructie voor docenten H13: OMTREK EN OPPERVLAKTE DOELEN VAN DIT HOOFDSTUK: Leerlingen weten wat de begrippen omtrek en oppervlakte betekenen.

Nadere informatie

Informatica: C# WPO 9

Informatica: C# WPO 9 Informatica: C# WPO 9 1. Inhoud Functies (functies met return-waarde) 2. Oefeningen Demo 1: Som Demo 2: Min en max of array Demo 3: Retourneer array van randomwaarden A: Absolute waarde A: Afstand A: Aantrekkingskracht

Nadere informatie

PYTHON REEKS 1: BASICS. Mathias Polfliet

PYTHON REEKS 1: BASICS. Mathias Polfliet PYTHON REEKS 1: BASICS Mathias Polfliet mpolflie@etrovub.be EENVOUDIGE REKENMACHINE 2 soorten getallen Getallen Z -> integers (gehele getallen) Getallen R -> floating points (reële getallen) Door beperkte

Nadere informatie

Uitleg: In de bovenstaande oefening zie je in het eerste blokje een LEES en een SCHRIJF opdracht. Dit is nog lesstof uit het tweede trimester.

Uitleg: In de bovenstaande oefening zie je in het eerste blokje een LEES en een SCHRIJF opdracht. Dit is nog lesstof uit het tweede trimester. In onderstaande oefeningen zijn kleuren gebruikt. Deze dienen aleen om de structuren makkelijker terug te kunnen herkennen. Ze worden niet standaard zo gebruikt. De dunne rood/roze balken zijn ook geen

Nadere informatie

Opgaven. Python Assessment

Opgaven. Python Assessment Opgaven Python Assessment Nijmegen - Utrecht www.atcomputing.nl Copyright 2015,2016 Versie: 1a Inleiding Met dit assessment kun je controleren of je voldoende parate kennis over Python hebt om te beginnen

Nadere informatie

Programmeren. a. 0, 0, 0 b. 0, 0, 27 c. 15, 12, 0 d. 15, 12, 27

Programmeren. a. 0, 0, 0 b. 0, 0, 27 c. 15, 12, 0 d. 15, 12, 27 Programmeren 0. (1 punt.) Stel, een "afhankelijk kind" is een persoon is die jonger is dan 18 jaar, en hooguit 8.000 euro verdient. Welke van de onderstaande expressies definieert een afhankelijk kind?

Nadere informatie

case: toestandsdiagrammen

case: toestandsdiagrammen Hoofdstuk 13 case: toestandsdiagrammen In dit hoofdstuk wordt het maken van de eerste versie van de toestandsdiagrammen voor het boodschappensysteem van Hans en Jacqueline uitgewerkt. 13.1 Vind klassen

Nadere informatie

Scala. Korte introductie. Sylvia Stuurman

Scala. Korte introductie. Sylvia Stuurman Korte introductie Sylvia Stuurman Wat is er zo bijzonder aan? Schaalbaar Objectgeoriënteerd (handiger dan Java!) Functioneel Scripts schrijven Gecompileerd: Java bytecode Pagina 2 voor scripts Pagina 3

Nadere informatie

[7] Variabelen en constanten

[7] Variabelen en constanten [7] Variabelen en constanten We gaan een eenvoudig programma schrijven waarbij we reclame maken voor CoderDojo Dendermonde. Volg mee via 07_VariabelenConstanten.py Dit is wat er moet verschijnen op het

Nadere informatie

Verder zijn er de nodige websites waarbij voorbeelden van objectgeoriënteerd PHP (of Objec Oriented PHP, OO PHP) te vinden zijn.

Verder zijn er de nodige websites waarbij voorbeelden van objectgeoriënteerd PHP (of Objec Oriented PHP, OO PHP) te vinden zijn. Objectgeoriënteerd PHP (versie 5) Kennisvereisten: Ervaring met programmeren in PHP met MySQL Je weet wat een class of klasse is Je weet wat een instantie van een klasse (een object) is Je weet wat een

Nadere informatie

Hoofdstuk 0. Van Python tot Java.

Hoofdstuk 0. Van Python tot Java. Hoofdstuk 0. Van Python tot Java. In dit eerste hoofdstuk maken we de overstap van Python naar Java. We bespreken de verschillen en geven wat achtergrondinformatie. In het volgende hoofdstuk gaan we dieper

Nadere informatie

Ontwerp van Informatiesystemen

Ontwerp van Informatiesystemen 1ste bach HIB Ontwerp van Informatiesystemen Prof. Verelst Q www.quickprinter.be uickprinter Koningstraat 13 2000 Antwerpen 112 2,50 Online samenvattingen kopen via www.quickprintershop.be Table of Contents

Nadere informatie

Disclaimer Het bestand dat voor u ligt, is nog in ontwikkeling. Op verzoek is deze versie digitaal gedeeld. Wij willen de lezer er dan ook op wijzen

Disclaimer Het bestand dat voor u ligt, is nog in ontwikkeling. Op verzoek is deze versie digitaal gedeeld. Wij willen de lezer er dan ook op wijzen Disclaimer Het bestand dat voor u ligt, is nog in ontwikkeling. Op verzoek is deze versie digitaal gedeeld. Wij willen de lezer er dan ook op wijzen dat er zowel typografische als inhoudelijke onvolkomenheden

Nadere informatie

Programmeren in C++ Efficiënte zoekfunctie in een boek

Programmeren in C++ Efficiënte zoekfunctie in een boek Examen Software Ontwikkeling I 2e Bachelor Informatica Faculteit Wetenschappen Academiejaar 2010-2011 21 januari, 2011 **BELANGRIJK** 1. Lees eerst de volledige opgave (inclusief de hints/opmerkingen)!

Nadere informatie

Les F-02 UML. 2013, David Lans

Les F-02 UML. 2013, David Lans Les F-02 UML In deze lesbrief wordt globaal beschreven wat Unified Modeling Language (UML) inhoudt. UML is een modelleertaal. Dat wil zeggen dat je daarmee de objecten binnen een (informatie)systeem modelmatig

Nadere informatie

1 Inleiding in Functioneel Programmeren

1 Inleiding in Functioneel Programmeren 1 Inleiding in Functioneel Programmeren door Elroy Jumpertz 1.1 Inleiding Aangezien Informatica een populaire minor is voor wiskundestudenten, leek het mij nuttig om een stukje te schrijven over een onderwerp

Nadere informatie

return an ; } private I L i s t l i j s t ;

return an ; } private I L i s t l i j s t ; In bovenstaande code werd de binding t e k s t. DataBindings. Add(new Binding ( Text, l i j s t, ) ) ; gebruikt om de eigenschap Text van het object tekst (dwz. tekst.text) te binden aan het object lijst.

Nadere informatie

Programmeermethoden. Recursie. week 11: november kosterswa/pm/

Programmeermethoden. Recursie. week 11: november kosterswa/pm/ Programmeermethoden Recursie week 11: 21 25 november 2016 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 Pointers Derde programmeeropgave 1 Het spel Gomoku programmeren we als volgt: week 1: pointerpracticum,

Nadere informatie

Programmeermethoden NA

Programmeermethoden NA Programmeermethoden NA Week 7: OOP & Modules Kristian Rietveld http://liacs.leidenuniv.nl/~rietveldkfd/courses/prna/ Bij ons leer je de wereld kennen 1 Tweede programmeeropdracht Uiteraard verwachten we

Nadere informatie

Instructies zijn niet alleen visueel, maar ook auditief, met hoogkwalitatief ingesproken geluid (geen computerstem).

Instructies zijn niet alleen visueel, maar ook auditief, met hoogkwalitatief ingesproken geluid (geen computerstem). Getallen 3 Doelgroep Getallen 3 is bedoeld voor leerlingen in klas 3-5 van de havo, klas 3-6 van het vwo en in mbo 3&4. Het programma is bijzonder geschikt voor groepen waarin niveauverschillen bestaan.

Nadere informatie

Practicum Programmeerprincipes

Practicum Programmeerprincipes OPLOSSINGEN REEKS 1 KENNISMAKING MET PICO Evaluatie van expressies Practicum Programmeerprincipes 2009-2010 fvdbergh@vub.ac.be Oefening 1. Oplossing van deze kennismakingsoefening gegeven in de les. Oefening

Nadere informatie

IMP Uitwerking week 13

IMP Uitwerking week 13 IMP Uitwerking week 13 Opgave 1 Nee. Anders moet bijvoorbeeld een venster applicatie een subklasse zijn van zowel Frame en WindowListener. Als de applicatie ook een button of een menu heeft, dan moet het

Nadere informatie

Gebruik van verschilbestanden

Gebruik van verschilbestanden Gebruik van verschilbestanden Inhoud Gebruik van verschilbestanden 1 Inhoud 2 1 Verschilbestanden 3 1.1 Inleiding 3 1.2 Bestanden en identificatoren 3 1.3 Onderzoeken waar de actuele versie verschilt van

Nadere informatie

Objectgeoriënteerd Programmeren: WPO 4B

Objectgeoriënteerd Programmeren: WPO 4B Objectgeoriënteerd Programmeren: WPO 4B 1. Inhoud Polymorfie 2. Oefeningen A: Polygon A: Rekenmachine A: Infection A: Waves E: Snake X: Pacman X: Planetendans 2.1 A: Polygon Herneem de opgave Polygon van

Nadere informatie

Constanten. Variabelen. Expressies. Variabelen. Constanten. Voorbeeld : varid.py. een symbolische naam voor een object.

Constanten. Variabelen. Expressies. Variabelen. Constanten. Voorbeeld : varid.py. een symbolische naam voor een object. een symbolische naam voor een object. Variabelen Constanten Variabelen Expressies naam : geeft de plaats in het geheugen aan waarde : de inhoud van het object identifier : een rij van letters en/of cijfers

Nadere informatie

Zelftest Inleiding Programmeren

Zelftest Inleiding Programmeren Zelftest Inleiding Programmeren Document: n0824test.fm 22/01/2013 ABIS Training & Consulting P.O. Box 220 B-3000 Leuven Belgium TRAINING & CONSULTING INLEIDING BIJ DE ZELFTEST INLEIDING PROGRAMMEREN Deze

Nadere informatie

Controle structuren. Keuze. Herhaling. Het if statement. even1.c : testen of getal even of oneven is. statement1 statement2

Controle structuren. Keuze. Herhaling. Het if statement. even1.c : testen of getal even of oneven is. statement1 statement2 Controle structuren De algemene vorm: 1 bloks door middel van indentatie Keuze Herhaling if expressie :...... In de volgende vorm is het else gedeelte weggelaten: if expressie :... Het if keuze- of conditioneel

Nadere informatie

VISUALISATIE VAN KROMMEN EN OPPERVLAKKEN. 1. Inleiding

VISUALISATIE VAN KROMMEN EN OPPERVLAKKEN. 1. Inleiding VISUALISATIE VAN KROMMEN EN OPPERVLAKKEN IGNACE VAN DE WOESTNE. Inleiding In diverse wetenschappelijke disciplines maakt men gebruik van functies om fenomenen of processen te beschrijven. Hiervoor biedt

Nadere informatie

PROS1E1 Gestructureerd programmeren in C Dd/Kf/Bd

PROS1E1 Gestructureerd programmeren in C Dd/Kf/Bd Inhoudsopgave 1 Inleiding... 1 2 Toekenning- en herhalingsopdrachten (for loop)... 2 2.1 De wet van Ohm... 3 2.2 De spaarrekening... 3 2.3 De transformator... 3 3 Keuze- en herhalingsopdrachten (if, switch,

Nadere informatie