[18:26] <FOAD> Ik ben er klaar voor.
[18:26] <DooitzedeJong> Ik ook :)
[18:27] <FOAD> Booyaka booyaka!
[18:29] <DooitzedeJong> Wolkom Hannie
[18:31] <commandoline> Welkom allemaal bij de 11e les uit de pythoncursus!
[18:31] <commandoline> deze keer weer gewoon via chat
[18:31] <commandoline> laten we beginnen met het huiswerk
[18:32] <commandoline> http://paste.ubuntu.com/597948/
[18:32] <commandoline> ik heb samen met Dooitze vandaag een uitwerking gemaakt
[18:32] <commandoline> met daarbij een interface die de meeste fouten e.d. afvangt.
[18:33] <commandoline> de interface kunnen jullie zelf bekijken
[18:33] <commandoline> wat ik wel even wil bespreken
[18:33] <commandoline> is de Woordenlijst class
[18:33] <commandoline> want daar zit alle logica in die jullie zelf ook (of niet :P) tegengekomen zijn
[18:34] <commandoline> ten eerste is er een __init__ die de property data definieert.
[18:35] <commandoline> de gebruiker communiceert daarmee via de verwijder(), zoek_op() en voeg_toe_of_verander_betekenis() methods
[18:36] <commandoline> die doen overigens niet veel bijzonders, ze vangen bijv. ook geen exceptions af
[18:36] <commandoline> dat doet de interface bij deze implementatie
[18:38] <commandoline> interessanter zijn de laad() en sla_op() methods
[18:38] <commandoline> de laad opent het bestand op regel 30
[18:38] <commandoline> en loopt door iedere regel op een manier die jullie nog niet kennen, maar wel handig is :)
[18:39] <commandoline> for regel in bestand:
[18:39] <commandoline> namelijk
[18:39] <commandoline> daarna scheiden we het woord van de betekenis:
[18:39] <commandoline> woord, betekenis = regel.split(" = ", 1)
[18:39] <commandoline> opnieuw een trucje
[18:40] <commandoline> erboven staat uitleg
[18:40] <commandoline> daarna roepen we op het resultaat nog .strip() aan
[18:40] <commandoline> en wordt ieder woord toegevoegd aan de dictionary self.data.
[18:40] <commandoline> oja, over die split()
[18:41] <commandoline> die krijgt hier dus een tweede argument
[18:41] <commandoline> dat argument geeft aan hoe vaak er gesplit moet worden
[18:41] <commandoline> sla op doet ongeveer het omgekeerde:
[18:42] <commandoline> - die loopt door iedere entry van self.data
[18:42] <commandoline> - bouwt daaruit een regel op
[18:42] <commandoline> - en voegt die toe aan 'tekst'
[18:43] <commandoline> daarna wordt het bestand geopend, dit keer met schrijfrechten, en daarna wordt de data weggeschreven m.b.v write()
[18:43] <commandoline> de interface zou ik zeker nog een keertje doorkijken vanwege de foutafhandeling die erin zit
[18:44] <commandoline> nl. IOError en KeyError, maar ook allerlei if-statements etc.
[18:45] <commandoline> hannie's programma ziet er ook goed uit, het bekijken waard :)
[18:45] <commandoline> iemand nog vragen over jullie uitwerkingen of de uitwerking van Dooitze en mij?
[18:45] <commandoline> of andere vragen?
[18:46] <DooitzedeJong> Hannie gaf aan dat het laden wel goed werkte maar "writelines"
[18:47] <DooitzedeJong> niet helemaal
[18:48] <DooitzedeJong> Van de code van Hannie: http://paste.ubuntu.com/597946/
[18:48] <commandoline> ok, toch even kort dan:
[18:49] <commandoline> nee, laat maar, kom ik later op terug :P
[18:50] <commandoline> jullie kennen nu al veel python zoals ook wel te zien is aan de programma's.
[18:50] <commandoline> wat ik vandaag wil doen is nog een aantal overgebleven dingetjes uitleggen
[18:51] <commandoline> ten eerste: tuples
[18:51] <commandoline> tuples zijn gelijk aan lists, het verschil is dat ze 'unmutable' zijn.
[18:51] <commandoline> dat houdt in dat je ze niet meer kan aanpassen nadat je ze hebt aangemaakt
[18:51] <commandoline> dat heeft een aantal voordelen:
[18:52] <commandoline> - je weet zeker dat je list niet wordt aangepast, als je dat niet wilt
[18:52] <commandoline> - het is een beetje sneller
[18:52] <commandoline> (19:52:07) hannie: moet ik bij tuples denken aan 'paren'?
[18:52] <commandoline> hannie: dat is de letterlijke vertaling ja, maar denk maar gewoon aan python lists.
[18:53] <commandoline> die snelheid is trouwens pas meetbaar als je een heleboel tuples hebt, maar als je toch je list niet hoeft aan te passen, kan je net zo goed een tuple gebruiken
[18:53] <commandoline> - je kunt tuples gebruiken als keys in dictionary
[18:54] <commandoline> we hebben tot nu toe daarvoor vooral strings gebruikt
[18:54] <commandoline> bijv. een list kan nl. niet
[18:54] <commandoline> een tuple dus wel
[18:54] <commandoline> een list kan nl. veranderen, en dat is niet handig voor een dictionary key
[18:55] <commandoline> een tuple kan dat niet, en daarom kan het wel
[18:55] <commandoline> ok, nog even over hoe je een tuple aanmaakt:
[18:55] <commandoline> (19:55:13) hannie: commandoline, een list kan nl. niet?????
[18:55] <commandoline> klopt, een list kan je niet als dictionary key gebruiken.
[18:55] <commandoline> tuple = ("item1", "item2", "item3")
[18:56] <commandoline> je kan nu allerlei dingen doen die je ook met lists kan:
[18:56] <commandoline> tuple[0] #item1
[18:56] <commandoline> "item1" in tuple #True
[18:56] <commandoline> wat niet kan:
[18:56] <commandoline> tuplle.append("waarde")
[18:56] <commandoline> *tuple
[18:57] <commandoline> ok, probeer het even uit zoals hannie al zegt.
[18:57] <commandoline> vragen over tuples? Want dit is eigenlijk alles wat je ervan moet weten :)
[18:58] <commandoline> (19:58:50) hannie: ik krijg een AttributeError
[18:59] <commandoline> (19:59:25) hannie: ik deed: tuple.append('item4')
[18:59] <commandoline> dat klopt
[18:59] <commandoline> want dat kan dus niet, een tuple heeft i.t.t. een list geen attributes
[18:59] <commandoline> (properties)
[19:00] <commandoline> (en methods)
[19:00] <commandoline> en daarom krijg je die error.
[19:00] <commandoline> (20:00:06) hannie: Hoe kan je dan een item toevoegen?
[19:00] <commandoline> niet, een tuple is niet meer te veranderen na het aanmaken
[19:00] <commandoline> en dat is dus het verschil met een lijst
[19:00] <commandoline> zie voor de voordelen een stukje naar boven
[19:00] <commandoline> ok, duidelijk?
[19:01] <FOAD> Ja
[19:01] <commandoline> (20:01:44) hannie: maar wat is dan het voordeel t.o.v. een lijst?
[19:02] <commandoline> (20:02:08) hannie: alleen sneller?
[19:02] <commandoline> nee, ze zijn dus ook te gebruiken als keys in dictionaries
[19:02] <commandoline> terwijl dat met lists niet kan
[19:03] <commandoline> (20:02:56) hannie: kan je daar een voorbeeldje van geven?
[19:03] <commandoline> dict = {}
[19:03] <commandoline> dict[(1, 2)] = "test"
[19:03] <commandoline> dict[[1, 2]] = "test"
[19:03] <commandoline> het eerste werkt, het tweede niet
[19:03] <commandoline> (20:03:35) hannie: en hoe krijg ik dan die tuple in dic{}?
[19:04] <commandoline> de eerste van de voorbeelden hierboven gebruikt een tuple als key
[19:04] <commandoline> de tweede een list
[19:05] <commandoline> (20:04:55) hannie: zie je dat aan de ronde haakjes ()?
[19:05] <commandoline> klopt, er is één uitzondering:
[19:05] <commandoline> tuple = (1,)
[19:05] <commandoline> als je één item hebt, moet die komma erbij
[19:05] <commandoline> anders werkt het als voorrangshaakje (net zoals bij wiskunde)
[19:06] <commandoline> ook, het volgende onderwerp wat ik behandelen is 'variable length argument lists'
[19:06] <commandoline> beter bekend als '*args, **kwargs'
[19:08] <commandoline> http://paste.ubuntu.com/597960/
[19:08] <commandoline> oh, ik ben nog wat vergeten...
[19:09] <commandoline> http://paste.ubuntu.com/597962/
[19:09] <commandoline> het * voor args geeft aan dat er op die plaats 0, 1 of meer argumenten kunnen worden gegeven
[19:10] <commandoline> en die argumenten komen dan in de tuple args terecht
[19:10] <commandoline> (20:10:02) FOAD: Moet het "*args" heten?
[19:10] <commandoline> nee, maar dat is wel aanbevolen, omdat iedere python programmeur direct zal weten wat je bedoelt als je *args gebruikt
[19:10] <commandoline> overigens, het is ook nog mogelijk om sum() zo aan te roepen:
[19:11] <commandoline> sum(*[1, 2, 4, 934])
[19:11] <commandoline> dat doet dus precies het omgekeerde
[19:11] <commandoline> alle items in een list worden ingevoerd als argumenten
[19:11] <commandoline> ok, door naar **kwargs
[19:11] <commandoline> (20:11:47) hannie: en mag dat ook tekst zijn?
[19:12] <commandoline> je kan op zich een string als argument meegeven, maar dat heeft als nadeel dat python tekst niet op kan tellen
[19:12] <commandoline> en dan krijg je één of andere exception
[19:13] <commandoline> oja, de functie sum() zit standaard in python, die hoef je zelf niet te schrijven
[19:13] <commandoline> (20:13:40) hannie: maar je telt gewoon een reeks cijfers bij elkaar op dus
[19:13] <commandoline> klopt
[19:14] <commandoline> ok, voordat ik **kwargs uit kan leggen moeten jullie weten dat je in python argumenten bij hun naam kan noemen, bijv:
[19:14] <commandoline> def doeIets(a, b=8, c=2):
[19:14] <commandoline>     #doe iets met a, b en c
[19:15] <commandoline> stel nu dat je argument a en c wil meegeven, maar dat je b wilt laten staan, je kan dan dit doen:
[19:15] <commandoline> doeIets(5, c=4)
[19:15] <commandoline> wat ook kan:
[19:15] <commandoline> doeIets(a=3, b=4, c=2)
[19:15] <commandoline> het mag dus altijd, de argumenten bij naam noemen
[19:16] <commandoline> begrijpen jullie wat ik daar doe?
[19:16] <commandoline> (20:16:04) hannie: neemt 5 dan de plaats in van variabele a?
[19:16] <commandoline> a wordt 5
[19:16] <commandoline> (20:16:10) FOAD: En dan maakt de volgorde niet uit?
[19:16] <commandoline> ik geloof het niet, hoewel ik dat eigenlijk niet zeker weet...
[19:16] <commandoline> dat zou je kunnen uitproberen :)
[19:17] <commandoline> (20:17:26) hannie: hoe kan c=2 dan c=4 worden? Dat deel begrijp ik niet
[19:17] <commandoline> argumenten kan je overschrijven
[19:17] <commandoline> iets concreter:
[19:18] <commandoline> def maak_person(naam="jan"):
[19:18] <commandoline>     #maak een persoon aan
[19:18] <commandoline> dan kan je deze twee dingen doen:
[19:18] <commandoline> person = maak_person()
[19:18] <commandoline> person = maak_person("klaas")
[19:18] <commandoline> (20:18:07) hannie: maar dan kan je toch gewoon 'c' declareren i.p.v. c-2?
[19:19] <commandoline> dat kan, maar dan is de standaard keuze dus niet beschikbaar
[19:20] <commandoline> goed, er bestaat in python een functie dict()
[19:20] <commandoline> je kan er een dictionary mee maken, hoewel we dat niet hebben gedaan omdat het makkelijker is om {} te gebruiken
[19:20] <commandoline> (20:20:16) hannie: even herleidend: ju kunt het argument dus meteen al een waarde meegeven
[19:20] <commandoline> (20:20:31) hannie: en die kan je later weer vervangen. Heb ik dat zo goed begrepen?
[19:20] <commandoline> ja
[19:20] <commandoline> (20:20:52) FOAD: Je geeft een soort van default waardes mee.
[19:21] <commandoline> dat is hoe ze heten, default values :)
[19:21] <commandoline> ok, de functie dict() kan je bijv. zo aanroepen:
[19:22] <commandoline> woordenboek = dict(voorbeeld="example", test="try")
[19:22] <commandoline> daarna is woordenboek gelijk aan:
[19:22] <commandoline> {"voorbeeld": "example", "test": "try"}
[19:23] <commandoline> het punt is, we geven hier geen argumenten op die dict standaard al kent
[19:23] <commandoline> als je zelf een dergelijk effect wilt bereiken, kan je **kwargs gebruiken
[19:24] <commandoline> (20:23:41) hannie: Ik zie nog niet helemaal het voordeel van een defaultwaarde instellen, maar dat komt nog wel
[19:24] <commandoline> het is vaak nuttig als je een argumenten hebt, waarvan de standaardinstelling in 90% van de gevallen voldoet. Dan hoeft de aanroeper niet 90% van de keren datzelfde argument mee te geven
[19:25] <commandoline> een voorbeeldje:
[19:25] <commandoline> http://paste.ubuntu.com/597964/
[19:26] <commandoline> ho, een sterretje te weinig...
[19:27] <commandoline> http://paste.ubuntu.com/597965/
[19:28] <commandoline> ok, de standaard dict functie zit ingewikkelder in elkaar
[19:28] <commandoline> maar ik hoop dat het idee duidelijk is, dat je alle 'keyword arguments' kunt opvragen in een dictionary
[19:28] <commandoline> (20:28:34) hannie: leg je die sterretjes nog even uit?
[19:29] <commandoline> één sterretje (bij conventie gevolgd door 'args') geeft aan dat je alle normale argumenten wilt hebben in de tuple 'args'
[19:29] <commandoline> twee sterretjes (bij conventie gevolgd door 'kwargs') geven aan dat je alle 'keyword' argumenten wilt hebben in een dictionary genaamd 'kwargs'
[19:30] <commandoline> en keywordargumenten zijn dus alle argumenten waarbij je een naam noemt bij het aanroepen
[19:30] <commandoline> in het bovenstaande voorbeeld dus a=4
[19:30] <commandoline> maar ook c=4
[19:30] <commandoline> zodra we a niet noemden
[19:30] <commandoline> doeIets(3, c=4) was het ofzo
[19:31] <commandoline> dan is 3 een 'normaal' argument (dat je zou krijgen met *args), en is c=4 een keyword argument, dat je zou krijgen via **kwargs.
[19:31] <commandoline> ok, vragen?
[19:32] <commandoline> het is vooral belangrijk om dit passief te snappen want het komt best veel voor in code. Actief snappen is handig, maar niet noodzakelijk en komt dan vanzelf wel
[19:34] <commandoline> Goed, dan nog even het huiswerk
[19:34] <commandoline> het is als je python schrijft handig om één stijl qua code aan te houden
[19:35] <commandoline> een voorbeeld is dat sommige mensen functie( argument1 , argument2 ) schrijven
[19:35] <commandoline> en anderen: functie(argument1, argument2)
[19:35] <commandoline> beide werkt, maar er zijn richtlijnen die vaststellen wat je het beste kan doen.
[19:36] <commandoline> de belangrijkste voor python is PEP8, de python style guide
[19:36] <commandoline> http://www.python.org/dev/peps/pep-0008/
[19:36] <commandoline> ik zou jullie aanraden om eens te kijken waar je wat ongeveer kan vinden daar.
[19:36] <commandoline> (even de kopjes scannen)
[19:36] <commandoline> (20:35:39) FOAD: Het eerste is mooier.
[19:36] <commandoline> (20:35:43) FOAD: Is dat het antwoord?
[19:36] <commandoline> (20:36:18) hannie: dat 2e druist in tegen onze schrijfwijze
[19:37] <commandoline> volgens PEP8 is het tweede mooier
[19:37] <commandoline> en het is ook wat ik doe :)
[19:37] <commandoline> en dat is tegelijk ook het huiswerk voor deze keer, kijk even hoe PEP 8 in elkaar zit
[19:37] <commandoline> zodat je er iets in op zou kunnen zoeken
[19:38] <commandoline> ok, tot volgende week, dat is waarschijnlijk de laatste, of anders op één na laatste, les!