Python – Leren programmeren – deel 5
Welcome back bij het 5e deel van Python – Leren Programmeren. Deze post wordt een blik in de overige Python functies. Na deze post gaan we een grotere Python code analyseren met al onze kennis die we de afgelopen posts geleerd hebben en that’s it voor de basis. Ok… still hanging on? Let’s go!
Logical Operators (And, Or, Not)
We kunnen code ook sturen d.m.v. zogenaamde “logical operators”. De ondersteunde logical operators in Python zijn “And”, “Or” en “Not”.
And = Als er aan de vorige en aan de volgende voorwaarde voldaan wordt
Or = Als er aan de vorige of aan de volgende voorwaarde voldaan wordt
Not = Als er niet aan de opgegeven voorwaarde voldaan wordt
Bijvoorbeeld:
leeftijd = 21 if ((leeftijd >= 1) and (leeftijd <= 10)): print ("Je krijgt een kinderfeestje") elif (leeftijd == 16) or (leeftijd == 21): print ("Je krijgt een super knalfeest") elif not (leeftijd <= 60): print ("Helaas geen feestjes meer") else: print ("Je krijgt een gewoon feestje") |
We zien hier dat de code een aantal controles doet. Allereerst wordt er gecontroleerd of de leeftijd tussen de 1 en 10 jaar is. Zo ja dan krijgt men een kinderfeestje. Vervolgens controleert de code of men 16 of 21 jaar is want dan staat er een knalfeest op stapel. Als ook dat niet het geval is dan controleren we of men niet ouder is dan 60 wantje, na je 60e krijg je helemaal geen feestjes meer. En als ook niet aan die waarde voldaan wordt dan krijgt men een “gewoon” feestje.
Net als bij een gewone IF loop is het zo dat wanneer men aan een waarde voldoet de code niet meer verder kijkt naar de andere mogelijkheden en meteen verder gaat met de volgende code (de loop / check wordt verbroken).
Formateren van een string
Strings kunnen op een bepaalde manier geformatteerd worden. In deze formatering maken we gebruik van zogenaamde “placeholders”:
%s = placeholder voor een string
%d = placeholder voor een nummer (decimal)
%c = placeholder welke gevuld wordt met het ASCII symbool op de aangegeven positie. Dus “print(“%c” % 50)” zal het cijfer 2 retourneren.
De waardes van deze placeholders kunnen via een tupel en de % operator weer gebruikt worden.
Een voorbeeld:
Naam = 'Jarno' Nummer = 500 print("%s %d" % (Naam, Nummer)) |
Jarno 500
Uiteraard is de uitkomst hetzelfde als dan wanneer we gewoon de variabele op zouden vragen:
print(Naam, Nummer) |
Jarno 500
Echter kunnen we geen string printen met daarin een variabele. Bijvoorbeeld:
mood = "TOP" print("Mijn stemming is mood") |
Mijn stemming is mood
Maar d.m.v. placeholders kan dit wel. Placeholders kunnen in een string geplaatst worden en kunnen de waarde opnemen van de refererende tuple achter de string. Om dit te doen plaats je achter de string dus een procent (%) teken en daarachter definieer je de tuple (met variabelen). Het volgende voorbeeld verduidelijkt dit:
String1 = "Jarno" String2 = "Baselier" String3 = "Leuk" String4 = "Gek" String5 = "Kusjes" String6 = "Tikjes" Nummer1 = 100 Nummer2 = 200 Nummer3 = 300 Nummer4 = 400 print("%s %s is %s en krijgt %d %s" % (String1, String2, String3, Nummer2, String5)) |
Jarno Baselier is Leuk en krijgt 200 Kusjes
Je ziet nu dat de eerste string placeholder (%s) zicht vult met String1, de 2e met String2 en de 3e met String 3. Daarna komt een decimaal placeholder (%d) welke zicht vult met Nummer2 en de laatste %s vult zich met String5.
Zo kunnen we ook variabelen vullen met de uitkomsten van reeds bestaande variabelen.
Get
Het “get()” commando vraagt de waarde van een bepaalde sleutel op. Als de waarde niet bestaat dan zal dit commando zich vullen met de standaard waarde. Het get commando werkt middels het volgende voorbeeld:
woordenboek.get(key, default=None) |
In bovenstaande commando zal “get” zoeken in het woordenboek naar een bepaalde “key” en als deze niet gevonden wordt dan wordt None (de default waarde) geretourneerd.
Ok, in een voorbeeldje:
Synoniemwoordenboek = {'Lekker': 'Aantrekkelijk', 'Vies': 'Smerig'} print ("Value : %s" % Synoniemwoordenboek.get('Lekker', "Lekker komt niet voor in het woordenboek")) print ("Value : %s" % Synoniemwoordenboek.get('Jummie', "Jummie komt niet voor in het woordenboek")) |
Value : Aantrekkelijk
Value : Jummie komt niet voor in het woordenboek
Nog een paar trucjes met strings
We kunnen nog veel meer leuke dingen doen met strings. Zo kunnen we bijvoorbeeld opzoeken bij welk karakter een bepaald woord in de string zich bevindt. Dit doen we zo:
string = "vandaag heb ik er helemaal geen zin in!" print(string.find("zin")) |
32
Of we kunnen de eerste letter automatisch starten met een hoofdletter:
string = "vandaag heb ik er helemaal geen zin in!" print(string.capitalize()) |
Vandaag heb ik er helemaal geen zin in!
Ook kunnen we controleren of de string alleen bestaat uit letter met de “isalnum” functie:
string = "vandaag heb ik er helemaal geen zin in!" string2 = "111" print(string.isalnum()) print(string.capitalize()) |
False
En:
string = "vandaag heb ik er helemaal geen zin in!" string2 = "111" print(string2.isalnum()) print(string.capitalize()) |
True
Met de “len” toevoeging kunnen we de lengte van de string achterhalen:
string = "vandaag heb ik er helemaal geen zin in!" string2 = "111" print(len(string)) |
39
We kunnen zelfs bepaalde woorden vervangen voor andere woorden:
string = "vandaag heb ik er helemaal geen zin in!" string2 = "111" print(string.replace("helemaal geen","heel veel")) |
vandaag heb ik er heel veel zin in!
Om een lijst te maken van een string gebruiken wede “split” functie:
%lijstnaam% = %string%.split(“%hoe moet het gesplitst worden%”)
string = "vandaag heb ik er helemaal geen zin in!" string2 = "111" lijst = string.split(" ") print(lijst) |
[‘vandaag’, ‘heb’, ‘ik’, ‘er’, ‘helemaal’, ‘geen’, ‘zin’, ‘in!’]
Werken met files / File IO
Vanuit Python kunnen we gemakkelijk werken met bestanden. Zo kunnen we bestanden maken, verwijderen en data toevoegen aan bestanden.
Laten we een bestand aanmaken en er iets naartoe schrijven:
bestand = open("test.txt", "wb") bestand.write(bytes("Ik ben de eerste tekst in het bestand\n", "UTF-8")) bestand.close() print(bestand.mode) print(bestand.name) |
wb
test.txt
Wat er hierboven gebeurt is het volgende:
Met “bestand = open(“test.txt”, “wb”)” open we een bestand genaamd “test.txt”. Als het bestand nog niet bestaat wordt deze aangemaakt. We openen het bestand in “wb” ofwel “write binary” mode. Deze modus zullen we vrijwel altijd gebruiken.
Vervolgens voeren we de “bestand.write(bytes(“Ik ben de eerste tekst in het bestand\n”, “UTF-8”))” regel uit. Hiermee schrijven we de regel (in bytes want het bestand is geopend in write binary mode) “Ik ben de eerste tekst in het bestand” naar het bestand met als indeling “UTF-8”.
Met “bestand.close()” sluiten we het bestand.
Vervolgens printen we de naam van het bestastand en de modus waarin deze geopend is met de print statements.
Als het bestand al bestaat en je voert bovenstaande commando uit dan wordt deze overschreven. Om iets toe te voegen gebruiken we de “ab+” mode:
bestand = ab+("test.txt", "ab+") bestand.write(bytes("Ik ben de tweede tekst in het bestand\n", "UTF-8")) bestand.close() |
Om content uit een bestand te lezen gaan we deze eerst heropenen in “r+” mode (reading and writing mode). Vervolgens maken we een nieuwe variabele waarin we de content opslaan met het “read” commando en tenslotte printen we de variabele:
bestand = open("test.txt", "r+") bestandsinhoud = bestand.read() print(bestandsinhoud) |
Ik ben de eerste tekst in het bestand
Ik ben de tweede tekst in het bestand
Om het bestand weer te verwijderen kunnen we gebruik maken van de OS module. Verwijderen is heel simpel. Gebruik het volgende commando:
import os os.remove("test.txt") |
Classes
Classes worden gebruikt in “Object Oriented Programming”. Een “class” is een door de gebruiker gedefinieerde prototype voor een object dat een aantal kenmerken van het object definieert. De kenmerken (de attributen) zijn datamembers (class variables en instance variabeles) en methodes die toegankelijk via puntnotatie.
Zie het als een aantal standaarden die we zelf meegeven. Zo zal een persoon eigenschappen als gewicht en lengte hebben en mogelijkheden als praten en luisteren. Classes worden gemaakt wanneer de code wordt uitgevoerd zodat deze meteen gebruikt en later aangepast kunnen worden. Stel je voor dat we een “class” hout gaan maken. En hout beschikt over diverse eigenschappen. Deze maken we dan als volgt:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 |
Hierboven maken we de class “Hout” aan en gebruiken we als extra documentatie over die class de “docstring”. Vervolgens definiëren we de eigenschappen van de class. Dit zijn variabelen welke we zowel binnen de class als buiten de class kunnen gebruiken. Om deze aan te roepen gebruiken we de class naam en de class eigenschap naam. Bijvoorbeeld: “Hout.aantHout”
Vervolgens definiëren we bepaalde eigenschappen zoals de naam, gewicht en formaat. Dit doen we door de “__init__()” functie te gebruiken definiëren we welke objecten gebruikt kunnen worden als Python de class opnieuw initialiseren. Deze functie noemen we dan ook wel de “class constructor” of de “initialization method”. Bijvoorbeeld:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 def __init__(self, naam, gewicht, lengte, breedte): self.naam = naam self.gewicht = gewicht self.lengte = lengte self.breedte = breedte Hout.aantHout += 1 |
Vervolgens kunnen we nieuwe class methods definiëren zoals we ook normale functies definiëren met als uitzondering dat we overal “self” toevoegen als eerste argument bij deze methodes. Bijvoorbeeld:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 def __init__(self, naam, gewicht, lengte, breedte): self.naam = naam self.gewicht = gewicht self.lengte = lengte self.breedte = breedte Hout.aantHout += 1 def displayCount(self): print ("Totaal aantal houtsoorten %d" % Hout.aantHout) def displayHout(self): print ("naam : ", self.naam, ", gewicht: ", self.gewicht, ", lengte: ", self.lengte, ", breedte: ", self.breedte) |
Om data (objecten) toe te voegen aan de class gaan we als volgt te werk:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 def __init__(self, naam, gewicht, lengte, breedte): self.naam = naam self.gewicht = gewicht self.lengte = lengte self.breedte = breedte Hout.aantHout += 1 def displayCount(self): print ("Totaal aantal houtsoorten %d" % Hout.aantHout) def displayHout(self): print ("naam : ", self.naam, ", gewicht: ", self.gewicht, ", lengte: ", self.lengte, ", breedte: ", self.breedte) hout1 = Hout("Vurenhout", 10, 1000, 100) hout2 = Hout("Eikenhout", 15, 1000, 50) |
Hier geven we dus aan welk object we toevoegen (hout1) en vervolgens in welke class we deze stoppen (Hout). Daarna parseren we de waardes in de volgorde waarin deze verwacht worden zoals naam, gewicht, lengte en breedte.
In bovenstaande voorbeeld voegen we 2 soorten hout toe. Om de waardes weer op te vragen en het totaal aantal houtsoorten te zien doen we het volgende:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 def __init__(self, naam, gewicht, lengte, breedte): self.naam = naam self.gewicht = gewicht self.lengte = lengte self.breedte = breedte Hout.aantHout += 1 def displayCount(self): print ("Totaal aantal houtsoorten %d" % Hout.aantHout) def displayHout(self): print ("naam : ", self.naam, ", gewicht: ", self.gewicht, ", lengte: ", self.lengte, ", breedte: ", self.breedte) hout1 = Hout("Vurenhout", 10, 1000, 100) hout2 = Hout("Eikenhout", 15, 1000, 50) hout1.displayHout() hout2.displayHout() print ("Totaal aantal houtsoorten %d" % Hout.aantHout) |
naam : Vurenhout , gewicht: 10 , lengte: 1000 , breedte: 100
naam : Eikenhout , gewicht: 15 , lengte: 1000 , breedte: 50
Totaal aantal houtsoorten 2
Als we later een waarde willen aanpassen dan roepen we deze nogmaals op. Bijvoorbeeld:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 def __init__(self, naam, gewicht, lengte, breedte): self.naam = naam self.gewicht = gewicht self.lengte = lengte self.breedte = breedte Hout.aantHout += 1 def displayCount(self): print ("Totaal aantal houtsoorten %d" % Hout.aantHout) def displayHout(self): print ("naam : ", self.naam, ", gewicht: ", self.gewicht, ", lengte: ", self.lengte, ", breedte: ", self.breedte) hout1 = Hout("Vurenhout", 10, 1000, 100) hout2 = Hout("Eikenhout", 15, 1000, 50) hout1.displayHout() hout2.displayHout() print ("Totaal aantal houtsoorten %d" % Hout.aantHout) hout2.naam = "Berkenhout" hout2.displayHout() |
naam : Vurenhout , gewicht: 10 , lengte: 1000 , breedte: 100
naam : Eikenhout , gewicht: 15 , lengte: 1000 , breedte: 50
Totaal aantal houtsoorten 2
naam : Berkenhout , gewicht: 15 , lengte: 1000 , breedte: 50
Nu kunnen we ook attributen bewerken met de volgende functies:
- hasattr – geeft “true” wanneer het attribuut bestaat
- getsattr – geeft de huidige waarde van het attribuut
- setsattr – Veranderd de waarde van het attribuut
- delattr – Verwijderd het attribuut
Dus:
hasattr(hout1, 'gewicht') print(hasattr(hout1, 'gewicht')) getattr(hout2, 'gewicht') print(getattr(hout2, 'gewicht')) setattr(hout2, 'gewicht', 8) print(getattr(hout2, 'gewicht')) delattr(hout2, 'gewicht') print(getattr(hout2, 'gewicht')) setattr(hout2, 'gewicht', 40) print(getattr(hout2, 'gewicht')) |
True
15
8
Erven / Inheritance
Bij het aanmaken van classes kunnen we gebruik maken van zogenaamde inheritance (erven). Op deze manier kunnen we al gebruik maken van alle waardes en functies die in een bestaande class aanwezig zijn. Stel je voor dat we een 2e class gaan maken waarbij we gebruik gaan maken van bovenstaande class. Deze class noemen we “Balken”. Om in de balken class de waardes van de “Hout” class te gebruiken doen we het volgende:
class Balken(Hout): aantBalken = 0 |
Nu willen we voor balken de waardes uit “Hout” gebruiken met als toevoeging van de waarde “vorm”. Alle andere waardes wil ik gebruiken vanuit de “Hout” class welke in dit geval een “superclass” wordt. Bijvoorbeeld:
class Balken(Hout): aantBalken = 0 def __init__(self, naam, gewicht, lengte, breedte, vorm): self.vorm = vorm super().__init__(naam, gewicht, lengte, breedte) Balken.aantBalken += 1 |
Vervolgens kunnen we gewoon alle waardes gebruiken en bestaande functies uit de superclass overschrijven. Bijvoorbeeld:
class Balken(Hout): aantBalken = 0 def __init__(self, naam, gewicht, lengte, breedte, vorm): self.vorm = vorm super().__init__(naam, gewicht, lengte, breedte) Balken.aantBalken += 1 def naarString(self): return "De houtsoort is: {}. Dit hout is {} kilo zwaar, {} cm lang en {} cm breed. De balk heeft een {} vorm.".format(self.naam, self.gewicht, self.lengte, self.breedte, self.vorm) balk1 = Balken("Vurenhout Balk", 20, 2000, 200, "vierkant") print (balk1.naarString()) |
De houtsoort is: Vurenhout Balk. Dit hout is 20 kilo zwaar, 2000 cm lang en 200 cm breed. De balk heeft een vierkant vorm.
Laten we met deze code een leuke nieuwe truck uithalen. Zowel bij de superclass Hout en bij de class Balken voegen we een nieuwe functie toe genaamd “get_type”.
Dus in Hout:
def get_type(self): print("Hout") |
en bij Balken:
def get_type(self): print("Balk") |
Dan maken we een nieuwe class aan die noemen we TestHout. Deze ziet er als volgt uit:
class TestHout: def get_type(self, Hout): Hout.get_type() |
Deze functie haalt nu de “get_type” functie op uit de “Hout” class en daarmee ook de “get_type” functie uit de subclass “Balken”.
Vervolgens maken we een HoutTesten object waarin we refereren naar de TestHout class. En daarna kunnen we opvragen wat het type is van een bepaald houten item. De totale code ziet er dan als volgt uit:
class TestHout: def get_type(self, Hout): Hout.get_type() HoutTesten = TestHout() HoutTesten.get_type(balk1) |
Balk
Bovenstaande is een voorbeeld van Python Polymorphism. Polymorphism komt uit het Grieks waar Poly (veel)en Morphism (vormen) betekend. Zowel hout1 als balk1 zijn houtsoorten maar hun toepassing is anders. Deze toepassing testen we in het laatste voorbeeld.
De gehele code zoals we die hebben gemaakt ziet er nu als volgt uit:
class Hout: "Deze classe bevat al eigenschappen van onze houtsoorten" aantHout = 0 def __init__(self, naam, gewicht, lengte, breedte): self.naam = naam self.gewicht = gewicht self.lengte = lengte self.breedte = breedte Hout.aantHout += 1 def set_naam(self, naam): self.naam = naam def get_naam(self): return self.naam def get_type(self): print("Hout") def displayCount(self): print ("Totaal aantal houtsoorten %d" % Hout.aantHout) def displayHout(self): print ("naam : ", self.naam, ", gewicht: ", self.gewicht, ", lengte: ", self.lengte, ", breedte: ", self.breedte) def naarString(self): return "De houtsoort is: {}. Dit hout is {} kilo zwaar, {} cm lang en {} cm breed.".format(self.naam, self.gewicht, self.lengte, self.breedte) hout1 = Hout("Vurenhout", 10, 1000, 100) hout2 = Hout("Eikenhout", 15, 1000, 50) print (hout1.naarString()) class Balken(Hout): aantBalken = 0 def __init__(self, naam, gewicht, lengte, breedte, vorm): self.vorm = vorm super().__init__(naam, gewicht, lengte, breedte) Balken.aantBalken += 1 def get_type(self): print("Balk") def naarString(self): return "De houtsoort is: {}. Dit hout is {} kilo zwaar, {} cm lang en {} cm breed. De balk heeft een {} vorm.".format(self.naam, self.gewicht, self.lengte, self.breedte, self.vorm) balk1 = Balken("Vurenhout Balk", 20, 2000, 200, "vierkant") class TestHout: def get_type(self, Hout): Hout.get_type() HoutTesten = TestHout() HoutTesten.get_type(balk1) |
De houtsoort is: Vurenhout. Dit hout is 10 kilo zwaar, 1000 cm lang en 100 cm breed.
Balk
Try loop – Error handling
Het “try” proces wordt vaak gebruikt om bepaalde error handling uit te voeren. Het try proces is feitelijk ook een loop en werkt als volgt:
- Allereerst worden alle statements tussen de “try” en “except” keywords uitgevoerd
- Als er geen uitzonderingen voordoen dan worden de “except” codeblokken genegeerd en eindigt de “try” loop.
- Als er zich wel een uitzondering voordoet dan zal het “try” proces onderbroken worden en zullen de “except” codeblokken uitgevoerd worden. Als de uitzondering voldoet aan de waarde achter de “except” statement dan wordt de except code uitgevoerd.
- Als de uitzondering niet voldoet aan de “except” statements dan zal de uitzondering doorgegeven aan bovenliggende try loops. Als ook hier geen match voordoet dan zal Python de uitzondering melden als “unhandled exception”
Bijvoorbeeld:
try: n = input("Vul een integer in: ") n = int(n) except ValueError: print("Dat is geen geldige integer, probeer het s.v.p. nogmaals.") |
Test
Dat is geen geldige integer, probeer het s.v.p. nogmaals.
Een try loop kan meerdere exception blokken hebben. Op die manier kunnen verschillende uitzonderingen worden getest en afgevangen.
Conclusie
Tot zover de beginselen van Python programmeren. We hebben in deze 4 posts veel voorbeelden, toepassingen en uitleg gekregen. In post nummer 5 gaan we kijken of we een langere code kunnen uitpluizen met de kennis die we nu hebben. Want echt… op dit moment kun je al aardig programmeren in Python en in de volgende post zie je wat voor leuks er bijvoorbeeld te maken is met deze kennis.