ID.nl logo
Zo kun je programmeren in Python - Deel 6
© Reshift Digital
Huis

Zo kun je programmeren in Python - Deel 6

In de href="https://computertotaal.nl/artikelen/pc/zo-kun-je-programmeren-in-python-deel-5/" rel="noopener noreferrer" target="_blank">vorige les</a> leerde je met bestanden werken en zag je hoe je je programma kunt laten reageren op exceptions. Zo beginnen je programma’s ondertussen al vrij complex te worden. Tijd dus om wat structuur in je programma’s te brengen, en dat doen we in deze les met functies en modules. We bekijken ook enkele standaardmodules van Python.

Wil je meer leren over programmeren? Bekijk dan onze Cursus: programmeren in Phyton (boek & online cursus).

Tot nu toe waren onze Python-programma’s vrij kort, maar je hebt ondertussen al genoeg Python-bagage om zelf al eens aan de slag te gaan en je eigen ideeën uit te werken in programma’s. En dan merk je al snel dat je programma lang en ondoorzichtig wordt. Gelukkig kent Python verschillende manieren om wat meer structuur in je programma’s te brengen.

De eerste manier ben je al tegengekomen: functies. We hebben immers in de vorige lessen al diverse standaardfuncties van Python gebruikt, zoals len, print, input, format, split, open, read en write. Een functie is een afzonderlijk stukje code dat een afgebakende taak uitvoert die je meerdere keren zou willen uitvoeren op verschillende gegevens. Zodra je in je programma dus merkt dat je een stukje code telkens aan het herhalen bent, zou je eerste gedachte moeten zijn: ik maak er een functie van!

Een functie definiëren

We tonen je als voorbeeld hoe je een functie maakt om te berekenen of een woord een palindroom is. Een palindroom of spiegelwoord is een woord dat van achteren naar voren gelezen hetzelfde is als van voor naar achter. Een eenvoudige functie om te bepalen of een woord een palindroom is, ziet er als volgt uit:

def is_palindroom(woord):letters = list(woord)palindroom = Truewhile len(letters) > 0 and palindroom:if letters[0] != letters[-1]:palindroom = Falseelse:letters.pop(0)if len(letters) > 0:letters.pop()return palindroom

Dit is niet de efficiëntste manier om te bepalen of een woord een palindroom is, maar wel een die goed te begrijpen is. Je ziet dat er in de definitie van deze functie eigenlijk maar twee zaken nieuw zijn: de eerste en de laatste regel. In de eerste regel geven we met def is_palindroom(woord): aan dat we een functie definiëren met de naam is_palindroom en dat die één parameter meekrijgt, die we woord noemen. Dan komt onze hele berekening, die je met al je kennis uit de vorige lessen na een kleine studie zou moeten begrijpen, en op het einde geven we met return palindroom aan dat we de waarde die na onze berekening in de variabele palindroom zit teruggeven.

Een functie aanroepen

Breek je hoofd nog even niet over de inhoud van de functie. Typ de code in Thonny in en sla het bestand op onder de naam palindroom.py. Voer het dan uit met een druk op F5. Er gebeurt niets, maar de functie is nu gedefinieerd. In de terminal onderaan Thonny kun je nu de functie aanroepen. Enkele voorbeelden:

>>> is_palindroom('nepalapen')True>>> is_palindroom('napalm')False>>> is_palindroom('koortsmeetsysteemstrook')True

Denk nu eens even na over wat er gebeurt als je is_palindroom('nepalapen') aanroept. De functie is_palindroom wordt dan uitgevoerd en aan de variabele woord van de functie wordt de string 'nepalapen' toegekend. Dan gebeurt die hele berekening, en geeft de functie als resultaat True of False. En voor elke andere string die je aan de functie doorgeeft, gebeurt de berekening op dezelfde manier. Op deze manier heb je de berekening ingekapseld in een afzonderlijk stukje code, de functie, die herbruikbaar is.

Overigens zijn door die inkapseling de parameter woord net zoals de variabelen letters en palindroom alleen binnen het blok van de functie gedefinieerd: het zijn wat we noemen lokale variabelen.

Recursieve functies

In onze functie is_palindroom gaan we met een while-lus alle letters in het woord af. Een andere manier om de functie te definiëren is met recursie: in de functie roepen we de functie opnieuw aan, maar op een deel van het woord. Dat ziet er als volgt uit:

def is_palindroom2(woord):if len(woord) < 2:return Trueif woord[0] != woord[-1]:return Falsereturn is_palindroom2(woord[1:-1])

Voeg deze functie in Thonny gewoon aan hetzelfde bestand toe als is_palindroom, sla het bestand op en druk op F5 om het uit te voeren. Je kunt nu deze functie is_palindroom2 uitproberen op enkele woorden. Het resultaat moet telkens hetzelfde zijn als is_palindroom op hetzelfde woord.

De functie is_palindroom2 is een mooi voorbeeld van een recursieve functie. We bekijken eerst of het woord minder dan twee letters bevat. In dat geval (het woord is leeg of heeft één letter) is het altijd een palindroom en daarom geven we in dat geval True terug. Daarna controleren we of de eerste letter verschilt van de laatste letter van het woord. Verschillen die, dan is het woord al zeker geen palindroom en geven we dus False terug.

Dan blijft er nog één geval over: de eerste en laatste letter van het woord zijn gelijk, maar van de andere letters weten we nog niets. Wat doen we dan? We roepen de functie is_palindroom2 opnieuw op, maar op die andere letters. Die verkrijgen we door de slice (zie les 2) [1:-1] op het woord toe te passen, die het woord zonder de eerste en laatste letter teruggeeft.

Belangrijk bij recursieve functies

Als je een recursieve functie schrijft, is het belangrijk dat je de functie telkens oproept op een kleinere invoer dan waarmee je begon, zodat je uiteindelijk bij een basistest uitkomt, zoals in ons geval if len(woord) < 2: en if woord[0] != woord[-1]:. In beide gevallen roepen we de functie is_palindroom2 niet meer aan, maar geven we een waarde True of False terug. Doordat we in het derde geval altijd de eerste en de laatste letter van het woord verwijderen voor we de functie opnieuw oproepen, verzekeren we dat de functie uiteindelijk altijd bij een van de basistests uitkomt.

Met modules werken

Zonder dat je het weet, heb je nu al je eerste module geschreven. Elk Python-bestand waarin je code schrijft, is immers een module voor Python. Maak nu een nieuw Python-bestand aan in Thonny en noem het bijvoorbeeld test_palindroom.py. Als je in dit bestand de code uit palindroom.py wilt gebruiken, moet je de module palindroom importeren. Dat gaat als volgt:

import palindroom

print(palindroom.is_palindroom("nepalapen"))

Met import palindroom zeggen we aan de Python-interpreter dat we toegang willen tot alle code in de module palindroom. Python zoekt dan naar bestanden met de naam palindroom.py in zijn zoekpad. Omdat de code test_palindroom.py in dezelfde directory staat als palindroom.py, vindt Python de module en zijn de functies is_palindroom en is_palindroom2 daarin beschikbaar onder de namen palindroom.is_palindroom en palindroom.is_palindroom2.

In dit geval is het niet zo handig dat je voor elke functie uit de module palindroom de aanduiding palindroom. dient te zetten, omdat dit nogal lang is. We kunnen de naam van een module die we gebruiken gelukkig ook afkorten:

import palindroom as pal

print(pal.is_palindroom("nepalapen"))

Het is ook mogelijk om het voorvoegsel voor de module volledig weg te laten door de specifieke functies die we willen gebruiken te importeren:

from palindroom import is_palindroom

print(is_palindroom("nepalapen"))

Dat kan ook met meerdere functies:

from palindroom import is_palindroom, is_palindroom2

print(is_palindroom("nepalapen"))

print(is_palindroom2("parterretrap"))

Zodra je Python-code wat langer wordt, is het aan te raden om ze in modules op te splitsen. Een goede vuistregel is dat elke module code voor één specifiek doel moet bevatten. In ons geval bevat de module bijvoorbeeld alle mogelijke code die met palindromen te maken heeft. Als we daarnaast ook code voor anagrammen zouden willen toevoegen, doe je dat het best in een afzonderlijke module, anagram.py.

Systeeminformatie

Python zelf bestaat ook uit een heleboel standaardmodules waarin allerlei handige functies zitten. Zo is er de module platform om informatie over het platform waarop je Python-programma draait op te vragen:

>>> import platform>>> platform.architecture()('64bit', 'ELF')>>> platform.platform()'Linux-4.15.0-33-generic-x86_64-with-Ubuntu-18.04-bionic'>>> platform.processor()'x86_64'>>> platform.python_version()'3.6.7'>>> platform.system()'Linux'

Verder bevat de standaardmodule os allerlei functies die met het besturingssysteem te maken hebben. Zo kun je een lijst opvragen van de bestanden in de huidige directory:

>>> import os>>> os.listdir()['palindroom.py', 'test_palindroom.py']

Werken met getallen

Als je met getallen wilt werken, komt de module math goed van pas. Die bevat allerlei functies voor berekeningen, zoals je in het volgende voorbeeld ziet:

>>> import math>>> math.floor(4.3)4>>> math.ceil(4.3)5>>> math.gcd(28, 12)4>>> math.sqrt(2)1.4142135623730951>>> math.e2.718281828459045>>> math.pi3.141592653589793>>> math.sin(2*math.pi)-2.4492935982947064e-16

In de laatste regel zie je al een nadeel van berekeningen met floats: door afrondingsfouten geeft de berekening van de sinus van 2 keer pi een heel klein getal (-2 en nog iets maal 10 tot de -16de macht) in plaats van het juiste resultaat 0.

Een andere nuttige module is random, waarmee je willekeurige getallen kunt genereren:

>>> import random>>> random.randint(1, 10)7>>> random.choice(['lies', 'jan', 'kees', 'mireille', 'koen', 'rob'])'rob'>>> namen = ['lies', 'jan', 'kees', 'mireille', 'koen', 'rob']>>> random.shuffle(namen)>>> namen['jan', 'rob', 'koen', 'mireille', 'lies', 'kees']

Zo geeft de functie randint(a, b) een willekeurig geheel getal tussen a en b terug (a en b inbegrepen). Met choice kies je een willekeurig element uit een lijst. En met shuffle schud je een lijst willekeurig door elkaar.

Samenvatting

In deze les heb je geleerd om je Python-code wat meer te structureren. Enerzijds heb je berekeningen die je vaak herhaalt in functies leren opnemen. Anderzijds heb je geleerd hoe je functies die bij elkaar horen kunt afscheiden in een afzonderlijke module. We hebben tot slot ook met enkele standaardmodules van Python kennisgemaakt. In de volgende les gaan we op de structuur van datatypes in: we tonen je hoe je zelf eigen datatypes kunt definiëren in de vorm van klassen.

Opdracht

Open de module palindroom.py in Thonny en voer ze uit met een druk op F5. Voer in de terminal onderaan de volgende opdrachten in: *>>> is_palindroom('parterretrap')True>>> woord**Traceback (most recent call last):**File "

Uitwerking

De parameter woord in de functie is een lokale variabele: die is alleen binnen het blok van de functie gedefinieerd. Als je de functie met het argument 'parterretrap' oproept, wordt die string in de functie aan de lokale variabele woord toegekend, maar na het uitvoeren van de functie is die variabele niet meer beschikbaar en geeft Python dus met een NameError aan dat het de naam woord niet kent.

Cheatsheet

Functie: een afzonderlijk stukje code dat je meerdere keren uitvoert. Importeren: aangeven dat je een module wilt gebruiken. Lokale variabele: een variabele die alleen binnen een specifiek blok (bijvoorbeeld van een functie) gedefinieerd is. Module: een afzonderlijk bestand met Python-code. Recursieve functie: een functie die zichzelf aanroept.

▼ Volgende artikel
Video trimmen in VLC: filmpjes eenvoudig inkorten
© monticellllo - stock.adobe.com
Huis

Video trimmen in VLC: filmpjes eenvoudig inkorten

Maak je weleens een filmpje? Daarin zitten meestal stukken die oninteressant zijn. Met de gratis tool VLC media player kun je zo’n video moeiteloos en nauwkeurig tot op het frame inkorten.

Mediatitel verbergen

VLC media player (www.videolan.org) is een van de populairste mediaspelers. Niet alleen omdat de opensource-software voortdurend wordt verbeterd, maar vooral omdat de app zoveel verschillende media moeiteloos kan afspelen en converteren. We gebruiken de tool ook graag om video in te korten. Standaard toont VLC in het begin gedurende enkele seconden de naam van het videobestand. Vind je dat (net als wij) storend, vooral als je in die zone een knip wilt geven? Schakel dit uit door de Eenvoudige voorkeuren te openen met Ctrl+P (met de P van preferences, op de Mac gebruik je Cmd+,). Ga naar het tabblad Ondertitels / OSD en haal het vinkje weg bij de optie Mediatitel weergeven bij starten van de video.

Zorg dat de mediatitel niet in beeld komt.

Beginpositie bepalen

Het splitsen van een video in VLC verloopt anders dan bij een gewone videobewerkingstool waar je een slider moet verplaatsen. Met VLC maak je een opname van het deel van de video dat je wilt extraheren uit een langer filmpje. Het ingekorte fragment wordt dan opgeslagen als een nieuw videobestand en het oorspronkelijke bestand blijft ongewijzigd. Open VLC en klik op Open bestand om de video te selecteren die je wilt inkorten. Laad de video en zoek de exacte positie waar je de video wilt splitsen. Om het je gemakkelijk te maken, kun je de spatiebalk gebruiken om het filmpje te pauzeren en met dezelfde toets zet je het terug in gang. Je kunt de video frame voor frame afspelen door de E-toets in te drukken. Als je de E-toets continu indrukt, verspringt de video in slow motion. Op deze manier ga je naar de plaats waar je de beginknip wilt geven. Klik dan op de rode opnameknop links onder de video.

Gebruik de opnameknop om het begin van het fragment aan te geven.

Opnemen

Laat de video verder lopen en/of gebruik de E-toets om de plaats te zoeken waar je het fragment wilt beëindigen. Klik opnieuw op dezelfde opnameknop om de laatste knip te geven. Dat is alles. De ingekorte video wordt automatisch opgeslagen in de map Video's op je computer. Op de Mac komt dit fragment in de map Films.

In de map Video’s staat het ingekorte filmpje.

▼ Volgende artikel
De Nothing Phone (3a) Lite is goedkoop, maar iets minder Nothing
© Nothing
Huis

De Nothing Phone (3a) Lite is goedkoop, maar iets minder Nothing

Het merk Nothing is inmiddels berucht én geliefd om zijn semi-transparante telefoons, dappere designkeuzes en de knipoog naar oldskool tech. Vandaag voegt het bedrijf daar een betaalbare variant aan toe: de Phone (3a) Lite. Die naam roept meteen vragen op, want hoe 'Lite' is hij eigenlijk?

Vandaag heeft Nothing de Phone (3a) Lite officieel onthuld. Vanaf 4 november ligt het toestel ook daadwerkelijk in de winkel voor een bedrag van 249 euro. Er zijn twee uitvoeringen beschikbaar met 8 GB RAM en 128 of 256 GB opslag, en die zijn leverbaar in de kleuren zwart en wit. Beide varianten bieden ruimte voor een microSD-kaart tot 2 TB, wat in deze prijsklasse vrij uitzonderlijk is.

Met die vriendelijke prijs positioneert Nothing het toestel overigens slim tussen de budget- en middenklasse in. Dus ónder de Nothing Phone (3a), maar boven instappers van bijvoorbeeld Realme of Motorola.

©Nothing

Kleine concessies

De transparante achterkant blijft, maar het Glyph-systeem – de lichtstrips waarmee je meldingen op de achterkant kunt waarnemen – lijkt te ontbreken. Nothing vermeldt het in elk geval niet op de officiële pagina, wat doet vermoeden dat het systeem hier is geschrapt of versoberd. Het toestel heeft een glass finish en een IP54-certificering tegen stof en spatwater, maar is vermoedelijk niet volledig van glas.

Het scherm is een 6,77-inch amoledpaneel met een resolutie van 1084 × 2392 pixels, een piekhelderheid van 3000 nits en een adaptieve verversing van 120 Hz. Het toestel draait op een MediaTek Dimensity 7300 Pro-chip (8-core, 4 nm, tot 2,5 GHz) met een Mali-G615 GPU. Niet de snelste op aarde, maar ruim voldoende voor dagelijks gebruik en je favoriete spelletjes. De batterij heeft een vermogen van 5000 mAh en kun je met 33 watt opladen; in twintig minuten zit je op 50 procent, volledig laden duurt ongeveer een uur. Ook reverse charging (5 watt) wordt ondersteund.

De camera’s zijn inmiddels officieel bevestigd: een 50 MP-hoofdcamera (f/1.88), een 8 MP-ultragroothoeklens (f/2.2) en een 2 MP-macrocamera (f/2.4). De selfiecamera telt 16 MP. Video’s schiet je in 4K met 30 fps of 1080p met tot 60 fps. Daarmee is het een nette, zij het eenvoudige, cameraconfiguratie voor deze prijsklasse.

Software

De telefoon draait op Nothing OS 3.5 (gebaseerd op Android 15). Versie 4.0, gebaseerd op Android 16, volgt later met nieuwe camera- en lockscreenfuncties zoals Stretch mode en Lock Glimpse.

Die laatste optie zorgt trouwens wel voor enige opschudding: Lock Glimpse zou advertenties laten zien op je vergrendelscherm. Gebruikers moeten naar links vegen om ze te bekijken en de functie is weliswaar opt-in, maar het is wél een breuk met Nothings eerdere ‘geen bloatware, geen onzin’-imago. Het voelt een beetje wrang: het merk dat ooit minimalisme predikte, introduceert nu vrijwillige reclame. Maar goed, een kleine prijs voor een lage prijs, zullen we maar zeggen.

Niettemin lijkt de Nothing Phone (3a) Lite een charmant compromis. Minder luxe, minder toeters en bellen, maar nog steeds een eigen gezicht in een markt vol generieke toestellen. Wie vooral design en merkbeleving zoekt voor een zacht prijsje, zal hier vermoedelijk blij van worden.

©Nothing

Conclusie

Met de Phone (3a) Lite brengt Nothing een deel van zijn kenmerkende design naar een lagere prijsklasse. De hardware is degelijk, de prijs scherp en de uitstraling is toch herkenbaar. Maar er zijn ook duidelijke concessies: geen Glyph-lichtshow deze keer, de camera’s zijn bescheiden, en die optionele advertenties...? Nou ja, een aantrekkelijke instapper dus, zolang je weet wat je inlevert voor dat lagere prijskaartje.