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

Zo kun je programmeren in Python - Deel 10

Tot nu toe leerden we je programmeren, maar we leerden je geen programma schrijven. Het verschil? Programmeren doe je voor jezelf; een programma schrijven voor iemand anders. Je wilt dat een gebruiker eenvoudig een programma kan oproepen met opties, een mooi resultaat te zien krijgt en ook hulp kan opvragen als hij niet weet hoe hij jouw programma moet gebruiken. Dat alles zien we in deze laatste les van Python.

In deze tiende les ronden we stilaan af. Tot nu toe leerde je allerlei aspecten van Python kennen en die brengen we in deze les allemaal samen. Op het einde van deze les heb je een programma dat je op de opdrachtregel kunt uitvoeren, dat argumenten afhandelt, foutmeldingen geeft en tekst in kleur toont.

Argumenten op de opdrachtregel

In les 3 al leerde je om invoer van de gebruiker te vragen met de functie input. En hoewel we ons programma daar in Thonny uitvoerden, vertelden we daar ook al dat je het programma in Windows, Linux of macOS ook op de opdrachtregel kunt uitvoeren met:

python3 naamvanprogramma.py

Maar van programma’s op de opdrachtregel verwachten we dat je er ook argumenten aan kunt doorgeven, zoals DIR /s in Windows of ls -R in Linux en macOS. Hoe zorgen we dat onze eigen programma’s dat ook kunnen? Daar heeft Python gelukkig een oplossing voor met de module argparse in de standaardbibliotheek. In deze les schrijven we een programma dat de module palindroom uit les 6 gebruikt om van woorden te controleren of ze een palindroom zijn, en dat programma gaan we enkele argumenten geven.

Argumenten toevoegen

Als eerste willen we dat het programma ons vertelt of een woord dat we als argument aan het programma doorgeven een palindroom is. Dat ziet er zo uit:

from argparse import ArgumentParser

from palindroom import is_palindroom

parser = ArgumentParser(description='Bepaal of een woord een palindroom is.')

parser.add_argument("-w", "--woord", required=True, help="Het woord waarvan je wilt controleren of het een palindroom is")

args = parser.parse_args()

resultaat = is_palindroom(args.woord)

if resultaat:

print("Het woord '{}' is een palindroom.".format(args.woord))

else:

print("Het woord '{}' is geen palindroom.".format(args.woord))

Je ziet dat met argparse werken niet zo moeilijk is. Je maakt eerst een ArgumentParser-object aan met de beschrijving van je programma. Daarna voeg je een argument toe (in ons geval in een korte versie -w en een lange versie --woord) en lees je met parser.parse_args() de argumenten uit die de gebruiker op de opdrachtregel ingegeven heeft. De inhoud van het argument --woord vind je dan in de variabele args.woord.

Heel wat functionaliteit

Voer het programma nu eens uit:

$ python3 palindroomchecker.py -w parterretrap

Het woord 'parterretrap' is een palindroom.

$ python3 palindroomchecker.py -w parterretrak

Het woord 'parterretrak' is geen palindroom.

Merk op: we krijgen heel wat functionaliteit ‘gratis’ omdat argparse die voor ons uitvoert. Zo krijg je een foutmelding als je na -w geen woord opgeeft of als je het programma zonder het argument -w uitvoert (omdat we het argument toegevoegd hebben met required=True). En we krijgen ook het argument --help er gratis bij. Als je dit opgeeft, toont het programma de beschrijving van je programma en van alle argumenten die je gedefinieerd hebt:

$ python3 palindroomchecker.py -w

usage: palindroomchecker.py [-h] -w WOORD

palindroomchecker.py: error: argument -w/--woord: expected one argument

$ python3 palindroomchecker.py

usage: palindroomchecker.py [-h] -w WOORD

palindroomchecker.py: error: the following arguments are required: -w/--woord

$ python3 palindroomchecker.py --help

usage: palindroomchecker.py [-h] -w WOORD

Bepaal of een woord een palindroom is.

optional arguments:

-h, --help

-w WOORD, --woord WOORD

Het woord waarvan je wilt controleren of het een

palindroom is

Argumenten die elkaar uitsluiten

We willen het programma nu uitbreiden zodat je de palindroomtest ook één voor één kunt uitvoeren op alle regels in een tekstbestand. Daarvoor voegen we het argument -b toe. Maar het heeft geen zin om zowel -w als -b tegelijk op te geven, dus we moeten kunnen aangeven dat beide argumenten elkaar uitsluiten. Ook dat kan eenvoudig met argparse:

parser = ArgumentParser(description='Bepaal of een woord een palindroom is.')

bron = parser.add_mutually_exclusive_group(required=True)

bron.add_argument("-w", "--woord", help="Het woord waarvan je wilt controleren of het een palindroom is")

bron.add_argument("-b", "--bestand", help="Het bestand met woorden waarvan je wilt controleren of ze een palindroom zijn")

args = parser.parse_args()

Met parser.add_mutually_exclusive_group maken we een groep argumenten aan die elkaar uitsluiten. Met required=True van die methode zegen we dat de gebruiker exact een van de argumenten uit de groep moet gebruiken. Daarna voegen we onze argumenten aan die groep toe in plaats van aan het object parser.

Als we nu de controle of een woord een palindroom is en het tonen van het resultaat afsplitsen in een afzonderlijke functie toon_resultaat (dat laten we als oefening over aan jou), kunnen we beide gevallen van invoer (een woord op de opdrachtregel of woorden in een bestand waarvan je de naam op de opdrachtregel doorgeeft) eenvoudig afhandelen:

if args.woord:

toon_resultaat(args.woord)

else:

with open(args.bestand, 'rt') as bestand:

for regel in bestand:

toon_resultaat(regel.strip())

Probeer dit maar eens uit. Je zult zien dat je programma een foutmelding geeft als je geen of juist allebei de argumenten opgeeft.

In kleur

Je kunt ook kleuren toevoegen aan de uitvoer van je programma. Daarvoor gebruiken we het pakket colorama, dat je eerst nog met pip3 (zie de vorige les) dient te installeren omdat het niet tot de standaardbibliotheek van Python behoort. We importeren enkele functies uit de module en initialiseren daarna colorama:

from colorama import init, Fore, Back, Style

init()

Daarna kun je spelen met de voorgrondkleur, achtergrondkleur en helderheid van de tekst:

print(Fore.RED + 'Rode tekst...')

print(Back.GREEN + '... met een groene achtergrond.')

print(Style.RESET_ALL + Fore.RED + Style.DIM + 'Dof...')

print(Fore.GREEN + Style.BRIGHT + '... of juist helder.')

print(Style.RESET_ALL)

print('En nu weer normaal!')

Op het einde van je programma voeg je het best altijd deze regel toe:

deinit()

Die reset de uitvoer, zodat de opdrachtregel na het uitvoeren van je programma niet plots helemaal in het rood is omdat je de voorgrondkleur bent vergeten terug te zetten!

Optionele argumenten

Die kleuren gaan we in onze palindroomchecker alleen gebruiken als je een optioneel argument --kleur aan je programma doorgeeft. Zo’n optioneel argument voegen we als volgt toe:

parser.add_argument("-k", "--kleur", action="store_true", help="Toon het gevraagde woord in kleur")

In ons programma kunnen we dan op de aanwezigheid van het optionele argument testen met if args.kleur:. Het if-else-blok uit ons originele programma vervangen we dan door de volgende geneste structuur:

if resultaat:

if args.kleur:

palindroom = Fore.GREEN + Style.BRIGHT + args.woord + Style.RESET_ALL

else:

palindroom = args.woord

print("Het woord '{}' is een palindroom.".format(palindroom))

else:

if args.kleur:

geen_palindroom = Fore.RED + Style.DIM + args.woord + Style.RESET_ALL

else:

geen_palindroom = args.woord

print("Het woord '{}' is geen palindroom.".format(geen_palindroom))

Fouten afhandelen

Als je nu in ons programma dat het argument -b voor een bestand ondersteunt een bestandsnaam doorgeeft die niet ondersteund is, breekt ons programma af met de volgende foutmelding en dan de bestandsnaam:

FileNotFoundError: [Errno 2] No such file or directory:

Bovendien krijg je ook de regel code te zien waarin het fout loopt. Voor een gebruiker die niets van Python kent, is dat nogal intimiderend. We gaan dus met een try-catch-blok die exception afhandelen (zie les 5) en een gebruiksvriendelijkere foutmelding tonen.

Voor we dat doen, moet je nog iets weten. Windows, Linux en macOS kennen drie ‘virtuele bestanden’ die belangrijk zijn op de opdrachtregel: stdin (de invoer van het toetsenbord), stdout (de normale uitvoer van het programma) en stderr (de foutenuitvoer van het programma). Standaard tonen we met print de uitvoer op stdout, maar met file=sys.stderr leiden we de foutenuitvoer om naar stderr. Dat ziet er dan als volgt uit (vergeet niet de regel import sys in het begin van je programma):

if args.woord:

toon_resultaat(args.woord)

else:

try:

with open(args.bestand, 'rt') as bestand:

for regel in bestand:

toon_resultaat(regel.strip())

except FileNotFoundError as fout:

print('Bestand {} niet gevonden'.format(fout.filename), file=sys.stderr)

We proberen hier dus het bestand te openen. Als dat niet lukt, vangen we een exception FileNotFoundError af. Merk op: met except FileNotFoundError as fout: kennen we de exception toe aan de variabele fout, zodat we nuttige informatie uit dit object kunnen opvragen. In dit geval is dat de bestandsnaam waarover het gaat (fout.filename). Die tonen we in de foutmelding aan de gebruiker, zodat die kan nakijken waarom het bestand niet bestaat.

De meldingen die we op stderr tonen, verschijnen overigens gewoon in de opdrachtregel zoals andere tekst die je met print toont. Maar het verschil is belangrijk. Zo kunnen andere programma’s bijvoorbeeld je foutmeldingen op stderr er uitfilteren.

Samenvatting

In deze les heb je geleerd hoe je een volledig Python-script ontwikkelt dat je op de opdrachtregel kunt uitvoeren. Je kunt argumenten afhandelen en foutmeldingen geven en je weet hoe je van kleur gebruik kunt maken in je programma. Daarmee sluiten we deze lessenreeks af. Je bent nu klaar om je eigen Python-programma’s te schrijven!

Opdracht

Voeg een optioneel argument ‘stil’ aan je programma toe dat alleen uitvoer geeft als het gevraagde woord een palindroom is, zodat je snel palindromen in grote bestanden kunt vinden.

Uitwerking

Het optionele argument voeg je eenvoudig als volgt toe: parser.add_argument("-s", "--stil", action="store_true", help="Toon het gevraagde woord als het een palindroom is; toon niets als het geen palindroom is.") Daarna definiëren we de functie toon_resultaat als volgt: def toon_resultaat(woord): resultaat = is_palindroom(woord) if resultaat: if args.stil: print(woord) else: print("Het woord '{}' is een palindroom.".format(woord)) else: if not args.stil: print("Het woord '{}' is geen palindroom.".format(woord)) In deze functie controleren we achtereenvolgens of het woord en palindroom is en of de gebruiker het optionele argument ‘stil’ heeft ingevoerd. Als we een palindroom hebben en het programma werkt stil, tonen we alleen het palindroom. Als we een palindroom hebben en het programma werkt niet stil, vertellen we in een hele zin dat het om een palindroom gaat. Als we geen palindroom hebben en het programma werkt stil, tonen we niets. En als we geen palindroom hebben en het programma werkt niet stil, vertellen we in een hele zin dat het niet om een palindroom gaat.

Cheatsheet

Stderr: de foutenuitvoer van een programma Stdout: de normale uitvoer van een programma

▼ Volgende artikel
Waar voor je geld: 5 gourmetsets voor minder dan 85 euro
Huis

Waar voor je geld: 5 gourmetsets voor minder dan 85 euro

Bij ID.nl zijn we dol op kwaliteitsproducten waar je niet de hoofdprijs voor betaalt. Een paar keer per week speuren we binnen een bepaald thema naar zulke deals. Met de feestdagen in aantocht gaan we weer gezellig met z'n allen eten. En omdat gourmetten daarbij erg populair is, zijn we op zoek gegaan naar vijf betaalbare modellen geschikt voor tot 10 personen.

Met een gourmetstel maak je avonden extra gezellig en informeel. Iedereen eet in zijn eigen tempo omdat je zelf bepaalt hoeveel je in je pannetje of op je grill legt. En zo is er ook meer tijd om lekker te kletsen. Wij vonden vijf mooie gourmetstellen geschikt tot wel 10 personen.

Tristar RA‑2746 Gourmetstel – 8 personen

De Tristar RA‑2746 is een gourmetstel waarmee je samen met het hele gezin of vriendengroep kunt bakken en grillen. Het apparaat heeft een vermogen van ongeveer 1400 watt en is voorzien van één grote bak‑ en grillplaat, zodat je tegelijk vlees, vis en groenten kunt bereiden. Dankzij de PFAS‑vrije antiaanbaklaag koeken ingrediënten niet vast en maak je het oppervlak na het eten eenvoudig schoon.. Bij de set worden acht kleine pannetjes meegeleverd, zodat iedereen zijn eigen gerecht kan samenstellen. De antislipvoetjes houden het toestel stevig op tafel en het snoer is lang genoeg voor gebruik aan een eettafel. Verder is het gourmetstel geschikt voor maximaal acht personen.

Tefal Inox & Design RE4588 - 10 personen

Bij de Tefal Inox & Design RE4588 richt alles zich op een combinatie van raclette en gourmet. Je beschikt over een groot vermogen van 1350 watt en een verstelbare thermostaat, zodat je de temperatuur precies kunt regelen voor vlees, groenten of raclettekaas. De tien bijgeleverde pannetjes en de grillplaat hebben een antiaanbaklaag waardoor je weinig olie hoeft te gebruiken en het schoonmaken minder tijd kost. Tefal heeft het snoer met ongeveer twee meter vrij lang gemaakt, waardoor je meer vrijheid hebt om het toestel op tafel te plaatsen. Een ingebouwd indicatielampje toont wanneer het apparaat de ingestelde temperatuur heeft bereik. Het apparaat wordt geleverd met hittebestendige handgrepen voor veilig gebruik en is geschikt voor maximaal tien personen.

Princess Raclette Gourmetstel XL - 10 personen

Met de Princess Raclette XL haal je een gourmet‑ en raclette‑stel voor tien personen in huis. De set gebruikt een vermogen van ongeveer 1500 watt en heeft een extra grote bakplaat voor vlees en groenten. De plaat is uitneembaar en heeft een PFAS‑vrije antiaanbaklaag, waardoor je niet veel olie nodig hebt en het toestel gemakkelijk schoonmaakt. Bij het apparaat worden tien pannetjes geleverd; zo kan iedereen tegelijkertijd minipannetjes gebruiken. De temperatuur regel je via een draaiknop, terwijl een controlelampje aangeeft dat het toestel opwarmt. Koelblijvende handgrepen en antislipvoetjes dragen bij aan veilig gebruik.

Princess Dinner4All Circle - 4 personen

De Princess Dinner4All Circle is een ronde gourmetset bedoeld voor kleinere groepen. Het apparaat is voorzien van een ronde bakplaat met een diameter van ongeveer 30 centimeter en gebruikt een vermogen van 1000 watt. Via een draaiknop stel je de temperatuur in tot circa 250 °C, waardoor je van langzaam garen tot snel grillen verschillende bereidingswijzen kunt kiezen. De set wordt geleverd met meerdere individueel te gebruiken kooktegels, zodat iedereen op zijn eigen tegel kan bakken zonder smaken te mengen. Dankzij de antiaanbaklaag zijn de platen eenvoudig schoon te maken, terwijl antislipvoetjes het toestel stabiel houden. Het snoer is ongeveer twee meter lang, waardoor je het gemakkelijk midden op tafel zet.

Princess Dinner4All Pure - 4 personen

Deze Dinner4All Pure‑gourmetset van Princess is opgebouwd uit meerdere kleine bakplaten, zodat elke gebruiker zijn eigen kookgedeelte heeft. Het systeem bestaat uit vier bamboe plates met antiaanbaklaag en afzonderlijke bakplaatjes, die samen op één centrale powerbox van 1000 watt worden aangesloten. Doordat iedere plaat een eigen stekker heeft, kun je de opstelling uitbreiden of verkleinen; handig als je met twee, drie of vier personen wilt eten. Het apparaat heeft een controlelampje en een eenvoudige bediening; je steekt de stekker in het stopcontact en kiest een temperatuur met de draaiknop. Dankzij de non‑stick afwerking maak je de platen na afloop gemakkelijk schoon.

▼ Volgende artikel
Review Ring Outdoor Cam Pro – Interessant, maar niet voor iedereen
© Wesley Akkerman
Zekerheid & gemak

Review Ring Outdoor Cam Pro – Interessant, maar niet voor iedereen

De Ring Outdoor Cam Pro is een redelijk prijzige, slimme beveiligingscamera voor buiten die flink wat in zijn mars heeft. Het apparaat kost 199,99 euro en daar komt – waarschijnlijk – nog maandelijks een abonnement bovenop.

Goed
Conclusie

De Ring Outdoor Cam Pro biedt fijne hardware, waaronder 4K-video met 10x digitale zoom (die nog redelijk acceptabel is ook). De installatie is eenvoudig, maar de camera mist wel de nodige smarthome-integraties (waardoor hij dus niet voor iedereen even handig is). Bovendien is hij aan de prijzige kant en heb je voor het optimale gebruik een abonnement nodig, waardoor je maandelijks of jaarlijks terugkerende kosten hebt. Daardoor betaal je hier meer voor dan bij Eufy, en daarom is de Outdoor Cam Pro alleen interessant als je al andere Ring-producten hebt.

Plus- en minpunten
  • Goede beeldkwaliteit
  • Nachtzicht met of zonder kleur
  • Installatie zo gepiept
  • Beschermd tegen weer en wind
  • Geen invloed op beeldkwaliteit
  • Abonnement voelt bijna nodig
  • Mist smarthomefuncties
  • Geen lokale opslagopties

De nieuwe Ring Outdoor Camera Pro heeft een compact, stabiel en minimalistisch ontwerp waardoor je hem direct als een Ring-apparaat herkent. Dankzij de compacte afmetingen kun je hem subtiel aan de muur ophangen. Je bent verzekerd van bescherming tegen weer en wind (een IP-rating is niet bekend) en er is een extra afdekking voor de kabelaansluitingen. Ring levert de camera daarnaast met een kogel-gelagerde muurbeugel en montagemateriaal. De stroomvoorziening verloopt via de usb-c-kabel achterop; dit is helaas geen model met eigen batterij.

De installatie is, zoals gebruikelijk bij Ring, snel en ongecompliceerd. Je maakt verbinding via wifi na het scannen van de QR-code en over het algemeen is de verbinding stabiel. We hebben gedurende de testperiode geen storingen opgemerkt. Mocht je de camera willen ophangen, dan moet je wel zelf even een gaatje boren; daar zit voornamelijk het werk in. In de doos zit overigens alles wat je nodig hebt om dat te doen. Denk dan aan die eerdergenoemde muurbeugel, maar ook aan alle schroeven en dergelijke. Je hoeft alleen de boor er zelf bij te pakken.

©Wesley Akkerman

Weinig zeggenschap over het beeld

De Ring Outdoor Cam Pro heeft een 4K-resolutie en een brede kijkhoek van 140 graden. Overdag zorgen natuurlijke kleuren en HDR-ondersteuning ervoor dat details en gezichten duidelijk herkenbaar blijven, zelfs bij tegenlicht. 's Nachts schakelt de camera automatisch over op helder zwart-witbeeld dankzij infrarood. Het systeem is bovendien in staat nachtvisie in kleur te leveren, maar daarvoor is er wel voldoende licht nodig. Hij schakelt automatisch van stand op basis van de hoeveelheid licht; je kunt helaas niet zelf bepalen of je in kleur of zwart-wit filmt.

Ring maakt verder gebruik van betrouwbare bewegingsdetectie, waarbij je via de app zones kunt instellen om vals alarm te voorkomen. De Ring Outdoor Cam Pro heeft 3D-bewegingsdetectie en Bird's Eye View (een typische Ring-uitvinding) voor nauwkeurige afstandsmetingen en het volgen van bewegingen. Met een Ring Protect-abonnement krijg je toegang tot geavanceerde herkenning van personen, dieren en voertuigen. Voor zaken als tweewegcommunicatie en de live-feed hoef je gelukkig niet in de buidel te tasten.

Het gebrek aan kleur komt door de mist.

Verplichte cloudopslag

Over het abonnement gesproken: daarmee krijg je ook nog toegang tot een uitgebreide videohistorie. Dat kost je wel minimaal 3,99 euro per maand. De opgenomen beelden blijven dan voor 180 dagen bewaard. Een belangrijk punt blijft echter de cloud-exclusiviteit; Ring maakt het nog steeds niet mogelijk om beelden lokaal op te slaan. Je bent dus verplicht een abonnement af te nemen als je je huisbeveiliging een beetje serieus neemt. De app faciliteert wel een overzichtelijk rechtenbeheer voor gezinsleden en waarschuwt bij allerlei ongeregeldheden.

De Ring-camera integreert tot slot met Alexa (de slimme assistent van Amazon) en IFTTT (een gratis en eenvoudige service voor smarthome-automatiseringen), maar mist helaas ondersteuning voor Google Home en Apple HomeKit (zoals dat al jaren het geval is). Via de Ring-app, beschikbaar voor Android en iOS, heb je de controle over de instellingen, inclusief het in- of uitschakelen van de sirene en bewegingsdetectie. De app toont een overzicht van gebeurtenissen en maakt het mogelijk voorgeprogrammeerde berichten af te spelen voor je bezoekers.

Van links naar rechts: infraroodnachtzicht, nachtzicht met kleur en nachtzicht zonder infrarood.

Lees ook onze review van de Ring Floodlight Cam Pro (2e gen)

Ring Outdoor Cam Pro kopen?

De Ring Outdoor Cam Pro biedt fijne hardware, waaronder 4K-video met 10x digitale zoom (die nog redelijk acceptabel is ook). De installatie is eenvoudig, maar de beveiligingscamera mist wel de nodige smarthome-integraties (waardoor hij dus niet voor iedereen heel handig is). Bovendien is hij aan de prijzige kant en heb je voor het optimale gebruik een abonnement nodig, waardoor je maandelijks of jaarlijks terugkerende kosten hebt. Daardoor betaal je hier meer voor dan bij Eufy, en daarom is de Outdoor Cam Pro alleen interessant als je al andere Ring-producten hebt.