[17:47] <leoquant> het staat hier nu op +m commandoline  en StefandeVries
[17:47] <leoquant> ik ga zo eten, maar op de tijd terug te zijn hier
[17:47] <StefandeVries> dank je, leoquant
[17:47] <StefandeVries> tot later
[17:48] <leoquant> alvast weer bedankt, en succes
[18:30] <commandoline> Welkom bij de zesde les Python allemaal
[18:30] <commandoline> we gaan vandaag verder met functies
[18:31] <commandoline> maar voordat we dat doen wil ik even het huiswerk bespreken
[18:31] <commandoline> ten eerste de opdracht om een eigen alternatief voor de len()-functie te schrijven.
[18:31] <commandoline> genaamd num()
[18:32] <commandoline> http://paste.ubuntu.com/579208/
[18:32] <commandoline> goed, even lijn voor lijn wat er gebeurd.
[18:33] <commandoline> we beginnen met het definiëren van de functie num(), zodat we die later kunnen gebruiken. De functie heeft één argument, items, wat de list/dictionary is waarvan we de lengte willen weten.
[18:33] <commandoline> daarna volgt de code om de eigenlijke lengte te berekenen:
[18:34] <commandoline> de code loopt met behulp van de for-loop door alle items, en hoogt voor ieder item de teller 'aantal' op met 1.
[18:34] <leoquant> hannie> Het werkt bij mij ook zonder argument
[18:34] <commandoline> ten slotte wordt aantal teruggegeven aan de aanroeper
[18:35] <commandoline> terwijl StefandeVries hannie's vraag beantwoord, leg ik nog even de laatste paar regels uit
[18:35] <commandoline> daar wordt de functie nl. gebruikt.
 hannie: het kan zijn dat dat toevallig goed ging, maar voor een goede programmeerstijl vooral erin houden
[18:36] <commandoline> was het antwoord.
[18:37] <commandoline> om de functie te testen maken we twee dingen (objecten) aan: een list en een dictionary
[18:37] <commandoline> over beide wordt zowel de functie num() als len() aangeroepen, en beide geven hetzelfde resultaat terug.
[18:38] <commandoline> overigens: de functie len() is intern anders geimplementeerd, en kan meer. Gebruik dus nooit een eigen implementatie in de praktijk, nergens voor nodig ;)
[18:38] <commandoline> goed, begrijpt iedereen wat er hier gebeurd?
[18:39] <commandoline> geen vragen? Dan gaan we verder naar de tweede opdracht
[18:39] <commandoline> http://paste.ubuntu.com/579219/
[18:40] <commandoline> wat we hier zien is het bekende rekenmachineprogramma, maar weer in een andere vorm.
[18:40] <commandoline> als je wat anders hebt hier is het niet vreemd, want het kan op verschillende manieren
[18:41] <commandoline> maar wat wij kortweg gedaan hebben:
[18:41] <commandoline> maar wat wij kortweg gedaan hebben:
[18:41] <commandoline> :(
[18:41] <commandoline> - een functie maken voor het menu, zoals we die dacht ik vorige les al hadden gezien.
[18:42] <commandoline> - ieder menuitem in een functie gezet, om de code wat duidelijker te houden.
[18:42] <commandoline> wat nog had gekunt was het vragen van getallen in een functie zetten, of het verplaatsen naar voor het if-statement
[18:42] <commandoline> (if keuze == 1; if keuze == 2 etc.)
[18:43] <commandoline> maar zoals ik al zei, er zijn hier meerdere mogelijkheden
[18:43] <commandoline> ok, nog vragen?
[18:43] <commandoline> goed, dan gaan we verder
[18:44] <commandoline> jullie weten nu hoe je zelf functies kan schrijven, en hoe je ze aanroept.
 Waarom geen switch-case?
[18:45] <StefandeVries> Die bestaat niet in Python
[18:45] <commandoline> er is overigens wel een mogelijkheid:
[18:45] <commandoline> een dictionary maken met functies daarin
[18:45] <commandoline> maar dat is hier denk ik alleen maar onduidelijker
[18:46] <leoquant> CasW> Waarom geen switch-case?
[18:46] <commandoline> het mooie aan python is, dat de makers ervan al een heleboel functies hebben geschreven die wij kunnen gebruiken in onze programma's met maar weinig moeite
[18:46] <commandoline> leoquant, die vraag is net beantwoord ;)
[18:46] <leoquant> !
[18:47] <commandoline> en vandaag wilde ik jullie dus een aantal van die functies laten zien
[18:47] <commandoline> allemaal gaat niet lukken, want het zijn er honderden
[18:47] <commandoline> maar ik zal er een aantal laten zien die ik en StefandeVries vaak gebruiken
[18:47] <commandoline> open allemaal een terminal met daarin python
[18:48] <commandoline> dit is makkelijker om uit te proberen in de interactieve sessie dan in een opgeslagen programma.
[18:48] <commandoline> dus:
[18:48] <commandoline> Toepassingen > Hulpmiddelen > Terminalvenster
[18:48] <commandoline> 'python' intikken en op enter drukken
[18:49] <commandoline> goed, omdat python zoveel functies ingebouwd heeft, zijn ze geordend in zogenaamde 'modules'.
[18:49] <commandoline> standaard zijn modules niet geladen, dat moeten we doen op het moment dat we ze willen gebruiken.
[18:49] <commandoline> De eerste module die ik jullie wil laten zien, is de os module
[18:50] <commandoline> die kun je laden door 'import os' in te tikken.
[18:50] <commandoline> overigens staat de uitgebreide (Engelstalige) documentatie van alle modules hier: http://docs.python.org/library/
[18:50] <commandoline> en van de os-module specifiek: http://docs.python.org/library/os.html
[18:51] <commandoline> goed, de eerste functie die ik wil bespreken is os.listdir()
[18:52] <commandoline> die heeft één argument, zoals ook hier te lezen valt: http://docs.python.org/library/os.html#os.listdir
[18:52] <commandoline> nl. een locatie
[18:52] <commandoline> de functie geeft na aanroepen een lijst terug met alle bestanden en mappen in 'locatie'
[18:52] <commandoline> type in:
[18:52] <commandoline> os.listdir(".")
[18:53] <commandoline> . is de huidige map, dat is in de meeste gevallen jullie home-map.
[18:53] <commandoline> je ziet trouwens ook alle verborgen bestanden, dus het kan nogal een lange lijst teruggeven.
[18:54] <commandoline> je kan ook een andere locatie ("path") proberen
[18:54] <commandoline> bijv.:
[18:54] <commandoline> os.listdir("/home")
[18:54] <commandoline> ok, volgende functie:
[18:54] <commandoline> os.remove()
[18:55] <commandoline> daarmee moet je oppassen
[18:55] <commandoline> het verwijdert nl. een bestand, en dat zonder te vragen of je het zeker weet o.i.d.
[18:56] <commandoline> je kan 'm uitproberen door een lege map aan te maken met daarin een leeg bestand
 moet je bij elke terminalsessie opnieuw importeren?
 Ja
[18:56] <commandoline> en dan dat bestand verwijderen
[18:56] <commandoline> het argument werkt net zoals bij os.listdir
[18:56] <commandoline> maar doe dat alleen als je bovenstaande instructies begrijpt.
[18:57] <commandoline> overigens kan je os.remove niet gebruiken om mappen weg te gooien
[18:57] <commandoline> alleen bestanden, en dan één voor één.
[18:57] <commandoline> voor mappen kun je os.rmdir gebruiken
[18:58] <commandoline> maar die werkt alleen als de map die je probeert te verwijderen compleet leeg is
[18:58] <commandoline> dan is er nog één functie uit os die ik jullie wil laten zien: os.walk()
 Vraag: Dus je gebruikt os.remove in combinatie met os.rmdir om een map met bestanden weg te gooien >?
[19:00] <commandoline> dat kan, zeker als je 'm combineert met os.walk die we nu bespreken zoals je straks misschien zult zien.
[19:00] <commandoline> maar makkelijker is om de shutil module te gebruiken.
[19:00] <commandoline> die heeft functies als rmtree()
[19:00] <commandoline> dat alles in een map verwijdert, dat zijn dus de echt gevaarlijke functies als je niet precies weet waar je mee bezig bent
[19:01]  * commandoline heeft er een keer m'n halve home map mee leeggegooid.
[19:01] <commandoline> *z'n, als ik /me gebruik :P
[19:01] <commandoline> ok, os.walk:
[19:01] <commandoline> http://docs.python.org/library/os.html#os.walk
[19:02] <commandoline> die functie wordt meestal gebruikt i.c.m. de for-loop
[19:02] <commandoline> ik zal een voorbeeldje ervan geven, maar het verder niet uitleggen.
[19:02] <commandoline> als het nu niet duidelijk is, komt dat vanzelf.
[19:03] <commandoline> http://paste.ubuntu.com/579427/
[19:04] <commandoline> je kan het overtypen in de terminal, maar als jullie syntax errors krijgen zet het dan gewoon even in een bestand
 En niet met "marten" zeker.
[19:04] <commandoline> even aanpassen idd
[19:04] <StefandeVries> Tenzij je Marten heet
[19:05] <commandoline> idd :P
[19:05] <commandoline> goed, tenzij iemand nog vragen heeft over os wil ik door met os.path
[19:06] <StefandeVries> Ik zie geen vragen =)
[19:06] <commandoline> os.path is een zogenaamde submodule van os
[19:07] <commandoline> en dat heeft als voordeel dat je 'm niet hoeft te importeren als je os al hebt geimporteerd
 ik krijg geen output
[19:07] <StefandeVries> hannie: staat er iets op je bureaublad, en heb je je gebruikersnaam aangepast?
[19:08] <commandoline> als de map niet bestaat zou hij een foutmelding geven, en hij geeft altijd wat output.
[19:08] <commandoline> het werkt hier gewoon, dus hier komen we later even op terug hannie
[19:08] <commandoline> importeren
 na enter zie ik >>>
[19:09] <commandoline> bedoel ik
[19:09] <commandoline> lijkt me toch dat het bureaublad leeg is, maar goed, zo verder.
[19:10] <commandoline> je kan os.path wel importeren via 'import os.path' overigens
[19:10] <commandoline> als je dat doet is os.listdir niet beschikbaar
[19:10] <commandoline> maar goed, jullie hebben os geimporteerd, dus automatisch ook os.path
[19:10] <commandoline> dus, door naar de eerste functie
[19:11] <commandoline> (nadat jullie de documentatie hebben gekregen van os.path: http://docs.python.org/library/os.path.html)
[19:11] <commandoline> de eerste functie uit os.path die ik wil behandelen is os.path
[19:12] <commandoline> stel je voor dat je weet dat je op linux werkt, en dat er een /home map bestaat.
[19:12] <commandoline> en de gebruikersnaam niet weet
[19:12] <commandoline> dan kun je die vragen aan de gebruiker
[19:12] <commandoline> je zou dan iets kunnen doen als:
[19:12] <commandoline> locatie = "/home/" + raw_input("Geef de gebruikersnaam: ")
[19:13] <commandoline> het probleem aan deze code is dat zodra de / achter home weg gaat, de code crasht
[19:13] <commandoline> voor dat soort problemen hebben de python ontwikkelaars de functie os.path.join() geschreven
[19:14] <commandoline> die werkt op ieder platform waarop python draait
[19:14] <commandoline> dus op linux, mac os x, windows, bsd, etc. etc.
[19:14] <commandoline> de code uit mijn voorbeeld wordt er als volgt mee herschreven:
[19:14] <commandoline> locatie = os.path.join("/home", raw_input("Geef de gebruikersnaam: "))
 als je de gebruikersnaam niet weet kan je hem ook niet intypen
 Je == de programmeur, voor als je een programma voor iemand anders schrijft
[19:15] <commandoline> ok, iedereen begrijpt de werking van os.path.join() ?
[19:15] <commandoline> de volgende is os.path.splitext()
[19:16] <commandoline> die kan je bijv. gebruiken als je een programma hebt dat bestanden maakt met de extensie .jdkf
[19:16] <commandoline> om een voorbeeld te noemen :P
[19:16] <commandoline> je wil dan contoleren of het bestand wat de gebruiker selecteert, eindigt op 'jdkf'
[19:17] <commandoline> dat kan op verschillende manieren, maar één daarvan is om de extensie op te vragen met os.path.splitext()
[19:17] <commandoline> het voorbeeld zou je bijv. kunnen vertalen naar de volgende code:
[19:17] <commandoline> if os.path.splitext("/locatie/die/eindigt/op.jdkf")[1] == "jdkf":
[19:18] <commandoline> #alles goed
 hiermee worden dus de naam en de extensie gescheiden
[19:18] <commandoline> inderdaad, er wordt een 'tuple' (een soort list) teruggegeven.
[19:18] <commandoline> met twee items:
[19:18] <commandoline> alles wat voor de extensie staat
[19:18] <commandoline> en de extensie
[19:18] <commandoline> met [1] krijg ik dus de extensie
[19:18] <commandoline> met [0] krijg ik alles wat daarvoor staat.
[19:19] <commandoline> ok, dat was alles wat ik wilde laten zien van os.path
[19:19] <commandoline> iemand nog vragen tot zover?
[19:19] <commandoline> nee, dan pakken we de volgende module erbij:
[19:19] <commandoline> math
[19:19] <commandoline> dus, doe allemaal:
[19:19] <commandoline> import math
[19:20] <commandoline> math bevat wiskundige functies, zoals sqrt (square root = vierkantswortel)
[19:20] <commandoline> je kan er dus de wortel mee uit een getal trekken.
[19:20] <commandoline> math.sqrt(2) geeft bijv.
[19:21] <commandoline> 1.4142135623730951
[19:21] <commandoline> en zo zitten er nog veel meer functies in.
[19:21] <commandoline> kijk gewoon de documentatie eens door als je ze nodig hebt:
[19:21] <commandoline> http://docs.python.org/library/math.html
[19:22] <commandoline> ok, ik heb nog twee modules, en omdat het idee zolangzamerhand wel duidelijk is, wil ik daar wat sneller doorheen
[19:22] <commandoline> we willen niet over de tijd heengaan...
[19:22] <commandoline> de eerste is subprocess
[19:22] <commandoline> import subprocess
[19:22] <commandoline> dus
[19:23] <commandoline> subprocess maakt het mogelijk om andere applicaties te starten
[19:23] <commandoline> probeer bijv. eens:
[19:23] <commandoline> subprocess.call(["firefox"])
[19:23] <commandoline> of: subprocess.call(["python", "bestand_om_uit_te_voeren.py"])
 Waarom die haakjes?
[19:24] <StefandeVries> FOAD: de ronde haakjes omdat het een functieaanroep is
[19:24] <StefandeVries> FOAD: de vierkante omdat elk argument een element van een lijst is
[19:25] <commandoline> en die functie vraagt nou eenmaal een lijst als invoer
[19:25] <StefandeVries> Helder?
[19:25] <StefandeVries> Mooi
[19:26] <commandoline> ok, het is mogelijk om i.p.v. subprocess.call os.system te gebruiken. De python handleiding zegt niet dat die laatste veroudert is, maar dat wordt door sommige mensen wel zo gezien.
[19:26] <commandoline> dus mijn persoonlijke advies is om gewoon de subprocess module te gebruiken om commando's uit te voeren als dat al moet
[19:26] <commandoline> want, door dit soort commando's uit te voeren, maak je je programma systeemafhankelijk
[19:27] <commandoline> sommige van deze commando's zouden mogelijk bijv. niet werken op windows.
[19:27] <commandoline> ok, dan de laatste module nog even snel: sys
[19:27] <commandoline> doe:
[19:27] <commandoline> import sys
[19:27] <commandoline> en vervolgens:
[19:27] <commandoline> sys.exit()
[19:28] <commandoline> en python is afgesloten
[19:28] <commandoline> je hebt ook de exit() functie hiervoor, maar die werkt in sommige gevallen niet
[19:28] <commandoline> (bijv. bij jython, even googlen als je nieuwsgierig bent daarnaar.)
[19:28] <commandoline> ook is het mogelijk om via sys argumenten mee te krijgen:
[19:29] <commandoline> bijv. als je programma zo wordt aangeroepen:
 waarom niet quit()
[19:29] <commandoline> python programma.py argument1 argument2
[19:29] <commandoline> dan kan je argument1 en argument2 zien via de list 'sys.argv'
[19:29] <commandoline> probeer het maar eens uit
[19:29] <StefandeVries> hannie: bij sommige Pythons werkt dit niet. sys.exit() werkt altijd en is veiliger
[19:29] <commandoline> en het is ook een keuze van de python ontwikkelaars geweest om het exit() te noemen :)
[19:30] <commandoline> ok, nog even huiswerk:
[19:30] <commandoline> schrijf een programma, dat de gebruiker om een map vraagt
[19:30] <commandoline> en vervolgens alle python programma's in die map uitvoert.
[19:31] <leoquant> leuk
[19:31] <commandoline> en dan hoop ik jullie volgende week allemaal weer te zien
[19:31] <commandoline> StefandeVries en ik zijn hier nog even voor vragen :)
[19:31] <StefandeVries> En dat hoop ik uiteraard ook ;)
[19:31] <commandoline> en ook door de week mag je altijd vragen stellen in #ubuntu-nl-mwanzo of via PM's aan ons.
[19:32]  * leoquant biedt virtuele bloemen aan de leiders
[19:33] <leoquant> dit kanaal is weer open nu