# Software Development 2025 # Programma ***jaar 1***
Periode 1 Periode 2Periode 3Periode 4
Blok 1Blok 2Blok 3Blok 4Blok 5Blok 6Blok 7Blok 8
Scratch -> PythonRetro Gaming Python Front End CSSBack End PHPJavaScriptDatabasesDeployement en FrameWorks Security en OOP
[Scratch 1](https://www.roc.ovh/books/software-development-2025/page/scratch-1)[Vallende Stenen](https://www.roc.ovh/books/software-development-2025/page/vallende-stenen)[HTML Phoenix](https://www.roc.ovh/books/software-development-2025/page/html-phoenix)[Prompt Engineering 1](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-1)[Prompt Engineering 2](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-2)[DB Design](https://www.roc.ovh/books/software-development-2025/page/database-1)[Prompt Engineering 3](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-3)[Prompt Engineering 4](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-4)
[Scratch 2](https://www.roc.ovh/books/software-development-2025/page/scratch-2) [Snake](https://www.roc.ovh/books/software-development-2025/page/snake)[CSS Phoenix](https://www.roc.ovh/books/software-development-2025/page/css-phoenix)[Intro Web XAMPP](https://www.roc.ovh/books/software-development-2025/page/php-intro)[JS 2 (DOM)](https://www.roc.ovh/books/software-development-2025/page/js-dom1-8os)[SQL](https://www.roc.ovh/books/software-development-2025/page/sql)[Deployement](https://www.roc.ovh/books/software-development-2025/page/deployement)[Cyber Security 1](https://www.roc.ovh/books/software-development-2025/page/cyber-security-1)
[naar Python](https://www.roc.ovh/books/software-development-2025/page/van-scratch-naar-python) [Intro AI](https://www.roc.ovh/books/software-development-2025/page/introductie-ai)[Intro JS Phoenix](https://www.roc.ovh/books/software-development-2025/page/intro-js)[PHP 2](https://www.roc.ovh/books/software-development-2025/page/php-1-10p)[JS 3 (Dom)](https://www.roc.ovh/books/software-development-2025/page/js-dom2)[PDO](https://www.roc.ovh/books/software-development-2025/page/pdo)[CMS](https://www.roc.ovh/books/software-development-2025/page/cms)[OOP](https://www.roc.ovh/books/software-development-2025/page/oop)
[Pak de Kaas](https://www.roc.ovh/books/software-development-2025/page/pak-de-kaas) [Snake Challenge](https://www.roc.ovh/books/software-development-2025/page/snake-challenge)[Portfolio Challenge](https://www.roc.ovh/books/software-development-2025/page/portfolio-challenge)[PHP Challenge](https://www.roc.ovh/books/software-development-2025/page/php-challenge)[JS Challenge](https://www.roc.ovh/books/software-development-2025/page/java-script-challenge)[Crud Challenge](https://www.roc.ovh/books/software-development-2025/page/crud-challenge)[Yii Intro](https://www.roc.ovh/books/software-development-2025/page/yii-introduction)[OOP Challenge](https://www.roc.ovh/books/software-development-2025/page/oop-challenge)
[Kennis-Check Blok 1](https://www.roc.ovh/books/software-development-2025/page/kennis-check-blok-1)[Kennis-Check Blok 2](https://www.roc.ovh/books/software-development-2025/page/kennis-check-blok-2)[Kennis-Check Blok 3](https://www.roc.ovh/books/software-development-2025/page/blok-3-kennis-check)[Kennis-Check Blok 4](https://www.roc.ovh/books/software-development-2025/page/kennis-check-blok-4)[Kennis-Check Blok 5](https://www.roc.ovh/link/913#bkmrk-%F0%9F%A7%AA-begripsvragen-%E2%80%93-ja)[Kennis-Check Blok 6](https://www.roc.ovh/books/software-development-2025/page/kennis-check-blok-6)Kennis-Check Blok 7[Kennis-Check Blok 8](https://www.roc.ovh/books/software-development-2025/page/kennis-check-blok-8)
## Blok 1 - van blok naar tekst *(totaal ongeveer 9-10 uur)* #### [▶️](https://www.roc.ovh/books/software-development-2025/page/scratch-1) ***Scratch 1 -(block-based programmeren)*** ##### 🎯 Wat ga je leren? In **Scratch 1** bouw je stap voor stap je eerste game – een doolhofspel: - Je ontdekt de **interface**: waar je blokken, sprites en kleuren checkt . - Je leert een sprite te laten **bewegen** met pijltjestoetsen of de groene vlag . - Daarna voeg je **loops** toe: code die automatisch herhaalt (handig voor lopen, dansen, geluidjes) . - Met **if-dan** logica voeg je slimme interactie toe: bijvoorbeeld, als je een muur raakt, gebeurt er iets . - Tot slot leer je variabelen voor je **score**, zodat je merkt dat je echt iets zelf aanstuurt – superpower!
Waarom dit vet is - **Je maakt écht iets**: geen saaie theorie, maar een game die je zelf bouwt. - **Visueel programmeren** maakt het laagdrempelig – je ziet meteen wat er gebeurt. - **Logisch denkwerk** wordt je nieuwe skill: je splits een probleem in stukjes, bedenkt hoe je dat moet oplossen, en bouwt het. - **Creatief bezig**: je kiest sprites, kleuren, bewegingen en geluidjes – alles om jouw game uniek te maken.
Het is in totaal zo’n ±145 minuten aan opdrachten, met video’s, uitleg en toffe challenges
OnderdeelGeschatte tijd (in minuten)
Uitleg en oriëntatie op interface20
Opdracht 1: Sprite laten bewegen15
Opdracht 2: Dansende sprite20
Opdracht 3: Geluid toevoegen15
Opdracht 4: Herhalen gebruiken20
Opdracht 5: Start met groene vlag10
Opdracht 6: Eigen sprite gebruiken20
Opdracht 7: Sprite reageert op toetsen25
**Totaal geschat****145 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/scratch-2) ***Scratch 2 (block-based programmeren)*** ##### 🎮 Bouw je eigen platformspel – net als Mario! In deze module leer je stap voor stap hoe je je **eigen platformspel maakt in Scratch** – een beetje zoals Super Mario, maar dan met jouw eigen ideeën en stijl! 🧱👾 Je begint eenvoudig: een sprite die kan **lopen en springen**. Maar al snel voeg je **muren, platforms en obstakels** toe. Daarna wordt het steeds leuker (en spannender): je leert hoe je **tegen monsters vecht**, hoe je **kunt springen tegen muren**, en hoe je **levels uitdagender maakt**.
Wat je gaat doen - Sprite laten **bewegen** en **springen** - Platforms bouwen waar je op kunt staan - Obstakels toevoegen die je moet **vermijden** - **Monsters** laten verschijnen (en verslaan!) - Effecten maken zoals schade of score - Bij elke stap krijg je duidelijke uitleg met een **video** - Je maakt screenshots van je werk om in te leveren en punten te verdienen
Waarom dit tof is - Je leert **hoe games echt werken** - Je oefent met **logisch denken en programmeren** - Je gebruikt je **creativiteit** om het spel helemaal van jou te maken - Je ziet **direct resultaat** van wat je bouwt – dat motiveert enorm!
Deze module kost in totaal ongeveer 160 minuten
OnderdeelGeschatte tijd (in minuten)
Uitleg random / willekeurige beweging15
Opdracht: sprite beweegt random20
Botsing detecteren tussen sprites20
Opdracht: reactie op botsing20
Variabele uitleg + maken van score20
Score zichtbaar maken op scherm10
Eindopdracht: game maken met score en botsing40
Testen / verbeteren van eigen game15
**Totaal geschat****160 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/van-scratch-naar-python) ***Van Scratch naar Python*** In deze module stap je over van Scratch naar échte code in Python. Geen blokjes meer, maar zelf typen! Je leert de basis zoals **inspringen**, **if-statements**, en **loops**, en ontdekt hoe je een stip laat bewegen, stuiteren of zelfs een spiraal laat tekenen. Alles gebeurt stap voor stap, met herkenbare voorbeelden uit Scratch. Je werkt in een makkelijke programmeeromgeving (Thonny), zodat je je kunt focussen op het leren. Aan het eind kijk je terug: wat heb je geleerd, wat ging goed en wat kun je nog verbeteren? **Kortom**: een supertoffe en toegankelijke eerste stap naar écht programmeren! 🧠💻
Deze module kost ongeveer 140 minuten
OnderdeelGeschatte tijd (in minuten)
Uitleg overgang Scratch → Python15
Eerste turtle-voorbeeld tekenen15
Uitleg over regels code en syntax20
Opdracht: vierkant tekenen15
Uitleg en gebruik van `for`-loop20
Opdracht: herhaling met `for`-loop20
Opdracht: maak een patroon met meerdere loops25
Reflectie of bespreking10
**Totaal geschat****140 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/pak-de-kaas) ***Pak de Kaas (eenvoudig spel in Python)*** In deze module leer je stap voor stap hoe je in Python een eigen game maakt. Je begint met het tonen van afbeeldingen (sprites) en leert daarna hoe je een speler laat bewegen en botsingen detecteert. Daarna voeg je extra’s toe zoals **willekeurige bewegingen**, een **score** en zelfs een **tijdslimiet**. Je oefent met belangrijke programmeerconcepten zoals **if-statements**, **loops** en **variabelen**. Ook leer je hoe je grote problemen opsplitst in kleine stukjes code – precies zoals echte programmeurs dat doen. Je leert dus niet alleen games maken, maar ook **slim nadenken in stappen**. Zo word je steeds handiger in het schrijven én begrijpen van code. 🚀💡
Deze module kost ongeveer 120 minuten
OnderdeelGeschatte tijd (in minuten)
Uitleg overgang Scratch → Python15
Eerste turtle-voorbeeld tekenen15
Uitleg over regels code en syntax20
Opdracht: vierkant tekenen15
Uitleg en gebruik van `for`-loop20
Opdracht: herhaling met `for`-loop20
Opdracht: maak een patroon met meerdere loops25
Reflectie of bespreking10
**Totaal geschat****140 minuten**
## Blok 2 - spelletjes in Python *(totaal ongeveer 8 - 9 uur)* #### [▶️](https://www.roc.ovh/books/software-development-2025/page/vallende-stenen) ***Vallende Stenen (spel Python)*** **🧠 Tover je kennis om in een eigen game** In deze module ga je verder met wat je al hebt geleerd in Scratch en “Van Scratch naar Python”. Je gebruikt **variabelen**, **if-statements** en **for-loops** om een spel te maken waarin objecten vallen en botsingen plaatsvinden. Je oefent met het **lezen en aanpassen van code**, zodat je snapt hoe iets werkt én hoe je het kunt verbeteren. Denk aan: voorkomen dat je speler uit beeld vliegt, of meerdere objecten tegelijk laten bewegen. Aan het eind laat je jouw **creativiteit los**: voeg zelf nieuwe functies toe zoals geluiden, power-ups of een andere look. Zo maak je het spel écht van jou! 🎨🎮
Deze module kost ongeveer 120 minuten
OnderdeelTijd (in minuten)
Spelconcept begrijpen10
Speler-sprite tekenen + toetsen besturen20
Steen laten vallen vanaf random plek25
Herhalen van de val (loop gebruiken)15
Botsing detecteren20
Spel laten stoppen of levens aanpassen15
Testen en bijschaven15
(Optioneel) Extra’s zoals score of geluid20
**Totaal zonder extra’s****120 minuten**
**Totaal met extra’s****140 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/snake) ***Snake (spel Python)*** **🐍 Bouw je eigen Snake-game in Python** In deze module ga je aan de slag met het maken van een echte **Snake-game** met Pygame Zero. Je herhaalt bekende concepten, maar de opdrachten zijn wat pittiger en de code wordt langer. Je leert nieuwe dingen, zoals **hoe de slang groeit** als hij iets eet – een tricky stukje logica! Aan het eind krijg je een opdracht waarbij je goed moet **nadenken over een game-probleem**, een mooie voorbereiding op later werk met AI en prompt engineering. Kortom: een leuke maar uitdagende module waarin je laat zien wat je al kunt, én nieuwe skills leert! 🧠💻
Deze module kost ongeveer 160 minuten
OnderdeelTijd (in minuten)
Spelidee en opdracht begrijpen10
Basisbesturing + beweging slang25
Eten plaatsen en detectie bij aanraking20
Snake laten groeien na eten25
Zelfbotsing implementeren25
Score bijhouden15
Game-over logica (botsing muur/zelf)15
Testen, debuggen en verbeteren20
(Optioneel) Extra functies20
**Totaal zonder extra’s****155 minuten**
**Totaal met extra’s****175 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/introductie-ai) ***Intro AI (wat is AI en wat zijn voor- en nadelen?)*** **🤖 Wat is AI – en hoe gebruik je het slim?** In deze korte module ontdek je het verschil tussen **klassiek programmeren** (met vaste regels) en **AI**, die juist **leert van data**. Je leert welke soorten AI er zijn – zoals **classificatie** en **voorspellen** – en je denkt na over de **voordelen én risico’s**van AI. Ook maak je kennis met **prompt engineering**: hoe stel je goede vragen aan AI om het nuttig en eerlijk te gebruiken. Deze les is een opwarmertje voor wat nog komt én een voorbereiding om AI slim in te zetten bij je Snake Challenge. 🧠⚙️
Deze module kost ongeveer 70 minuten
OnderdeelTijd (in minuten)
Klassikale uitleg en voorbeelden20–30
Video of demonstratie (indien aanwezig)10
Vragen beantwoorden en bespreken20–30
Reflectie of groepsdiscussie15
(Optioneel) korte opdracht of Kahoot10–15
**Totaal****60–90 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/snake-challenge) ***Snake Challenge (Python/AI challenge)*** Studenten woerden in deze **challange** uitgedaagd om een **eigen versie** van hun Snake game te maken.
Deze module duurt ongeveer 120 minuten
ActiviteitTijd (in minuten)
Ideeën bedenken (eventueel klassikaal)15
Eén uitbreiding kiezen en implementeren30–45
Tweede uitbreiding maken30–45
Testen, verbeteren en eventueel presenteren20–30
**Totaal geschat****100–135 minuten**
## Blok 3 (web front-end) *(totaal ongeveer 8-9 uur)* #### [▶️](https://www.roc.ovh/books/software-development-2025/page/html-phoenix) ***HTML / Phoenix** * In deze module leer je stap voor stap hoe HTML werkt. Elke les behandelt een duidelijk onderwerp, zoals de structuur van een webpagina, tekst opmaken, afbeeldingen en links toevoegen, lijsten en tabellen maken, en formulieren bouwen. Je werkt in Phoenix Code, een makkelijke editor in je browser waar je direct kunt zien wat je maakt. Door de opdrachten leer je niet alleen losse onderdelen, maar werk je toe naar een eigen mini-project: een persoonlijke homepage die je helemaal zelf bouwt met wat je hebt geleerd.
Deze module kost ongeveer 100 minuten
OnderdeelTijd (in minuten)
Introductie HTML + structuur uitleg15
Voorbeelden tags + experimenteren25
Werken met Phoenix (inloggen, omgeving leren)10
Opdracht: eigen pagina maken30–40
Testen en bespreken10–15
**Totaal geschat****90–105 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/css-phoenix) ***CSS / Phoenix*** In deze module ontdek je wat CSS is en waarom het onmisbaar is om je webpagina er mooi en overzichtelijk uit te laten zien. Je leert hoe je kleuren, lettertypes, marges, uitlijning en achtergronden aanpast, en hoe je met het box-model werkt (margin, padding, border). Ook selectors zoals element, class en ID komen aan bod, zodat je precies weet hoe je onderdelen van je site kunt stylen. Met Flexbox leer je moderne lay-outs maken die netjes meeschalen en mooi uitgelijnd zijn. 🌟 Het einddoel is dat je zelf goed uitziende, strak opgebouwde webpagina’s kunt maken met jouw eigen stijl.
Deze module kost ongeveer 100 minuten
OnderdeelTijd (in minuten)
Uitleg wat CSS is en hoe het werkt15
CSS-syntaxis + voorbeelden toepassen25
Werken met selectors10
Opdracht: bestaande HTML-pagina stylen30–40
Experimenteren en verbeteren10–15
**Totaal geschat****90–105 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/intro-js) ***Intro JS / Phoenix*** 🧠 In deze module duik je in de wereld van JavaScript – de taal die websites tot leven brengt. Je leert hoe je met variabelen, functies en if/else-logica slimme en interactieve onderdelen maakt. Je gaat meteen praktisch aan de slag in de browserconsole en met HTML-bestanden, zodat je direct ziet wat jouw code doet.Laat je pagina reageren op wat de gebruiker doet, verwerk invoer uit formulieren en bouw je eigen berekeningen. Met heldere uitleg, leuke opdrachten en reflectievragen leer je stap voor stap hoe jij een simpele website verandert in een echte interactieve webapp.
Deze module kost ongeveer 80 minuten
OnderdeelTijd (in minuten)
Uitleg wat JavaScript is en hoe het werkt10–15
Console openen en verkennen10
Voorbeelden doornemen en uitvoeren20
Opdracht: zelf experimenteren met `console.log`25–30
Klassikale bespreking of korte quiz10
**Totaal geschat****75–85 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/snake-challenge) Snake ***Challenge*** *De portfolio Challenge combineert persoonlijk profileren met web design en daagt de student uit een eigen portfolio te maken.*
Deze module kost ongeeer 150 minute.
OnderdeelTijd (in minuten)
Opdracht lezen en onderwerp kiezen15
Schets of opzet maken15–20
HTML schrijven (structuur opzetten)30–45
CSS toevoegen en verbeteren30–45
(Optioneel) JavaScript toevoegen30
Testen en bijschaven20–30
Reflectie/samenvatting/afronding10–15
**Totaal geschat (zonder JS)****120–150 minuten**
**Totaal geschat (met JS)****150–180 minuten**
## Blok 4 (web back-end) *(ongeveer 7-8 uur)* #### [▶️](https://www.roc.ovh/books/software-development-2025/page/php-intro) ***PHP - XAMPP*** 🧩 In deze module leer je wat het verschil is tussen frontend (wat je ziet) en backend (wat er op de server gebeurt) – een belangrijke eerste stap richting echte webontwikkeling. 💻 Je installeert tools als XAMPP en Visual Studio Code om zelf lokaal met PHP aan de slag te gaan en je code te testen. Je maakt je eerste PHP-pagina’s, werkt met variabelen en teksten, en bouwt interactieve onderdelen zoals formulieren en een kortingscalculator. Alle oefeningen zijn praktisch en helder opgebouwd, zodat je direct merkt wat je doet én waarom. Zo leer je echt webapplicaties bouwen, van de basis tot iets dat werkt!
Deze module kost ongeveer 90 minuten
OnderdeelTijd (in minuten)
Uitleg over wat PHP is10–15
Eerste regels code schrijven en testen15
Uitleg over `echo` en variabelen15
Opdrachten uitvoeren (3 à 4 opdrachten)30–40
Testen, fouten zoeken en verbeteren10–15
**Totaal geschat****80–100 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-1) ***Prompt Enineering*** De module, "Prompt Engineering 1", dient als een handleiding voor het effectief communiceren met AI-modellen zoals ChatGPT. 🧠 In deze module leer je hoe je beter kunt communiceren met AI, zoals ChatGPT. Je ontdekt dat hoe duidelijker en specifieker je vraag is, hoe beter het antwoord dat je krijgt. Je werkt met zes belangrijke elementen van een goede prompt: context, details, duidelijkheid, doel, vorm en toon. ✍️ Door praktische voorbeelden en opdrachten leer je hoe je deze elementen toepast om slimme, gerichte vragen te stellen. Zo haal je meer uit AI en krijg je antwoorden die echt passen bij wat jij nodig hebt – handig voor school, projecten en later werk!
De module kost ongeveer 90 minuten
OnderdeelTijd (in minuten)
Introductie prompt engineering10–15
Voorbeelden en klassikale analyse15
Tips bespreken10
Opdrachten: prompts verbeteren + AI testen30–40
Reflectie of klassikale bespreking10–15
**Totaal geschat****80–95 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/php-1-10p) ***PHP 2*** In deze module leer je hoe je met PHP de achterkant van een website bouwt – alles wat de gebruiker niet ziet, maar wel gebeurt op de server. Je leert veilig gegevens versturen via GET en POST, en hoe je je code slim organiseert met include en require. Met arrays en loops verwerk je makkelijk data, en met functies maak je je code herbruikbaar en overzichtelijk. Ook werk je met datum en tijd, en ontdek je hoe je sessies gebruikt om bijvoorbeeld een simpele login te maken met gebruikersgegevens. Elke les bevat uitleg, opdrachten en reflectievragen waarmee je stap voor stap werkt aan je skills als webdeveloper.
De module kost ongeveer 90 minuten
OnderdeelTijd (in minuten)
Uitleg over formulieren in HTML15
Uitleg over `$_GET` en hoe data via URL binnenkomt15
Eerste voorbeeld doornemen en uitvoeren20
Opdracht uitvoeren: formulier maken + verwerken25–30
Testen, fouten oplossen, extra uitdaging10–15
**Totaal geschat****85–95 minuten**
#### [▶️](https://www.roc.ovh/books/software-development-2025/page/php-challenge) ***PHP Challenge*** 🚀 In deze PHP Challenge laat je zien wat je hebt geleerd door zelf een mini-website te bouwen met echte backend-functies. Je kiest zelf wat je maakt – bijvoorbeeld een persoonlijke site, quiz of simpele webshop – zolang het project maar voldoet aan de technische eisen.Denk aan meerdere PHP-pagina’s, het gebruik van formulieren, sessies, functies, arrays en loops. Aan het eind laat je jouw project zien en reflecteer je op wat je hebt geleerd. Zo toon je niet alleen je resultaat, maar ook je groei als developer.
De module kost ongeveer 110 minuten
OnderdeelTijd (in minuten)
Uitleg opdracht en doelen begrijpen10–15
Zelf quizvragen bedenken en formulier opzetten20–30
PHP-code schrijven om antwoorden te controleren25–30
Score berekenen en tonen15
Testen, debuggen en verbeteren15–20
(Optioneel) Extra’s zoals feedback of styling15–20
**Totaal geschat****100–130 minu**
## Blok 5 (web back-end 2) #### [▶️](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-2) Prompt Engineering 2 🧠 Deze module bouwt voort op wat je al weet over prompt engineering en neemt je mee naar **geavanceerde technieken**die je helpen AI écht slim in te zetten. Je werkt aan **zes praktische strategieën** die niet alleen je prompts verbeteren, maar ook je probleemoplossend denken scherpen Met per techniek handige uitleg, voorbeeldprompts en opdrachten leer je niet alleen AI te sturen, maar ook zelf kritisch na te denken – handig voor complexe taken zoals prompt engineering. Het resultaat? Jij weet hoe je met slimme prompts AI antwoorden krijgt die aansluiten op jouw situatie en leerbehoefte. Deze module is de perfecte springplank voor je Snake Challenge en verdere AI-projecten! #### [▶️](https://www.roc.ovh/books/software-development-2025/page/js-dom1-8os) JavaScript 2 (DOM) In deze module leer je hoe je met JavaScript de **DOM** (Document Object Model) kunt aanpassen om je webpagina interactiever te maken. e leert HTML-elementen **selecteren** (zoals met getElementById of querySelectorAll) en de **inhoud en stijl** ervan aanpassen via JavaScript. Je oefent met **events**, zoals klikken en muisbewegingen, en leert reageren op gebruikersinput met addEventListener Je maakt nieuwe elementen aan (createElement) en voegt ze toe of verwijdert ze in de DOM met appendChild, remove() of event.target. Met classList.toggle voeg je eenvoudig styling classes toe of haal je ze weg om interactie visueel te maken. Door stap-voor-stap opdrachten bouw je van basisselectie tot volledige interactiviteit – van tekst aanpassen, elementen markeren en dynamisch toevoegen tot verwijderen en style toggles. Zo leer je hoe je JavaScript écht kan inzetten om je pagina levendiger te maken. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/js-dom2) Javascript 3 (DOM) In deze module duik je dieper in het **DOM**, een model dat jouw webpagina omzet in objecten waar JavaScript mee kan werken – de brug tussen HTML en interactieve code. Je gaat creatief aan de slag met het **aanmaken, toevoegen en verwijderen van elementen** (createElement, appendChild, remove()), en je leert hoe je attributen instelt of classes toggle’t voor dynamische effectjes Met opdrachten bouw je van basisselectie tot volledige interactiviteit: je markeert dingen, voegt nieuwe componenten toe of verwijdert ze, en maakt pagina’s echt levend Het resultaat? Je krijgt niet alleen inzicht in hoe de DOM werkt, maar je krijgt ook de tools om je webpagina’s interactief te maken op een manier die echt gaat leven. Veel plezier met knutselen! #### [▶️](https://www.roc.ovh/books/software-development-2025/page/java-script-challenge) JavaScript Challenge In deze JavaScript Challenge bouw je een volledig interactieve webapp om je front-end skills te showen. Je laat de DOM tot leven komen met events, functies en dynamische updates op basis van user-input. Kies je eigen concept—todo-app, quiz of mini-game—zolang je CRUD-acties en strakke UX gebruikt. Presenteer je app, reflecteer op je code en bewijs dat jij JavaScript onder de knie hebt! ## Blok 6 (Database / PDO) #### [▶️](https://www.roc.ovh/books/software-development-2025/page/database-1) ***Database*** Deze module gaat over **databaseontwerp**. Het leidt de student stapsgewijs door de fundamentele concepten van databases, beginnend met **wat een database is** en waarom deze nodig is voor het organiseren van gegevens. De module introduceert cruciale terminologieën zoals **entiteiten en attributen**, legt het belang uit van een **Primary Key (PK)** voor unieke identificatie, en behandelt **1:N-relaties en Foreign Keys (FKs)** om tabellen te verbinden. Tot slot wordt dieper ingegaan op **datatypen**, de **modellering van realistische scenario's**, en de complexere **N:N-relaties**, waarbij het creëren van tussentabellen wordt uitgelegd voor optimale datastructuren. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/sql) ***SQL*** In deze module ga je aan de slag met **SQL en databases**, zodat je leert hoe je data effectief opslaat, opvraagt en beheert. Je start met de basis: wat SQL is en waarom het essentieel is voor het bouwen van dynamische webapplicaties. Je leert hoe je tabellen maakt en vult, hoe je specifieke gegevens ophaalt met SELECT, en hoe je data aanpast met INSERT, UPDATE en DELETE. Relaties tussen tabellen komen aan bod: je maakt query’s met **JOINs** om gegevens uit meerdere tabellen te combineren. Ook verdiep je je in belangrijke SQL-technieken zoals **GROUP BY**, **WHERE**, **ORDER BY**, en eenvoudige **aggregatiefuncties** zoals COUNT() en SUM(). Door praktische oefeningen leer je hoe je SQL gebruikt om echte businessvragen te beantwoorden: van rapportages maken tot data-analyse in je database. Het doel is dat je na deze module zelfstandig databasequery’s schrijft om informatiesystemen te bouwen die écht werken – een onmisbare skill voor elke developer! #### [▶️](https://www.roc.ovh/books/software-development-2025/page/pdo) ***PDO*** In deze module leer je werken met **PDO**, de moderne en veilige manier om met databases te praten in PHP. Je maakt verbinding met een database, voert queries uit en gebruikt **prepared statements** om SQL-injecties te voorkomen. Je oefent met data ophalen (fetch), invoegen, updaten en verwijderen – allemaal op een nette en herbruikbare manier. Ook kijk je hoe je PDO slim inzet in je eigen project, bijvoorbeeld met een klasse of in combinatie met forms. Na deze module schrijf je zelfverzekerd veilige en nette databasecode – klaar voor het echte werk! #### [▶️](https://www.roc.ovh/books/software-development-2025/page/crud-challenge) CRUD Challenges In deze **CRUD Challenge** laat je zien wat je met PHP en PDO geleerd hebt door een werkende mini-website te bouwen – net als een echte developer. 🎯 Je kiest zelf een project, bijvoorbeeld een persoonlijke site, quiz of webshop, en bouwt dat in meerdere PHP-pagina’s. Daarbij pas je toe wat geleerd is: **formulieren**, **arrays**, **loops**, **functies** en **sessies** (voor inlog of winkelwagen). ## Blok 7 (PHP Frameworks) #### [▶️](https://www.roc.ovh/books/software-development-2025/page/prompt-engineering-3) Prompt Engineering 3 Prompt Engineering 3 is een gedetailleerde handleiding voor **geavanceerde prompt-technieken** binnen softwareontwikkeling, specifiek gericht op het optimaliseren van interacties met AI-modellen. Het document bouwt voort op eerdere modules over basale promptkenmerken zoals **context, details, duidelijkheid, doelgerichtheid, vorm en toon**, en introduceert zes geavanceerde methoden. Deze omvatten het **gebruiken van rollen (role prompting)**, het vragen om **alternatieven of variaties**, **iteratief verbeteren** van antwoorden, het toepassen van **prompt templates**, het stimuleren van **zelfvragen (self-questioning)** door de AI, en het benutten van **kritiek als leermoment (prompt debugging)**. Het doel is gebruikers te leren hoe ze effectievere en relevantere output van AI kunnen verkrijgen door middel van strategische en kritische promptformulering. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/deployement) Deployement Deze module leidt studenten stap voor stap door het proces van het online zetten van een website of webapplicatie. Belangrijke onderwerpen zijn het verkrijgen van **toegang tot PLESK**, een beheerpaneel voor webhosting, het **beveiligen van een domein met een SSL-certificaat** voor een veilige verbinding, en het **aanmaken van een FTP-account** om bestanden naar de server te uploaden. Verder wordt uitgelegd hoe een **database wordt aangemaakt** en hoe een zelfgebouwde webapplicatie **live wordt geïnstalleerd**, inclusief de noodzaak om databaseverbindingen aan te passen voor de live-omgeving. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/cms) CMS Wordpress is het meest gebruikte Content Management Systeem. Meer dan 43% van alle websites op internet draait op WordPress (stand juni 2025). In deze module leer je Wordpress installeren en daarnaast leer je alle basisconcepten van Wordpress. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/yii-introduction) Yii Intro Deze module introduceert de basisprincipes van **webapplicatieontwikkeling** met behulp van het **Yii2 PHP-framework**. De tekst gidst de student door de installatie van Yii en essentiële tools zoals Composer en XAMPP, en demonstreert vervolgens hoe een **CRUD-applicatie** (Create, Read, Update, Delete) snel kan worden gegenereerd voor databasebeheer. Belangrijke concepten zoals het **MVC-architectuurpatroon** (Model-View-Controller) en **routing** worden uitgelegd, waarbij de structuur van een webapplicatie en de manier waarop URL's worden afgehandeld duidelijk worden gemaakt. Tot slot wordt dieper ingegaan op het aanpassen van de specifieke Yii-gebruikersinterface via de **Gridview-widget**, waardoor de student leert hoe kolommen, labels en inhoud dynamisch kunnen worden beheerd. ## Blok 8 #### ▶️ Prompt Engineering 4 Inhoud nog nader te bepalen. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/cyber-security-1) Cyber Security 1, *"Deze lessen zijn ontworpen om studenten niet alleen theoretische kennis bij te brengen, maar ook praktische vaardigheden en een kritische houding ten aanzien van digitale veiligheid."* In deze module stap je in de wereld van **cybersecurity** – een wereld waarin hackers, virussen en datadieven dagelijks op de loer liggen. Maar geen zorgen: jij leert hoe je je daartegen kunt verdedigen. We beginnen met een duidelijke uitleg van de **grootste gevaren op internet**, zoals **phishing** en **malware**. Je ontdekt hoe eenvoudig het soms is om iemand te misleiden – en hoe jij dat dus kunt herkennen én voorkomen. Daarna duiken we in de techniek achter **veilige websites**: wat doet dat slotje in je browser precies? Wat is **HTTPS**, en waarom zijn **SSL-certificaten** belangrijk? Je leert hoe versleuteling werkt, met zowel **symmetrische als asymmetrische encryptie**. We laten je zien waarom wachtwoorden alleen hashen **niet genoeg is** – en waarom een beetje “salt” het verschil maakt tussen veilig en kwetsbaar. Ook onderwerpen als **Rainbow Tables** en **Brute Force-aanvallen** komen voorbij, mét strategieën om ze tegen te houden. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/oop) OOP In deze module leer je het verschil tussen procedureel programmeren (zeg maar 'gewoon' programmeren) en **OOP**. Deze module is een voorbereiding op het leren omgaan met Frameworks zoals Yii2, Laravel, Flask, etc. etc. Met **OOP** kun je code beter **organiseren**, deze **herbruiken** en je programma makkelijker uitbreidbaar maken. Je leert complexe systemen op te splitsen in beheersbare blokken met behulp van concepten als **klassen**, **objecten**, **properties** en **methods**. **Constructors** zorgen ervoor dat je automatisch waarden kunt toekennen bij het aanmaken van objecten, wat efficiëntie bevordert. Bovendien biedt **encapsulation** de mogelijkheid om data te beschermen, waardoor fouten worden voorkomen en je gecontroleerde toegang tot eigenschappen krijgt via **getters** en **setters**. #### [▶️](https://www.roc.ovh/books/software-development-2025/page/oop-challenge) OOP Challenge De OOP Challenge is een fantastische kans om jouw vaardigheden in **objectgeoriënteerd programmeren** (OOP) naar een hoger niveau te tillen en direct toe te passen in de praktijk. Je combineert je **Cyber Security** vaardigheden met de **OOP** vaardigheden. Je hebt de **keuze** uit twee boeiende projecten; Je kunt een login systeem maken of je kunt een Complete Mobiele ToDo manager maken. \-- # Introductie ## 1 Introductie Schooljaar & Leeromgeving ### 🎯 Leerdoelen - Je weet wie je studiecoach is en wat zijn of haar taken zijn. - Je kent de belangrijkste regels in de klas en begrijpt waarom deze er zijn. - Je weet wat de afspraken zijn rondom te laat komen en kunt hierop reflecteren. ### 💡 Uitleg In deze les leer je hoe het schooljaar is opgebouwd, wie jou gaat begeleiden, en wat we van elkaar verwachten. We starten met de studiecoach, de regels in de klas en afspraken over te laat komen. Jouw studiecoach is jouw eerste aanspreekpunt en hij/zij zal jou in de gaten houden en met jouw in gesprek gaan als dingen (dreigen) mis te lopen. Je ziet je studiecoach in principe minimaal twee maal per week in de de studiecoachingsuren. ### 🛠️ Opdracht 1. Vraag aan je docent of medestudent: **Wie is jouw studiecoach?** 2. Noem twee taken van de studiecoach. ### 🧠 Reflectie - Waarom is het handig om een vaste studiecoach te hebben? - Wat zou jij aan jouw studiecoach kunnen vragen? ### 📤 Inleveren - Schrijf de naam van jouw studiecoach op in een .txt- of .pdf-bestand. - Noem twee taken van de studiecoach in datzelfde bestand. ## 2 Opbouw van het eerste jaar ### 🎯 Leerdoelen - Je weet hoe het eerste studiejaar is opgebouwd. - Je weet hoe de blokken, kennischecks en herkansingen werken. - Je weet wat er gebeurt als je achterloopt of als je wilt versnellen. ### 💡 Uitleg Het eerste jaar bestaat uit **4 onderwijsperiodes** van ongeveer 8 tot 10 weken. In elke periode werk je aan **2 blokken** van het vakgebied software development. Na een jaar heb je dus 8 blokken afgerond. Elk blok wordt afgesloten met een **kennis-check**. Ongeveer twee weken later is er een herkansing mogelijk. Het hoogste cijfer telt als je eindcijfer voor het blok. **Minimaal 55%** is nodig om een blok voldoende af te ronden. Wil je versnellen, dan heb je **minimaal 65%** nodig op je kennis-check. Na elk blok kijkt je studiecoach hoe je ervoor staat. Er zijn drie situaties mogelijk: - 📈 **Je ligt op schema**: Je volgt gewoon het programma. - 📉 **Je loopt achter**: Je krijgt **verplichte extra lessen** om weer bij te komen. - 🚀 **Je ligt op schema en wilt versnellen**: Geef dit aan bij je studiecoach. Er wordt dan besproken of je daarvoor in aanmerking komt. Voorwaarden zijn o.a. dat je geen achterstand hebt en meer dan voldoende scoort. Elke periode is dus een moment van **evaluatie** en eventueel bijsturen. Zo zorgen we ervoor dat jij het maximale uit je studie haalt. ### 🛠️ Opdracht 1. Hoeveel blokken zijn er in totaal in het eerste jaar? 2. Wanneer krijg je een tweede kans voor een kennis-check? 3. Wat moet je minimaal scoren om een blok voldoende af te ronden? 4. Wat gebeurt er als je achterloopt met je blokken? 5. Wat moet je doen als je sneller door je opleiding wilt? ### 🧠 Reflectie - Wat vind jij van het systeem met blokken en kennis-checks? - Wat is voor jou een haalbaar doel: op schema blijven of versnellen? Waarom? ### 📤 Inleveren - Beantwoord de vijf opdrachtvragen en de twee reflectievragen in een tekstbestand (.txt of .pdf) en lever dit in via de leeromgeving. ## 3 Regels in de klas ### 🎯 Leerdoelen - Je kent de belangrijkste gedragsregels in de klas. - Je begrijpt waarom deze regels belangrijk zijn voor een goede leeromgeving. - Je kunt de link leggen tussen klasregels en professioneel gedrag op de werkvloer. ### 💡 Uitleg In de klas gelden duidelijke afspraken die bijdragen aan een fijne en productieve sfeer. Deze regels lijken misschien streng, maar ze bereiden je voor op de beroepspraktijk waar ook structuur, respect en samenwerking belangrijk zijn. - 📵 **Geen mobieltjes** - 🚫 **Niet eten in de les** - 🧥 **Jassen uit bij binnenkomst** - 🎧 **Oortjes uit** (alleen bij zelfstandig werken toegestaan) - 🤝 **Actief meedoen en elkaar helpen** ### 🛠️ Opdracht 1. Kies twee regels uit het rijtje hierboven. 2. Leg in je eigen woorden uit waarom jij deze regels belangrijk vindt. 3. Geef bij elk van de twee regels een voorbeeld van hoe deze regel ook in een werksituatie zou gelden. ### 🧠 Reflectie - Welke regel vind jij het meest logisch, en waarom? - Wat doe jij als iemand zich niet aan de regels houdt? ### 📤 Inleveren - Verwerk jouw antwoorden en reflectie in een tekstbestand (.txt of .pdf). ## 4 Te laat komen ### 🎯 Leerdoelen - Je kent de regels rondom te laat komen. - Je begrijpt waarom deze regels bestaan en hoe ze bijdragen aan een goed leerklimaat. - Je kunt reflecteren op je eigen punctualiteit en hoe je daarmee omgaat. ### 💡 Uitleg Te laat komen heeft gevolgen voor jezelf, je klasgenoten en de docent. Daarom zijn er duidelijke afspraken gemaakt: - 🚪 **Je streeft ernaar om 100% op tijd aanwezig te zijn.** - 📍 **Bij te laat komen meld je je eerst bij de receptie.** - 🚫 **De deur gaat dicht bij aanvang van de les en pas na 30 minuten weer open.** - 📌 **Wacht bij de lockers of in de hal – niet voor het lokaal.** - 📧 **Bij 5 keer te laat worden je ouders geïnformeerd (als je jonger bent dan 18).** - 📉 **Bij 10 keer te laat volgt een gesprek met de opleidingsmanager.** ### 🧠 Reflectie - Welke regels zou jij de meeste moeite mee hebben en waarom? - Wat vind jij de beste regel en waarom? - Bekijk de afspraken welke afspraak vind je onlogisch en waarom? - Wat zou jij doen als je vaak te laat komt, maar er een goede reden voor is? ### 📤 Inleveren - Beantwoord de reflectievragen in een tekstbestand (.txt of .pdf). ## 5 Verzuim en vervolgacties ### 🎯 Leerdoelen - Je begrijpt wat ongeoorloofd verzuim is. - Je weet wat de standaard en mogelijke acties zijn bij verzuim. - Je begrijpt waarom aanwezigheid belangrijk is voor jouw studie en toekomst. ### 💡 Uitleg Als je zonder geldige reden afwezig bent, spreken we van **ongeoorloofd verzuim**. De opleiding houdt dit bij en onderneemt acties om je te helpen op tijd weer aan te haken. #### Standaard acties - **Na 9 uren ongeoorloofd verzuim** (in 4 weken): Gesprek met je studiecoach + aantekening in je dossier. Indien je <18 bent: ouders krijgen een brief. - **Na 16 uren ongeoorloofd verzuim** (in 4 weken): Melding bij leerplicht of RMC. Opnieuw een gesprek met je studiecoach + aantekening in je dossier. Indien je <18 bent: ouders krijgen een brief. #### Mogelijke vervolgacties - Je wordt in contact gebracht met de **GGD schoolarts**. - Er kan een **huisbezoek** volgen door een **ARBO-dienst**. - Je kunt worden doorverwezen naar het **LEC (ondersteuningscentrum)**. ### 🛠️ Opdracht - Wat zijn de standaard stappen als je vaak ongeoorloofd afwezig bent? - Noem één reden waarom het belangrijk is dat dit bijgehouden wordt. ### 🧠 Reflectie - Wat zou jij doen als je weet dat je een tijdje niet naar school kunt komen? - Wat vind jij van de regel om bij 16 uur verzuim te melden bij leerplicht? ### 📤 Inleveren - Beantwoord de opdracht en de twee reflectievragen in een .txt- of .pdf-bestand. ## 6 Ziektemelding en verlofregels ### 🎯 Leerdoelen - Je weet hoe je verlof moet aanvragen voor verschillende situaties. - Je begrijpt het verschil tussen medische afspraken, officiële instanties en overmacht. - Je kunt uitleggen waarom het belangrijk is om je op tijd af te melden. ### 💡 Uitleg Als je een afspraak hebt waardoor je (deels) niet aanwezig kunt zijn op school, dan moet je dit melden. Dit verlof moet vóór **8:30 uur** telefonisch worden doorgegeven via de voicemail van het MBO Amstelland College.

**MBO College Amstelland**: **020-5791299, optie 1**.

Afhankelijk van de soort afspraak gelden er verschillende regels: - **Medisch** (zoals ziek, tandarts, huisarts): → Meld via voicemail. Vanaf 18 jaar doe je dit zelf, anders via je ouders. - **Overmacht** (zoals ziek kind, waterschade thuis): → Meld via voicemail. Vanaf 18 jaar zelf, anders via je ouders. - **Afspraak met officiële instanties** (zoals ambassade, rechtszaak, paspoort ophalen): → Overleg met je SLB’er. Die overlegt met de zorgcoördinator. - **Ziekenhuisopname**: → Zo snel mogelijk melden bij de zorgcoördinator en je SLB’er. - **Ziek tijdens schooldag**: → Eerst een verlofformulier halen bij de receptie, laten tekenen door de zorgcoördinator, en weer inleveren bij de receptie. - **Verlof bij verhuizing, uitvaart, huwelijk of rijexamen**: → Uiterlijk 4 schoolweken van tevoren aanvragen via een Eduarteformulier bij je SLB’er. Deze overlegt met de zorgcoördinator. ### 🛠️ Opdracht 1. Stel: je moet naar de tandarts en je bent 17 jaar. Wat doe je? 2. Stel: je moet een paspoort ophalen bij de gemeente. Wat is dan de juiste procedure? 3. Je ouders gaan trouwen in het buitenland. Hoe regel je dit verlof? 4. Wat doe je als je op school plots ziek wordt? ### 🧠 Reflectie - Waarom is het belangrijk om je op tijd af te melden bij afwezigheid? - Welke risico's loop je als je zonder melding afwezig bent? ### 📤 Inleveren - Beantwoord de vier opdrachtvragen en de twee reflectievragen in een .txt- of .pdf-bestand. ## 7 Communicatie via Teams ### 🎯 Leerdoelen - Je weet via welk kanaal er binnen de school wordt gecommuniceerd. - Je kent de regels en verwachtingen rondom bereikbaarheid van docenten en SLB’ers. - Je kunt op een professionele manier communiceren via Teams. ### 💡 Uitleg Binnen onze school gebruiken we **Microsoft Teams** voor alle communicatie tussen studenten en docenten. - 📅 Docenten zijn alleen bereikbaar op **schooldagen** via Teams. - ⏳ Een **studiecoach** probeert binnen één schooldag te reageren. Maar soms lukt dat niet meteen. Je mag gerust na een dag vriendelijk vragen of je bericht al is gezien. Voorbeeld: *"Beste .... heeft u al tijd gehad om naar mijn vraag over ...... te kijken?"* - 📬 Stuur je een bericht naar een **andere docent** (die niet jouw les geeft of SLB’er is), dan geldt: **houd rekening met een reactietijd van een week**. Pas na een week kun je een vriendelijke reminder sturen. - 🚫 Gebruik **geen “??”** of andere dwingende berichten. Dit wordt als onprofessioneel beschouwd. Een nette en duidelijke communicatie helpt jou én je docent verder. Het lijkt misschien formeel, maar het is goede voorbereiding op de beroepspraktijk. ### 🛠️ Opdracht 1. Stel: je hebt op dinsdagmiddag een vraag gesteld aan je SLB’er. Het is woensdagmiddag en je hebt nog geen reactie. Wat doe je? 2. Stel: je wilt een vraag stellen aan een docent van een ander vak. Hoe lang moet je wachten voordat je een herinnering mag sturen? 3. Je hebt een docent een bericht gestuurd en je bent ongeduldig. Je wilt “??” sturen. Wat kun je beter doen? ### 🧠 Reflectie - Wat vind jij van de regel om een week te wachten op een reactie van een andere docent? - Wat is voor jou een goede balans tussen geduld en doorvragen? ### 📤 Inleveren - Beantwoord de drie opdrachtvragen en de twee reflectievragen in een .txt- of .pdf-bestand. ## 8 Verantwoordelijkheid & Studiehouding ### 🎯 Leerdoelen - Je begrijpt wat er van jou wordt verwacht als student op het MBO. - Je kunt uitleggen waarom verantwoordelijkheid nemen belangrijk is voor je succes. - Je kunt voorbeelden geven van goed studiegedrag. ### 💡 Uitleg Op het MBO verwachten we dat je zelfstandig leert werken, maar dat betekent niet dat je er alleen voor staat. Verantwoordelijkheid nemen betekent dat je zelf op tijd aan de bel trekt als iets niet lukt of als je hulp nodig hebt. Ook betekent het dat je je werk plant, aanwezig bent, je best doet en afspraken nakomt. Een goede studiehouding helpt je niet alleen nu, maar ook straks op je stage en werk. Daar wordt van je verwacht dat je zelf initiatief neemt, op tijd komt, goed samenwerkt, en openstaat voor feedback. ### 🛠️ Opdracht 1. Geef drie voorbeelden van verantwoordelijk gedrag op school. 2. Geef een voorbeeld van een situatie waarin je hulp zou kunnen vragen aan je studiecoach of docent. 3. Bedenk een situatie waarin je motivatie een dipje heeft. Wat zou jij dan doen? ### 🧠 Reflectie - Wat vind jij lastig aan verantwoordelijkheid nemen voor je eigen studie? - Wat is voor jou een goede manier om gemotiveerd te blijven als het even tegenzit? ### 📤 Inleveren - Beantwoord de drie opdrachtvragen en de twee reflectievragen in een tekstbestand (.txt of .pdf) en lever deze in via de leeromgeving. ## 9 Voorbereiding op de kennischeck Bekijk onderstaande vragen en antwoorden om je goed voor te bereiden op de kennistoets over het introductieprogramma en de leeromgeving.
👤 Wat is de rol van jouw studiecoach? Je studiecoach is je eerste aanspreekpunt op school. Hij of zij begeleidt je studievoortgang, bespreekt problemen en helpt je als dingen niet goed gaan. Je ziet je studiecoach minimaal twee keer per week.
📚 Hoe is het eerste leerjaar opgebouwd? Het jaar bestaat uit 4 perioden van 8-10 weken. In elke periode werk je aan 2 blokken. In totaal zijn er dus 8 blokken in het eerste jaar.
📈 Wanneer heb je een herkansing voor een kennis-check? Na elke blok is er een kennis-check. Ongeveer 2 weken later is er een herkansing. Het hoogste cijfer van de twee telt.
✅ Wat is het minimumcijfer om een blok voldoende af te ronden? Je moet minimaal 55% halen op je kennis-check of herkansing om een blok af te ronden.
🚀 Wat moet je doen als je sneller wilt studeren? Je geeft dit aan bij je studiecoach. Die bespreekt of je voldoet aan de voorwaarden: minimaal 65% scoren, geen achterstand en deelname aan een extra les.
📵 Waarom zijn er klasregels zoals geen telefoons of jassen aan? Deze regels zorgen voor rust, respect en concentratie in de les. Ze bereiden je voor op professioneel gedrag in de werkomgeving.
⏰ Wat zijn de afspraken rond te laat komen? Je meldt je eerst bij de receptie. De deur gaat dicht bij aanvang van de les en pas na 30 minuten weer open. Bij herhaald te laat komen worden ouders of de manager ingeschakeld.
📉 Wat gebeurt er bij ongeoorloofd verzuim? Bij 9 uur verzuim volgt een gesprek met je studiecoach. Bij 16 uur wordt leerplicht of RMC geïnformeerd. Er zijn ook vervolgacties mogelijk zoals contact met GGD of ARBO.
📞 Hoe meld je je ziek of vraag je verlof aan? Je belt voor 8:30 uur naar het nummer van MBO College Amstelland. De procedure verschilt per situatie (bijv. medisch, overmacht, officiële instanties). Soms is overleg met de SLB’er of zorgcoördinator nodig.
💬 Wat zijn de regels voor communicatie via Teams? Gebruik Teams alleen op schooldagen. Wacht 1 schooldag op je SLB’er en 1 week bij andere docenten voor je een reminder stuurt. Gebruik geen dwingende berichten zoals "??".
🧠 Wat betekent het om verantwoordelijkheid te nemen voor je studie? Je plant je werk, komt op tijd, vraagt hulp als iets niet lukt, en houdt je aan afspraken. Zo bereid je je voor op zelfstandigheid in het werkveld.
### 🛠️ Opdracht Maak nu de kennis-check. Dit is een oefening zodat je weet wat je straks kan verwachten. Kennis-check-naam: C25.B1.01 en C25.B1.02 ### 📤 Inleveren Aan het einde van de kennis-check ontvang je een certificaat. Maak een schermafdruk en lever deze in. # Blok 1 van Scratch naar Python # Scratch 1 *Deze pagina biedt een **stap-voor-stap handleiding** om te leren programmeren in Scratch door het bouwen van een **doolhofspel**. Je volgt de lessen door middel van **uitlegvideo's**, maakt **opdrachten direct in Scratch** en leert daarbij belangrijke programmeerconcepten zoals beweging, loops, if-then-else statements, variabelen en het resetten van de speltoestand. De cursus begeleidt je van de introductie en het opzetten van het startproject tot het afronden van je eigen unieke versie van het spel en het reflecteren op wat je hebt geleerd.* ## Introductie en start Welkom! We gaan je stap voor stap helpen om Scratch te begrijpen, zodat je zelf leert programmeren. Maar wat gaan we eigenlijk doen? **Wat kun je verwachten?** - Je bekijkt korte uitlegvideo's van Felienne, een docent aan de TU Delft. - Je maakt opdrachten direct in Scratch. - Je leert stap voor stap hoe je een eigen doolhofspel bouwt. Als je nog meer wilt weten van deze module dan kan je [hier](https://www.roc.ovh/link/898#bkmrk-scratch-1-1) meer informatie vinden. **Spelregels** - Je bouwt het spel stap voor stap op. Daarna maak je je eigen variant. - Het inleveren van andermans werk is fraude en kan ertoe leiden dat je een extra module moet doen. - Maar het is ook écht leuk om je eigen spel te maken! Kom je er even niet uit, dan mag je natuurlijk wel een medestudent om hulp vragen. - Voor deze opdrachten gebruiken we (nog) geen AI — dat komt later. - Bij elke opdracht lever je iets in: soms is dat je code (of een screenshot daarvan), soms een antwoord op één of meer vragen. Ook die antwoorden schrijf je in je eigen woorden. Door zelf na te denken over de vragen, begrijp je de stof beter — en zo word je uiteindelijk een goede softwaredeveloper. **Voorbereiding:** Open dit project in Scratch: [https://scratch.mit.edu/projects/96709199/#editor](https://scratch.mit.edu/projects/96709199/#editor) (of download het bestand hier: [Doolhof Start.sb3](https://www.roc.ovh/attachments/93)) ##### Taal aanpassen Standaard staat de taal op English, deze module is in het **Nederlands** dus als je de taal wil aanpassen dan kan dat onder **settings** - **laguage**. Je zou dit startscherm moeten zien: ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-04/scaled-1680-/image.png) #### Bekijk de uitlegvideo In deze video legt Felienne uit wat je gaat bouwen en hoe je aan de slag kunt. Let goed op de uitleg over hoe Scratch werkt. **Alternatieve link:** [Klik hier als de video hierboven niet werkt](https://my.hidrive.com/lnk/BgMqZWb7F#file) ### 🛠️ Opdracht Beschrijf in één zin in je eigen woorden wat je denkt dat je gaat maken. ### 📤 Inleveren Typ je zin in het tekstvak hieronder. Gebruik je eigen woorden en denk aan wat je in het spel gaat bouwen. ## Stap 1 – Beweging We beginnen met de besturing van je hoofdpersonage, Giga. In deze stap leer je hoe je Giga kunt laten bewegen met de pijltjestoetsen. **Wat leer je?** - Bewegen over de X-as (links en rechts). - Bewegen over de Y-as (omhoog en omlaag). #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/GKwgvRLdP#file) ### 🛠️ Opdracht Hoeveel richtingen kan jouw poppetje bewegen aan het einde van deze stap? ### 📤 Inleveren Vul in het tekstvak in hoeveel richtingen jouw sprite beweegt. ## Stap 2 – De lus (loop) In deze stap leren we hoe je een herhaling maakt met een lus. Hiermee kun je code telkens opnieuw uitvoeren zolang een bepaalde voorwaarde klopt. **Wat leer je?** Je gebruikt een herhaalblok om acties te blijven herhalen. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/N0uU0crpj) ### 🛠️ Opdracht Leg in je eigen woorden uit wat een lus (loop) doet in een programma. ### 📤 Inleveren Typ je uitleg over de lus in het tekstvak. ## Stap 3 – Als-dan-anders We voegen nu logica toe: wat moet er gebeuren als iets gebeurt? Je leert nu het *als-dan-anders*-blok gebruiken. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/TXHILqicx#file) ### 🛠️ Opdracht Wat doet een als-dan-anders (if-then-else)-blok in je code? Leg het uit in je eigen woorden. ### 📤 Inleveren Typ je uitleg in het tekstvak. ## Stap 4 – Terug naar startpositie Als Giga een muur raakt, willen we dat hij teruggaat naar het begin. In deze stap leer je hoe je zijn positie reset. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/alnZpLpma#file) ### 🛠️ Opdracht Welke coördinaten (X en Y) gebruikt jouw spel om Giga terug te zetten naar de start? ### 📤 Inleveren Typ de X- en Y-positie in het tekstvak. ## Stap 5 – De sleutel Je spel is bijna klaar! In deze stap voeg je een sleutel toe. Als Giga deze aanraakt, is het spel gewonnen. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/GCx79dnoY) ### 🛠️ Opdracht Maak een screenshot van je hele browser waarin je de gemaakte code laat zien. ### 📤 Inleveren Upload de screenshot met jouw Scratch-code. ## Stap 6 – Monster toevoegen We maken het spannend! Voeg een monster toe dat je moet ontwijken. Laat het monster bewegen. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/VI2bYDZ6z) ### 🛠️ Opdracht Laat het monster bewegen. Lever een screenshot in van de code die het monster laat bewegen. ### 📤 Inleveren Upload de screenshot van de code van het monster. ## Stap 7 – Game over Als het monster Giga raakt, is het spel afgelopen. Je leert nu hoe je het spel opnieuw kunt laten starten. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/bhEztZfFA) ### 🛠️ Opdracht Laat zien dat Giga teruggezet wordt naar het begin wanneer hij de muur of het monster raakt. ### 📤 Inleveren Lever een screenshot in van de code die dit laat zien. ## Stap 8 – Alles terugzetten Als het spel opnieuw begint, moeten zowel het monster als Giga teruggezet worden naar hun beginpositie. Pas ook de snelheid aan als het spel te moeilijk is. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/MDRS95fwh) ### 🛠️ Opdracht Pas de snelheid van het monster aan en laat zien hoe je alles terugzet. ### 📤 Inleveren Lever een screenshot in van de code waarin het monster wordt teruggezet en je de snelheid hebt aangepast. ## Stap 9 – Punten bijhouden We voegen nu een score toe met behulp van een variabele.
Een variabele is een waarde die je kunt opslaan en aanpassen tijdens het spel.
#### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/DemPL63Dk) ### 🛠️ Opdracht Laat zien hoe je de score bijhoudt. ### 📤 Inleveren Lever een screenshot in van je code waarin je de score bijhoudt met een variabele. ## Stap 10 – Afronden We maken het spel af en zorgen dat het er goed uitziet. Je kunt je spel opslaan op je laptop of online delen. #### Bekijk de uitlegvideo **Alternatieve link:** [Bekijk de video via HiDrive](https://my.hidrive.com/lnk/d496LGsE2) ### 🛠️ Opdracht Maak het spel af, voeg iets unieks toe en sla het op. ### 📤 Inleveren Lever jouw eigen unieke versie van het spel in. ## Stap 11 – Wat heb je geleerd? Je hebt veel geleerd over programmeren. Nu kijk je terug op wat je allemaal hebt gedaan. ### 🛠️ Opdracht - **Vraag 1:** Waarvoor heb je in dit spel een lus gebruikt? - **Vraag 2:** Waarvoor heb je een als-dan-anders-blok gebruikt? - **Vraag 3:** Waarvoor heb je een variabele gebruikt? ### 📤 Inleveren Schrijf je drie antwoorden op en lever ze in. # Scratch 2 *Deze pagina biedt een reeks lessen voor het **maken van een platformspel** in Scratch 2, vergelijkbaar met Super Mario. De instructies leiden gebruikers stap voor stap door het proces, beginnend bij **basisbeweging** en voortschrijdend naar complexere elementen zoals **springen op muren**, het vermijden van obstakels, en het **toevoegen en verslaan van monsters**. Elke sectie bevat een **video-tutorial**, opdrachten, en vereist screenshots voor **inlevering en punten**.* ## Introductie en start Wil je precies weten wat je in de module gaat doen, dan kan je [hier](https://www.roc.ovh/link/898#bkmrk-scratch-2-%28block-bas) meer informatie vinden. **Spelregels** Weet je nog wat de [spelregels ](https://www.roc.ovh/link/876#bkmrk-spelregels)waren, deze helden nog steeds? **Aan de slag....** We slaan een paar stappen over en gaan direct aan de slag met het maken van een soort 'Mario-spel'. We beginnen met deze 'code': [Giga Platformer Start.sb3](https://www.roc.ovh/attachments/95) We gaan code gebruiken die we in *Scratch 1* hebben gemaakt. Hiervoor gebruiken we de 'rugzak'. Dit wordt in de video uitgelegd. Alternatieve link: [https://my.hidrive.com/lnk/ApKeEML7P](https://my.hidrive.com/lnk/ApKeEML7P) ### 🛠️ Opdracht Bekijk de video en laat Giga vloeiend bewegen met een *herhaal-als*-blok; in het als-blok herhaal je de beweging zolang de toets is ingedrukt. ### 📤 Inleveren Een screenshot van je 'code'. ## Springen We gaan Giga laten springen. In de video wordt uitgelegd hoe. Alternatieve link: [https://my.hidrive.com/lnk/dHHmCfJHa](https://my.hidrive.com/lnk/dHHmCfJHa) Aan het eind van de video krijg je de uitdaging om de springbeweging vloeiender te maken. ### 🛠️ Opdracht Maak de springbeweging en probeer deze vloeiender te maken. ### 📤 Inleveren Een screenshot van je 'code'. ## Muur We gaan een muur in het veld plaatsen en het spel zo maken dat we op de muur kunnen springen. Bekijk de video voor instructies. Aan het eind blijven we in de lucht hangen. Dat is niet de bedoeling. Kun jij dat oplossen? Alternatieve link: [https://my.hidrive.com/lnk/KwzJbR6t3](https://my.hidrive.com/lnk/KwzJbR6t3) ### 🛠️ Opdracht Zorg ervoor dat Giga niet meer in de lucht blijft zweven als je springt. ### 📤 Inleveren Een screenshot van je 'code'. ## Niet meer door de muur We lopen dwars door de muur heen en dat is niet de bedoeling. We gaan dat in deze stap oplossen. Staan we op de muur, dan kunnen we opeens niet meer bewegen. Dat kun jij vast oplossen door naar de Y-positie te kijken. Bekijk de video voor instructies. Alternatieve link: [https://my.hidrive.com/lnk/cLNtywaNd](https://my.hidrive.com/lnk/cLNtywaNd) ### 🛠️ Opdracht Kun jij ervoor zorgen dat Giga, als hij op de muur staat, nog steeds kan bewegen? ### 📤 Inleveren Een screenshot van je 'code'. ## Van links en rechts Staan we op de muur, dan kun je nu wel bewegen omdat we met behulp van de Y-positie controleren of we op de muur staan. Maar als we vanaf de rechterkant teruglopen, kunnen we nog door de muur heen. Kun jij dat oplossen? Alternatieve link: [https://my.hidrive.com/lnk/JYozfTzCk](https://my.hidrive.com/lnk/JYozfTzCk) ### 🛠️ Opdracht Kun jij ervoor zorgen dat Giga niet meer door de muur heen kan lopen als hij terugloopt? ### 📤 Inleveren Een screenshot van je 'code'. ## Lopen door het level We moeten het platform laten bewegen om door het level heen te lopen. We gaan de muur laten bewegen zodat het lijkt alsof we door het level heen lopen. Dat is best een beetje ingewikkeld, want de muur moet pas bewegen als we ongeveer in het midden staan. In de video wordt dit uitgelegd en voorgedaan. Alternatieve link: [https://my.hidrive.com/lnk/MvsuRrGFy](https://my.hidrive.com/lnk/MvsuRrGFy) ### 🛠️ Opdracht Kun jij de muur, als die uit beeld is, opnieuw laten verschijnen? ### 📤 Inleveren Een screenshot van je 'code'. ## Tijd voor monsters We gaan een 'monster' (ook wel 'vijand' genoemd) maken. Deze beweegt net als de muur, zodat het lijkt alsof je door het level loopt. We gaan het 'monster' laten bewegen. Alternatieve link: [https://my.hidrive.com/lnk/egNP9MPj2](https://my.hidrive.com/lnk/egNP9MPj2) ### 🛠️ Opdracht Kun jij het monster heen en weer laten bewegen? ### 📤 Inleveren Een screenshot van je 'code'. ## Monster bewegen Het monster beweegt, maar blijft nog aan de muur plakken. Alternatieve link: [https://my.hidrive.com/lnk/Z0y7vVvHj](https://my.hidrive.com/lnk/Z0y7vVvHj) ### 🛠️ Opdracht Laat het monster wachten tot de muur op positie 100 staat en laat het monster dan pas verschijnen. ### 📤 Inleveren Een screenshot van je 'code'. ## Game Over! Als het monster je raakt, ben je 'af'. Als je af bent, stopt het spel. Alternatieve link: [https://my.hidrive.com/lnk/IrCnwcFwx](https://my.hidrive.com/lnk/IrCnwcFwx) ### 🛠️ Opdracht Zet 'Game Over' in beeld als je af bent, zodat je weet dat je 'af' bent. ### 📤 Inleveren Een screenshot van je 'code'. ## Aanvallen We gaan het spel zo aanpassen dat we het monster kunnen 'verslaan'. Alternatieve link: [https://my.hidrive.com/lnk/dvVi8f5dQ](https://my.hidrive.com/lnk/dvVi8f5dQ) ### 🛠️ Opdracht Als Giga tegen het monster aanloopt, is het 'Game Over', maar als je op het monster springt, moet het monster worden geplet. Schrijf hiervoor de code (tip: dit lijkt op de code van de muur waarop we kunnen springen). ### 📤 Inleveren Een screenshot van je 'code'. ## Monster verdwijnt Als je het monster 'plet', wil je dat het geen 'Game Over' is. Het monster moet worden geplet en daarna verdwijnen. We maken een aanpassing zodat het monster weer terugkomt nadat het is geplet. Alternatieve link: [https://my.hidrive.com/lnk/Eolifu5Sn](https://my.hidrive.com/lnk/Eolifu5Sn) ### 🛠️ Opdracht Oeps, we hebben nog een bug. Het monster verschijnt weer terug, maar is nog steeds geplet. Kun jij dit oplossen? ### 📤 Inleveren Een screenshot van je 'code'. ## Stop als je geplet bent We moeten ervoor zorgen dat zodra het monster is geplet, het niet meer beweegt. Alternatieve link: [https://my.hidrive.com/lnk/DSscj5iKz](https://my.hidrive.com/lnk/DSscj5iKz) ### 🛠️ Opdracht Kun jij het monster stilzetten zodra het is geplet? ### 📤 Inleveren Een screenshot van je 'code'. ## Klaar We zijn klaar! Alternatieve link: [https://my.hidrive.com/lnk/XZVISW0jy](https://my.hidrive.com/lnk/XZVISW0jy) ### 🛠️ Opdracht Je hebt 12 screenshots ingeleverd. Als deze goed zijn, heb je 12 x 5 = 60 punten. Voor een vinkje moet je 84 punten of meer hebben. Laat het hele spel aan een docent zien. Je kunt tot 35 punten krijgen. De docent kan vragen stellen over hoe jouw spel werkt. Het spel moet aan de volgende voorwaarden voldoen: ##### Verplicht (+25 punten) - Je kunt door het spel heen bewegen: naar links en naar rechts. - Je kunt niet door de muur heen lopen, maar je kunt er wel op springen. - Je hebt een monster; als je die raakt, is het 'Game Over'. Er verschijnt een 'Game Over'-melding en het spel stopt. - Je kunt het monster pletten: je ziet het geplette monster, waarna het verdwijnt en even later weer terugkomt. ### 📤 Inleveren In het tekstveld tik je in dat je klaar bent. De docent zal samen met een aantla sutdenten het werk doornemen en goedkeuren. \-- ## \### ### Youtube Links 1. [https://www.youtube.com/watch?v=zRWO9vWytPA](https://www.youtube.com/watch?v=zRWO9vWytPA) 2. [https://www.youtube.com/w atch?v=iw7YvogC5Uo](https://www.youtube.com/watch?v=iw7YvogC5Uo) 3. [https://www.youtube.com/watch?v=vOAI\_YY6Ntk](https://www.youtube.com/watch?v=vOAI_YY6Ntk) 4. [https://www.youtube.com/watch?v=L8q4OR8n\_yw](https://www.youtube.com/watch?v=L8q4OR8n_yw) 5. [https://www.youtube.com/watch?v=mluq9\_b4xSI](https://www.youtube.com/watch?v=mluq9_b4xSI) 6. [https://www.youtube.com/watch?v=Cg9T9HoI7tY](https://www.youtube.com/watch?v=Cg9T9HoI7tY) 7. [https://youtu.be/jlPn-XL4T\_c](https://youtu.be/jlPn-XL4T_c) 8. [https://www.youtube.com/watch?v=CQby8IzbkZg](https://www.youtube.com/watch?v=CQby8IzbkZg) 9. [https://www.youtube.com/watch?v=dM9a4XprB7o](https://www.youtube.com/watch?v=dM9a4XprB7o) 10. [https://www.youtube.com/watch?v=CHWy9lLV4bA](https://www.youtube.com/watch?v=CHWy9lLV4bA) 11. [https://www.youtube.com/watch?v=dV4ivXfP2q0](https://www.youtube.com/watch?v=dV4ivXfP2q0) 12. [https://www.youtube.com/watch?v=a9ubC4LTcrs&t=3s](https://www.youtube.com/watch?v=a9ubC4LTcrs&t=3s) 13. [https://www.youtube.com/watch?v=0xFosaKxcgY](https://www.youtube.com/watch?v=0xFosaKxcgY) \-- # Van Scratch naar Python ##### Status: alles uitgevoerd en getest *Deze webpagina, getiteld "Van Scratch naar Python", dient als een tutorial om beginners te helpen overstappen van de visuele programmeertaal Scratch naar de tekstgebaseerde taal Python. De lessen behandelen belangrijke programmeerconcepten zoals **indentatie** (hoe codeblokken worden herkend in Python), het gebruik van **commentaar** om code te verduidelijken, en de implementatie van **if-statements** voor beslissingslogica en **loops** (zoals `for`- en `while`-loops) voor herhalende acties. Door middel van praktische opdrachten met een bewegende stip (sprite) leren gebruikers deze concepten toe te passen en steeds complexere bewegingspatronen, zoals stuiteren, vierkante bewegingen en spiralen, te creëren in de Thonny Python-omgeving, waarbij ook het gebruik van de `pygame` library en een specifieke `scratch_lib.py` wordt uitgelegd.* ## 0 Wat gaan we leren? We gaan code maken. We gaan daarvoor Python gebruiken. Wat gaan we leren: - waarom en hoe we inspringen in Python. - wat commentaar in code is - hoe we in Python een if-statement maken - hoe we in python een loop (lus) maken ##### In deze lessen worden de volgende Scratch blokken in geschreven code omgezet.
##### IF - THEN ##### IF - THEN - ELSE ##### FOR LOOP (repeat)
[![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/Qdzimage.png)](https://www.roc.ovh/uploads/images/gallery/2025-05/Qdzimage.png) [![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/FRkimage.png)](https://www.roc.ovh/uploads/images/gallery/2025-05/FRkimage.png) ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/v93image.png)
### 🛠️ Opdracht Leg in eigen woorden uit: 1. wat is het verschil tussen een `if-then` en een `if-then-else` ? 2. Waarvoor gebruik je een for-loop (of een repeat; dat is hetzelfde)? ### Inleveren Een antwoord op de twee vragen, in eigen woorden (geen AI)! Maak een txt bestand en schrijf daarin je antwoorden. ## 1 Installatie Python (Thonny) We hebben geprogrammeerd in Scratch en we gaan nu programmeren in een echte programmeertaal: Python. We gaan echte code maken, maar daarvoor moeten we eerst wat zaken installeren. We gaan gebruikmaken van [Thonny](https://thonny.org/) [📥Download](https://my.hidrive.com/lnk/L4OQAv45D) Pak het bestand uit en zet het op een plek die voor jou logisch is, bijvoorbeeld op je bureaublad. ### Installatie *pygame* Library Programmeertalen hebben libraries (ook wel 'packages' genoemd). Deze libraries bevatten code die jij kunt gebruiken. Wij gaan de *pygame* library installeren omdat we die straks nodig hebben. Als je Thonny opstart, ga dan naar *Tools - Manage packages...* ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/9ffimage.png) Zoek dan naar *pygame* ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/84Cimage.png) Klik op *pygame* en daarna op de knop *Install* ### 📥Download code Download de code [startcode-python-scratch.zip](https://www.roc.ovh/attachments/100) Pak de code uit, start Thonny en open het bestand `student.py` ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/a2bimage.png) Druk op het groene 'run'-symbool en kijk wat er gebeurt. Het programma wordt regel voor regel van boven naar beneden uitgevoerd. ### ℹ️Uitleg code Hieronder zie je de uitleg. Het kan zijn dat je niet alles in één keer begrijpt, maar probeer in ieder geval de rode uitleg te begrijpen. ##### Regel 1 Hier worden libraries ingeladen. Dit zijn stukjes code die al klaar zijn en die in het bestand `scratch_lib.py` staan. ##### Regel 3 Hier wordt de sprite gemaakt en op een positie gezet. Let op dat positie (0, 0) linksboven is (en niet in het midden zoals bij Scratch). ##### Regel 5 Hier maken we een functie waarmee de sprite wordt bewogen. Dit is nodig om de library te kunnen gebruiken. ##### Regel 6 Hiermee bewegen we de sprite 10 pixels naar rechts en 0 pixels naar beneden. ##### Regel 7 We pauzeren een aantal frames. ##### Regel 9 Hiermee starten we het spel. ### 🛠️ Opdracht Probeer de getallen op regel 6 eens aan te passen en kijk wat er gebeurt. Verander de getallen zodanig dat de groene stip van linksboven **diagonaal** richting rechtsonder beweegt. ### Inleveren Maak een screenshot van de code die jij hebt aangepast zodat de groene stip diagonaal van linksboven naar rechtsonder beweegt. ## 2 De stuiterbal In deze opdracht leer je hoe je een sprite (een groene stip) van links naar rechts kunt laten bewegen **en** hoe je met een `if`-statement de richting verandert zodra de sprite de rechterkant van het scherm bereikt. ### Begincode Je gebruikt de volgende code als uitgangspunt: ```python from scratch_lib import create_sprite, move, run_animation, get_x # Maak de sprite en zet hem links op het scherm sprite = create_sprite("green_dot.png", 0, 300) # Variabele om te onthouden of we naar rechts bewegen moving_right = True def animate(): global moving_right # We gaan deze variabele aanpassen # Haal de huidige x-positie op x = get_x(sprite) # TODO: Als x groter of gelijk is aan 550, verander moving_right naar False # if ???: # moving_right = False # Beweeg de sprite op basis van de richting if moving_right: move(sprite, 5 , 0 ) else: move(sprite, 0 , 0 ) # Start de animatie run_animation([sprite], animate, steps=1000) ``` Als je deze code uitvoert, zie je dat de groene stip van links naar rechts beweegt, maar **hij stopt niet of verandert niet van richting**. Hij verdwijnt uit beeld. ### ℹ️ Wat is inspringen in Python? #### Inspringen = blok = identation In Python is de **inspringing** (ook wel *indentatie* genoemd) heel belangrijk. Python gebruikt inspringen om aan te geven welke code bij elkaar hoort. Als je bijvoorbeeld een`if`-statement gebruikt, dan moet de code die daarbij hoort \*\*een stukje naar rechts inspringen\*\* (meestal 4 spaties). ```python if x >= 100: move(sprite, 5, 0) # deze regel hoort bij het if-blok # dit staat buiten het if-blok print("Ik ben klaar!") ``` #### 🔁 Vergelijking met Scratch In Scratch zie je blokken zoals *"als ... dan"* of *"herhaal ..."*. De blokken die **in** zo'n constructie staan, vallen daar letterlijk *in*. Ze zijn visueel naar binnen geschoven. In Python doe je dat met spaties: - De **buitenste structuur** (zoals `if` of `for`) sluit je af met een dubbele punt `:`. - De regels die **bij dat blok horen**, zet je eronder en laat je 4 spaties naar rechts inspringen. Als je dit vergeet, krijg je in Python een foutmelding zoals: ``` IndentationError: expected an indented block ``` #### ✅ Juiste voorbeeld ```python if moving_right: move(sprite, 5 , 0 ) ``` #### ❌ Fout voorbeeld ```python if moving_right: move(sprite, 5 , 0 ) ``` Controleer dus goed dat de regels die bij een `if` of `for` horen, netjes zijn ingesprongen. #### Wat gaan we doen? We willen dat de bal **van richting verandert** als hij de rechterkant bereikt (bijvoorbeeld bij `x = 550`). Daarvoor heb je een paar dingen nodig: De variabele `moving_right` die onthoudt of de sprite naar rechts beweegt (`True`) of niet (`False`). Een `if`-statement (regel 15, 16 en 17) die controleert of de `x`-waarde van de sprite groter is dan 550. Als dat zo is, moet de sprite naar links bewegen in plaats van naar rechts (regel 19, 20, 21, 22 en 23). De code is nog niet helemaal af. #### \# Commentaar In de code zie je af en toe een hekje `#` aan het begin van de regel staan. Dit betekent dat dit **commentaar** is. De regel wordt **niet** uitgevoerd. Het dient om jou als programmeur te helpen begrijpen wat de code doet. ### 🛠️ Opdracht Haal het hekje weg op regel 16 en 17, maar zorg ervoor dat de uitlijning goed blijft: voor de `if` **vier** spaties en op de regel `moving_right = False` **acht** spaties. Op de plaats van de `???` plaats je nu de juiste conditie. Je vergelijkt of de x-positie van de sprite groter of gelijk is aan 550. In Python ziet dat er als volgt uit: ```python if var_a >= 550: ``` `var_a` is een variabele. Plaats deze conditie in de code en vervang `var_a` door de juiste variabele die de x-positie bevat. → Test je code. Geen foutmeldingen? OK! Wat gebeurt er nu als de x-positie 550 is? Precies — de bal staat stil! Kijk nog eens goed naar het `if`-statement op regel 20 t/m 23 en probeer de code aan te passen zodat de bal niet meer stil staat als hij positie 550 heeft bereikt, maar dat hij terug beweegt. Gebruik daarna een tweede `if`-statement om te bepalen **hoe** de sprite moet bewegen: - Als `moving_right` `True` is → beweeg naar rechts. - Anders, dus als `moving_right` `False` is → beweeg naar links. Denk eraan: een positief getal beweegt de sprite vooruit, een negatief getal beweegt hem achteruit. ### Inleveren Maak een screenshot van de aangepaste code. ## 3 De stuiterbal – heen en weer In deze opdracht breiden we de vorige oefening uit. De groene stip moet nu niet alleen van links naar rechts bewegen, maar ook weer **terug naar links** als hij de rechterrand heeft bereikt, en daarna **weer naar rechts** als hij de linkerrand bereikt. ### Begincode Je gebruikt de volgende code als uitgangspunt. Deze lijkt op de vorige, maar nu gaan we twee richtingen controleren. ```python from scratch_lib import create_sprite, move, run_animation, get_x # Maak de sprite en zet hem links op het scherm sprite = create_sprite("green_dot.png", 0, 300) # Variabele om te onthouden of we naar rechts bewegen moving_right = True def animate(): global moving_right x = get_x(sprite) # Keer om als de sprite de rechterkant raakt if x >= 550: moving_right = False # TODO: Voeg hier een extra if-statement toe: # Als de sprite aan de linkerkant is (x <= 0), dan moet moving_right weer True worden if moving_right: move(sprite, 5, 0) else: move(sprite, -5, 0) run_animation([sprite], animate, steps=1000) ``` #### Als we een if maken dan kennen we de volgende vergelijking
==is gelijk aan?
<is kleiner dan?
>is groter dan?
<=is kleiner of gelijk aan?
>=is groter of gelijk aan?
!=is ongelijk aan?
#### if-then-else - Vergelijking met Scratch **If-loop** ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/hLximage.png) **if-then-else loop** ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/tsGimage.png) #### Wat moet je doen? Je gaat nu een extra `if`-statement toevoegen die controleert of de bal de **linkerkant** van het scherm heeft bereikt (dus bij `x <= 0`). Als dat zo is, verander dan de waarde van `moving_right` weer naar `True`. Daardoor beweegt de sprite weer naar rechts. ### 🛠️ Opdracht - Voeg onder de eerste `if`-statement een tweede `if`-statement toe. - Controleer of `x <= 0`. - Als dat zo is, zet `moving_right = True`. - Test je code. Werkt het? Dan beweegt de bal nu heen en weer! ### 💡 Tip Als je wilt, kun je bij beide `if`-statements ook een `print()` toevoegen, zodat je in het log kunt zien wanneer de richting verandert. ```python if x >= 550: moving_right = False print("Rechterkant bereikt – keer om") if x <= 0: moving_right = True print("Linkerkant bereikt – keer om") ``` ### Inleveren Maak een screenshot van jouw code waarin je beide `if`-statements hebt toegevoegd en de sprite heen en weer beweegt. ## 4 De vierkante beweging In deze opdracht leer je hoe je een sprite (de groene stip) kunt laten bewegen in de vorm van een **vierkant**. De sprite moet dus eerst naar rechts, dan naar beneden, dan naar links, en tot slot weer omhoog. Daarna herhaalt hij dit patroon. ### Begincode Je gebruikt de volgende code als uitgangspunt. Deze keer gaan we bijhouden in welke **richting** de sprite moet bewegen, en telkens van richting veranderen als hij een hoekpunt bereikt. ```python from scratch_lib import create_sprite, move, run_animation, get_x, get_y # Startpositie linksboven sprite = create_sprite("green_dot.png", 10, 10) # We gebruiken een getal om de richting bij te houden: # 0 = rechts, 1 = naar beneden, 2 = naar links, 3 = omhoog richting = 0 def animate(): global richting x = get_x(sprite) y = get_y(sprite) Op basis van de richting, kies hoe de sprite moet bewegen if richting == 0: # boven naar rechts bewegen move(sprite, 5, 0) if x >= 550: richting = 1 # volgende richting: aan de rechter kant naar beneden bewegen elif richting == 1: # rechts naar beneden bewegen move(sprite, 0, 5) if y >= 550: richting = 2 # volgende richting: beneden langs naar links bewegen # ToDo maak de code hier af # we hebben moeten nog 2 blokjes maken: # beneden langs naar rechts bewegen # linker kant omhoog bewegen. # (je kunt het blokje op regel 22-25 kopiëren en aanpassen) run_animation([sprite], animate, steps=2000) ``` #### Wat moet je doen? In de code staat al aangegeven welke stappen moeten worden uitgevoerd. Maar niet alles is compleet. - Controleer of je begrijpt wat de waarde van `richting` betekent. - De sprite moet telkens van richting veranderen als hij een hoekpunt van het vierkant heeft bereikt. - De richtingsveranderingen gebeuren met behulp van een `if` of `elif`-structuur. - Pas eventueel de getallen 550 aan als jouw sprite kleiner of groter is. ### 🛠️ Opdracht - Vul de `TODO` op regel 27 aan door goed te begrijpen wat elke `if` doet. - Test je code. Beweegt de sprite in een vierkant? Perfect! ### Inleveren Maak een screenshot van jouw werkende code waarin je laat zien dat de sprite een vierkant loopt. ## 5 Vierkant met sprongen op elke hoek In deze opdracht ga je de sprite in een **kleiner vierkant** laten bewegen. Maar dat is nog niet alles: **op elk hoekpunt van het vierkant** springt de sprite vijf keer op en neer. Hiervoor ga je gebruikmaken van een `for`-loop. ### Begincode We hebben de code voor je voorbereid zodat de sprite een kleiner vierkant loopt. Dit vierkant is 100 stappen breed en hoog. Voer deze code uit en kijk wat er gebeurt: ```python from scratch_lib import create_sprite, move, run_animation, get_x, get_y, force_redraw import time # Startpositie linksboven sprite = create_sprite("green_dot.png", 80, 80) # We gebruiken een getal om de richting bij te houden: # 0 = rechts, 1 = naar beneden, 2 = naar links, 3 = omhoog richting = 0 def animate(): global richting x = get_x(sprite) y = get_y(sprite) if richting == 0: # naar rechts move(sprite, 5, 0) if x >= 470: # SPRINGEN: plak hier onderstaande code richting = 1 # volgende richting: naar beneden elif richting == 1: # naar beneden move(sprite, 0, 5) if y >= 470: # SPRINGEN: plak hier onderstaande code richting = 2 # volgende richting: naar links elif richting == 2: # naar links move(sprite, -5, 0) if x <= 80: # SPRINGEN: plak hier onderstaande code richting = 3 # volgende richting: naar boven elif richting == 3: # naar boven move(sprite, 0, -5) if y <= 80: # SPRINGEN: plak hier onderstaande code richting = 0 # opnieuw naar rechts run_animation([sprite], animate, steps=2000) ``` ### Sprongen op elk hoekpunt Nu willen we dat de sprite **op elk hoekpunt van het vierkant** vijf keer op en neer springt. Op en neer betekent dat de sprite eerst iets omhoog en dan weer omlaag beweegt. Dat doen we in een `for`-loop. ### 🔁 Wat is een `for`-loop? Een `for`-loop gebruik je in Python als je iets **meerdere keren wilt herhalen**. Dat kan bijvoorbeeld zijn: de sprite 5 keer naar rechts bewegen, of 10 keer springen. #### 🔤 De basisvorm van een `for`-loop ```python for i in range(5): move(sprite, 5, 0) ``` Wat gebeurt hier? - `for i in range(5)`: dit betekent dat de code in het blok **5 keer wordt uitgevoerd**. - De variabele `i` krijgt automatisch de waarden 0, 1, 2, 3 en 4 (vijf keer in totaal). - Elke keer dat de loop draait, voert Python de ingesprongen regels onder de `for`-regel uit. #### 🔄 Loop - Vergelijking met Scratch In Scratch gebruik je bijvoorbeeld: ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/v93image.png) > *Herhaal 10 keer → \[doe iets\]* Dat is precies hetzelfde idee! De blokken die je in Scratch ín een herhaal-blok sleept, zijn in Python de regels die je moet inspringen (met spaties). #### ✅ Juiste voorbeeld ```python for i in range(3): print("Hallo") ``` Uitvoer: ``` Hallo Hallo Hallo ``` #### ℹ️ Handig om te weten Wil je iets 10 keer doen? ```python for i in range(10): ``` Wil je iets maar 1 keer doen? Dan heb je eigenlijk geen loop nodig 😉 #### 🛠️ Oefening (optioneel) Wat doet onderstaande code? Probeer het te voorspellen. ```python for i in range(2): move(sprite, 0, -20) force_redraw() time.sleep(0.1) move(sprite, 0, 20) force_redraw() time.sleep(0.1) ``` 👉 Antwoord: de sprite springt 2 keer op en neer. #### Wat moet je doen? - Kopieer bovenstaande `for`-loop. - Plak die op vier plekken in de `animate()`-functie: - Vlak voordat `richting = 1` wordt uitgevoerd (na de rechterkant). - Vlak voordat `richting = 2` wordt uitgevoerd (na beneden). - Vlak voordat `richting = 3` wordt uitgevoerd (na links). - Vlak voordat `richting = 0` wordt uitgevoerd (na boven). ### 🛠️ Opdracht - Kopieer en plak de `for`-loop op de juiste plekken in je code (op elk hoekpunt). - Test je code. De sprite moet netjes in een vierkant bewegen **en** op elke hoek vijf keer op en neer springen. ### Inleveren Maak een screenshot van jouw code waarin de sprite op elk hoekpunt springt. ## 6 Spring vaker op twee hoeken In deze korte opdracht breid je je bestaande script uit. De sprite moet nu alleen **rechtsboven** en **linksonder** springen, telkens **vijf keer**. Maar dit keer springt de sprite niet omhoog en omlaag, maar **naar links en naar rechts** (horizontaal). ### ℹ️ Weet je nog wat inspringen is? #### Inspringen = blok = identation

In Python is de **inspringing** (ook wel *indentatie* genoemd) heel belangrijk. Python gebruikt inspringen om aan te geven welke code bij elkaar hoort.

Ook bij een`for`-statement , moet de code die daarbij hoort \*\*een stukje naar rechts inspringen\*\* (meestal 4 spaties). ```python for i in range(5): move(sprite, 0, -20) force_redraw() ``` Dus de regels 2 én 3 horen bij het for-blok en worden 5x uitgevoerd. #### 🔁 Vergelijking met Scratch In Scratch zie je blokken zoals *"als ... dan"* of *"herhaal ..."*. De blokken die **in** zo'n constructie staan, vallen daar letterlijk *in*. Ze zijn visueel naar binnen geschoven. In Python doe je dat met spaties: - De **buitenste structuur** (zoals `if` of `for`) sluit je af met een dubbele punt `:`. - De regels die **bij dat blok horen**, zet je eronder en laat je 4 spaties naar rechts inspringen. Als je dit vergeet, krijg je in Python een foutmelding zoals: ``` IndentationError: expected an indented block ``` #### ✅ Juiste voorbeeld ```python for i in range(5): move(sprite, 0, -20) force_redraw() ``` #### ❌ Fout voorbeeld ```python for i in range(5): move(sprite, 0, -20) # geen inspringing! force_redraw() ``` Controleer dus goed dat de regels die bij een `if` of `for` horen, netjes zijn ingesprongen. ### Wat moet je doen? - Zoek in je code de momenten waarop de sprite de **rechterbovenhoek** en de **linkeronderhoek** bereikt. - Op die plekken laat je de sprite 5X (in plaats van 2X) springen. Zorg dat je deze code **alleen** toevoegt bij de overgang van: - - `richting == 0` → als `y <= 80` (rechtsboven) - `richting == 2` → als `y >= 470` (linksonder) ### Inleveren Maak een screenshot van de code in Thonny waarop te zien is dat de sprite alleen rechtsboven en linksonder **horizontaal** springt, vijf keer per keer. ## 7 Spiraal – stap 1 ### *"vaste richtingen in een patroon"* In deze opdracht ga je de sprite **steeds twee richtingen bewegen** met een vaste afstand. Je doet dit een paar keer achter elkaar. Uiteindelijk zal dit het begin worden van een spiraal. Maar eerst leer je het patroon maken: **rechts → omlaag → links → omhoog**. ### 📥 Begincode ```python from scratch_lib import create_sprite, move, pause_for_frames sprite = create_sprite("green_dot.png", 300, 300) # Afstand per richting afstand = 100 # Herhaal het patroon 3 keer for i in range(3): # Beweeg naar rechts for j in range(afstand // 5): move(sprite, 5, 0) pause_for_frames(1) # Beweeg naar beneden for j in range(afstand // 5): move(sprite, 0, 5) pause_for_frames(1) # Beweeg naar links for j in range(afstand // 5): move(sprite, -5, 0) pause_for_frames(1) # Beweeg naar boven for j in range(afstand // 5): move(sprite, 0, -5) pause_for_frames(1) ``` ### ℹ️ Uitleg Je ziet hierboven een herhaling (een `for`-loop) die het patroon van 4 richtingen 3 keer uitvoert. Elke richting bestaat uit een eigen `for`-loop waarin de sprite telkens kleine stapjes zet. De afstand is verdeeld in blokjes van 5 pixels, zodat je het goed kunt zien bewegen. ### 🛠️ Opdracht - Experimenteer met `afstand = 100`. Wat gebeurt er als je die verandert in 200? - Voeg commentaar toe bij elke richting, zodat je het patroon beter begrijpt. - Test wat er gebeurt als je `range(3)` verandert in `range(1)` of `range(5)`. ### 📤 Inleveren Maak een screenshot van je code én van het pad dat de sprite aflegt in het venster. ## 8 Spiraal – stap 2 ### *"kleiner wordende afstanden"* In de vorige opdracht heb je een patroon gemaakt: de sprite bewoog rechts, omlaag, links, omhoog – en dat een paar keer. Het pad bleef telkens even groot. Nu gaan we iets nieuws doen: **na elke twee richtingen wordt de afstand kleiner**. Hierdoor lijkt het alsof de sprite langzaam een spiraal naar binnen loopt. ### 📥 Begincode ```python from scratch_lib import create_sprite, move, pause_for_frames sprite = create_sprite("green_dot.png", 300, 300) afstand = 200 # beginafstand for i in range(5): # we doen 5 spiraal-lagen # naar rechts for j in range(afstand // 5): move(sprite, 5, 0) pause_for_frames(1) # naar beneden for j in range(afstand // 5): move(sprite, 0, 5) pause_for_frames(1) afstand = afstand - 40 # we maken de afstand kleiner # naar links for j in range(afstand // 5): move(sprite, -5, 0) pause_for_frames(1) # naar boven for j in range(afstand // 5): move(sprite, 0, -5) pause_for_frames(1) afstand = afstand - 40 # opnieuw iets kleiner maken ``` ### ℹ️ Uitleg - We beginnen met `afstand = 200`. - Na twee richtingen verkleinen we de afstand met 40. - Daarna bewegen we weer twee richtingen (links en boven). - We verkleinen opnieuw met 40. Zo wordt het pad kleiner en kleiner – alsof je een vierkante spiraal naar het midden tekent. ### 🛠️ Opdracht - Pas de waarde `afstand = 200` aan. Wat gebeurt er bij 300? - Wat als je niet met 40 verkleint, maar met 20? - Voeg een `print(afstand)` toe onder elke `afstand = afstand - 40`. Wat zie je in de console? ### 📤 Inleveren Maak een screenshot van je aangepaste code én van de spiraal die de sprite tekent. ## 9 Spiraal – stap 3 ### *"automatisch stoppen"* Je hebt nu al een mooie spiraal gemaakt waarbij de sprite steeds kleinere vierkantjes loopt. Maar misschien heb je gemerkt: op een gegeven moment is de afstand zo klein dat de sprite nauwelijks nog beweegt of zelfs gekke dingen gaat doen. Daarom gaan we in deze stap zorgen dat het script **zelf stopt** als de afstand te klein wordt. ### 📥 Begincode ```python from scratch_lib import create_sprite, move, pause_for_frames sprite = create_sprite("green_dot.png", 300, 300) afstand = 200 # Herhaal zolang de afstand groter is dan 20 while afstand > 20: # naar rechts for j in range(afstand // 5): move(sprite, 5, 0) pause_for_frames(1) # naar beneden for j in range(afstand // 5): move(sprite, 0, 5) pause_for_frames(1) afstand = afstand - 20 # naar links for j in range(afstand // 5): move(sprite, -5, 0) pause_for_frames(1) # naar boven for j in range(afstand // 5): move(sprite, 0, -5) pause_for_frames(1) afstand = afstand - 20 ``` ### ℹ️ Uitleg - In plaats van `for i in range(5)` gebruiken we nu een **`while`-loop**. - Die zorgt ervoor dat het patroon doorgaat **zolang de afstand groter is dan 20**. - Als de afstand kleiner wordt dan of gelijk is aan 20, stopt de loop vanzelf. ### 🛠️ Opdracht - Test de code. Kun je zien waar de sprite stopt? - Wat gebeurt er als je de `afstand > 20` verandert in `afstand > 40`? - Voeg een `print(afstand)` toe aan het einde van elke herhaling om te zien wanneer het stopt. - Kun je de sprite laten starten in het midden van het scherm in plaats van linksboven? ### 📤 Inleveren Maak een screenshot van jouw spiraal **die vanzelf stopt** wanneer het midden bereikt is. ## 10 Reflectie: wat heb je geleerd? Je hebt nu gewerkt aan meerdere opdrachten waarbij je de sprite steeds meer hebt aangestuurd met code. Je hebt geleerd hoe je met een `for`-loop en `if`-statements herhaling en logica kunt combineren, en je hebt een echte spiraalbeweging gemaakt in Python. In deze laatste opdracht ga je **terugkijken op je leerproces**. Wat ging goed? Wat vond je moeilijk? En wat wil je nog beter leren? ### ℹ️ Wat is een reflectie? Reflecteren betekent dat je **nadenkt over wat je gedaan hebt**. Je kijkt niet alleen naar het resultaat, maar vooral naar hoe je het hebt aangepakt en wat je daarvan leert. ### 📝 Opdracht Beantwoord de volgende vragen in een kort reflectieverslag (ongeveer 5 zinnen per vraag is voldoende): 1. **Wat ging goed?** Geef een voorbeeld van iets dat je zelfstandig hebt opgelost of goed begreep. 2. **Wat vond je lastig?** Was er iets dat je niet meteen snapte? Welke opdracht kostte meer tijd dan je dacht? 3. **Noem drie dingen die je hebt geleerd o ver Python.** Wat zijn specifieke dingen die je hebt geleerd over Python? 4. **Wat heb je geleerd over if-statements?** Beschrijf kort wat je nu beter begrijpt over herhaling of logica in code. 5. **Wat heb je geleerd over loops?** Beschrijf kort wat je nu beter begrijpt over herhaling of logica in code. 6. **Wat zou je de volgende keer anders doen?** Denk aan hoe je je werk hebt aangepakt, of hoe je omging met fouten. 7. **Waar wil je nog meer mee oefenen?** Zijn er onderwerpen waarvan je denkt: dit wil ik nóg beter snappen of meer mee oefenen? 8. **Welke uitleg was duidelijk?** Welke opdracht(en) vond je goed uitgelegd? 9. **Welkke uitleg was onduidelijk?** Welke opdrachten waren niet duidelijk genoeg uitgelegd en hoe zou jij het ander/beter doen? ### 📤 Inleveren Lever je reflectie in als een PDF-bestand. ## \### ## \# Docenten opdracht 4 ``` from scratch_lib import create_sprite, move, run_animation, get_x, get_y # Startpositie linksboven sprite = create_sprite("green_dot.png", 10, 10) # We gebruiken een getal om de richting bij te houden: # 0 = rechts, 1 = naar beneden, 2 = naar links, 3 = omhoog richting = 0 def animate(): global richting x = get_x(sprite) y = get_y(sprite) # TODO: Op basis van de richting, kies hoe de sprite moet bewegen if richting == 0: # naar rechts move(sprite, 5, 0) if x >= 550: richting = 1 # volgende richting: naar beneden elif richting == 1: # naar beneden move(sprite, 0, 5) if y >= 550: richting = 2 # volgende richting: naar links elif richting == 2: # naar links move(sprite, -5, 0) if x <= 0: richting = 3 # volgende richting: naar boven elif richting == 3: # naar boven move(sprite, 0, -5) if y <= 0: richting = 0 # opnieuw naar rechts run_animation([sprite], animate, steps=2000) ``` # Pak de Kaas ##### Status: alles uitgevoerd en getest *Dit is een lessenserie over een programmeerproject met **Python en Pygame Zero** genaamd "Pak de Kaas". Het leidt leerlingen door zes stappen om een eenvoudig spel te maken waarin een muis kaas verzamelt. De lessen behandelen basisconcepten zoals het weergeven en verplaatsen van **afbeeldingen (sprites)**, het detecteren van **botsingen** tussen objecten, het gebruik van **willekeurige getallen** om de kaas te verplaatsen, het bijhouden van een **score** en het toevoegen van een **tijdslimiet** voor een "Game Over" scenario. Het document bevat ook een **docentenhandleiding** met leerdoelen, potentiële valkuilen en suggesties voor differentiatie en beoordeling.* ## 0 Wat gaan we leren We gaan nog een projectje maken met Thonny (uit de vorige les) en bij dit project gaan we gebruik maken van de standaard Python library: **pgzero** Weet je nog hoe je een pacakge installeert in Thonny? Yep, Tools - Manage Packages en dan pgzero zoeken en installeren. Als je het niet meer weer weet kijk dan even naar de vorige [les.](https://www.roc.ovh/link/887#bkmrk-installatie-pygame-l) ## 1 Pak de Kaas – Les 1 Je hebt pgzero in Thonny geinstalleerd? Nee kijk dan bij de vorige stap. In deze les gaan we met Python en Pygame Zero leren hoe je plaatjes (sprites) op het scherm kunt zetten. Je leert hoe je het scherm wist, en hoe je sprites op een bepaalde positie tekent. ### Wat gaan we doen? We gaan een muis en een stuk kaas op het scherm laten verschijnen. ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/kqsimage.png) Hiervoor gebruiken we `screen.blit()` in de `draw()`-functie van Pygame Zero. ### 📦 Benodigdheden - Thonny met Pygame Zero geïnstalleerd - Een map `images/` met daarin twee bestanden: `mouse.png` en `cheese.png` ### 🔰 Startercode ```python # importeer library import pgzrun # Spelgrootte WIDTH = 800 HEIGHT = 600 def draw(): screen.clear() screen.blit("mouse", (150, 150)) screen.blit("cheese", (50, 50)) #start programma pgzrun.go() ``` ### ℹ️ Uitleg - De code wordt van **boven** naar **beneden**, regel voor regel uitgevoerd. - `import pgzrun` hiermee vertellen we dat de library pgrun gaan gebruiken. Sommige computer-comando's 'sdie straks gaan gebruiken staat beschreven in deze library. - `WIDTH` en `HEIGHT` bepalen hoe groot het venster is - `draw()` is een speciale functie die automatisch wordt aangeroepen om het scherm te tekenen - `screen.clear()` is een library functie die het scherm bij elke frame wist - `screen.blit("mouse", (150, 150))` tekent het plaatje `mouse.png` op positie (150, 150). Dit zijn ook beide library functies. ### 🛠️ Opdracht Pas de coördinaten van de muis en de kaas aan en kijk wat er gebeurt. - Zet de muis linksboven in beeld - Zet de kaas rechtonder in beeld Wat gebeurt er als deze posities gebruikt? `    screen.blit("mouse", (50, 50))` `    screen.blit("cheese", (30, 30))`

Denk na over de volgorde waarin de commando's worden uitgevoerd.

### 📤 Inleveren Maak een screenshot de code met de coordinaten waarbij de muis linksboven in beeld in beeld staat en de kaas rechtsonder. ## 2 Beweeg de muis In deze les gaan we de muis laten bewegen met de pijltjestoetsen. We doen dat door de positie van de muis aan te passen telkens als een toets wordt ingedrukt. ### Wat gaan we doen? We maken twee variabelen `mouse_x` en `mouse_y` om de positie van de muis bij te houden. In de functie `update()` passen we deze coördinaten aan als je een pijl indrukt. ### 🔰 Startercode ```python # importeer library import pgzrun # Spelgrootte WIDTH = 800 HEIGHT = 600 # Startpositie van de muis mouse_x = 150 mouse_y = 150 def draw(): screen.clear() screen.blit("mouse", (mouse_x, mouse_y)) screen.blit("cheese", (50, 50)) def update(): global mouse_x, mouse_y if keyboard.left: mouse_x -= 5 if keyboard.right: mouse_x += 5 if keyboard.up: mouse_y -= 5 if keyboard.down: mouse_y += 5 #start programma pgzrun.go() ``` ### ℹ️ Uitleg - `mouse_x` en `mouse_y` zijn variabelen die bijhouden waar de muis staat - `update()` wordt meerdere keren per seconde uitgevoerd - Met `keyboard.left` controleer je of de linkerpijl wordt ingedrukt - Bij elke toetsdruk wordt de positie een klein stukje aangepast ### 🛠️ Opdracht - Voer de code uit en beweeg de muis met de pijltjestoetsen - Pas de waarde `5` aan naar een groter of kleiner getal. Wat merk je? - Probeer ervoor te zorgen dat de muis niet buiten het scherm kan verdwijnen (zie extrat uitleg). - Als de muis en de kaas op dezelfde positie staan dan verdwijnt de muis onder de kaas. Zorg ervoor dat de muis boven de kaas komt. Zoals hier is weegegven: ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/95qimage.png) #### 💡 Extra uitleg Laat de muis **niet** verder bewegen als hij het scherm uit dreigt te gaan. Voeg hiervoor `if`-statements toe zoals: ```python if keyboard.left and mouse_x > 10: mouse_x -= 5 ``` Dus hier staat: las de linker pijtjes toets is ingedrukt én de x coördinaat is > 10 zet de postie van de muis dan op de huidige positie - 5. Dus trek 5 van de huisdige posite af. Doe dit in vier stappen en test **elke** stap. 1. Doe dit eerst voor keyboard.left en test of het werkt. 2. Doe dit ook voor de keyboard.right en test of het werkt. 3. Doe dit daarna ook voor de keyboard.up en test of het werkt. 4. Doe dit tenslotte voor de keyboard.down en test of het werkt. ### 📤 Inleveren Maak een screenshot van je aangepaste code waarbij de **muis boven de kaas** beweegt én waarbij de muis **niet uit het scherm** kan bewegen. ## 3 Botsing met de kaas In deze les gaan we kijken of de muis de kaas aanraakt. Daarvoor gebruiken we een `if`-statement en controleren we of de muis en de kaas elkaar overlappen. ### Wat gaan we doen? We maken een rechthoek rondom de muis en rondom de kaas, en gebruiken `colliderect()` om te kijken of ze elkaar raken. Als de muis de kaas raakt, tonen we een bericht in de console met `print()`. ### 🔰 Startercode ```python # importeer library import pgzrun # Spelgrootte WIDTH = 800 HEIGHT = 600 # Startpositie van de muis en kaas mouse_x = 150 mouse_y = 150 cheese_x = 50 cheese_y = 50 def draw(): screen.clear() screen.blit("mouse", (mouse_x, mouse_y)) screen.blit("cheese", (cheese_x, cheese_y)) def update(): global mouse_x, mouse_y if keyboard.left: mouse_x -= 5 if keyboard.right: mouse_x += 5 if keyboard.up: mouse_y -= 5 if keyboard.down: mouse_y += 5 # Botsing controleren mouse_rect = Rect((mouse_x, mouse_y), (50, 50)) cheese_rect = Rect((cheese_x, cheese_y), (100, 100)) if mouse_rect.colliderect(cheese_rect): print("Gevonden!") else: print('-') #start programma pgzrun.go() ``` ### ℹ️ Uitleg - Een `Rect` is een rechthoek: (x, y, breedte, hoogte) - `colliderect()` geeft `True` als twee rechthoeken elkaar raken - In dit voorbeeld zijn muis 50x50 pixels en de kaas beide 100x100 pixels groot. - Als er een botsing is, toont Python het woord `Gevonden!` ### 🛠️ Opdracht - Probeer de muis met de pijltjestoetsen naar de kaas te bewegen - Als je `Gevonden!` ziet in de console, werkt de botsing - De kaas is niet helemaal 100x100 (in alle richtingen). Pas de grootte van de `Rect` aan zodat je alleen een melding "Gevonden!" krijgt als de muis duidelijk de kaas raakt en duidelijk 'op de kaas zit'. - Zorg er ook voor dat de muis **op** de kaas komt en niet eronder! #### 💡 Extra uitdaging Toon een boodschap op het scherm als de muis de kaas heeft gevonden: ```python gevonden = False def update(): ... if mouse_rect.colliderect(cheese_rect): gevonden = True def draw(): ... if gevonden: screen.draw.text("Gevonden!", (350, 10), fontsize=60, color="red") ``` ### 📤 Inleveren Maak een screenshot van je console waarin je ziet dat "Gevonden!" verschijnt als de muis de kaas aanraakt. ## 4 Kaas verspringt In deze les gaan we ervoor zorgen dat de kaas naar een nieuwe plek springt als de muis hem aanraakt. We doen dat met de functie `random.randint()` om een willekeurige positie te kiezen. ### Wat gaan we doen? We importeren de `random`-bibliotheek en maken een functie die een nieuwe plek kiest voor de kaas. Als er een botsing is, roepen we die functie aan en verplaatsen we de kaas. ### 🔰 Startercode ```python import random WIDTH = 800 HEIGHT = 600 mouse_x = 150 mouse_y = 150 cheese_x = 50 cheese_y = 50 def nieuwe_kaas_plek(): x = random.randint(0, WIDTH - 64) y = random.randint(0, HEIGHT - 64) return x, y def draw(): screen.clear() screen.blit("mouse", (mouse_x, mouse_y)) screen.blit("cheese", (cheese_x, cheese_y)) def update(): global mouse_x, mouse_y, cheese_x, cheese_y if keyboard.left: mouse_x -= 5 if keyboard.right: mouse_x += 5 if keyboard.up: mouse_y -= 5 if keyboard.down: mouse_y += 5 mouse_rect = Rect((mouse_x, mouse_y), (64, 64)) cheese_rect = Rect((cheese_x, cheese_y), (64, 64)) if mouse_rect.colliderect(cheese_rect): cheese_x, cheese_y = nieuwe_kaas_plek() ``` ### ℹ️ Uitleg - `import random` zorgt ervoor dat we willekeurige getallen kunnen gebruiken - `random.randint(a, b)` geeft een willekeurig getal tussen `a` en `b` - `WIDTH - 64` zorgt ervoor dat het plaatje niet buiten beeld komt - Als de muis de kaas raakt, wordt `cheese_x` en `cheese_y` aangepast ### 🛠️ Opdracht - Laat de muis de kaas aanraken en kijk of deze naar een nieuwe plek verspringt - Probeer het een paar keer en kijk of het altijd binnen het scherm blijft - Pas de afmetingen van de sprite aan als jouw plaatjes groter of kleiner zijn dan 64x64 #### 💡 Extra uitdaging Kies een leuk geluidseffect op : [https://www.wavsource.com/sfx/sfx.htm](https://www.wavsource.com/sfx/sfx.htm) 📁 Zet dan ook een bestand, bijvoorbeeld `bloop_x.wav` in de (nieuwe) map `sounds/` Voeg een geluid toe dat afspeelt als de muis de kaas raakt: ```python if mouse_rect.colliderect(cheese_rect): sounds.blook_x.play() cheese_x, cheese_y = nieuwe_kaas_plek() ``` ### 📤 Inleveren Maak een screenshot van je werkende code waar de kaas verspringt. Leg kort uit wat `random.randint()` doet en waarom je `WIDTH - 64` gebruikt. ## 5 Score bijhouden In deze les gaan we een score bijhouden: elke keer als de muis de kaas raakt, telt de score één punt op. Deze score tonen we ook op het scherm. ### Wat gaan we doen? We maken een variabele `score` die begint op 0 en steeds verhoogd wordt bij een botsing. In de `draw()`-functie tekenen we de score linksboven in het scherm. ### 🔰 Startercode ```python # importeer library import pgzrun import random WIDTH = 800 HEIGHT = 600 mouse_x = 150 mouse_y = 150 cheese_x = 50 cheese_y = 50 score = 0 def nieuwe_kaas_plek(): x = random.randint(0, WIDTH - 64) y = random.randint(0, HEIGHT - 64) return x, y def draw(): screen.clear() screen.blit("mouse", (mouse_x, mouse_y)) screen.blit("cheese", (cheese_x, cheese_y)) screen.draw.text(f"Score: {score}", (10, 10), fontsize=40, color="white") def update(): global mouse_x, mouse_y, cheese_x, cheese_y, score if keyboard.left: mouse_x -= 5 if keyboard.right: mouse_x += 5 if keyboard.up: mouse_y -= 5 if keyboard.down: mouse_y += 5 mouse_rect = Rect((mouse_x, mouse_y), (64, 64)) cheese_rect = Rect((cheese_x, cheese_y), (64, 64)) if mouse_rect.colliderect(cheese_rect): cheese_x, cheese_y = nieuwe_kaas_plek() score += 1 #start programma pgzrun.go() ``` ### ℹ️ Uitleg - `score = 0` zet de score aan het begin op nul - Elke keer als de muis de kaas aanraakt, wordt de score verhoogd met `score += 1` - `screen.draw.text()` toont tekst op het scherm ### 🛠️ Opdracht - Speel het spel een paar keer en kijk of de score steeds verder oploopt - Pas de tekstkleur of positie aan van de score - Maak de tekst groter of kleiner door `fontsize` aan te passen #### 💡 Extra uitdaging Laat de kleur van de tekst veranderen bij een bepaalde score: ```python kleur = "black" if score >= 5: kleur = "red" screen.draw.text(f"Score: {score}", (10, 10), fontsize=40, color=kleur) ``` ### 📤 Inleveren Maak een screenshot van het spel waarbij de score zichtbaar is (minimaal 3 punten). Leg in een zinnetje uit wat `score += 1` betekent. ## 6 Tijdslimiet In deze les gaan we een tijdslimiet toevoegen. De speler heeft bijvoorbeeld 30 seconden om zoveel mogelijk kaas te pakken. Aan het einde tonen we “Game Over” en stoppen we het spel. ### Wat gaan we doen? We maken een teller `tijd_over` die elke seconde met 1 omlaag gaat. Als de tijd op is, stopt het spel. We tonen de tijd linksboven in beeld naast de score. ### 🔰 Startercode ```python # importeer library import pgzrun import random WIDTH = 800 HEIGHT = 600 mouse_x = 150 mouse_y = 150 cheese_x = 50 cheese_y = 50 score = 0 tijd_over = 30 game_over = False def nieuwe_kaas_plek(): x = random.randint(0, WIDTH - 64) y = random.randint(0, HEIGHT - 64) return x, y def draw(): screen.clear() screen.blit("mouse", (mouse_x, mouse_y)) screen.blit("cheese", (cheese_x, cheese_y)) screen.draw.text(f"Score: {score}", (10, 10), fontsize=40, color="white") screen.draw.text(f"Tijd: {tijd_over}", (10, 50), fontsize=40, color="blue") if game_over: screen.draw.text("Game Over", center=(WIDTH//2, HEIGHT//2), fontsize=60, color="red") def update(): global mouse_x, mouse_y, cheese_x, cheese_y, score if game_over: return if keyboard.left: mouse_x -= 5 if keyboard.right: mouse_x += 5 if keyboard.up: mouse_y -= 5 if keyboard.down: mouse_y += 5 mouse_rect = Rect((mouse_x, mouse_y), (64, 64)) cheese_rect = Rect((cheese_x, cheese_y), (64, 64)) if mouse_rect.colliderect(cheese_rect): cheese_x, cheese_y = nieuwe_kaas_plek() score += 1 def verlaag_tijd(): global tijd_over, game_over if tijd_over > 0: tijd_over -= 1 if tijd_over == 0: game_over = True clock.schedule_interval(verlaag_tijd, 1.0) #start programma pgzrun.go() ``` ### ℹ️ Uitleg - `tijd_over` begint op 30 (seconden) - `clock.schedule_interval(verlaag_tijd, 1.0)` zorgt ervoor dat elke seconde de functie `verlaag_tijd()` wordt aangeroepen - Als `tijd_over` op 0 staat, verandert `game_over` in `True` en stopt het spel - In de `draw()`-functie tonen we de resterende tijd en, als het spel voorbij is, de tekst “Game Over” ### 🛠️ Opdracht deel 1 - Laat het spel lopen en probeer zoveel mogelijk punten te halen binnen de tijd - Pas de tijd aan naar 10 of 60 seconden – wat vind je leuker? - Laat bij “Game Over” ook de eindscore groter in beeld zien. ### 🛠️Opdracht deel 2 (opnieuw uitvoeren) - Zorg ervoor dat de **muis niet uit het beeld** kan worden bewogen (zoals we bij opgave 2 hebben gedaan). - Zorg ervoor dat de muis **op de kaas** en niet onder de kaas verdwijnt. #### 💡 Extra uitdaging Voeg een herstart-mogelijkheid toe met de `R`-toets: ```python def on_key_down(key): global score, tijd_over, game_over, mouse_x, mouse_y, cheese_x, cheese_y if key == keys.R: score = 0 tijd_over = 30 game_over = False mouse_x, mouse_y = 150, 150 cheese_x, cheese_y = nieuwe_kaas_plek() ``` ### 📤 Inleveren 1. Maak een screenshot van het spel als de tijd op is en je “Game Over” ziet en zet een mooie score neer! 2. Bewaar je code als een bestand (in Thonny, file - save as...) en lever het .py bestand met de code in. ## 7 Eindopdracht ### 🎮 Eindopdracht Kies één (of meerdere) van de volgende uitbreidingen en voeg die toe aan je spel: - 🧀 Zet meerdere stukjes kaas tegelijk op het scherm (gebruik een `for`-loop) - 💣 Voeg een “giftige” kaas toe: als je die pakt, verlies je punten - 🔊 Voeg geluiden toe voor eten, botsing of game over - 🎨 Verander het uiterlijk van de muis of de achtergrond - 🕒 Laat het spel moeilijker worden naarmate de tijd verstrijkt (bijv. snellere muis of bewegende kaas) 💡 Bedenk zelf ook een uitbreiding? Schrijf het plan op, laat het goedkeuren door je docent en priobeer het te maken!

Bij deze opgave mag je AI gebruiken!

### 📤 Inleveren Lever één van de volgende dingen in: - Een werkend Python-bestand (.py) waarin jouw uitbreiding is verwerkt - Een screenshot van je spel én; - Uitleg in tekst (.txt) wat je hebt gedaan. ## 8 Reflectie In deze les kijk je terug op wat je hebt gemaakt, én krijg je de kans om je spel op een leuke manier uit te breiden of aan te passen. ### 🧠 Reflectie Als je terugkijkt naar deze opgave. Vraag je zelf de volgende dingen af: - Wat vond je het leukste om te doen? - Wat vond je moeilijk of lastig om te begrijpen? - Welke onderdelen van Python begrijp je nu beter? - Waar ben je trots op. ### 📤 Inleveren 1. Lever je reflectie in met de antwoorden op de (reflectie) vragen in een PDF bestand.

Let op: gebruik je eigen woorden en wees specifiek!

## \### ## \# Docenten ## 🎓 Docentenhandleiding ### 📘 Overzicht - **Doelgroep:** Leerlingen van 12-15 jaar (instapniveau Python) - **Duur:** 6 lessen van ±45-60 minuten - **Software:** Thonny + Pygame Zero - **Spelconcept:** Een muis beweegt met de pijltjestoetsen en pakt steeds opnieuw verschijnende kaasjes ### 🎯 Leerdoelen - Begrijpen hoe coördinaten werken in een 2D-scherm - Gebruik van `draw()` en `update()` in een animatie - Werken met variabelen voor positie en beweging - Detecteren van botsingen met `Rect` en `colliderect()` - Gebruik van `random` en herhaalde logica - Score bijhouden en tonen - Reflecteren op eigen code en uitbreidingen bedenken ### 📚 Lesoverzicht
LesOnderwerpNieuwe concepten
1Muis en kaas tekenen`draw()`, `screen.blit()`, coördinaten
2Muis beweegt met toetsen`keyboard.left`, `update()`, grenzen
3Botsing detecteren`Rect()`, `colliderect()`
4Kaas verspringt op random plek`random.randint()`, logica
5Score bijhouden`score += 1`, `screen.draw.text()`
6Reflectie & uitbreidenReflecteren, creatief uitbreiden
### ⚠️ Valkuilen - `colliderect()` werkt niet → verkeerde grootte/positie van Rect - Sprites bewegen niet vloeiend → `update()` mist `force_redraw()` (indien nodig) - Kaas verschijnt buiten het scherm → randomwaarden buiten bereik - Score telt verkeerd → `score += 1` buiten juiste `if`-blok ### 🧠 Differentiatie #### Voor snelle leerlingen - Voeg meerdere stukjes kaas toe tegelijk - Laat een “slechte” kaas verschijnen die de score verlaagt - Gebruik afbeeldingen en laat muis draaien in richting #### Voor langzamere leerlingen - Werk eerst zonder `Rect`, laat botsing handmatig triggeren - Gebruik alleen horizontale beweging - Geef startscripts per les met al werkende onderdelen ### 📊 Beoordeling (optioneel)
CriteriumOmschrijvingScore (1-5)
Spel werktMuis beweegt, kaas wordt gepakt, score telt🟩
CodekwaliteitVariabelen zijn logisch, overzichtelijk🟩
CreativiteitLeerling heeft iets extra’s toegevoegd (geluid, extra levels, design)🟩
ReflectieLeerling beantwoordt de reflectievragen met inzicht🟩
### 💡 Lesaanpak & tips - Laat leerlingen direct runnen en testen na elke wijziging - Gebruik klassikale codebesprekingen met testvoorbeelden - Moedig leerlingen aan om “stukjes code” zelf te veranderen - Laat ze uitleggen wat ze doen: peer programming werkt goed bij deze opdracht ### 🧰 Benodigdheden - Thonny + Pygame Zero geïnstalleerd - Afbeeldingen: muis.png, cheese.png (optioneel) - Toetsenbord met pijltjestoetsen - Basiskennis Python (variabelen, `if`, `def`) # Kennis-check Blok 1 ## *Kennis-check Blok 1* *Om je voor te bereiden op de multiple choice kennis-check kun je voor je zelf proberen de ondersrtaand evragen te beantwoorden.* *Als je op de vraag klikt dan verschijnt het antwoord. Op die manier kun je zelf jou antwoord controleren. Begrip je d euitleg neit, vraag dan aan de docent om extra uitleg.* ### *Scratch 1*
**Wat is een lus in programmeren en waarom is het handig?** Een lus (of "loop") is een blokje in Scratch dat zorgt dat een stukje code steeds opnieuw wordt uitgevoerd. Bijvoorbeeld: als je wilt dat een sprite (Giga) blijft bewegen zolang het spel bezig is, kun je een "herhaal" of "herhaal zolang" blok gebruiken. Dit is handig, omdat je dan niet elke stap apart hoeft te programmeren – het gebeurt automatisch steeds opnieuw.
**Wat is een als-dan-anders blok (if-then-else)?** Een als-dan-anders-blok in Scratch controleert of iets waar is. Als dat zo is, doet het programma het eerste stukje code. Anders doet het iets anders. Bijvoorbeeld: *als* de muis is ingedrukt, *dan* laat een sprite (Giga) iets zeggen, *anders* doet hij niets of zegt hij iets anders. Zo kan je programma reageren op wat er gebeurt.
**Wat is een variabele en hoe kun je die gebruiken om de score bij te houden?** Een variabele is een blokje waarmee je informatie kunt opslaan, zoals een getal dat kan veranderen. In een spel kun je een variabele maken die "score" heet. Aan het begin zet je die op 0. Elke keer dat Giga bijvoorbeeld een sleutel aanraakt, verhoog je de score met 1. Zo weet het spel hoeveel punten je hebt.
**Wat is het verschil tussen gewoon “als…dan” en “als…dan…anders”?** **“Als…dan”** voert alleen code uit *als* de voorwaarde waar is. Als het niet waar is, gebeurt er helemaal niks. **"Als…dan…anders”** voert óf de ene actie uit als de voorwaarde waar is, óf een andere actie als de voorwaarde niet waar is. Dus: - Met “als…dan” doe je iets óf niks. - Met “als…dan…anders” doe je altijd iets: óf de ene actie óf de andere.
### *Scratch 2*
**Wat betekent het als een sprite op x: 0 en y: 0 staat?** Dat betekent dat de sprite precies in het **midden van het speelveld** staat. In Scratch is (0, 0) het **middelpunt van het scherm**. - De x-coördinaat (horizontaal) is dan in het midden van links naar rechts. - De y-coördinaat (verticaal) is in het midden van boven naar beneden.
**In welke richting beweegt een sprite als je de x-coördinaat groter maakt?** Dan beweegt de sprite **naar rechts**. - Hoe groter de x-waarde, hoe verder naar rechts de sprite op het scherm staat. - Als je de x-coördinaat juist kleiner maakt, beweegt de sprite naar links.
**Wat gebeurt er als je bij x een heel grote waarde gebruikt, zoals 5000?** De sprite verdwijnt **buiten beeld**. - Het Scratch-scherm heeft grenzen: ongeveer van x = -240 (helemaal links) tot x = 240 (helemaal rechts). - Als je een waarde gebruikt zoals x = 5000, dan staat de sprite ver buiten het zichtbare scherm, dus je ziet hem niet meer.
**Hoe kun je zorgen dat een sprite niet buiten het scherm beweegt?** Gebruik een **“als…dan”**-blok om te controleren of x of y binnen een bepaalde grens. ``` als x-positie < 240 dan wijzig x met 10 ```
### Van Scratch naar Python
**Waarom is inspringen (indentatie) belangrijk in Python, terwijl Scratch dat niet nodig heeft?** Omdat Python aan de hand van inspringen (spaties) bepaalt welke code bij elkaar hoort. Als je dat niet goed doet, begrijpt Python niet wat je bedoelt, en krijg je een foutmelding. 📌 *Voorbeeld:* ``` if x > 10: print("x is groot") # ❌ fout: geen inspringing ``` ``` if x > 10: print("x is groot") # ✅ goed: ingesprongen ```
**Leg uit wat een `#` in Python doet** Een `#` wordt gebruikt om commentaar toe te voegen in je code. Alles wat na het `#` staat, wordt genegeerd door de computer. Het is alleen bedoeld voor de programmeur zelf, om uit te leggen wat de code doet. 📌 *Voorbeeld:* ``` # Dit is een commentaarregel x = 5 # We geven x de waarde 5 ```
**Hoe ziet een if-then-else er uit in Python?** In Python gebruik je `if`, `else` (en soms `elif`). De code die bij elke voorwaarde hoort moet ingesprongen staan. 📌 *Voorbeeld:* ``` if x > 10: print("x is groter dan 10") else: print("x is 10 of kleiner") ```
**Wat doet een for-loop in Python?** Een `for`-loop herhaalt een blokje code een vast aantal keren. 📌 *Voorbeeld:* ``` for i in range(5): print("Hallo") ```
**Noem verschillen tussen Python en Scratch**
ScratchPython
Werkt met blokken die je sleeptWerkt met tekst die je zelf typt
Geen spaties of haakjes nodigSpaties en dubbele punten zijn belangrijk
Visueel en kleurrijkTekstgebaseerd, je moet meer onthouden
Makkelijk te starten zonder foutenFoutgevoelig bij typefouten of inspringen
**Wat leert de student bij 'Pak de Kaas'?** In dit Python/Pygame Zero-project leren studenten onder andere: - Sprites op het scherm tonen met `screen.blit()` - De muis laten bewegen via variabelen en `update()` - Botsingen detecteren tussen muis en kaas - Willekeurige verplaatsing van de kaas met `random` - Score bijhouden bij het verzamelen van kaas - Tijdslimiet instellen zodat het spel eindigt ("Game Over")
**Hoe detecteer je dat de muis de kaas raakt?** Gebruik een `if`-statement met `collide` of vergelijk coördinaten van de muis en kaas, bijvoorbeeld: ``` if mouse_x == cheese_x and mouse_y == cheese_y: score += 1 ```
**Waarom gebruik je willekeurige getallen bij het verplaatsen van de kaas na botsing?** Zodat de kaas steeds op een nieuwe plek verschijnt. Bijvoorbeeld met: ``` import random cheese_x = random.randint(0, WIDTH) cheese_y = random.randint(0, HEIGHT) ```
**Wat doet `random.randint()` precies?** De functie `random.randint(a, b)` geeft een willekeurig geheel getal terug tussen **a** en **b**, inclusief beide grenzen. 📌 *Voorbeeld:* ``` import random getal = random.randint(1, 10) print(getal) ``` Dit print een willekeurig getal tussen 1 e
### Pak de Kaas
**Hoe detecteer je dat de muis de kaas raakt?** Gebruik een `if`-statement met `collide` of vergelijk coördinaten van de muis en kaas, bijvoorbeeld: ``` if mouse_x == cheese_x and mouse_y == cheese_y: score += 1 ```
**Waarom gebruik je willekeurige getallen bij het verplaatsen van de kaas na botsing?** Zodat de kaas steeds op een nieuwe plek verschijnt. Bijvoorbeeld met: ``` import random cheese_x = random.randint(0, WIDTH) cheese_y = random.randint(0, HEIGHT) ```
**Wat doet `random.randint()` precies?** De functie `random.randint(a, b)` geeft een willekeurig geheel getal terug tussen **a** en **b**, inclusief beide grenzen. 📌 *Voorbeeld:* ```python import random getal = random.randint(1, 10) print(getal) ``` Dit print een willekeurig getal tussen 1 en 10, zoals 3 of 9. Handig voor bijvoorbeeld het willekeurig verplaatsen van een sprite in een spel.
**Wat gebeurt er als je de muis buiten het scherm laat bewegen?** Als je de variabelen `mouse_x` of `mouse_y` zo aanpast dat de sprite buiten het scherm komt, dan **verdwijnt de muis uit beeld**. - Het spel zelf blijft werken, maar de speler ziet de muis niet meer. - De sprite staat dan op een coördinaat die buiten het zichtbare venster valt (bijvoorbeeld x = -50 of y = 1000).
**Hoe zorg je ervoor dat de muis niet buiten het spel beweegt? Gebruik je een loop of een if-then?** Om te voorkomen dat de muis buiten het scherm beweegt, gebruik je een **`if`-statement**, geen `loop`. Daarmee controleer je of de muis nog binnen de grenzen is voordat je de positie verandert. 📌 *Voorbeeld:* ```python if mouse_x < WIDTH - 50: mouse_x += 5 if mouse_x > 0: mouse_x -= 5 ```
### 🛠️ Opdracht Maak nu de kennis-check. ### 📤 Inleveren Aan het einde van de kennis-check ontvang je een certificaat. Maak een schermafdruk en lever deze in. \-- # Blok 2 - Retro gaming with Python # Vallende stenen ## 0 Wat gaan we leren We gaan nog een projectje maken met Thonny (uit de vorige les) en bij dit project gaan we gebruik maken van de standaard Python library: pgzero Weet je nog hoe je een pacakge installeert in Thonny? Yep, Tools - Manage Packages en dan pgzero zoeken en installeren. ## 1 Teken speler en steen In deze les gaan we de speler en één vallende steen tekenen. We beginnen met een eenvoudige versie: een blokje onderaan dat je straks kunt besturen, en een steen die we straks laten vallen. ### Wat gaan we doen? We tekenen een rechthoek voor de speler en een rechthoek voor de steen. We gebruiken vaste posities om de eerste versie werkend te krijgen. ### 🔰 Code ```python import pgzrun WIDTH = 800 HEIGHT = 600 # Speler onderaan het scherm player_x = 400 player_y = 550 player_width = 80 player_height = 20 # Vallende steen bovenaan rock_x = 300 rock_y = 0 rock_size = 40 def draw(): screen.clear() screen.draw.filled_rect(Rect((player_x, player_y), (player_width, player_height)), "blue") screen.draw.filled_rect(Rect((rock_x, rock_y), (rock_size, rock_size)), "gray") pgzrun.go() ``` ### ℹ️ Uitleg - `player_x` en `player_y`: positie van de speler (een blauw blokje onderaan) - `rock_x` en `rock_y`: positie van de steen - `screen.draw.filled_rect(...)`: tekent een blokje op het scherm ### 🛠️ Opdracht - Verplaats de steen naar een andere plek op het scherm door `rock_x` en `rock_y` aan te passen - Maak de speler breder of smaller - Verander de kleuren van speler en steen #### 💡 Extra uitdaging - Teken meerdere stenen op het scherm (gebruik meerdere `draw.filled_rect()`) ### 📤 Inleveren 1. Maak een screenshot waarop je de speler en minstens één steen ziet (waarbij je de plaats van de steen dus hebt aangepast). ## 2 Speler bewegen In deze les gaan we de speler besturen met de pijltjestoetsen. De speler beweegt alleen naar links en rechts, en mag niet buiten het scherm gaan. ### Wat gaan we doen? We bewerken de `update()`-functie om de `x`-positie van de speler aan te passen als je op pijltjes drukt. We voegen een maximale en minimale positie toe zodat de speler niet van het scherm glijdt. ### 🔰 Code ```python import pgzrun WIDTH = 800 HEIGHT = 600 player_x = 400 player_y = 550 player_width = 80 player_height = 20 player_speed = 5 rock_x = 300 rock_y = 0 rock_size = 40 def draw(): screen.clear() screen.draw.filled_rect(Rect((player_x, player_y), (player_width, player_height)), "blue") screen.draw.filled_rect(Rect((rock_x, rock_y), (rock_size, rock_size)), "gray") def update(): global player_x if keyboard.left: player_x -= player_speed if keyboard.right: player_x += player_speed # Speler binnen scherm houden if player_x < 0: player_x = 30 if player_x > WIDTH - player_width: player_x = WIDTH - player_width pgzrun.go() ``` ### ℹ️ Uitleg - `player_speed`: hoe snel de speler beweegt - `keyboard.left` en `keyboard.right`: detecteren of een toets is ingedrukt - `if player_x > WIDTH - player_width`: voorkomt dat de speler buiten beeld schuift ### 🛠️ Opdracht - Beweeg de speler heen en weer met je pijltjestoetsen - Verander `player_speed` – wordt de speler sneller of trager? - Aan de linker kant van het scherm stuitert de speler terwijl aan de rechterkant de speler netjes op de rand stopt. Zie jij hoe dat komt? Probeer dit aan te passen, probeer gewoon maar wat, je kan niets kapot maken!

Tip: bij welke `if` wordt gekeken of de speler tegen de linkerkant van het scherm aan zit?

#### 💡 Extra uitdaging - Laat de speler sneller bewegen als je de toets langer inhoudt - Laat de speler automatisch naar links of rechts bewegen als je een extra toets indrukt (bijvoorbeeld `A` of `D`) ### 📤 Inleveren 1. Leg in eigen woorden uit hoe de `player_speed` de snelheid van het spel veranderd. 2. Leg uit waarom de speler aan de linkerkant van het scherm 'stuitert' en wat heb je aangepast om dit te voorkomen? ## 3 Steen laten vallen In deze les gaan we de steen automatisch laten vallen. Zodra de steen de onderkant van het scherm bereikt, verschijnt hij opnieuw bovenaan op een willekeurige plek. ### Wat gaan we doen? We voegen een `rock_speed` toe en laten de `y`-positie van de steen langzaam toenemen in `update()`. We controleren of de steen het scherm uit valt, en zetten hem dan opnieuw bovenaan met een willekeurige x-positie. ### 🔰 Code ```python import pgzrun import random WIDTH = 800 HEIGHT = 600 player_x = 400 player_y = 550 player_width = 80 player_height = 20 player_speed = 5 rock_x = random.randint(0, WIDTH - 40) rock_y = 0 rock_size = 40 rock_speed = 3 def draw(): screen.clear() screen.draw.filled_rect(Rect((player_x, player_y), (player_width, player_height)), "blue") screen.draw.filled_rect(Rect((rock_x, rock_y), (rock_size, rock_size)), "gray") def update(): global player_x, rock_y, rock_x, rock_size if keyboard.left: player_x -= player_speed if keyboard.right: player_x += player_speed if player_x < 0: player_x = 0 if player_x > WIDTH - player_width: player_x = WIDTH - player_width # Steen laten vallen rock_y += rock_speed # Als de steen onderaan is, zet hem weer bovenaan met random x if rock_y > HEIGHT: rock_y = 0 rock_x = random.randint(0, WIDTH - rock_size) pgzrun.go() ``` ### ℹ️ Uitleg - `rock_speed`: bepaalt hoe snel de steen valt - `rock_y += rock_speed`: laat de steen naar beneden bewegen - `random.randint(...)`: zorgt voor een willekeurige x-positie als de steen opnieuw verschijnt ### 🛠️ Opdracht - Verander de `rock_speed` – wat gebeurt er? - Maak de steen groter of kleiner door `rock_size` aan te passen. - Zorg er nu voor dat elke keer als de steen opnieuw valt de rock\_size wordt aangepast en een random grootte krijgt. - Met random.randint(1, 10) wordt er een getal tussen 1 en 10 gegenereerd. Bedenk zelf mooie waarden en pas de code aan zodat de grootte van de steen telkens anders wordt. #### 💡 Extra uitdaging - Laat meerdere stenen tegelijk vallen - Laat elke steen een willekeurige snelheid hebben ### 📤 Inleveren 1. Leg uit hoe je ervoor hebt gezorgdt dat de steen telkens een ander grootte kijgt. ## 4 Botsing & Game Over In deze les gaan we controleren of de speler de steen raakt. Als er een botsing is, stopt het spel en verschijnt er de tekst “Game Over”. ### Wat gaan we doen? We maken een `Rect` van de speler en van de steen, en gebruiken `colliderect()` om te zien of ze elkaar raken. We gebruiken een variabele `game_over` om te stoppen met het spel als er een botsing is. ### 🔰 Code ```python import pgzrun import random from pygame import Rect WIDTH = 800 HEIGHT = 600 player_x = 400 player_y = 550 player_width = 80 player_height = 20 player_speed = 5 rock_x = random.randint(0, WIDTH - 40) rock_y = 0 rock_size = 40 rock_speed = 3 game_over = False def draw(): screen.clear() if game_over: screen.draw.text("GAME OVER", center=(WIDTH // 2, HEIGHT // 2), fontsize=60, color="red") return screen.draw.filled_rect(Rect((player_x, player_y), (player_width, player_height)), "blue") screen.draw.filled_rect(Rect((rock_x, rock_y), (rock_size, rock_size)), "gray") def update(): global player_x, rock_y, rock_x, game_over if game_over: return if keyboard.left: player_x -= player_speed if keyboard.right: player_x += player_speed if player_x < 0: player_x = 0 if player_x > WIDTH - player_width: player_x = WIDTH - player_width rock_y += rock_speed if rock_y > HEIGHT: rock_y = 0 rock_x = random.randint(0, WIDTH - rock_size) # Botsing detecteren speler_rect = Rect(player_x, player_y, player_width, player_height) steen_rect = Rect(rock_x, rock_y, rock_size, rock_size) if speler_rect.colliderect(steen_rect): game_over = True pgzrun.go() ``` ### ℹ️ Uitleg - `Rect(x, y, w, h)` maakt een rechthoek op de juiste plek - `colliderect()` kijkt of twee rechthoeken elkaar raken - `game_over` bepaalt of het spel nog doorgaat ### 🛠️ Opdracht - Laat de speler de steen raken en kijk of het spel stopt - Verplaats de speler naar de andere kant van het scherm – bots je dan nog? - Verander de “GAME OVER” tekst (bijvoorbeeld kleur of grootte) #### 💡 Extra uitdaging - Laat het spel herstarten als je op de `R`-toets drukt - Speel een geluid af bij de botsing (bijv. `sounds.hit.play()`) ### 📤 Inleveren 1. Leg eersts stap-voor-stap in he eigen woorden uit hoe er een botsing van de steen met de speler wordt gedetecteerd. 2. Leg daarna stap-voor-stap, in eigen woorden uit wat er allemaal gebeurt als de steen tegen de speler aan komt. Verwijs daarbij naar de code. ## 5 Meerdere stenen & moeilijker maken In deze les gaan we meerdere stenen tegelijk laten vallen. Bovendien maakt het spel zichzelf moeilijker naarmate je langer speelt: de stenen vallen sneller. ### Wat gaan we doen? We maken een lijst van stenen, elk met hun eigen positie en snelheid. We laten deze stenen vallen en bij een botsing stoppen we het spel. We laten het spel steeds moeilijker worden door de snelheid te verhogen na een paar seconden. ### 🔰 Code ```python import pgzrun import random from pygame import Rect WIDTH = 800 HEIGHT = 600 player_x = 400 player_y = 550 player_width = 80 player_height = 20 player_speed = 5 rocks = [] game_over = False rock_timer = 0 rock_interval = 60 # frames difficulty = 1.0 # Start met een paar stenen for _ in range(3): x = random.randint(0, WIDTH - 40) speed = random.uniform(2, 4) rocks.append({"x": x, "y": 0, "size": 40, "speed": speed}) def draw(): screen.clear() if game_over: screen.draw.text("GAME OVER", center=(WIDTH // 2, HEIGHT // 2), fontsize=60, color="red") return screen.draw.filled_rect(Rect((player_x, player_y), (player_width, player_height)), "blue") for rock in rocks: screen.draw.filled_rect(Rect((rock["x"], rock["y"]), (rock["size"], rock["size"])), "gray") def update(): global player_x, game_over, rock_timer, difficulty if game_over: return if keyboard.left: player_x -= player_speed if keyboard.right: player_x += player_speed player_x = max(0, min(WIDTH - player_width, player_x)) speler_rect = Rect(player_x, player_y, player_width, player_height) for rock in rocks: rock["y"] += rock["speed"] * difficulty if rock["y"] > HEIGHT: rock["y"] = 0 rock["x"] = random.randint(0, WIDTH - rock["size"]) rock["speed"] = random.uniform(2, 5) rock_rect = Rect(rock["x"], rock["y"], rock["size"], rock["size"]) if speler_rect.colliderect(rock_rect): game_over = True # Verhoog de moeilijkheid langzaam rock_timer += 1 if rock_timer % 300 == 0: difficulty += 0.2 pgzrun.go() ``` ### ℹ️ Uitleg - Elke steen is een dict met `x`, `y`, `size` en `speed` - We gebruiken een `for`-loop om alle stenen te laten vallen - Met `difficulty` verhogen we langzaam de snelheid van de stenen ### 🛠️ Opdracht - Test het spel en kijk of het spel moeilijker wordt na ongeveer 15 seconden - Nu gaan we de grootte van de stenen weer aanpassen naar een random waarde zoals we dat bij de vorige opdracht ook hebben gedaan. - Dat gaat iets anders omdat we nu meerdere 'rocks' hebben. In de` for rock in rocks:` loop worden één voor één alle blokken behandeld. De grootte van de rock staat in `rock["size"]`

Tip: weet je nog dat je met `random.randint(1,4)` een getal tussen 1 en 4 kan genereren?

#### 💡 Extra uitdaging - Laat het aantal stenen toenemen naarmate het spel langer duurt - Laat een andere kleur steen verschijnen bij hogere moeilijkheid. - Laat elke steen een ander formaat hebben - Toon je “score” op het scherm: hoe lang heb je overleefd? ### 📤 Inleveren 1. Lever je code (.py bestand) in. \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* ## 6 Score, Reflectie & Uitbreiding In deze les voeg je een score toe die laat zien hoelang je het hebt volgehouden. Daarnaast kijk je terug op je eigen werk én kies je een uitbreiding om het spel leuker of moeilijker te maken. ### Wat gaan we doen? - We voegen een `score` toe die telt hoeveel frames je overleeft - We tonen deze score linksboven op het scherm - Bij Game Over laten we je eindscore zien ### 🔰 Toevoegingen aan bestaande code ```python score = 0 # bij de andere variabelen def draw(): screen.clear() if game_over: screen.draw.text("GAME OVER", center=(WIDTH // 2, HEIGHT // 2), fontsize=60, color="red") screen.draw.text(f"Score: {score}", center=(WIDTH // 2, HEIGHT // 2 + 50), fontsize=40, color="black") return ... screen.draw.text(f"Score: {score}", (10, 10), fontsize=40, color="black") def update(): global score if game_over: return ... score += 1 ``` ### ℹ️ Uitleg - `score` wordt bij elke frame 1 hoger → hoe langer je speelt, hoe hoger je score - `screen.draw.text()` toont je score tijdens én na het spel ### 🧠 Reflectie Beantwoord de volgende vragen onderaan je code als commentaar of in een apart document: - Wat vond je het leukst om te maken in dit spel? - Wat vond je moeilijk, en hoe heb je dat opgelost? - Wat heb je geleerd over Python en programmeren? - Waar ben je trots op? ### 🎮 Uitbreiding (kies er één) - 💥 Laat een explosie zien of geluid horen bij Game Over - 🧱 Voeg bewegende obstakels toe - 🏆 Houd een highscore bij (hoogste score van de sessie) - 🚀 Geef de speler power-ups: tijdelijk onsterfelijk, versnellen, etc. - 🎨 Verander het uiterlijk van de speler of achtergrond na elke 30 seconden #### 💡 Eigen idee? Bedenk zelf een uitbreiding en probeer deze te maken. Schrijf kort op wat jouw idee is en hoe je het hebt aangepakt. ### 📤 Inleveren - Lever je eindversie van het spel in (inclusief score en uitbreiding) - Voeg een korte beschrijving toe van wat je hebt toegevoegd of aangepast - Lever ook je reflectie in (de 4 vragen) - Optioneel: voeg een screenshot of kort filmpje toe van je spel ## 🧠 Reflectieopdracht Deze reflectieopdracht helpt je om stil te staan bij wat je hebt geleerd tijdens het programmeren van je spel. Beantwoord de onderstaande vragen eerlijk en in je eigen woorden. Je mag je antwoorden inleveren via een apart document of onderaan je Python-bestand als commentaar zetten. ### 📋 Vragen - 🔹 Wat vond je het leukste om te maken of uit te proberen? - 🔹 Wat vond je lastig? Hoe heb je dat opgelost? - 🔹 Wat heb je geleerd over Python (of programmeren in het algemeen)? - 🔹 Waar ben je trots op in jouw eindresultaat? - 🔹 Wat zou je de volgende keer anders willen doen of verbeteren? ### 📤 Inleveren Lever je reflectie in bij je docent via de afgesproken manier (document, upload of als commentaar in je code). ## \### ## \# Docenten ## 🎓 Docentenhandleiding ### 📘 Overzicht - **Doelgroep:** Leerlingen met basiskennis Python (13-16 jaar) - **Duur:** 6 lessen van ±45-60 minuten - **Software:** Thonny + Pygame Zero - **Spelconcept:** De speler ontwijkt vallende objecten (stenen) en het spel wordt steeds moeilijker ### 🎯 Leerdoelen - Werken met coördinaten en schermlogica - Gebruik van `draw()` en `update()` - Toetsenbordbesturing met `keyboard.left` en `keyboard.right` - Beweging simuleren met variabelen - Objecten detecteren met `Rect` en `colliderect()` - Werken met lijsten voor meerdere objecten - Reflecteren op het leerproces en zelf uitbreidingen bedenken ### 📚 Lesoverzicht
LesOnderwerpNieuwe concepten
1Speler en steen tekenen`draw()`, rechthoek tekenen, coördinaten
2Speler beweegt`update()`, keyboard input, begrenzen
3Steen valt en komt terugBeweging, `random`, logica
4Botsing + Game Over`Rect`, `colliderect()`, boolean vlag
5Meerdere stenen + moeilijkheidLijsten, `for`-loops, moeilijkheidsschaal
6Score, Reflectie & UitbreidingScorevariabele, `draw.text()`, vrije opdracht
### ⚠️ Valkuilen - Speler glijdt van het scherm → `if player_x > WIDTH - breedte` vergeten - Botsing werkt niet → verkeerde waarden in `Rect()` - Alle stenen bewegen tegelijk, maar maar één wordt gecheckt op botsing - Score telt door na game over → geen check op `if not game_over:` ### 🧠 Differentiatie #### Voor snelle leerlingen - Voeg power-ups toe (onzichtbaarheid, levens, vertraging) - Laat speler en stenen met sprites tekenen in plaats van rechthoeken - Laat leerlingen zelf een nieuw spelelement verzinnen #### Voor langzamere leerlingen - Laat maar één steen vallen (geen lijst) - Geef per les kant-en-klare startercode mee - Werk samen in tweetallen ### 📊 Beoordeling (optioneel)
CriteriumOmschrijvingScore (1-5)
Werkt het spelGeen fouten, spel werkt zoals bedoeld🟩
Code is leesbaarLogische structuur, goede naamgeving🟩
Uitbreiding toegevoegdCreatieve of technische aanvulling🟩
ReflectieAntwoorden zijn volledig en met inzicht🟩
### 💡 Tips voor in de les - Laat leerlingen na elke wijziging op F5 drukken → directe feedback is motiverend - Gebruik klassikale demo’s bij fouten: “Waarom crasht deze versie?” - Laat leerlingen zelfstandig kleine uitbreidingen testen vanaf les 5 - Bespreek reflectievragen klassikaal in les 6 ### 🧰 Benodigdheden - Thonny geïnstalleerd (met Pygame Zero via `pip install pgzero` indien nodig) - Werkende computer (Windows, Linux of macOS) - Toetsenbord met pijltjestoetsen # Snake ##### Status: alles uitgevoerd en getest ## 0 Snake Lessenserie Welkom bij de Snake lessenserie! In deze serie leer je stap voor stap hoe je het klassieke spelletje **Snake** maakt met `Python` en `Pygame Zero`. Je begint met het tekenen van een blokje en eindigt met een compleet werkend spel – inclusief groeiende slang, score en Game Over! ### 📚 Overzicht van de lessen 1. [Les 1 – Teken de slangkop](https://roc.ovh/link/896#bkmrk-1-snake-les-1-teken-de-slangkop) 2. [Les 2 – Beweeg de slang](https://roc.ovh/link/896#bkmrk-2-snake-les-2-beweeg-de-slang) 3. [Les 3 – Botsing met schermrand](https://roc.ovh/link/896#bkmrk-3-snake-les-3-automatische-beweging) 4. [Les 4 – Richting automatisch volgen](https://roc.ovh/link/896#bkmrk-4-snake-les-4-randbotsing) 5. [Les 5 – Teken een appel en detecteer botsing](https://roc.ovh/link/896#bkmrk-5-snake-les-5-geen-omkeren) 6. [Les 6 – Laat de slang groeien](https://roc.ovh/link/896#bkmrk-6-snake-les-6-appel) 7. [Les 7 – Begrijp insert() en pop()](https://roc.ovh/link/896#bkmrk-7-snake-les-7-de-slang-groeit) 8. [Les 8 – Vertraagde beweging](https://roc.ovh/link/896#bkmrk-8-snake-les-8-vertraging-en-snelheid) 9. [Les 9 – Score en Game Over](https://roc.ovh/link/896#bkmrk-9-snake-les-9-score-en-game-over) 10. [Les 10 – Challenge en uitbreiding](https://roc.ovh/link/896#bkmrk-10-snake-les-10-eindopdracht) ### 🎯 Leerdoelen - Je leert werken met de `draw()` en `update()` functies van Pygame Zero - Je oefent met variabelen, lists en toetsenbordinvoer - Je leert wat een game loop is en hoe je controle krijgt over beweging - Je leert je eigen code uitbreiden, testen en verbeteren ### 🛠️ Benodigdheden - Thonny geïnstalleerd met de package `pgzero` - Een beetje basiskennis van Python (variabelen, if, functies) ### 💬 Hoe werk je? Elke les bevat uitleg, voorbeeldcode, opdrachten én een extra uitdaging. Voer je code steeds uit in Thonny en probeer alle opdrachten echt zelf op te lossen. Je mag hulp vragen of AI gebruiken, maar probeer te begrijpen wat er gebeurt. ### 🎓 Klaar? Lever je eindspel in, samen met je antwoorden op de reflectievraag. Veel succes en vooral: veel plezier met programmeren! ### 🛠️ Opdracht We gaan nog een projectje maken met Thonny (uit de vorige les) en bij dit project gaan we gebruik maken van de standaard Python library: pgzero Weet je nog hoe je een package installeert in Thonny? Yep, Tools - Manage Packages en dan pgzero zoeken en installeren. ### 📤 Inleveren Niets, maar zorg ervoor dat je Thonny werkt en dat je een neiuw project maak.

Tip: Kopieer je vorige project en noem het anders.

## 1 Teken de slangkop In deze les gaan we beginnen met het maken van een eigen versie van Snake in Python met Pygame Zero. We gaan eerst de kop van de slang tekenen op het scherm. Je ziet dan een vierkantje dat straks kan gaan bewegen. ### Wat gaan we doen? We maken een slangkop als vierkant met een bepaalde positie en grootte, en tekenen die in de `draw()`-functie. ### 📦 Benodigdheden - Een werkende Python-omgeving met Pygame Zero (zoals Thonny) - Geen plaatjes nodig – we tekenen de slang met blokken ### 🔰 Startercode ```python # importeer library import pgzrun # Spelgrootte WIDTH = 600 HEIGHT = 400 # Startpositie van de slangkop snake_x = 100 snake_y = 100 tile_size = 20 def draw(): screen.clear() screen.draw.filled_rect(Rect((snake_x, snake_y), (tile_size, tile_size)), "green") #start programma pgzrun.go() ``` ### ℹ️ Uitleg - `WIDTH` en `HEIGHT`: grootte van het spelvenster - `snake_x` en `snake_y`: positie van de slangkop - `tile_size`: grootte van het blokje - `screen.draw.filled_rect(...)`: tekent een gevuld vierkantje op het scherm ### 🛠️ Opdracht - Pas de waarde van `snake_x` en `snake_y` aan – wat gebeurt er? - Maak het vierkant groter of kleiner door `tile_size` te wijzigen - Verander de kleur van het vierkant in bijvoorbeeld `"blue"` of `"orange"` #### 💡 Extra uitdaging Teken een tweede blokje naast de slangkop alsof er al een stukje staart is. Gebruik nog een `screen.draw.filled_rect()`. ### 📤 Inleveren 1. Maak een screenshot van je 'slangkop' op het scherm waarbij je de 'slangkop'op een andere positie hebt gezet. ## 2 Beweeg de slang In deze les gaan we de slangkop laten bewegen met de pijltjestoets die je indrukt. We gebruiken daarvoor de `update()`-functie van Pygame Zero en de toetsenbordinput. ### Wat gaan we doen? We maken een richting-variabele en passen de positie van de slang aan op basis van de pijltjes die je indrukt. ### 🔰 Code Dit is een **deel van de code**, je moet jouw bestaande code aanpassen aan de hand van deze nieuwe code. Je hoeft dus niet alles opnieuw te typen. Plaats de `update()` functie en pas eventueel `snake_x`, `snake_y`, `tile_size` en `step` aan in jouw bestaande code. ```python # Startpositie van de slangkop snake_x = 200 snake_y = 200 tile_size = 10 step = 1 def draw(): screen.clear() screen.draw.filled_rect(Rect((snake_x, snake_y), (tile_size, tile_size)), "green") def update(): global snake_x, snake_y if keyboard.left: snake_x -= step if keyboard.right: snake_x += step if keyboard.up: snake_y -= step if keyboard.down: snake_y += step ``` ### ℹ️ Uitleg - `update()` wordt automatisch meerdere keren per seconde uitgevoerd - `keyboard.left` controleert of de linkerpijl is ingedrukt - Telkens als je een toets indrukt, verandert de positie van de slang - `step` bepaalt hoe ver de slang per stap beweegt ### 🛠️ Opdracht - Beweeg de slang door het scherm met de pijltjes - Pas `step` aan naar een andere waarde – wat merk je? - Laat de slang sneller of langzamer bewegen door minder of meer pixels per keer te verplaatsen #### 💡 Extra uitdaging Laat de slang automatisch blijven bewegen in de laatst gekozen richting: - Gebruik een variabele `richting` die je bijwerkt met `on_key_down()` - Laat de slang dan elke update in die richting verder bewegen ### 📤 Inleveren 1. Leg uit wat de variable step doet. 2. Welke waarde heb je gekozen, waarom? (je kunt dit inleveren in het tekst veld of in een .txt. bestandje) ## 3 Automatische beweging In deze les gaan we de slang automatisch laten blijven bewegen in de richting van de laatste pijltjestoets die je hebt ingedrukt. ### 🔍 Wat gaan we doen? - We maken een nieuwe variabele `richting`. - Als je op een pijltjestoets drukt, verandert de waarde van `richting`. - In de `update()` functie verplaatst de slang zich elke keer opnieuw in de gekozen richting – ook als je de toets niet ingedrukt houdt! ### 🔰 Code Gebruik deze versie als nieuwe code (je mag dit toevoegen aan of combineren met je bestaande code): ```python import pgzrun WIDTH = 600 HEIGHT = 400 snake_x = 200 snake_y = 200 tile_size = 20 step = 10 richting = "right" def draw(): screen.clear() screen.draw.filled_rect(Rect((snake_x, snake_y), (tile_size, tile_size)), "green") def update(): global snake_x, snake_y if richting == "left": snake_x -= step elif richting == "right": snake_x += step elif richting == "up": snake_y -= step elif richting == "down": snake_y += step def on_key_down(key): global richting if key == keys.LEFT: richting = "left" elif key == keys.RIGHT: richting = "right" elif key == keys.UP: richting = "up" elif key == keys.DOWN: richting = "down" pgzrun.go() ``` ### ℹ️ Uitleg - `richting`: deze variabele onthoudt de laatst gekozen richting - `on_key_down()`: dit is een functie die wordt uitgevoerd als je op een toets drukt - `update()`: deze functie verplaatst de slang elke keer in de gekozen richting, ook als je geen toets indrukt ### 🛠️ Opdracht - Test of je slang automatisch blijft bewegen nadat je een pijl indrukt - Wat gebeurt er als je twee keer snel op een andere richting drukt? - Probeer met `tile_size` en `step` te spelen voor een ander effect #### 💡 Extra uitdaging Voeg grenzen toe aan je spel: laat de slang stoppen of ergens anders naartoe gaan als hij de rand van het scherm raakt. ### 📤 Inleveren 1. Leg in je eigen woorden uit wat de functie `on_key_down()` doet (Lever dit in via het tekstvak of via een upload.) ## 4 Randbotsing en automatische richting In deze les zorgen we ervoor dat de slang niet zomaar het scherm verlaat. Zodra hij een rand raakt, verandert hij automatisch van richting. Zo beweegt hij steeds binnen het scherm! ### 🔍 Wat gaan we doen? - We controleren of de slang de rand van het scherm raakt. - Als dat zo is, passen we automatisch de richting aan. ### 🔰 Code (let op: onvolledig!) Hieronder zie je de code. Eén belangrijke regel ontbreekt – die moet jij toevoegen! ```python import pgzrun WIDTH = 600 HEIGHT = 400 snake_x = 200 snake_y = 200 tile_size = 20 step = 5 richting = "right" def draw(): screen.clear() screen.draw.filled_rect(Rect((snake_x, snake_y), (tile_size, tile_size)), "green") def update(): global snake_x, snake_y, richting if richting == "left": snake_x -= step elif richting == "right": snake_x += step elif richting == "...": snake_y -= step elif richting == "...": snake_y += step # 🧠 Hier controleren we of de slang de rand raakt if snake_x < 0: richting = "right" elif snake_x + tile_size > WIDTH: richting = "left" elif snake_y < 0: richting = "..." elif snake_y + tile_size > HEIGHT: richting = "..." def on_key_down(key): global richting if key == keys.LEFT: richting = "left" elif key == keys.RIGHT: richting = "right" elif key == keys.UP: richting = "up" elif key == keys.DOWN: richting = "down" pgzrun.go() ``` Als je de linker- of rechterkant raakt, dan 'stuitert' je terug. Dat gebeurt niet als je de boven- of onderkant aanraakt. Pas de code aan zodat je ook terugstuiters als je de onder-of bovenkant aanraakt. ### ℹ️ Uitleg - `snake_x + tile_size > WIDTH`: betekent dat de slang voorbij de rechterrand gaat - Als de slang een rand raakt, verander je de variabele `richting` - De ontbrekende waarde is wat de slang moet doen als hij links het scherm uit dreigt te gaan ### 🛠️ Opdracht - Voeg de ontbrekende regel toe zodat de slang niet door de linkerkant verdwijnt - Test of de slang de andere richtingen goed oppikt - Verander eventueel de standaardrichting of startpositie om verschillende randen te testen #### 💡 Extra uitdaging Laat de slang bij elke randbotsing van kleur veranderen! (Tip: maak een variabele `kleur` en gebruik bijvoorbeeld `random.choice()`) ### 📤 Inleveren 1. Leg uit wat je hebt aangepast en waarom dat werkt. (Lever dit in via het tekstvak of via een upload.) ## 5 Geen omkeren toegestaan In deze les zorgen we ervoor dat de slang niet meteen omkeert. In een echte Snake-game kun je namelijk niet ineens van rechts naar links bewegen – dan zou de slang zichzelf opeten! ### 🔍 Wat gaan we doen? - We voorkomen dat de slang direct de tegenovergestelde richting kiest. - We vergelijken de huidige richting met de nieuwe richting voordat we die veranderen. ### 🔰 Code (let op: onvolledig!) De volgende code voorkomt omkeren, maar jij moet één voorwaarde nog zelf aanvullen. ```python import pgzrun WIDTH = 600 HEIGHT = 400 snake_x = 200 snake_y = 200 tile_size = 20 step = 1 richting = "right" def draw(): screen.clear() screen.draw.filled_rect(Rect((snake_x, snake_y), (tile_size, tile_size)), "green") def update(): global snake_x, snake_y if richting == "left": snake_x -= step elif richting == "right": snake_x += step elif richting == "up": snake_y -= step elif richting == "down": snake_y += step def on_key_down(key): global richting if key == keys.LEFT and richting != "right": richting = "left" elif key == keys.RIGHT and richting != "left": richting = "right" elif key == keys.UP and richting != "down": richting = "up" elif key == keys.DOWN and richting != "...": richting = "down" pgzrun.go() ``` ### Stuiteren tegen randen werkt niet meer Het botsen tegen de randen wat in stap 4 is gedaan, zit niet in deze code. Dat is express gedaan. We proberen op deze manier een ding gelijktijdig uit te leggen en het voorkomt dat je op dit moment "*door de bomen het bos niet meer ziet*". ### ℹ️ Uitleg - We gebruiken een `if`-voorwaarde om te voorkomen dat je teruggaat in de tegenovergestelde richting. - De ontbrekende regel is die voor `keys.DOWN`: welke richting is dan niet toegestaan? ### 🛠️ Opdracht - Vul de ontbrekende voorwaarde aan zodat de slang niet van "up" naar "down" mag keren - Test alle richtingen: kun je nog steeds normaal draaien? Keren lukt niet meer, toch? #### 💡 Extra uitdaging Laat de slang een geluidje maken als je op een toets drukt, maar de richting wordt niet veranderd (bijv. als je wél op links drukt, maar dat mag niet). Met deze code kan je ene geluidje afspelen. ``` sounds.beep.play() ``` Om een sound af te kunnen spelen moet jouw project folder een mapje maken sounds en daarin moet een beep.wav komen. ``` mijn_project/ ├── main.py └── sounds/ └── beep.wav ``` ##### Geluidjes toevoegen Je kunt zelf geluidjes toevoegen, stel je hebt een geluidje **bel.wav** dan plaats je dat in de sounds directory en dan gebruik je het commando `souds.bel.play()` ### 📤 Inleveren 1. Leg uit wat je hebt veranderd en hoe het werkt. (Lever dit in via het tekstvak of via een upload.) ## 6 Appel tekenen en raken In deze les voegen we een appel toe aan het spel. De appel verschijnt op een willekeurige plek op het scherm. Als de slang de appel raakt, verschijnt er een bericht in de console. ### 🔍 Wat gaan we doen? - We gebruiken de `random`-module om een appel op een willekeurige positie te tekenen. - We tekenen de 'appel' met een geel cirkeltje of vierkantje. - We detecteren of de slang de appel raakt. ### 📦 Benodigdheden - Je slangkop beweegt al automatisch over het scherm - Je hebt al gewerkt met `tile_size` en `snake_x`/`snake_y` ### 🔰 Code (let op: onvolledig!) Onderstaande code tekent een slangkop en een appel. De botsing werkt al, maar na een botsing blijft de appel op dezelfde plek staan. Vul zelf aan wat er moet gebeuren! ```python import pgzrun import random WIDTH = 600 HEIGHT = 400 tile_size = 20 snake_x = 100 snake_y = 100 richting = "right" step = 3 # Appelpositie (willekeurig op het grid) apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size def draw(): screen.clear() screen.draw.filled_rect(Rect((snake_x, snake_y), (tile_size, tile_size)), "green") screen.draw.filled_circle((apple_x + tile_size // 2, apple_y + tile_size // 2), tile_size // 2, "yellow") def on_key_down(key): global richting if key == keys.LEFT and richting != "right": richting = "left" elif key == keys.RIGHT and richting != "left": richting = "right" elif key == keys.UP and richting != "down": richting = "up" elif key == keys.DOWN and richting != "up": richting = "down" def update(): global snake_x, snake_y, apple_x, apple_y if richting == "left": snake_x -= step elif richting == "right": snake_x += step elif richting == "up": snake_y -= step elif richting == "down": snake_y += step # Botst de slang met de appel? snake_rect = Rect((snake_x, snake_y), (tile_size, tile_size)) apple_rect = Rect((apple_x, apple_y), (tile_size, tile_size)) if snake_rect.colliderect(apple_rect): print("🍏 Appel geraakt!") # 👇 VUL HIER AAN: genereer een nieuwe positie voor de appel # apple_x = ... # apple_y = ... pgzrun.go() ``` ### ℹ️ Uitleg - `random.randint()`: geeft een willekeurig geheel getal terug - De appelpositie wordt op het grid berekend, zodat deze altijd netjes uitlijnt - `filled_circle()`: tekent een geel rondje (je kunt ook `filled_rect()` gebruiken) ### 🛠️ Opdracht - Test of de appel op het scherm verschijnt - Beweeg de slang naar de appel – zie je de console-uitvoer? - Vul de ontbrekende regels in zodat de appel na een botsing op een **nieuwe plek** verschijnt #### 💡 Extra uitdaging Laat de appel niet precies op dezelfde plek als de slang verschijnen wanneer hij opnieuw wordt gegenereerd! ### 📤 Inleveren 1. Lever de code in .py bestand. ## 7 De slang groeit In deze les maak je van je slang een échte slang: eentje die uit meerdere blokjes bestaat en langer wordt als hij een appel eet. ### 🔍 Wat gaan we doen? - We veranderen de slang van één blokje naar een lijst van blokjes - De slang groeit bij het eten van een appel - We houden de lengte gelijk als er geen appel wordt gegeten ### 📘 Strategie De code wordt nu iets ingewikkelder. Het is niet erg als je niet alles direct begrijpt. Probeer wel te volgen wat er gebeurt. We bespreken de strategie: 1. De slang bestaat uit meerdere delen. De code in de `draw()`-functie tekent elk stukje. 2. Bij elke update wordt er een nieuw blokje toegevoegd aan de kop van de slang. 3. Als de slang een appel raakt: dan blijft de slang langer. 4. Als er geen appel is geraakt: dan wordt het laatste stukje van de slang verwijderd. Dus in het kort: 1. Teken de slang 2. Voeg een stukje toe aan de kop 3. Geen appel? Verwijder de staart ### 🔰 Code ```python import pgzrun import random WIDTH = 600 HEIGHT = 400 tile_size = 20 snake = [(100, 100)] richting = "right" step = 3 apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size def draw(): screen.clear() for segment in snake: screen.draw.filled_rect(Rect(segment, (tile_size, tile_size)), "green") screen.draw.filled_circle((apple_x + tile_size // 2, apple_y + tile_size // 2), tile_size // 2, "yellow") def on_key_down(key): global richting if key == keys.LEFT and richting != "right": richting = "left" elif key == keys.RIGHT and richting != "left": richting = "right" elif key == keys.UP and richting != "down": richting = "up" elif key == keys.DOWN and richting != "up": richting = "down" def update(): global apple_x, apple_y head_x, head_y = snake[0] if richting == "left": head_x -= step elif richting == "right": head_x += step elif richting == "up": head_y -= step elif richting == "down": head_y += step new_head = (head_x, head_y) snake.insert(0, new_head) head_rect = Rect(new_head, (tile_size, tile_size)) apple_rect = Rect((apple_x, apple_y), (tile_size, tile_size)) if head_rect.colliderect(apple_rect): print("🍏 Appel geraakt!") apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size else: snake.pop() # staart verwijderen if new_head in snake[1:]: # Deze code detecteerd of de slang zichzelf raakt. print("🚫 Game over! De slang raakte zichzelf.") exit() pgzrun.go() ``` ### ℹ️ Uitleg - `snake = [(x, y), ...]`: lijst van alle slangsegmenten - `insert(0, new_head)`: voegt een nieuw blokje toe aan de voorkant - `pop()`: verwijdert het laatste stukje (staart) - `if new_head in snake[1:]`: controle of slang zichzelf raakt ``` Voorbeeld bij beweging: Stap 1: slang = [(4,2), (3,2), (2,2)] Stap 2: kop wordt (5,2) → slang = [(5,2), (4,2), (3,2)] Stap 3: geen appel → staart eraf → slang = [(5,2), (4,2)] ``` #### 📚 Waarom werkt dit zo? Door altijd eerst een kop toe te voegen, beweegt de slang vooruit. Als er geen appel is geraakt, halen we de staart weg zodat de lengte gelijk blijft. Wordt er wél een appel geraakt, dan blijft de slang langer: we doen dan geen `pop()`. Dit is hoe de slang groeit! ### 🛠️ Opdracht - Controleer of de slang groeit als hij een appel eet - Controleer of hij even lang blijft als er geen appel wordt geraakt ### 📄 Inleveren 1. Beantwoord de vraag: **Wat gebeurt er als je `snake.pop()` vergeet?** (Lever dit in via het tekstvak of als bestand.) ## 8 De slang sneller maken met vertraging In deze les leer je hoe je de slang sneller kunt laten groeien door de `step` te vergroten, zonder dat het spel te snel en onspeelbaar wordt. ### 🔍 Wat is het probleem? Je denkt misschien: "Ik wil dat de slang sneller beweegt, dus ik maak `step` groter." Maar als je `step = 20` doet, wordt het spel ineens **veel te snel**. Dat komt omdat `update()` standaard 60 keer per seconde wordt uitgevoerd. Dus je slang maakt dan 60 sprongen van 20 pixels per seconde: dat is 1200 pixels! ### ❌ Fout idee ```python step = 20 # grotere stap # maar het spel gaat nu te snel! ``` ### ✅ Goede oplossing: beweging vertragen We laten de slang **niet elke update** bewegen, maar bijvoorbeeld 1x per 10 frames. Zo kun je `step` groter maken, zonder dat het spel onbestuurbaar wordt. ### 🔰 Code ```python import pgzrun import random WIDTH = 600 HEIGHT = 400 tile_size = 20 step = 20 vertraging = 10 # aantal frames wachten frames = 0 snake = [(100, 100)] richting = "right" apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size def draw(): screen.clear() for segment in snake: screen.draw.filled_rect(Rect(segment, (tile_size, tile_size)), "green") screen.draw.filled_circle((apple_x + tile_size // 2, apple_y + tile_size // 2), tile_size // 2, "yellow") def on_key_down(key): global richting if key == keys.LEFT and richting != "right": richting = "left" elif key == keys.RIGHT and richting != "left": richting = "right" elif key == keys.UP and richting != "down": richting = "up" elif key == keys.DOWN and richting != "up": richting = "down" def update(): global frames frames += 1 if frames < vertraging: return frames = 0 beweeg_slang() def beweeg_slang(): global apple_x, apple_y head_x, head_y = snake[0] if richting == "left": head_x -= step elif richting == "right": head_x += step elif richting == "up": head_y -= step elif richting == "down": head_y += step new_head = (head_x, head_y) snake.insert(0, new_head) head_rect = Rect(new_head, (tile_size, tile_size)) apple_rect = Rect((apple_x, apple_y), (tile_size, tile_size)) if head_rect.colliderect(apple_rect): print("\U0001F34F Appel geraakt!") apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size else: snake.pop() if new_head in snake[1:]: print("\u274C Game over! De slang raakte zichzelf.") exit() pgzrun.go() ``` ### 🧠 Waarom werkt dit? - `frames += 1`: telt hoe vaak `update()` al is uitgevoerd - Pas als `frames >= vertraging`, beweegt de slang echt - `step` bepaalt nu de grootte van de stap, niet de snelheid van het spel ### 🚀 Opdracht - Stel `step = 20` in en test of de slang nu sneller groeit - Experimenteer met `vertraging = 5` of `vertraging = 15` - Wat is een fijne balans tussen stapgrootte en snelheid? - Test het spel; wat gebeurt er precies als de slang tegen zijn eigen staart botst? #### 🔎 Extra uitdaging Laat de slang naarmate hij langer wordt automatisch steeds iets sneller bewegen (tip: verlaag `vertraging` bij elke appel). ### 📄 Inleveren 1. Leg uitwat er gebeurt als de slang tegen zijn staart aankomt. 2. Probeer te vertellen wat je zou willen veranderen; wat moet er gebeuren als de slang tegen zijn slang aan botst? (Lever dit in via het tekstvak of als bestand.) ## 9 Score bijhouden en Game Over tonen In deze les voegen we een score toe aan het spel. Elke keer als je een appel eet, krijg je 1 punt. En als de slang zichzelf raakt, laten we **"Game Over"** op het scherm zien en stopt het spel. ### 🔍 Wat gaan we doen? - Een variabele `score` bijhouden - De score op het scherm tonen met `screen.draw.text()` - Bij een botsing met jezelf: `game_over = True` - Het spel stoppen en "Game Over" tonen ### 🔰 Startercode ```python import pgzrun import random WIDTH = 600 HEIGHT = 400 tile_size = 20 step = 20 vertraging = 10 frames = 0 snake = [(100, 100)] richting = "right" score = 0 apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size game_over = False def draw(): screen.clear() if game_over: screen.draw.text("GAME OVER", center=(WIDTH // 2, HEIGHT // 2), fontsize=60, color="red") screen.draw.text(f"Score: {score}", center=(WIDTH // 2, HEIGHT // 2 + 50), fontsize=40, color="white") else: for segment in snake: screen.draw.filled_rect(Rect(segment, (tile_size, tile_size)), "green") screen.draw.filled_circle((apple_x + tile_size // 2, apple_y + tile_size // 2), tile_size // 2, "yellow") screen.draw.text(f"Score: {score}", topleft=(10, 10), fontsize=30, color="white") def on_key_down(key): global richting if key == keys.LEFT and richting != "right": richting = "left" elif key == keys.RIGHT and richting != "left": richting = "right" elif key == keys.UP and richting != "down": richting = "up" elif key == keys.DOWN and richting != "up": richting = "down" def update(): global frames if game_over: return frames += 1 if frames < vertraging: return frames = 0 beweeg_slang() def beweeg_slang(): global apple_x, apple_y, score, game_over head_x, head_y = snake[0] if richting == "left": head_x -= step elif richting == "right": head_x += step elif richting == "up": head_y -= step elif richting == "down": head_y += step new_head = (head_x, head_y) if new_head in snake[1:]: print("❌ Game over! De slang raakte zichzelf.") game_over = True return snake.insert(0, new_head) head_rect = Rect(new_head, (tile_size, tile_size)) apple_rect = Rect((apple_x, apple_y), (tile_size, tile_size)) if head_rect.colliderect(apple_rect): print("\U0001F34F Appel geraakt!") score += 1 apple_x = random.randint(0, (WIDTH - tile_size) // tile_size) * tile_size apple_y = random.randint(0, (HEIGHT - tile_size) // tile_size) * tile_size else: snake.pop() pgzrun.go() ``` ### 🧠 Waarom werkt dit? - We tekenen de score linksboven tijdens het spel - We zetten `game_over = True` bij een zelfbotsing - Als `game_over` waar is, stoppen we de beweging en tonen een ander scherm ### 🚀 Opdracht - Laat de slang een paar appels eten en kijk of de score klopt - Laat de slang zichzelf raken en controleer of "Game Over" verschijnt #### 🔎 Extra uitdaging - Laat de score ook in de console printen bij elke appel - Laat het spel automatisch herstarten na een paar seconden (of met een toets) ### 📄 Inleveren 1. Beantwoord: **Hoe weet de code dat het "Game Over" is?** Leg stap-voor-stap uit wat er gebeurt. Kijk goed naar de code! (Lever dit in via het tekstvak of als bestand.) ## 10 Snake – Eindopdracht ### 🌯️ Houd de slang binnen het scherm Op dit moment kan de slang zomaar van het scherm verdwijnen als je te ver naar links, rechts, boven of onder beweegt. Bedenk zelf hoe je dat kunt oplossen! **Tip:** je kunt controleren of de kop van de slang buiten het scherm terechtkomt. Bijvoorbeeld: ```python if head_x < 0 or head_x >= WIDTH or head_y < 0 or head_y >= HEIGHT: game_over = True ``` Op deze manier ben je 'af' als je het scherm raakt. Je zou ook van richting kunnen veranderen, maar dit is wat lastiger om uit te voeren. ### 🛠️ Opdracht Zorg ervoor dat de slang niet buiten het beeld kan verdwijnen. Je kunt het natuurlijk zo maken dat als je de rand raakt, het spel klaar is ("Game over"). Een ander optie is om van richting te veranderen. Dat is lastiger, weet je waarom? Hoe zou je het op een goede manier kunnen uitvoeren? ### 📄 Inleveren 1. Leg uit waarom het lastig is om de slang van richting te laten veranderen als die de rand van het scherm raakt. Je hoeft het niet te coderen, maar leg uit hoe je de slang precies van richting zou kunnen laten veranderen als die de rand raakt. En werkt dit ook in de hoeken? #### 🔎 Extra uitdaging Als je goed hebt beschreven wat er precies moet gebeuren en je hebt ook rekening gehouden met de hoeken dan kun je misschien AI vragen jouw te helpen om dit echt te bouwen? Als het lukt, wordt het spel leuker om te spelen! \-- # Introductie AI ### Introductie In deze les leren we wat AI is en we gaan kijken naar het verschil van programmeren met en zonder AI. We kijken naar de kracht van AI maar ook naar de tekortkomingen. We gaan de volgende dingen leren: 1. Wart is AI? 2. Wat zijn de AI toepassingen? 3. AI versus klasieke ('gewone') code. Wa tis het verschil? 4. Voordelen van AI 5. Nadelen van AI 6. Hoe kan je AI slim gebruiken 7. Prompt Engineering (intro) ## 1, wat is AI? Bekijk deze video: [https://www.youtube.com/watch?v=QJE\_ycgR8E8](https://www.youtube.com/watch?v=QJE_ycgR8E8) ### Opdracht 1 Vat in één tot drie zinnen samen wat de kernboodschap van dit filmpje is. ### Inleveren 1. Maak de samenvatting in een text document en vul deze in. Lever een **TXT** document in. ## 2, AI toepassingen AI is veel meer dan alleen ChatGPT. In deze video wordt uitgelegd waarvoor AI kan worden gebruikt. Bekijk deze video: [https://www.youtube.com/watch?v=stw2upLHCuI](https://www.youtube.com/watch?v=stw2upLHCuI) ### Theorie AI-toepassingen per taaktype Hieronder staan concrete voorbeelden van hoe kunstmatige intelligentie (AI) wordt toegepast in verschillende soorten taken
**✦ 1. Classificatie**
- **Wat is het?**: Het toewijzen van gegevens aan een bepaalde categorie. - **Voorbeeld**: Een e-mailsysteem dat automatisch bepaalt of een e-mail *spam* is of *geen spam*, op basis van de inhoud, afzender en gebruikte woorden.
**✦ 2. Associatie**
- **Wat is het?**: Het ontdekken van patronen of combinaties van items die vaak samen voorkomen. - **Voorbeeld**: Een webshop gebruikt AI om te ontdekken dat klanten die een *laptop* kopen ook vaak een *laptophoes* kopen. Op basis daarvan worden aanbevelingen gedaan: "Andere klanten kochten ook...".
**✦ 3. Optimalisatie**
- **Wat is het?**: Het vinden van de beste oplossing uit veel mogelijkheden, vaak onder bepaalde voorwaarden. - **Voorbeeld**: Een AI-systeem voor routeplanning bepaalt de *snelste bezorgroutes* voor een pakketdienst, rekening houdend met afstand, verkeer en bezorgtijd.
**✦ 4. Voorspelling**
- **Wat is het?**: Het voorspellen van toekomstige waarden of gebeurtenissen op basis van eerdere gegevens. - **Voorbeeld**: Een bakker gebruikt AI om op basis van eerdere verkoopdata te voorspellen hoeveel *brood* er de komende week nodig is.
**✦ 5. Creatie**
- **Wat is het?**: Het genereren van nieuwe inhoud of ideeën met behulp van AI. - **Voorbeeld**: Een AI-systeem zoals ChatGPT of DALL·E kan een *gedicht schrijven* of een *afbeelding maken* op basis van een beschrijving, bijvoorbeeld: "Een robot die schildert in een zonnebloemenveld". ### Opdracht Bepaal van elk van de voorbeelden bij welk type AI-toep\[assing (creatie, assiociatie, optimalisatie, voorpellen, creatie) dit hoort. 1. Netflix geeft je aanbevelingen voor films op basis van wat je eerder hebt gekeken. 2. Een game bepaalt of je gedrag verdacht is en je mogelijk aan het valsspelen bent. 3. Een routeplanner voor je fietsrit kiest de route met de minste verkeerslichten. 4. TikTok voorspelt welke video je het langst gaat kijken en laat die eerder zien. 5. Een AI-programma maakt een unieke profielfoto in cartoonstijl van jou. ### Inleveren 1. Neem de punten over in een text document en vul deze in. Lever een **TXT** document in. ## 3, AI en 'gewone' computer code. **Wat is het verschil tussen 'gewone' code en AI-code?** **Gewone code (klassieke algoritmes)** is gebaseerd op vaste instructies: als je A invoert, gebeurt altijd B. Dit maakt het **voorspelbaar** en **betrouwbaar**. Denk aan een rekenmachine of een robotarm in een fabriek die elke minuut exact dezelfde beweging maakt. De computer voert precies uit wat je hebt geprogrammeerd. **AI-code** werkt anders. Die is **getraind op heel veel voorbeelden** (zoals tekst, beelden of data) en leert daarvan zelf **patronen te herkennen**. Dat lijkt een beetje op hoe onze hersenen leren. AI is vaak **minder voorspelbaar**, omdat het zelf beslissingen neemt op basis van wat het geleerd heeft. Hierdoor kan het ook **fouten maken**, zeker als het iets nog niet eerder gezien heeft. ChatGPT is bijvoorbeeld een AI die voorspelt welk woord het beste past, op basis van miljarden voorbeelden. ### Opdracht **Opdracht: AI-code of klassieke code?** Lees de eigenschappen hieronder. Bepaal of het hoort bij klassieke code of bij AI-code. Zet er een kruisje bij:
EigenschapKlassieke codeAI-codeGeen van beiden
Voert altijd precies dezelfde handeling uit
Kan leren van voorbeelden
Maakt soms fouten bij onbekende situaties
Is goed in rekenen en logica
Kan patronen herkennen
Is 100% voorspelbaar
Kan nieuwe dingen maken (zoals een tekening)
Kan adviseren of je in Bitcoin moet stappen of moet verkopen
Zal altijd goed advies geven voor de aankoop/verkoop van Bitcoin
Kan jouw foto veranderen en jou in een hele vreemde situatie zetten
### Inleveren 1. Neem de tabel over in een Word document en vul deze in. Lever een **PDF** document in. ## 4, voordelen van AI ### Voordelen van AI AI heeft een aantal sterke kanten die het nuttig maken in allerlei toepassingen: - **AI kan grote hoeveelheden data analyseren** en daarin snel patronen ontdekken die mensen zouden missen. - **AI werkt 24/7**, zonder pauzes of vermoeidheid. - **AI kan gepersonaliseerde aanbevelingen geven**, bijvoorbeeld op YouTube of Spotify. - **AI helpt bij medische diagnoses**, doordat het patronen in röntgenfoto’s of scans herkent. - **AI automatiseert saaie of gevaarlijke taken**, zoals kwaliteitscontrole in fabrieken of het inspecteren van pijpleidingen met drones. ### Opdracht Hieronder zie je een aantal situaties. Geef per situatie aan of AI hier een voordeel zou kunnen bieden, en leg uit waarom. 1. Een docent moet elke week 200 toetsresultaten controleren op fouten. 2. Een leerling zoekt elke dag naar nieuwe muziek die past bij zijn smaak. 3. Een ziekenhuis wil sneller afwijkingen op longfoto’s opsporen. 4. Een bedrijf wil weten welke producten waarschijnlijk snel uitverkocht raken. 5. Een bakker wil weten hoeveel broden hij volgende week moet bakken. ### Inleveren 1. Neem de punten over in een text document en vul deze in. Lever een **TXT** document in. ## 5, nadelen van AI ### Nadelen van AI Hoewel AI veel voordelen heeft, zijn er ook belangrijke nadelen en aandachtspunten: - **AI kan fouten maken** als het situaties tegenkomt die het niet kent of niet goed begrijpt. - **AI is afhankelijk van data** — als de data onvolledig of bevooroordeeld is, kan het systeem verkeerde beslissingen nemen. - **AI is vaak een ‘black box’** — het is soms moeilijk te begrijpen waarom een AI iets doet of beslist. - **AI kan banen vervangen**, vooral bij repetitieve taken, wat zorgt voor zorgen over werkgelegenheid. - **AI heeft geen ethiek of gevoel** — het kan geen morele afwegingen maken zoals mensen dat doen. - **AI kan misbruikt worden** — bijvoorbeeld voor deepfakes, spam of het beïnvloeden van meningen via sociale media. ### Opdracht: Waar is AI een risico of nadeel? Bekijk de onderstaande situaties. Geef per situatie aan of je denkt dat AI hier een **risico of nadeel** kan zijn, en leg kort uit waarom. 1. Een AI-systeem beoordeelt sollicitaties automatisch en kiest wie wordt uitgenodigd. 2. Een AI-chatbot geeft medisch advies zonder dat een arts meekijkt. 3. Een zelfrijdende auto moet een noodbeslissing nemen in het verkeer. 4. Een bedrijf gebruikt AI om te controleren hoeveel pauze werknemers nemen. 5. Een leerling gebruikt AI om al zijn schoolopdrachten te laten schrijven. ### Inleveren 1. Neem de punten over in een text document en vul deze in. Lever een **TXT** document in. ## 6, slim gebruik van AI ### Hoe benut je de voordelen en vermijd je de nadelen? AI is een krachtig hulpmiddel, maar het is belangrijk dat je er **bewust en slim mee omgaat**. Dat betekent: weten wanneer je AI goed kunt inzetten, en ook herkennen wanneer het beter is om zelf na te denken of iets te controleren. #### ✔ Zo benut je de voordelen van AI: - Gebruik AI als **assistent**, niet als vervanger van je eigen denkwerk. - Laat AI je **helpen bij brainstormen**, schrijven of samenvatten — maar **controleer altijd de output**. - Gebruik AI om **saaie of repetitieve taken te versnellen**, zoals opmaak of vertalingen. - Combineer AI-output met je **eigen kennis en creativiteit**, zodat het persoonlijk blijft. #### ✘ Zo vermijd je de nadelen van AI: - **Geloof niet alles wat AI zegt** — **controleer** feiten en cijfers. - **Gebruik AI niet voor belangrijke beslissingen** zonder menselijk toezicht. - **Denk na over privacy en veiligheid** — deel geen persoonlijke gegevens. - **Gebruik AI niet om te spieken** of werk van anderen als je eigen werk in te leveren - **Weet wanneer je AI niet moet gebruiken**: Soms is menselijk oordeel belangrijker, bijvoorbeeld bij gevoelige onderwerpen of ethische keuzes. ### Opdracht: Slim of niet slim gebruik van AI? Lees de onderstaande situaties. Geef per situatie aan of dit **slim gebruik van AI** is of juist **onverstandig**, en leg uit waarom. 1. Een leerling vraagt ChatGPT om 5 ideeën voor een spreekbeurt en kiest daarna zelf het beste idee. 2. Iemand plakt een volledige schoolopdracht in ChatGPT en levert het antwoord in zonder iets aan te passen. 3. Een student laat AI een samenvatting maken van een moeilijke tekst en controleert die daarna met de originele tekst erbij. 4. Iemand vraagt aan een AI wat de beste medicijnen zijn voor zijn klachten, zonder met een arts te praten. 5. Een leerling gebruikt AI om zijn code te verbeteren, maar probeert eerst zelf te begrijpen wat het doet. ### Inleveren 1. Neem de punten over in een text document en vul deze in. Lever een **TXT** document in. ## 7, Prompt engineering **Prompt engineering** is het slim en bewust formuleren van opdrachten of vragen (prompts) voor een AI-systeem zoals ChatGPT, zodat je een zo goed mogelijk en bruikbaar antwoord krijgt. Als jij aan een mede student vraagt of hij je met de vorige opdracht kan helpen, dan weet hij waarschijnlijk waar je het voer hebt. Een AI zoals ChatGPT weet dat niet. Omdat CHatGPT de context niet weet. De contect is alles om een vraag heen. ##### Voorbeeld > *"Maak een quiz."* Deze opdracht is vaag. De AI weet niet: - Over welk onderwerp? - Voor welke doelgroep? - Hoeveel vragen? - Meerkeuze of open vragen? ### Voorbeeld met goede prompt engineering: > *"Maak een quiz van 5 meerkeuzevragen voor leerlingen van 14 jaar over het onderwerp 'kunstmatige intelligentie'. Geef bij elke vraag vier antwoordopties en geef aan welk antwoord het juiste is."* Deze prompt: - geeft **context** (leeftijd, onderwerp) - is **duidelijk** (5 vragen, meerkeuze) - is **doelgericht** (quiz maken) - bevat extra **details** (aantal opties en juiste antwoord) We gaan hier in de mdule prompt engineering verder mee werken, maar we gaan nu vast een oefening doen. ### Opdracht, maak een prompt Maak één prompt waarin je je AI vraagt een PHP programma dat zoveel mogelijk lijkt op: ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-05/scaled-1680-/Yunimage.png) Je hoeft geen database te maken, je hoeft alleen front-end code te maken. Maak dit met één prompt en wees zo compleet mogelijk. ### Inleveren 1. De door jouw gemaakte prompt 2. Het resultaat in code # Snake Challenge ## Snake Challenge! ### Maak je eigen snake versie! In deze laatste les ga je zelf aan de slag. Je krijgt een paar uitdagingen waar je zelf oplossingen voor moet bedenken. De code werkt al goed, maar nog niet perfect: je slang kan bijvoorbeeld zomaar uit beeld verdwijnen. En misschien wil je het spel ook leuker of spannender maken? ### ✨ Bedenk en bouw je eigen toevoeging Voeg nu zelf iets toe aan het spel. Kies uit een van de onderstaande ideeën, of verzin er zelf een! #### 🚀 Idee 1: Maak het spel sneller Verlaag de vertraging een beetje elke keer als je een appel eet. Dan wordt het spel steeds spannender! ```python vertraging = max(1, vertraging - 1) ``` #### 🎈 Idee 2: Verander de kleur van de slang bij elke appel Gebruik bijvoorbeeld `random.choice(["green", "blue", "purple"])` om de kleur van de slang steeds te wisselen. #### ⛅️ Idee 3: Maak obstakels op het scherm Voeg een vaste lijst toe met blokken waar de slang niet overheen mag. Als hij ze raakt: game over! ### 💡 Extra idee? Heb je zelf een ander idee? Ga ervoor! Laat je creativiteit zien. Denk aan een "pauze-knop", meerdere appels tegelijk, of een level-systeem. ### 📄 Inleveren 1. Maak een korte beschrijving van wat je hebt aangepast (txt bestand) 2. Lever je aangepaste en werkende spel in. # Kennis Check Blok 2 ## Kennis Check Blok 2 ### Vallende Stenen
**Waarom is het handig om de speler en de vallende steen elk met een eigen variabele voor x en y te beheren?** Zo kun je de positie van elk object onafhankelijk aanpassen en er later berekeningen mee doen, zoals bewegen of botsing detecteren. Als je maar één variabele zou gebruiken, zou je die flexibiliteit verliezen.
**Wat is het verschil tussen tekenen op het scherm en het updaten van een positie?** Tekenen op het scherm gebeurt in de `draw()`-functie en bepaalt wat de speler ziet. Updaten van posities gebeurt in de `update()`-functie en bepaalt waar objecten zich bevinden. Zonder update gebeurt er niets; zonder draw zie je niets.
**Waarom gebruik je een functie zoals `colliderect()` en schrijf je geen eigen code om te controleren of objecten elkaar raken?** `colliderect()` is getest en betrouwbaar. Zelf botsingsdetectie schrijven is foutgevoelig en complex. Door bestaande functies te gebruiken maak je je code korter, leesbaarder en minder foutgevoelig.
**Waarom wordt er gewerkt met `random.randint()` om de x-positie van de steen te kiezen?** Daardoor weet de speler niet waar de volgende steen zal vallen, wat het spel spannender maakt. Zonder toeval zou het spel voorspelbaar en saai worden.
**Wat gebeurt er als je geen limiet stelt aan de onderkant van het scherm voor vallende objecten?** Dan vallen stenen eindeloos door en verdwijnen ze uit beeld, wat kan zorgen voor geheugenproblemen of verwarring bij de speler. Je moet ze resetten of verwijderen als ze te ver vallen.
**Waarom wordt in het spel vaak gebruik gemaakt van globale variabelen?** Omdat `draw()` en `update()` automatisch worden aangeroepen door Pygame Zero en geen parameters gebruiken, moeten variabelen buiten deze functies beschikbaar zijn. Globale variabelen maken dit mogelijk.
**Wat is het verschil tussen een spel dat ‘reageert’ op invoer en een animatie die altijd hetzelfde doet?** Een spel reageert op wat de speler doet, zoals het indrukken van pijltjestoetsen. Bij een animatie loopt alles vanzelf, zonder dat de gebruiker invloed heeft. Interactiviteit is wat van een animatie een spel maakt.
### Snake
**Waarom bestaat een slang uit een lijst met segmenten in plaats van één positie?** Doordat de slang uit meerdere segmenten bestaat kun je de groei en beweging ervan beter simuleren: bij eten wordt een segment toegevoegd en anders wordt het achterste segment verwijderd. Zo ontstaat een realistische slangbeweging.
**Wat is het nut van een timer variabele in `update(dt)`?** De timer bepaalt hoe snel de slang beweegt (bijv. elke 0.15 seconden). Door `dt` op te tellen weet je precies wanneer de slang een stapje moet maken, los van de framerate.
**Waarom gebruiken we een `direction\_queue` in plaats van alleen de huidige richting?** Een queue maakt het mogelijk om meerdere toetsaanslagen op te slaan vóór de volgende beweging. Zo kan de slang snel achter elkaar van richting veranderen, zonder meteen om te draaien en zichzelf te 'eten'.
**Waarom gebruiken we `colliderect()` of gelijkwaardigheidsonderzoek in plaats van handmatige afstandsvergelijking?** `colliderect()` is eenvoudiger en betrouwbaarder: het controleert rechthoekige botsingen automatisch. Handmatig rekenen op coördinaten kan fouten veroorzaken.
**Waarom laten we de slang 'wrappen' naar de andere kant van het scherm bij randbotsing?** Door wrappen speelt het spel vloeiender en blijft de slang ononderbroken bewegen. Zonder wrap zou botsen op de rand een abrupt einde betekenen.
**Hoe draagt het willekeurig plaatsen van voedsel bij aan de speelervaring?** Het willekeurig zetten van voedsel voorkomt patronen en houdt het spel uitdagend. De speler moet telkens de slang naar een onverwachte plek sturen.
**Wat gebeurt er als de slang op zichzelf botst, en waarom willen we dat checken vóór het toevoegen van een nieuw segment?** Botst de slang op zichzelf, dan eindigt het spel. Door te checken vóór je de kop toevoegt, voorkom je dat de slang in al zijn segmenten terechtkomt — dat voorkomt onverwacht gedrag.
**Waarom hebben we een `reset()`-functie die opnieuw alles initialiseert?** Een `reset()`-functie zorgt voor een strak begin na Game Over, met dezelfde beginvoorwaarden (slangpositie, timer, richting). Zo kun je herstarten zonder fouten.
**Hoe maak je het spel moeilijker zonder de basiscode te veranderen?** Je kunt de moeilijkheid verhogen door de bewegingstimer in te korten, extra obstakels toe te voegen, of minder ruimte voor voedsel te geven. Zo blijft het uitdagend.
### Introductie AI
**Wat maakt AI anders dan gewone code?** AI-code is gebaseerd op het leren uit voorbeelden en herkent patronen, terwijl gewone code exact reageert op geprogrammeerde instructies. AI kan dus variabelen voorspellen, terwijl gewone code voorspelbaar blijft :contentReference\[oaicite:1\]{index=1}.
**Waarom onderscheidt men AI-toepassingen in categorieën als classificatie, associatie, enz.?** Zo kun je concrete voorbeelden koppelen aan de manier waarop AI werkt. Elke categorie heeft eigen eigenschappen: classificatie herkent labels, optimalisatie zoekt naar de beste oplossing, creatie gaat over nieuwe inhoud maken, etc. :contentReference\[oaicite:2\]{index=2}.
**Hoe helpt het indelen van AI in typen zoals voorspelling en optimalisatie om je begrip te verdiepen?** Je leert zo dat AI niet één technologie is, maar verschillende werkwijzen heeft afhankelijk van het doel—zoals voorspellen van verkoop of optimaliseren van routes. Dit maakt het makkelijker te kiezen welke techniek geschikt is voor een probleem. :contentReference\[oaicite:3\]{index=3}.
**Wat betekent het dat AI 'minder voorspelbaar' is dan klassieke code?** Normale code geeft altijd hetzelfde resultaat bij dezelfde input. AI geeft verschillende output, omdat het leert van data en tot een inschatting komt. Hierdoor kan het fouten maken in onbekende situaties :contentReference\[oaicite:4\]{index=4}.
**Waarom is het belangrijk om de voor- en nadelen van AI te begrijpen?** AI heeft veel kracht, zoals patronen herkennen en personaliseren, maar kan ook fouten maken, bevooroordeeld zijn of ondoorzichtig zijn ("black box"). Door deze aspecten te begrijpen kun je AI verantwoordelijk en effectief inzetten. :contentReference\[oaicite:5\]{index=5}.
**Hoe zorgt goede prompt engineering ervoor dat je AI beter helpt begrijpen wat je wilt?** Door context, doel, doelgroep en format duidelijk te geven, krijgt de AI de juiste informatie om relevante en bruikbare output te leveren. Vage prompts leiden vaak tot onsamenhangende antwoorden.
**Waarom moet je AI‑output altijd controleren, vooral in belangrijke situaties?** AI-systemen kunnen fouten maken, ongepaste of bevooroordeelde antwoorden geven—vooral zonder toezicht. Daarom is menselijke verificatie essentieel, bijvoorbeeld bij medische of juridische adviezen. :contentReference\[oaicite:6\]{index=6}.
**Wat betekent het dat AI een ‘black box’ is, en waarom is dat problematisch?** Je weet vaak niet precies hoe een AI tot een bepaalde beslissing komt. Dit maakt het lastig om die beslissing uit te leggen of te controleren, wat risico's kan veroorzaken in gevoelige toepassingen. :contentReference\[oaicite:7\]{index=7}.
### 🛠️ Opdracht Maak nu de kennis-check. ### 📤 Inleveren Aan het einde van de kennis-check ontvang je een certificaat. Maak een schermafdruk en lever deze in. # Blok 3 - Web Front End # HTML - Phoenix ## 1 Introductie Phoenix Code *In deze les leer je werken met Phoenix Code: een makkelijke code-editor in de browser. Je maakt je eerste HTML-bestand aan en bekijkt het resultaat in je browser.* ### 🎯 Leerdoelen - Je weet wat Phoenix Code is en waarvoor je het gebruikt - Je kunt een HTML-bestand maken en bewerken - Je kunt je werk bekijken in de browser ### 💡 Wat is Phoenix Code? - Phoenix Code is een gratis code-editor die in je browser werkt - Je kunt er HTML, CSS en JavaScript mee maken - Het werkt zonder installatie en je kunt alles opslaan als ZIP ### 🔰 Wat gaan we doen? - We openen Phoenix Code - We maken een HTML-bestand aan - We bekijken het resultaat in de browser ### 🛠️ Stappenplan #### 1. Open Phoenix Code - Ga naar [https://phoenixcode.dev](https://phcode.dev/) - Klik op**File - StartProject** en kies **HTML5 project**. Je hebt nu een standaard HTML bestand (index.htm). #### 2. Maak een nieuw HTML-bestand - Klik links op de map - Klik op `+` en kies **File** - Geef het bestand de naam `myfirst.html` #### 3. Zet deze voorbeeldcode erin ```html Hallo wereld

Hallo allemaal!

Dit is mijn eerste HTML-pagina in Phoenix Code.

``` #### 4. Bekijk het resultaat - Klik bovenaan op **Run** of **Live Server** - De pagina verschijnt rechts of opent in een nieuw tabblad - Klik aan de rechterkant op de verschillende onderdelen; je ziet nu welke HTML bij dezeonderdelen horen. - Je kunt ook op het bestand dubbelklikken ### Opdracht Waarvoor dient HTML? Zet deze vraag en het antwoord op jouw HTML pagina. ### 🧠 Vragen - Wat denk je dat <h1> en </h1> doet? - En <p>....</p>, wat doent die denk je? ### 📤 Inleveren 1. Screenshot van je browser waarin de vraag "Waarom dient HTML?" en jouw antwoord zichtbaar zijn. ### Voorbeeld screenshot ![image.png](https://www.roc.ovh/uploads/images/gallery/2025-06/scaled-1680-/image.png) ## 2 Wat is HTML? *In deze les leer je wat HTML is, waarom het belangrijk is voor websites, en maak je je eerste eenvoudige webpagina met koppen en tekst.* ### 🎯 Leerdoelen - Je weet waar HTML voor wordt gebruikt - Je kent de structuur van een HTML-pagina - Je kunt zelf een eenvoudige HTML-pagina maken ### 💡 Wat is HTML? - HTML betekent **HyperText Markup Language** - Het is de **basis van elke webpagina** - HTML vertelt de browser wat er op een pagina moet staan: tekst, afbeeldingen, knoppen, enzovoort ### 🎬Video - korte uitleg HTML [https://www.youtube.com/watch?v=it1rTvBcfRg](https://www.youtube.com/watch?v=it1rTvBcfRg) ### 🔰 Wat gaan we doen? - We maken een nieuw HTML-bestand in Phoenix Code - We schrijven een pagina over onszelf met koppen en tekst ### 🛠️ Stappenplan #### 1. Maak een nieuw project in Phoenix Code - Ga naar [https://phoenixcode.dev](https://phcode.dev/) - Voeg een bestand toe met de naam `opdracht2.html` #### 2. Typ deze HTML-code ```html Over mij

Hallo! Ik ben [jouw naam]

Ik ben [leeftijd] jaar oud en ik zit op school bij [schoolnaam].

Mijn favoriete hobby is [hobby].

``` #### 3. Pas de tekst aan - Vervang `[jouw naam]`, `[leeftijd]`, `[schoolnaam]` en `[hobby]` door je eigen gegevens #### 4. Bekijk je werk - Klik op **Run** of **Live Server** om je webpagina te bekijken ### Uitleg Tekst staat tussen tags. Deze tags geeft aan hoe een tekst moet worden weergegeven. Vrijwel alle HTML tags bestaan uit een open-tag (bijvoorbeeld <p> en een sluit tag bijvoorbeeld </p> **<p>...</p>** betekent dat de tekst een **pragraaf** is. **<h1>...</h1>** betekent dat de tekst een **header** is. Je hebt nog meer headers: <h2>, <h3>, ..... ### Opdracht 1. Vervang de header die tussen <h1>...</h1> staat door een kleinere header. 2. Zoek op hoe je tekst vet kan afdrukken en laat jouw naam ver afdrukken. ### 📤 Inleveren 1. Maak een screenshot van je webpagina met aangepasgte header en jouw naam ver gedrukt. ## 3 Tekst en opmaak *In deze les leer je hoe je tekst opmaakt met HTML. Je leert koppen, paragrafen, vetgedrukte tekst, cursieve tekst en regels afbreken.* ### 🎯 Leerdoelen - Je kunt kopjes en paragrafen maken met HTML - Je weet hoe je tekst vet of schuin maakt - Je kunt regels afbreken met een <br>-tag ### 💡 Wat kun je met HTML-opmaak? - HTML laat je tekst er beter uitzien en duidelijker maken voor de lezer - Je gebruikt kopjes om structuur aan te brengen, en `

` om losse alinea's te maken - Je kunt woorden **vet** of *schuin* maken om ze op te laten vallen ### 🔰 Wat gaan we doen? - We maken een pagina met meerdere kopjes en paragrafen - We oefenen met ``, `` en `
` ### 📝 Eenvoudige HTML-tags voor tekstopmaak

TagBetekenisVoorbeeldUitleg
`

` t/m `

`
Koppen`

Grote titel

`
`

` is de grootste kop, `

` de kleinste
`

`

Paragraaf / alinea`

Dit is een stukje tekst.

`
Zorgt voor witruimte vóór en na
``Vetgedrukt (belangrijk)`Let op!`Wordt ook door screenreaders benadrukt
``Cursief (nadruk)`Heel belangrijk`Geeft nadruk, ook voor screenreaders
`
`
Regellijn afbreken`Eerste regel
Tweede regel`
Breekt een regel zonder nieuwe paragraaf (deze tag bestaat alleen uit een openingstab)
### 🛠️ Stappenplan #### 1. Maak een nieuw project of nieuw bestand in Phoenix Code - Noem het bestand `tekst.html` #### 2. Typ of plak deze HTML-code ```html Mijn interesses

Over mij

Hallo! Ik ben [jouw naam]. Ik ben enthousiast over programmeren.

Mijn hobby's

Ik hou van muziek maken
voetballen
en gamen.

Toekomst

Later wil ik werken als programmeur bij een groot bedrijf.

``` #### 3. Pas de inhoud aan - Vervang de tekst door jouw eigen naam en interesses - Gebruik minstens één ``, één `` en één `
` #### 4. Bekijk je werk - Klik op **Run** of **Live Server** om het resultaat te zien ### 🧠 Reflectie - Wat doet `
` precies? - Wanneer zou je `` gebruiken en wanneer ``? - Hoe maak je een tekst extra duidelijk voor de lezer? ### 📤 Inleveren 1. Maak een screenshot van jouw pagina waarin opmaak en breekregels zichtbaar zijn ## 4 Afbeeldingen en links *In deze les leer je hoe je een afbeelding op een webpagina toont en hoe je een klikbare link toevoegt naar een andere website.* ### 🎯 Leerdoelen - Je kunt een **afbeelding** invoegen met HTML - Je kunt een **link** maken naar een andere website - Je begrijpt wat attributen zoals `src`, `alt` en `href` doen ### 💡 Wat zijn afbeeldingen en links in HTML? - **Afbeelding:** je gebruikt de tag `` om een foto of plaatje te tonen - **Link:** je gebruikt de tag `` om een klikbare link te maken - Je gebruikt attributen zoals: - `src` = locatie van de afbeelding - `alt` = tekst als de afbeelding niet geladen wordt - `href` = doel van de link ### 🎬Voorbeeld ##### Hoe maak je een link? [https://www.youtube.com/watch?v=gOioxltfh48](https://www.youtube.com/watch?v=gOioxltfh48) ##### Hoe voeg je een plaatje toe op je web pagina? [https://www.youtube.com/watch?v=Hh\_se2Zqsdk](https://www.youtube.com/watch?v=Hh_se2Zqsdk) ### 🔰 Wat gaan we doen? - We voegen een afbeelding toe aan onze pagina - We maken een link naar een favoriete website ### 🛠️ Stappenplan #### 1. Maak een nieuw HTML-bestand in Phoenix Code - Noem het bestand `afbeelding.html` #### 2. Typ of plak deze HTML-code ```html Afbeelding en link

Mijn favoriete dier

Foto van een kat

Meer informatie over katten vind je op Wikipedia.

``` #### 3. Pas de inhoud aan - Vervang de afbeelding met een plaatje dat jij leuk vindt (gebruik Google of Wikipedia en kopieer de afbeeldingslink) - Verander de link naar jouw favoriete website - Verander de tekst zodat het bij jouw afbeelding past #### 4. Bekijk je werk - Klik op **Run** of **Live Server** om je pagina te testen ### 🧠 Reflectie - Wat gebeurt er als je een verkeerde link of afbeelding gebruikt? - Waarom is het belangrijk om de `alt`-tekst te gebruiken? ### 📤 Inleveren 1. Maak een screenshot van je webpagina met een afbeelding én een werkende link ## 5 Lijsten in HTML *In deze les leer je hoe je lijsten maakt met HTML. Je leert zowel opsommingen als genummerde lijsten maken.* ### 🎯 Leerdoelen - Je weet wat het verschil is tussen een genummerde en een opsomming - Je kunt een lijst maken met HTML - Je kunt zelf kiezen welk type lijst het best past ### 💡 Wat zijn lijsten in HTML? - Je gebruikt een lijst om dingen op een rijtje te zetten - **Opsomming (bullets):** gebruik je met `
    ` = **unordered list** - **Genummerde lijst:** gebruik je met `
      ` = **ordered list** - Elk item in een lijst staat in een `
    1. ` = list item ### 🔰 Wat gaan we doen? - We maken een lijst van hobby’s - We maken een genummerde top 3 van favoriete dingen ### 🎬Voorbeeld [https://www.youtube.com/watch?v=2O8pkybH6po](https://www.youtube.com/watch?v=-kXZvKxs9oA) ### 🛠️ Stappenplan #### 1. Maak een nieuw HTML-bestand in Phoenix Code - Noem het bestand `lijsten.html` #### 2. Typ of plak deze HTML-code ```html Mijn lijsten

      Mijn hobby's

      • Gamen
      • Voetballen
      • Tekenen

      Top 3 favoriete snacks

      1. Pizza
      2. Frikandel
      3. Chips
      ``` ### Opdracht Verander de pagina en maak: 1. een **numbered list** van dingen die jij luek vind om te doen. Op nummer 1 staat dan wat je het leukst vnd, op 2 wat je daarna het leukts vind, etc. etc. Noem tenminst 5 dingen. 2. een **unnumbered lists** van dingen die je tot nu hebt geleerd van software development. Klik op **Run** of **Live Server** om je pagina te testen ### 📤 Inleveren 1. Maak een screenshot van jouw webpagina met beide lijsten zichtbaar ## 6 Tabellen in HTML *In deze les leer je hoe je een eenvoudige tabel maakt met HTML. Je gebruikt dit om informatie netjes in kolommen en rijen te tonen.* ### 🎯 Leerdoelen - Je weet wat een HTML-tabel is en waarvoor je die gebruikt - Je kunt een eenvoudige tabel maken met rijen en kolommen - Je gebruikt de tags ``, ``, `
      ` en `` ### 💡 Wat is een tabel in HTML? - Een tabel is een manier om informatie te tonen in rijen (horizontaal) en kolommen (verticaal) - `` = de hele tabel - `` = een rij (table row) - `
      ` = een cel met gegevens (table data) - `` = een kopcel (table header) In een HTML tabel moet elke regel evenveel kolommen bevatten. Om dat voor elkaar te krijgen zou je lege kolommen kunne toevogen als een regel te weinig kolommen heeft.

      In een tabell moet elke regel precies evenveel kolommen bevatten!

      ### 🎬Voorbeeld [https://www.youtube.com/watch?v=2O8pkybH6po](https://www.youtube.com/watch?v=iDA0kF5lrVk) ### 🔰 Wat gaan we doen? - We maken een tabel met onze schoolrooster of favoriete eten - We geven de bovenste rij een titel (kopjes) ### 🛠️ Stappenplan #### 1. Maak een nieuw HTML-bestand in Phoenix Code - Noem het bestand `tabel.html` #### 2. Typ of plak deze HTML-code ```html Mijn schoolrooster

      Mijn schoolrooster

      Dag Vakken
      Maandag Nederlands, Wiskunde
      Dinsdag Engels, Gym
      ``` #### 3. Pas de inhoud aan - Vervang de dagen en vakken door jouw eigen rooster #### 4. Bekijk je werk - Klik op **Run** of **Live Server** om je tabel te bekijken ### 📤 Inleveren 1. Maak een screenshot van jouw tabel met minstens 6 rijen (kopregel plus maamndag t/m vrijdag) ## 7 Formulieren in HTML *In deze les leer je hoe je een formulier maakt in HTML. Je leert invoervelden gebruiken en een knop toevoegen om informatie te versturen.* ### 🎯 Leerdoelen - Je weet wat een formulier is en waarvoor je het gebruikt - Je kunt invoervelden maken voor tekst, getallen en knoppen - Je kunt een formulier laten verzenden naar een ander HTML- of PHP-bestand ### 💡 Wat is een formulier? - Een formulier gebruik je om gegevens in te voeren op een website - Denk aan: contactformulieren, inlogvelden, zoekvelden, bestellingen - Je gebruikt tags zoals: - `
      ` – de container - `` – invoerveld - `
      **Chs\_hr\_fdgdhl!**
      Kan jij dit wachtwoord kraken? ### 🧠 Reflectie - Is het Caesar algoritme een vorm van symmetrische- of asymetrische encryptie? Leg uit waarom. - Hoe zou jij aan een niet programmeur uitleggen wat Caesar encryptie is? - Hoe heb je het wachtwoord gehacked? Welke stappen heb je doorlopen? - Als je een andere en misschien een iets lastigere wachtwoord moest kraken dat met het Caesar algoritme is ge-encrypt, hoe zou je dat dan aanpakken? ### 📤 Inleveren 1. Antwoorden op de reflectiie PDF ## 4 Hashing ### 🎯 Leerdoelen - Je weet hashing betekenen en waarvoor ze gebruikt worden. - Je kunt wachtwoorden op een veilige manier hashen in PHP. - Je weet hoe je hashed wachtwoorden zou kunnen hacken. #### ❓ Wist je dat .... **Blockchain** en **crypto** gebouwd is op de principes van hashing? Wil je weten hoe, kijk dan naar deze video; het is niet erg als je het gedeelte over block-chain niet helemaal begrijpt. ### 💡 Uitleg, wat is hashing? Hashing is een soort encryptie die maar één kant op werkt; Je kunt wel encrypten maar niet de-crypten! Hashing is dus **eenrichtingsversleuteling**: je zet een waarde om in een versleutelde vorm die je **niet meer kunt terugrekenen** naar het origineel. Dit wordt vaak gebruikt voor het **veilig opslaan van wachtwoorden**. In PHP kun je een wachtwoord hashen met: ```php $hash = hash("sha256", "geheim123"); ``` Het resultaat is bijvoorbeeld: `$2y$10$f0849a42909dc18035cb470d239e485acbc1cdd1e48bc41f7a2801e3b08bdbdb` Je kunt dit **niet** terug rekenen naar `geheim123` #### **🔑 Wat gebeurt er bij het inloggen?** Bij het inloggen controleer je of het ingevoerde wachtwoord overeenkomt met de opgeslagen hash: ```php if hash("sha256", $ingevoerdWachtwoord) == $hash { echo "Ingelogd!"; } ``` > ⚠️ Je moet het zo zien dat het ingevoerde wachtwoord opnieuw wordt omgezet met de hash-functie. Is het resultaat hetzelfde als de opgeslagen $hash dan is het ingevoerde wachtwoord goed. ### 🛠️ Opdracht 2 Hashing Neem om te beginnen de start code, `form.htm` en `check.php` over. Controleer of het werkt en probeer in te loggen met admin/wachtwoord. Probeer de code te begrijpen. ##### form.html ```html Loginformulier

      Login







      ``` ##### check.php ```php '', 'lisa' => '', 'admin' => 'e0NRta6G8WpOMOMK9qOC6O3z6F7cJcmA0r8GRPt4NeWcAUO4ED8Di' // Vaste hash van "wachtwoord" ]; $melding = ''; $gebruikersnaam = $_GET['gebruikersnaam']; $wachtwoord = $_GET['wachtwoord']; if (isset($gebruikers[$gebruikersnaam])) { if (password_verify($wachtwoord, $gebruikers[$gebruikersnaam])) { $melding = "✅ Ingelogd als $gebruikersnaam!"; } else { $melding = "❌ Fout wachtwoord."; } } else { $melding = "❌ Gebruiker bestaat niet."; } ?> ``` Als je de code begrijpt dan is de volgende opdracht niet moeilijk.
      **👉** Zorg ervoor dat de gebruikers **max** en **lisa** kunnen inloggen met de volgende wachtwoorden.
      **Gebruikersnaam****Wachtwoord**
      **max****top-secret123!**
      **llisa****sinclair1974**
      Probeer te ontdekken hoe je dit moet doen en hoe je de juiste wachtwoorden toe kan voegen. ### **👨‍💻** Hack-opdracht Ste je hebt de volgende code onderschept; ```php $gebruikers = [ 'max' => '$2y$10$AF4UcvDki/VEQKCUzHQxIudD9cYLRaF9v4GIkhTyTzWzxCN/Yo0q6', 'lisa' => '$2y$10$nWGSzTcP7TShCVwz78eNGO3LjoxR/FPR3WjZqxbodWHQUe/XEzZC.', 'admin' => '$2y$10$e0NRta6G8WpOMOMK9qOC6O3z6F7cJcmA0r8GRPt4NeWcAUO4ED8Di' ]; ``` Aan jouw de taak om de wachtwoorden te 'kraken'.
      Tip 1 Tip Het is niet mogelijk om de hash terug te rekenen vanuit de hash naar een wachtwoord.
      Tip 2 Tip 2Je kunt natuurlijk wel een wachtwoorden in een hash omzetten en kijken of de hash hetzelfde is.
      Tip 3 Lisa en Max hebben wachtwoorden die veel gebruikt worden en niet erg veilig zijn.
      **😀** Had je **geen tips** nodig, dan ben je een ***meester hacker***! ### 🧠 Reflectie - Waarom is het ***geen*** goed idee om wachtwoorden encrypted (versleuteld) op te slaan en waarom kun je beter hashing gebruiken? Leg uit wat er mis zou kunnen gaan als je encryptie gebruikt voor het opslaan van wachtwoorden. - Stel je hebt een bestand gekregen met allemaal userid's en wachtwoorden. De wachtwoorden zijn hashed. Leg uit hoe je mogelijk toch achter de wachtwoorden kan komen. ### 📤 Inleveren 1. aangepaste `check.php` 2. de antwoorden op de vragen uit de reflectie in pdf ## 5 Brute Force-aanvallen en Loginbeveiliging ### 🎯 Leerdoelen - Je weet wat een brute force-aanval is. - Je kunt een eenvoudige loginpagina maken in PHP. - Je begrijpt hoe je zo'n loginpagina kunt beveiligen tegen brute force-aanvallen. ### 💡 Uitleg #### Wat is een brute force-aanval? Bij een brute force-aanval probeert een aanvaller heel veel verschillende wachtwoorden achter elkaar uit om zo toegang te krijgen tot een account. Als er geen beperking zit op het aantal pogingen, kan dit op den duur succes hebben. #### Hoe bescherm je hiertegen? Je kunt brute force-aanvallen voorkomen door bijvoorbeeld: - Een limiet te stellen op het aantal pogingen - Een vertraging inbouwen bij het inloggen en deze laten groeien als je vaker een fout wachtwoord hebt ingevuld. - Tijdelijk een gebruiker of IP-adres te blokkeren (=black listing) - Van te voren alleen bepaalde ip adressen toelaten (=white listing) - Captcha toe te voegen - Twee-factor authenticatie toe te passen - Zet alle mislukte inlogpogingen in een logbestand. Deze laatste bescherming met logfile voorkomt niet zozeer dat er brute force aanvallen plaatsvinden, maar je kunt wel zien als er wat vreemds gebeurt. Je kan dan op dat moment (extra) maatregelen nemen. #### Wachtwoord lengte Een wachtwoord bestaat over het algemeen uit hoofdletter, gewonen letters, cijfers en een aantal spciale karakters. In totaal zijn dat ongeveel 70 tekens. Dat beteketn dat je 70 verschillende wachtwoorden kan maken, bij een wachtwoord lengte van 2 is dit 4 900 verschillende wachtwoorden. Dti aantal loopt snel op:
      wachtwoord lengteaantal mogelijkheden
      170
      24 900
      3343 000
      424 010 000
      51 680 700 000
      6117 649 000 000
      Dit lijkt heel veel maar met één snelle computer met een snelle GPU kan je 10 miljard wachtwoorden per seconden testen. Een wachtwoord van 6 posities heb je dan dus binnen ongeveer 10 seconden gekraakt.
      Hoe lang moet mijn wachtwoord dan zijn, is 10 posities voldoende? ##### Jouw wachtwoord veiligheid hangt af van: - de gebruikte encypty of hashing (bijvoorbeeld SHA256) - welke hardware kan je gebruiken om te hacken (via cloudcomputing kan je 1000-den snelle GPU's inztten). ##### Voorbeeld: - Je gebruikt de wat verouderde **SHA256** hashing. - Je gebruikt **10** hele snelle GPU's (NVidia **RTX4080**) Rekentijd ongeveer **16 dagen** 😲Bedrijven als **OpenAI, Microsoft, Amazon** of **Google** hebben zoveel rekenkracht dat ze jouw wachtwoord van 10 tekens binnen 20 seconden met brute force *zouden kunnen* kraken. Ga je naar een wacthwoord van **12 tekens**, dan loopt dit zelfs voor deze bedrijven al snel op naar een **2 tot 3 jaar.**
      ### 🛠️ Opdracht #### Maak een eenvoudige loginpagina Maak een bestand `login.php` met het volgende formulier: ```html
      Gebruikersnaam:
      Wachtwoord:
      ``` Maak daarna een eenvoudige `inlogcontrole.php `in PHP: ```php = 3) { die("Te veel pogingen. Probeer het later opnieuw."); } if ($_GET) { if ($_GET['username'] === $gebruikersnaam && $_GET['password'] === $wachtwoord) { echo "Welkom!"; $_SESSION['pogingen'] = 0; } else { echo "Foutieve inlog."; $_SESSION['pogingen']++; } } ?> ``` In het form wordt $\_GET gebruikt, is dat handig? Vanuit het oogpunt van cyber security is het beter om $\_POST te gebruiken. Weet je nog waarom? ##### Aanpassingen - Verander het formulier en de vervolgpagina zodat je geen post meer gebruikt en zodat het user id en wachtwoord niet meer in de URL staan. - Voeg een vertraging toe met `sleep(1)` bij een mislukte poging. - Voeg logging toe aan een tekstbestand zodat je pogingen kunt terugzien. ##### Extra uitdaging - Als je bijhoud hoevaak een gebruiker probeert in te loggen (met een sessie variabele), dan kan je de tijd tussen twee pogingen laten groeien: de eerste keer moet je 1 seconden wachten, dan 2 dan 4 dan 8 dan 16, etc. etc. Kan jij dat implementeren? ### 🧠 Reflectie - Waarom is het belangrijk om een limiet te stellen op het aantal inlogpogingen? - Wat gebeurt er als je de sessiegegevens wist of in een andere browser werkt? - Welke nadelen heeft deze eenvoudige beveiliging? ### 📤 Inleveren - De aangepaste code `inlogcontrole.php ` - Reflectie met antwoorden op bovenstaande vragen in pdf. ## 6 Rainbow tables ### 🎯 Leerdoelen - Je begrijpt wat een rainbow table is en waarom het gevaarlijk is bij wachtwoordbeveiliging. - Je kunt handmatig een wachtwoord opzoeken in een rainbow table. - Je snapt waarom salting rainbow tables onbruikbaar maakt. Menses gebruiken vaak 'standaard' wachtwoorden.
      Wat denk jij dat het meest gebruikte wachtwoord is? Er zijn [sites](https://nordpass.com/most-common-passwords-list/?utm_source=chatgpt.com) waarom de meest gebruikte wachtwoorden staan. 👉 Ga naar de site van [Nordpass](https://nordpass.com/most-common-passwords-list/?utm_source=chatgpt.com) en controleer of jouw antwoord klopt.
      ### 💡 Uitleg: Wat is een rainbow table? Een **rainbow table** is een lijst van veelgebruikte wachtwoorden met hun bijbehorende hashes. Aanvallers gebruiken dit om snel te achterhalen welk wachtwoord hoort bij een bepaalde hash. Stel: iemand vindt een lijst met gebruikersnamen en gehashte wachtwoorden. Als jouw wachtwoord in zo'n rainbow table staat, kan die hash direct worden terugvertaald naar het originele wachtwoord – zonder te hoeven raden. #### Waarom werken rainbow tables? - Hash-algoritmes zoals SHA256 geven altijd dezelfde output voor dezelfde input. - Veel mensen gebruiken zwakke, veelvoorkomende wachtwoorden. #### Starters code Deze code vraag om een wachtwoord te resetten. Het wachtwoord wordt in JSON bestand opgeslagen. Controleer of de code werkt en controleer of het wachtwoord wordt opgeslagen in `gebruikers.json .` ```php Wachtwoord succesvol opgeslagen voor gebruiker $userid.

      "; echo "

      SHA256 hash: $hashed

      "; exit; } ?> Wachtwoord resetten

      Reset je wachtwoord







      ``` ### **👨‍💻** Hack-opdracht
      200 meest voorkomende wachtwoorden (internationaal) 123456 123456789 12345 qwerty password 12345678 111111 123123 1234567890 1234567 qwerty123 000000 1q2w3e aa12345678 abc123 password1 1234 qwertyuiop 123321 password123 1qaz2wsx iloveyou admin qazwsx 123qwe 123abc 654321 666666 superman 112233 1q2w3e4r asdfghjkl zxcvbnm 121212 1qazxsw2 letmein trustno1 hello 888888 football monkey !@#$%^&\* charlie batman 696969 hottie flower loveme donald login pokemon starwars jordan dragon michael shadow master killer maggie biteme qwerty1 freedom whatever cheese pepper princess jennifer michelle tigger hunter sunshine ashley michael1 lovely qwe123 777777 ginger cookie welcome taylor summer soccer test asdf internet google qweasd merlin mustang baseball hannah snoopy thomas mypass computer daniel jessica pepper123 pass 6969 1111 999999 88888888 444444 222222 555555 333333 7777777 0000 1212 1004 2000 abcd1234 1989 1987 1979 1978 q1w2e3r4 zxcvbn a1b2c3 azerty passw0rd 123123123 147258 1g2w3e4r 1a2b3c4d 2580 qazxsw 987654321 password! hunter2 11111111 131313 159753 a123456 abc123456 myspace1 9999 147147 aaaaaa zaq12wsx q1w2e3 8888 iloveyou1 killer123 qwe123456 123456a abcdef asdasd poop zxcvbn123 dragon123 trustno1! abcd 12344321 password01 987654 test123 cool 123123a internet123 letmein123 master123 welcome1 football1 qwert batman123 super123 77777777 5555 ninja tinkle red123 star123 hello123 pass123 admin123 1password love123 66666666 mypass123 superman123 samsung qwerty12 asdfgh admin1 loveyou pokemon123 iloveu justin asdf1234 hottie123 shadow123 hannah123 sunshine1 admin@123
      1. Vraag een mede-student een wachtwoord uit de lijst van 200 meest voorkomende wachtwoorden te kiezen (lijst staat hier boven). 2. Vraag de student dit wachtwoord in te vullen op jouw Lappie met de "starters code" die je net hebt getest. 3. Laat de mede-student zien dat je het JSON bestand kan lezen en dat je dus zijn hashed wachtwoord kan leven. 4. Hoe kom je er nu achter welke wachtwoord jouw mede-student heeft gebruikt? 5. Precies: je maakt code die alle 200 wachtwoorden hashed en je vergelijkt de gevonden hashes met de hash van je mede student. ### 🛠️ Opdracht: Vind het wachtwoord Maak een "mini-rainbow table" van de 200 meest voorkomende wachtwoorden en bepaal welk wachtwoord jouw mede-student had ingevoerd. ##### Have I been Powned Op [https://haveibeenpwned.com/Passwords](https://haveibeenpwned.com/Passwords) staat een hele groot bestand met gehashte wachtwoorden. Deze lijst is ook bekend bij hackers en als die een hashed wachtwoord hebben kunnen ze deze opzoeken in deze database en jouw wachtwoord achterhalen. De lijst bevat alle hashed wachtwoorden die ooit een keer zijn 'gevonden', bijvoorbeeld in een database die is gehacked. ### 🧠 Reflectie - Wat maakt rainbow tables zo gevaarlijk? - Wat zou er gebeuren als we bij elk wachtwoord een andere salt toevoegen? - Hoe helpt salting om rainbow tables tegen te gaan? ### 📤 Inleveren - Een kort verslag met de gevonden wachtwoorden. - Een antwoord op de reflectievragen in PDF. ## 7 Salting en encryptie ### 🎯 Leerdoelen - Je begrijpt wat een **salt** is en waarom het wordt gebruikt bij hashing van wachtwoorden. - Je kunt zelf code schrijven om te demonstreren hoe salting werkt. - Je kunt uitleggen hoe je een wachtwoord controleert dat is gehasht met een salt. ### ⁉️Waarom Salt Salting is een beveiligingstechniek die je kan toepassen bij het opslaan van wachtwoorden, omdat het je systeem **v**eel beter beschermt tegen aanvallen zoals **rainbow table-aanvallen**. ### 💡 Uitleg: Wat is een salt? Een **salt** is een extra stukje tekst dat je aan een wachtwoord toevoegt voordat je het versleutelt (hasht). Daardoor ziet het wachtwoord er elke keer anders uit, zelfs als iemand hetzelfde wachtwoord gebruikt. Stel: zonder salt geeft het wachtwoord `geheim123` altijd dezelfde hash. Met een salt (bijv. `!x8Zp#`) wordt het `!x8Zp#geheim123` en krijg je een andere hash. 📌 In dit voorbeeld gebruiken we één vaste salt voor alle wachtwoorden, om het idee simpel te houden. #### Waarom is salting belangrijk? - Het maakt het moeilijker om gehashte wachtwoorden terug te vinden met voorgeprogrammeerde lijsten (rainbow tables). - Het maakt brute force-aanvallen minder effectief.
      🧂 Waarom heet het “salt”? ##### Stel je voor Je hebt een bord rijst (= het wachtwoord). Als iedereen precies dezelfde rijst krijgt, smaakt het bij iedereen hetzelfde. Maar als jij er wat zout aan toevoegt, wordt het uniek. Hetzelfde gebeurt met wachtwoorden: - Zonder “salt” = iedereen met hetzelfde wachtwoord krijgt **dezelfde hash**. - Met “salt” = elk wachtwoord krijgt **een eigen smaak** (een unieke hash), zelfs als het wachtwoord hetzelfde is. ##### **🔒 In de techniek** Het **“zout”** is een willekeurig extra stukje tekst dat je toevoegt aan het wachtwoord voordat je het versleutelt of “hasht”. ```php $salt = "x!9f3L"; $wachtwoord = "123456"; $hash = hash('sha256', $salt . $wachtwoord); ```
      ### 🛠️ Opdracht: Hashen met één vaste salt Schrijf een klein PHP-script dat laat zien hoe salting werkt. ```php $wachtwoord = "geheim123"; $salt = "ROCAmstelland"; // vaste salt voor alle wachtwoorden $hash = hash("sha256", $salt . $wachtwoord); echo "Wachtwoord: $wachtwoord\n"; echo "Hash: $hash\n"; ``` #### Controle bij inloggen Als iemand probeert in te loggen, moet je het ingevoerde wachtwoord opnieuw hashen met dezelfde salt en vergelijken met de opgeslagen hash. ```php $ingevoerd = "geheim123"; $bekende_hash = .......; // aanvullen $salt = "ROCAmstelland"; // vul deze regel code aan zodat de hash wordt gecontroleerd. $controle_hash = ...... if ($controle_hash === $bekende_hash) { echo "✅ Ingelogd"; } else { echo "❌ Fout wachtwoord"; } ``` 1. Bereken met de eerste code de hash van het wachtwoord geheim123 2. Plaats de hash dan in de 2de code ($bekende\_hash) en vul regel 6 aan zodat de hash wordt gecontroleerd. ### 🧠 Reflectie - Waarom is het veiliger om een salt toe te voegen? - Wat zou nog veiliger zijn dan één vaste salt voor iedereen? - Stel je wil hacken met behulp van Rainbow tables en je weet welke salt er is gebruikt, wat moet je dan doen? - In de (laatste) opgave maken we gebruik van een vaste salt waarde. Denk je dat je de beveilig kan verbeteren door een ander salt waarde te kiezen? Zo ja welke en waaorm, leg uit in eigen woorden. ### 📤 Inleveren 1. Je PHP-script waarin je laat zien hoe je een wachtwoord hasht met een salt en controleert bij inloggen. 2. Een PDF met de antwoorden op de reflectievragen. ## **📊**Test je kennis #### Hoofdstuk 1: Wat is Cyber Security? 1\. Wat is de primaire focus van Cyber Security? - a) Het beschermen van websites tegen computer-bugs - b) Het beschermen van computersystemen tegen aanvallen en misbruik. - c) Het ontwikkelen van nieuwe softwareprogramma's. - d) Het beheren van netwerkinfrastructuur.
      ✅ Antwoord b) Het beschermen van computersystemen tegen aanvallen en misbruik.
      2\. Welke van de volgende cyberaanvallen omvat het misleiden van iemand om wachtwoorden af te geven, vaak via nep-e-mails? - a) Malware - b) DDoS-aanval - c) Phishing - d) SQL-injection
      ✅ Antwoord c) Phishing
      Welke term wordt gebruikt voor software die ontworpen is om ongevraagd advertenties te tonen en je naar bepaalde webwinkels stuurt? - a) Adware - b) Spam - c) Malware - d) Commerceware
      ✅ Antwoord c) Adware
      Welke vorm van malware kan zichzelf verspreiden naar andere bestanden of programma's zodra het op een computer is geïnstalleerd? - a) Worm - b) Spyware - c) Virus - d) Adware
      ✅ Antwoord c) Virus
      #### Hoofdstuk 2: HTTPS en netwerkveiligheid 3\. Wat is het belangrijkste verschil tussen HTTP en HTTPS? - a) HTTPS is alleen voor professionele websites, HTTP voor persoonlijke. - b) HTTPS staat voor HyperText Transfer Protocol Secure en versleutelt de communicatie tussen browser en server. - c) HTTP is sneller dan HTTPS. - d) HTTP gebruikt een SSL-certificaat, HTTPS niet.
      ✅ Antwoord b) HTTPS staat voor HyperText Transfer Protocol Secure en versleutelt de communicatie tussen browser en server.
      4\. Waarvoor biedt HTTPS geen bescherming? - a) Het onderscheppen van ingevulde wachtwoorden door derden. - b) Het veranderen van informatie terwijl deze onderweg is. - c) Het downloaden van virussen of malware. - d) Verbinding maken met de echte website in plaats van een nepserver.
      ✅ Antwoord c) Het downloaden van virussen of malware.
      #### Hoofdstuk 3: Encryptie 5\. Wat is de definitie van encryptie? - a) Het proces van het verbergen van bestanden op een computer. - b) Het omzetten van gegevens zodat ze onleesbaar zijn voor onbevoegden, tenzij men de juiste ‘sleutel’ heeft. - c) Het back-uppen van gegevens naar een externe schijf. - d) Het controleren van de integriteit van gegevens.
      ✅ Antwoord b) Het omzetten van gegevens zodat ze onleesbaar zijn voor onbevoegden, tenzij men de juiste ‘sleutel’ heeft.
      6\. Welk type encryptie gebruikt dezelfde sleutel voor zowel versleuteling als ontsleuteling? - a) Asymmetrische encryptie - b) Hash-encryptie - c) Symmetrische encryptie - d) Kwantumencryptie
      ✅ Antwoord c) Symmetrische encryptie
      #### Hoofdstuk 4: Hashing 7\. Waarom wordt hashing vaak gebruikt voor het opslaan van wachtwoorden? - a) Omdat de wachtwoorden dan eenvoudig terug te rekenen zijn voor de gebruiker. - b) Omdat het een eenrichtingsversleuteling is die niet terug te rekenen is naar het origineel. - c) Omdat het wachtwoorden comprimeert om opslagruimte te besparen. - d) Omdat het helpt bij het snel ophalen van verloren wachtwoorden.
      ✅ Antwoord b) Omdat het een eenrichtingsversleuteling is die niet terug te rekenen is naar het origineel.
      8\. Hoe controleert een systeem een ingevoerd wachtwoord als het opgeslagen wachtwoord gehasht is? - a) Het systeem probeert de opgeslagen hash terug te rekenen naar het originele wachtwoord. - b) Het systeem stuurt een resetlink naar het e-mailadres van de gebruiker. - c) Het systeem zet het ingevoerde wachtwoord om met de hash-functie en vergelijkt het resultaat met de opgeslagen hash. - d) Het systeem vraagt de gebruiker om een tweede authenticatiefactor.
      ✅ Antwoord c) Het systeem zet het ingevoerde wachtwoord om met de hash-functie en vergelijkt het resultaat met de opgeslagen hash.
      #### Hoofdstuk 5: Brute Force-aanvallen en Loginbeveiliging 9\. Wat is een brute force-aanval? - a) Een aanval waarbij een server wordt overspoeld met aanvragen. - b) Een aanval waarbij kwaadaardige software op een systeem wordt geïnstalleerd. - c) Een aanval waarbij systematisch heel veel verschillende wachtwoorden worden geprobeerd om toegang te krijgen. - d) Een aanval waarbij via een formulier een database wordt gehackt.
      ✅ Antwoord c) Een aanval waarbij systematisch heel veel verschillende wachtwoorden worden geprobeerd om toegang te krijgen.
      10\. Welke van de volgende is ***geen*** methode om brute force-aanvallen te voorkomen? - a) Een limiet stellen op het aantal pogingen. - b) Tijdelijk een gebruiker of IP-adres blokkeren. - c) Twee-factor authenticatie toepassen. - d) Het gebruik van $\_GET voor het versturen van inloggegevens.
      ✅ Antwoord d) Het gebruik van $\_GET voor het versturen van inloggegevens.
      #### Hoofdstuk 6: Rainbow tables 11\. Wat is een rainbow table? - a) Een lijst van alle mogelijke wachtwoorden. - b) Een database van gehackte IP-adressen. - c) Een lijst van veelgebruikte wachtwoorden met hun bijbehorende hashes. - d) Een hulpmiddel om SSL-certificaten te genereren.
      ✅ Antwoord c) Een lijst van veelgebruikte wachtwoorden met hun bijbehorende hashes.
      12\. Waarom zijn rainbow tables gevaarlijk voor wachtwoordbeveiliging? - a) Ze zorgen ervoor dat servers overbelast raken. - b) Ze maken het mogelijk om gehashte wachtwoorden snel terug te vertalen naar het origineel als het wachtwoord in de tabel staat. - c) Ze installeren malware op het systeem van de gebruiker. - d) Ze versleutelen de communicatie tussen de gebruiker en de website.
      ✅ Antwoord b) Ze maken het mogelijk om gehashte wachtwoorden snel terug te vertalen naar het origineel als het wachtwoord in de tabel staat.
      #### Hoofdstuk 7: Salting en encryptie 13\. Wat is het hoofddoel van 'salting' bij het hashen van wachtwoorden? - a) Om het hash-algoritme complexer te maken. - b) Om ervoor te zorgen dat hetzelfde wachtwoord elke keer een unieke hash krijgt, wat rainbow tables minder effectief maakt. - c) Om de snelheid van het hashen te verhogen. - d) Om te controleren of een wachtwoord sterk genoeg is.
      ✅ Antwoord b) Om ervoor te zorgen dat hetzelfde wachtwoord elke keer een unieke hash krijgt, wat rainbow tables minder effectief maakt.
      14\. Hoe wordt een gehasht wachtwoord met een 'salt' gecontroleerd bij het inloggen? - a) Het systeem probeert de opgeslagen hash te ontsleutelen met de salt. - b) Het ingevoerde wachtwoord wordt gehasht zonder de salt en vergeleken met de opgeslagen hash. - c) Het ingevoerde wachtwoord wordt opnieuw gehasht samen met dezelfde opgeslagen salt, en het resultaat wordt vergeleken met de opgeslagen hash. - d) De gebruiker wordt gevraagd om de salt handmatig in te voeren. # OOP ## 1 Wat is OOP en waarom gebruiken we het? ### 🎯 Leerdoelen - Je begrijpt het verschil tussen procedureel programmeren en OOP. - Je weet wat een class, object en method zijn. - Je kunt herkennen wanneer OOP handig is in grotere projecten. ### 💡 Uitleg #### Wat is OOP? OOP staat voor **Objectgeoriënteerd programmeren** (object geörienteerd programmeren). In plaats van losse functies en variabelen, werk je met objecten die gedrag (via classes) en gegevens (properties) combineren. #### Waarom OOP gebruiken? - Je kunt code beter organiseren en hergebruiken. - Je maakt je programma makkelijker uitbreidbaar. - Je kunt complexe systemen opdelen in logische blokken (objecten). #### Voorbeeld: procedureel vs OOP **Procedureel:** ```php ``` **Objectgeoriënteerd:** ```php naam; } } $tessa = new Persoon(); $tessa->naam = "Tessa"; $tessa->leeftijd = 19; $tessa->begroet(); ?> ``` 👉 Je ziet hier dat de funvtie en de variabelen in één blok (class) staan. We gebruiken bij OOP soms vreemde termen:
      ProcedureelOOP
      variabele**property** (van een class)
      functie**method**
      ### 🛠️ Opdracht – Van procedureel naar objectgeoriënteerd Je gaat een simpel PHP-script omzetten naar OOP. 1. Maak een bestand `mijn-procedureel.php` en schrijf de volgende code: ```php ``` 2. Maak nu een tweede bestand: `mijn-oop.php` en herschrijf dit script in OOP-stijl: ```php merk = "Toyota"; $auto->bouwjaar = 2018; $auto->toon(); ?> ``` ### 🧠 Reflectie - Wat vond je makkelijker: de procedurele of de OOP-versie? - Waarom denk je dat OOP belangrijk is bij grotere projecten? ### 📤 Inleveren - Lever beide bestanden in: `mijn-procedureel.php` en `mijn-oop.php` - Maak een kort reflectiebestand: `reflectie-les1-.txt` - Let op: je code moet uitvoerbaar zijn in de browser (via XAMPP of localhost). ## 2 Classes en objects ### 🎯 Leerdoelen - Je weet wat een class en een object zijn. - Je kunt een eenvoudige class maken in PHP. - Je kunt een object aanmaken op basis van die class en ermee werken. ### 💡 Uitleg #### Wat is een class? Een class is een soort blauwdruk of bouwtekening. Je beschrijft hiermee hoe een bepaald type object eruitziet en wat het kan doen. #### Wat is een object? Een object is een concreet exemplaar van een class. Je maakt een object aan met `new`. Een class kun je meerdere keren gebruiken om verschillende objecten te maken. Class, Object, Properties en Methods worden nog een keer duidelijk gemaakt in: [https://slides.com/jamescandan/oop-php-for-beginners-1-2/fullscreen#/5](https://slides.com/jamescandan/oop-php-for-beginners-1-2/fullscreen#/5) Dus een class is een sjabloon van een object en met het commando `new ` maken we een nieuw object van de sjabloon. In een class heten de variabelen **properties** en de fucnties heten **methods**. #### Voorbeeld: ```php naam; } } $mijnHond = new Hond(); $mijnHond->naam = "Rex"; $mijnHond->leeftijd = 3; $mijnHond->blaf(); $jouwHond = new Hond(); $jouwHond->naam = "Sip"; $jouwHond->leeftijd = 5; $jouwHond->blaf(); ?> ``` 👉Je hebt **één class**, maar je hebt **twee objecten** (honden) van deze class: `$mijnHond` en `$jouwHond` ### 🛠️ Opdracht – Maak je eigen class 1. Maak een nieuw bestand: `mijn-klas.php` 2. Maak hierin een class `Student` met de eigenschappen `voornaam`, `achternaam` en `opleiding`. 3. Maak een methode `stelVoor()` die zegt: "Hallo, ik ben \[voornaam\] \[achternaam\] en ik doe de opleiding \[opleiding\]." 4. Maak **drie** objecten (`$student01`, `$student02`, en` $student03`) van de class en test het resultaat in je browser. ### 🧠 Reflectie - Wat viel je op bij het maken van een object? - Wat gebeurt er als je een properties (voornaam, achternaam en opleiding) **niet** vult voor je `stelVoor()` gebruikt? ### 📤 Inleveren - Bestandsnaam: `mijn-klas.php` - Reflectievragen in een apart txt- of PDF-bestand. ## 3 Constructors en eigenschappen ### 🎯 Leerdoelen - Je weet wat een constructor is in een class. - Je kunt automatisch waarden toekennen bij het maken van een object. - Je begrijpt het verschil tussen eigenschappen (properties) en methoden. ### 💡 Uitleg #### Wat is een constructor? Een constructor is een speciale methode die automatisch wordt uitgevoerd als je een object maakt. In PHP heet deze methode `__construct()`. #### Waarom handig? Met een constructor hoef je niet handmatig eigenschappen toe te wijzen nadat je een object hebt aangemaakt. #### Voorbeeld zonder constructor: ```php merk = "Toyota"; $auto->bouwjaar = 2018; ?> ``` #### Voorbeeld met constructor: ```php merk = $merk; $this->bouwjaar = $bouwjaar; } } $auto = new Auto("Toyota", 2018); ?> ``` ### 🛠️ Opdracht – Constructor gebruiken 1. Maak een nieuw bestand: `les3-student.php` 2. Maak opnieuw een class `Student` met eigenschappen: `voornaam`, `achternaam` en `opleiding`. 3. Voeg een constructor toe waarin deze waarden worden ingesteld. 4. Maak een methode `stelVoor()` die de gegevens netjes toont. 5. Maak minstens twee objecten aan en laat de `stelVoor()`-methode zien in de browser. ### 🧠 Reflectie - Wat is het voordeel van een constructor ten opzichte van handmatige toekenning? - Wat gebeurt er als je het aantal parameters niet goed doorgeeft? - Wat betekent `$this->...` in de constructor? ### 📤 Inleveren - Bestandsnaam: `les3-student.php` - Reflectievragen in een apart bestand: `reflectie-les3-.txt` ## 4 Methoden met parameters en returnwaardes ### 🎯 Leerdoelen - Je begrijpt hoe je een methode maakt die parameters accepteert. - Je kunt een methode schrijven die een waarde teruggeeft met `return`. - Je ziet hoe objectmethoden kunnen samenwerken met parameters uit de code. ### 💡 Uitleg #### Wat is een parameter? Een parameter is een waarde die je doorgeeft aan een methode, zodat deze methode die waarde kan gebruiken in de berekening of actie. #### Wat is een returnwaarde? Met `return` geef je een resultaat terug uit een methode, zodat je dat resultaat ergens anders kunt gebruiken. #### Voorbeeld: ```php stort(50); echo "Je saldo is: ". $mijnRekening->toonSaldo(); ?> ``` ### 🛠️ Opdracht – Werk met parameters en return 1. Maak een nieuw bestand: `les4-rekening.php` 2. Maak een class `Rekening` met een startsaldo van 0. 3. Voeg een methode `stort($bedrag)` toe die het bedrag bij het saldo optelt. 💡Tip: vegeet niet` $this->` te gebruiken! 4. Voeg een methode `opname($bedrag)` toe die het bedrag van het saldo afhaalt. 5. Voeg een methode `toonSaldo()` toe die het saldo teruggeeft met `return`. 6. Test de class met een **paar stortingen** en **paar** opnames. Toon aan dat: - dat stortingen het saldo verhogen - dat opnames het saldo verlagen - dat een te hoge opname het saldo niet verandert Probeer het zonder code, maar kom je er niet uit dan kun je deze code als template gebruiken .
      Template ```php echo ""; $rekening = new Rekening(); // Test 1: stort 50 // ....... echo "Test 1: verwacht 50 → resultaat: "...... // Test 2: opname van 20 // ...... echo "Test 2: verwacht 30 → resultaat: " ........ // Test 3: opname van 100 (te veel) ....... echo "Test 3: verwacht nog steeds 30 → resultaat: " ........ echo ""; ```
      ### 🧠 Reflectie - Wat gebeurt er als je een opname doet die groter is dan je saldo? - Waarom heeft de constructor in de class Rekening in het voorbeeld geen parameter (om het saldo op 0 te zetten)? - Wat zijn de voordelen van werken met `return`? ### 📤 Inleveren - Bestandsnaam: `les4-rekening.php` - Reflectievragen in een apart bestand: `reflectie-les4-.txt` ## 5 Checkpoint: Wat heb je geleerd? ### 🚦Samenvatting 1. **Classes & Objects** - Je kent het verschil tussen een class (blauwdruk) en een object (instantie). - Je weet hoe je met `new` een object maakt. 2. **Properties & Methods** - Je gebruikt `public` properties om data in een object op te slaan. - Je roept methods aan met parameters (`method($param)`) en begrijpt wat een returnwaarde is. 3. **Constructors** - Je kunt een `__construct()` schrijven om bij creatie van een object meteen eigenschappen in te stellen. - Je weet dat `$this->…` verwijst naar de huidige instantie. 4. **Encapsulation Basics** - Je begrijpt waarom je data soms `private` maakt en via getters/setters benadert. > **Tip:** Ga kort na of je in je eigen voorbeelden bovenstaande concepten herkent en toepast voordat je verdergaat naar encapsulation en private properties in Les 5. ### 🛠️ Opdracht Maak van elk van de vier genoemde onderwerpen een mulitple choice vraag, met 3 foute en één goed antwoord. Als de vragen goed zijn dan zullen ze terug komen in de kennis-check. ##### Voorbeeld/template ``` Vraag: Wat is een object? A: Dat is een variabele in een class. B: Dat is een instantie van een class. C: Dat is een functie in een class D: Dat is een data-structuur in PHP. Juiste antwoord is B Vraag: A: B: C: D: Juiste antwoord is: Vraag: A: B: C: D: Juiste antwoord is: Vraag: A: B: C: D: Juiste antwoord is: Vraag: A: B: C: D: Juiste antwoord is: ``` ### 📤 Inleveren De vier mulitple choice vragen in txt bestand. ## 6 Encapsulation en private properties ### 🎯 Leerdoelen - Je weet wat encapsulation is. - Je begrijpt het verschil tussen `public` en `private`. - Je kunt `getters` en `setters` gebruiken om toegang tot eigenschappen te regelen. ### 💡 Uitleg Encapsulation betekent dat je data (properties van een class) beschermt tegen direct aanpassen van buiten de class. In plaats daarvan gebruik je methods om de data op een gecontroleerde manier te bekijken of aan te passen. #### Waarom gebruiken? Zo voorkom je fouten doordat andere delen van je code zomaar eigenschappen aanpassen zonder controle. #### Voorbeeld: ```php 0) { $this->saldo += $bedrag; } } public function getSaldo() { return $this->saldo; } } $rekening = new Bankrekening(); $rekening->stort(100); echo "Saldo: ".$rekening->getSaldo(); ?> ``` ### 🛠️ Opdracht – Bescherm je data 1. Maak een nieuw bestand: `les5-bankrekening.php` 2. Maak een class `Bankrekening` met een `private` eigenschap `$saldo`. 3. Maak een `stort()`-methode die alleen positief bedrag accepteert. 4. Maak een `getSaldo()`-methode die het saldo teruggeeft. 5. Test de class met verschillende stortingen en probeer ook een negatieve storting (die moet worden geweigerd). 6. Maak nu een `opnemen($bedrag)` waarmee je geld kan opnemen. Zorg ervoor dat je alleen geld kan opnemen als je voldoende saldo hebt. Heb je dat niet, dan vind er geen opname plaats. 7. Test de method opname($bedrag) uit! ### 🧠 Reflectie - Wat is het verschil tussen `public` en `private`? - Waarom zou je eigenschappen `private` maken? - Wat gebeurt er als je probeert `$saldo` direct aan te passen: `$rekening->saldo = 1000;` Wat zie je? En hoe verklaar je dat? ### 📤 Inleveren - Bestandsnaam: `les5-bankrekening.php` - Reflectievragen in pdf. ## 7 Bibliotheeksysteem met Twee Classes ### 🎯 Leerdoelen - Je maakt en gebruikt meerdere classes in één project. - Je begrijpt hoe objecten van verschillende classes met elkaar communiceren. - Je oefent met private properties, getters/setters en method-parameters. - Je bouwt een klein functioneel systeem met relaties tussen objecten. ### 💡 Uitleg In dit mini-project bouw je een eenvoudig bibliotheeksysteem met slechts twee classes: 1. **Book**: een boek met een titel, auteur en beschikbaarheidsstatus. 2. **Library**: beheert een collectie boeken en wie ze geleend heeft. --- ### 🛠️ Opdracht – Bouw je eigen bibliotheek #### Book Class Book.php bevat de **class Book** waarmee je het object book kan maken. Een boek heeft een **title,** een **author** en een **available (beschikbaarheid)**. De class bevat **getters** en **setters** om deze properties te lezen en aan te passen.
      book.php ```php title = $title; $this->author = $author; } public function getTitle(): string { return $this->title; } public function getAuthor(): string { return $this->author; } public function isAvailable(): bool { return $this->available; } public function setAvailable(bool $avail): void { $this->available = $avail; } } ?> ```
      #### Library Class De **class Library** maakt gebruik van de class Book. Deze class kan boeken **toevoegen** aan de library, kan boeken **uitlenen** en boeken weer **terugnemen**. Als laatst is er een method waarmee je alle boeken uit de library kan tonen.
      library.php ```php books[$book->getTitle()] = $book; } public function lendBook(string $title, string $member): string { // Bestaat het boek? if (!isset($this->books[$title])) { return "Boek “{$title}” bestaat niet.\n"; } $book = $this->books[$title]; // Is het al uitgeleend? if (!$book->isAvailable()) { return "Boek “{$title}” is al uitgeleend.\n"; } // Leen uit $book->setAvailable(false); $this->loans[$title] = $member; return "{$member} leent “{$title}”.\n"; } public function returnBook(string $title): string { // Bestaat het boek? if (!isset($this->books[$title])) { return "Boek “{$title}” bestaat niet.\n"; } // Was het uitgeleend? if (!isset($this->loans[$title])) { return "Boek “{$title}” was niet uitgeleend.\n"; } // Verwerk retour $member = $this->loans[$title]; unset($this->loans[$title]); $this->books[$title]->setAvailable(true); return "{$member} brengt “{$title}” terug.\n"; } public function listBooks(): string { $output = ''; foreach ($this->books as $book) { if ($book->isAvailable()) { $status = 'beschikbaar'; } else { $status = 'uitgeleend aan ' . $this->loans[$book->getTitle()]; } $output .= $book->getTitle() . ' – ' . $status . "\n"; } return $output; } } ```
      #### Main code In de main code wordt de class library gebruikt om boeken in de library te zetten en uit te lenen of terug te nemen. Met deze code wordt de library- en book class getest. Kijk goed wat er gebeurt en probeer het te begrijpen.
      main.php ```php addBook(new Book('1984', 'George Orwell')); $lib->addBook(new Book('De Avonden', 'Gerard Reve')); echo "Leen boek 1884 uit aan Alice
      resultaat: "; echo $lib->lendBook('1984', 'Alice'); echo "
      "; echo "Leen boek 1884 uit aan Bob
      resultaat: "; echo $lib->lendBook('1984', 'Bob'); // Alice heeft het nog echo "
      "; echo "Laat alle Boeken zien
      resultaat: "; echo $lib->listBooks(); echo "
      "; echo "Boek 1984 wordt tgeruggebracht
      resultaat: "; echo $lib->returnBook('1984'); echo "
      "; echo "Leen boek 1884 uit aan Bob
      resultaat: "; echo $lib->lendBook('1984', 'Bob'); // nu kan Bob lenen echo "
      "; echo "Laat alle Boeken zien
      resultaat: "; echo $lib->listBooks(); echo "
      "; echo '' ?> ```
      #### Overzicht
      **Opdracht:** draai dit script in je browser en verifieer de uitvoer.
      Hier zie je een eenvoudige UML-class-diagram die laat zien hoe de class Library en de class Book met elkaar communiceren **![image.png](https://www.roc.ovh/uploads/images/gallery/2025-06/scaled-1680-/rrMimage.png)** - **Library** - Bevat een collectie (`books`) van `Book`-objecten. - Methoden zoals `addBook()`, `lendBook()`, `returnBook()` en `listBooks()` gebruiken de `Book`-objecten. - **Book** - Heeft private eigenschappen: `title`, `author`, `available` (en eventueel `loansCount`). - Biedt publieke getters (`getTitle()`, `isAvailable()`) en een setter (`setAvailable()`) om zijn status te wijzigen. De pijlen geven aan dat de `Library` klas methoden aanroept op de `Book` objecten, bijvoorbeeld bij het uitlenen (zetten `available` op `false`) en het terugbrengen (zetten `available` op `true`). Zo zie je visueel hoe de objecten samenwerken binnen het systeem.
      ### 🛠️ Opdracht Van elk boek wi je bijhouden hoevaak ht is uitgeleend. 1. Voeg een property toe aan de class Book en nome die `$aantalKeerUitgeleend`. 2. Verhoog de property als een boek wordt uitgeleend met 1. 3. Voeg een method `getUileenData()` toe in de class Book en laat deze van elk boek, de titel, auteur en het aantal keer dat dit boek is uitgeleend zien. 4. Test dit via de code in mainn.php, 1984 is al twee maal uitgeleend, maak nog een derde boek en leen dat ook één maal uit. Aan het iend hebben we dus drie boeken: één boek is nooit uitgleend, één boek is 1x uitgeleend en één boek is twee maal uitgleend. ## 🧠 Reflectie 1. Wat doet de `foreach loop` in de method `listBooks()` ? 2. Waarom is `$author` private in **Book** en kan je de $author van een Book wijzigen? 3. In de key van `$books` uit de class `Library `staat de *titel van het boek*, wat staat er in de *value*? 4. Beschijf wat er in de *key* en de *value* staat van de $loans uit de class Library. ## 📤 Inleveren 1. De aangepast class Book (book.php). 2. De aangepaste main.php 3. Antwoord op de reflectievragen (pdf) ## 8 Complete mini‐project (ga niet verder voordat je de vorige opdracht goed hebt afgerond) ### 🎯 Leerdoelen - Je past classes, objects en constructors toe. - Je gebruikt public en private properties met getters/setters. - Je schrijft methods met parameters en returnwaardes. - Je beheert data in een klein OOP‐systeem. ### 💡 Uitleg Je bouwt een klein “winkelmandje”‐systeem in PHP. Je maakt twee classes: - `Product` met `private $naam`, `private $prijs` en een constructor. Voeg getters toe: `getNaam()` en `getPrijs()`. - `Winkelmandje` met `private $items = []`. Voeg methods toe om `voegToe(Product $p, int $aantal)`, `verwijder(Product $p)` en `getTotaal(): float` te implementeren. ### 🛠️ Opdracht – Winkelmandje bouwen 1. Maak bestand `les6-product.php` en definieer class `Product`: ```php ``` 2. Maak bestand `les6-winkelmandje.php` en definieer class `Winkelmandje`: ```php Product, 'aantal' => int] public function voegToe(Product $p, int $aantal): void { // voeg product toe of verhoog aantal // Kijk of het product al in het mandje zit // loop door het winkelmandje heen foreach ($this->items as &$item) { if ($item['product']->getNaam() === $p->getNaam()) { // kijk of we het prodcut al hebben // Verhoog het bestaande aantal $item['aantal'] += $aantal; return; // klaar } } // Anders (hebben we geen return gehad dus: nieuw item toevoegen $this->items[] = [ 'product' => $p, 'aantal' => $aantal ]; } public function verwijder(Product $p): void { // verwijder product volledig uit items ...... } public function getTotaal(): float { // bereken en return totaalprijs ...... } } ?> ``` 3. Maak een testscript `les6-test.php`: ```php voegToe($p1, 2); $mandje->voegToe($p2, 1); $mandje->verwijder($p2); echo "Totaal: €" . $mandje->getTotaal(); ?> ``` ### 🧠 Reflectie - Hoe zorg je ervoor dat een `Product` niet negatief geprijsd kan zijn? - Wat gebeurt er als je `voegToe` aanroept met `$aantal = 0`? - Waarom gebruik je hier `private` properties en geen `public`? - Hoe kun je de code uitbreiden met een `updateAantal(Product $p, int $nieuwAantal)`? - In de function `voegToe(Product $p, int $aantal)` moeten we controleren of het prodcut al bestaat. Als dat zo is dan verhogen we het aantal, aders moeten we het product aanmaken. We zouden verwachten dat we met een` if-then-else` controleren of eht product al bestaat. Waarom staat er in de code geen `if-then-else`? ### 📤 Inleveren - Bestanden: `les6-product.php`, `les6-winkelmandje.php`, `les6-test.php` - Reflectie in apart bestand: `reflectie-les6-.txt` ## 9 Test je Kennis
      Wat betekent OOP en hoe verschilt het van procedureel programmeren? OOP staat voor *Objectgeoriënteerd programmeren*. In plaats van functies en variabelen apart te gebruiken, bundel je bij OOP data en gedrag in objecten. Zo kun je code beter organiseren, hergebruiken en opsplitsen in logische blokken .
      Wat is een klasse in OOP? Een klasse is een blauwdruk of sjabloon waarin je beschrijft welke gegevens (*properties*) en functies (*methods*) een object moet hebben .
      Wat is een object? Een object is een concreet exemplaar van een klasse, gemaakt met new. Je kunt meerdere objecten maken van dezelfde klasse, elk met eigen waarden .
      Hoe noem je in OOP een variabele en een functie binnen een klasse? In OOP noem je variabelen **properties**, en functies **methods**
      Wat is encapsulation? Encapsulation betekent dat je de data (properties) van een object beschermt. Je maakt gegevens vaak private en gebruikt methods om ze gecontroleerd te lezen of aanpassen .
      Wat is het verschil tussen public en private properties/methods? - **public**: toegankelijk en aanpasbaar van buiten de class. - **private**: alleen toegankelijk binnen de class zelf. Dit beschermt de interne gegevens.
      Waarom is OOP handig bij grote projecten? Omdat je code makkelijker kunt organiseren in logische blokken (objecten), hergebruiken, uitbreiden en onderhouden. Daardoor is je programma stabieler en schaalbaarder .
      Waarvoor genbruik je '$this' -> in PHP? `$this->` verwijst naar een property of een object uit **dit** object. Met dit object wordt bedoeld het object waar `$this->` in staat.
      ## 7 Inheritance (Overerving) ### 🌟 Leerdoelen - Je weet wat inheritance (overerving) betekent in OOP. - Je kunt een class maken die eigenschappen en methodes **erft** van een andere class. - Je ziet waarom inheritance handig is: minder herhaling, meer overzicht. ### 💡 Uitleg #### Wat is inheritance? Inheritance betekent dat je een nieuwe class maakt die eigenschappen en methodes **overneemt** van een andere class. Dit heet overerving. De 'ouderclass' noem je ook wel de *superclass*, en de 'kindclass' de *subclass*. #### Voorbeeld ```php naam . " ademt.\n"; } } class Hond extends Dier { public function blaf() { echo $this->naam . " zegt: Woef!\n"; } } $rex = new Hond(); $rex->naam = "Rex"; $rex->adem(); // komt uit Dier $rex->blaf(); // komt uit Hond ?> ``` 👉 De class `Hond` **erft** de methode `adem()` van `Dier`, maar voegt ook zijn eigen gedrag toe: `blaf()`. ### 🛠️ Opdracht – Maak je eigen dier met overerving 1. **Bestand: dier.php** Maak een class `Dier` met: - een property `$naam` - een methode `beweeg()` die `"{$this->naam} beweegt."` toont 2. **Bestand: vogel.php** Maak een class `Vogel` die `extends Dier`: - een methode `vlieg()` die `"{$this->naam} vliegt!"` toont 3. **Bestand: test.php** - Maak een object `$mus` van de class `Vogel` - Stel zijn naam in op `"Mus"` - Roep zowel `beweeg()` als `vlieg()` aan ### 🧠 Reflectie - Wat gebeurt er als je `vlieg()` oproept op een `Dier`-object? - Kun je uitleggen waarom `Vogel` de methode `beweeg()` kan gebruiken zonder die zelf te schrijven? ### 📄 Inleveren - `dier.php`, `vogel.php`, `test.php` - Reflectie in `reflectie-les7-.txt` # OOP Challenge ## Challenge A: OOP Login Systeem ### 🔰 Inleiding, wat ga je doen? De OOP Challenge is een fantastische kans om jouw vaardigheden in **objectgeoriënteerd programmeren** (OOP) naar een hoger niveau te tillen en direct toe te passen in de praktijk. Je combineert je **Cyber Security** vaardigheden met de **OOP** vaardigheden. Je hebt de keuze uit twee boeiende projecten; - je maakt een[ OOP Login Systeem](https://www.roc.ovh/link/929#bkmrk-8-challenge%3A-bouw-ee), of - je maakt een [(mobiele) ToDo manager](https://www.roc.ovh/link/929#bkmrk-8-challenge%3A-bouw-ee) die je kan omzetten naar een mobiele applicatie, dit is lastiger maar ook veel leuker want je maakt een echte mobiele app! ### 🌟 Leerdoelen - Je past klassen, objecten, constructors en methodes toe in een realistisch scenario. - Je gebruikt encapsulation om gebruikersgegevens te beveiligen. - Je slaat gebruikers op met PDO en hashed wachtwoorden. - Je maakt een registratie- en loginroutine in OOP-stijl. ### 💡 Opdrachtbeschrijving **Situatie:** Je werkt bij een klein webbureau en een klant wil een eenvoudig maar veilig **login-systeem** laten bouwen in PHP. Je gaat dit project zelfstandig uitvoeren als een mini-challenge. Dit is een uitstekende kans om je **OOP-vaardigheden** te laten zien in je **GitHub portfolio**. Dat kan je helpen om sneller een stage of baan te vinden in de webdevelopment-sector! **Wat je gaat bouwen:** - Een registratiepagina waar nieuwe gebruikers zich kunnen aanmelden - Een loginpagina waar gebruikers zich kunnen aanmelden - Beveiligde opslag van wachtwoorden via `password_hash()` - Gebruik van `PDO` voor communicatie met de database (bijv. SQLite of MySQL) ### 📄 Structuur en Klassen - **Class User** - Properties: `private $id`, `$username`, `$passwordHash` - Constructor stelt naam + wachtwoord in (en hashed het wachtwoord) - Methode `verifyPassword($plainText)` vergelijkt met hash - Getters voor `getId()` en `getUsername()` - **Class UserDatabase** - Maakt verbinding via `PDO` (gebruik SQLite of MySQL) - Methodes: `addUser(User $user)`, `findUserByUsername($name)` - Prepared statements verplicht! ### 🚀 Technische vereisten - Gebruik **password\_hash()** en **password\_verify()** voor wachtwoorden - PDO met **prepared statements** (geen ruwe SQL!) - Toon foutmeldingen bij fouten (bestaande user, fout wachtwoord, etc.) ### 🛠️ Bestanden - `User.php` – beschrijft de user zelf - `UserDatabase.php` – regelt opslag en ophalen - `register.php` – laat gebruiker registreren - `login.php` – laat gebruiker inloggen - `login-success.php` – pagina die je ziet na succesvol inloggen ### 🧠 Reflectie - Wat zijn de voordelen van wachtwoord hashing? - Waarom gebruiken we een aparte klasse voor opslag en een voor gebruikers? - Wat zou je uitbreiden als je dit systeem echt online wilde zetten? ### 📅 Bonus: Voor je portfolio Zet dit project op **GitHub** met een korte uitleg in de README over hoe het werkt. Voeg schermafbeeldingen toe van het registratie- en loginproces. Dit is een mooi voorbeeldproject om te laten zien wat je kunt! ### ✨ Gebruik AI AI gebruik op de juiste manier, zoals geleerd tijdens de lessen, is toegestaan en wordt zelfs aangemoedigd. Het is wel verplicht om de AI log in te leveren en je moet je code kunnen uitleggen! ### 📄 Inleveren - AI log - alle hulp van AI inleveren! - SQL export. - Alle bestanden nodig voor jouw website. - Reflective in PDF - (Optioneel) Link naar je GitHub repository ## Challenge B: (mobiele) OOP ToDo Manager ### 🔰 Inleiding, wat ga je doen? De OOP Challenge is een fantastische kans om jouw vaardigheden in **objectgeoriënteerd programmeren** (OOP) naar een hoger niveau te tillen en direct toe te passen in de praktijk. Je combineert je **Cyber Security** vaardigheden met de **OOP** vaardigheden. Je hebt de keuze uit twee boeiende projecten; - je maakt een[ OOP Login Systeem](https://www.roc.ovh/link/929#bkmrk-8-challenge%3A-bouw-ee), of - je maakt een [(mobiele) ToDo manager](https://www.roc.ovh/link/929#bkmrk-8-challenge%3A-bouw-ee) die je kan omzetten naar een mobiele applicatie, dit is lastiger maar ook veel leuker want je maakt een echte mobiele app! ### 🌟 Leerdoelen - Je past OOP toe in een realistisch webproject. - Je maakt meerdere klassen die met elkaar samenwerken. - Je gebruikt PDO en password hashing op een veilige manier. - Je bouwt een werkend mini-systeem dat je op GitHub kunt zetten. ### 💡 Opdrachtbeschrijving **Situatie:** Een start-up wil een prototype van een eenvoudige "ToDo Manager" waarin gebruikers taken kunnen aanmaken, afvinken en verwijderen. Jij bouwt dit systeem in PHP met OOP. Dit is een mooie kans om een compleet mini-project te maken voor je **GitHub portfolio** — ideaal om te laten zien bij een sollicitatie voor stage of werk! ### 📄 Functionaliteiten - Registratiepagina: nieuwe gebruikers kunnen zich aanmelden - Loginpagina: gebruikers kunnen inloggen met hun wachtwoord - Taakpagina: ingelogde gebruikers kunnen taken toevoegen, afvinken en verwijderen - Alle data wordt opgeslagen in een database met **PDO** (SQLite of MySQL). ### 📱 Mobiele App (optioneel) - Je kan de ToDo manager omzetten naat een **Progressive Web App**. Je krijgt de beste gebruikers ervaring als je je ToDO manager zoveel mogelijk omzet naar een **Single Page Web Application** (SPA). Dat kan met een Framework, maar ook met JavaScript.
      Wat is een SPA en een Progressive Web App? Een **one page applicatie** (of **Single Page Application**, afgekort **SPA**) is een webapplicatie of website die uit **één HTML-pagina** bestaat en **dynamisch inhoud laadt**, zonder de hele pagina opnieuw te laden bij navigatie of interactie. ##### **🔧 Hoe werkt het?** Bij een SPA: - Wordt bij het eerste bezoek één HTML-pagina geladen. - Daarna worden alleen **delen van de pagina aangepast via JavaScript** (meestal met behulp van frameworks zoals React, Vue of Angular). - Communicatie met de server gebeurt via **AJAX** of **fetch()-aanroepen** om data op te halen of op te slaan, vaak in JSON-formaat. Je kunt een SPA omzetten in een PWA, Progressieve Web App. #### **💡 Wat is een PWA?** Een **PWA** is een **website die aanvoelt als een app**. Je opent hem in de browser, maar je kunt hem ook **op je telefoon zetten als icoon**, net zoals een echte app uit de App Store of Play Store. ##### **📱 Hoe werkt het?** Een PWA: - Start gewoon via je browser (zoals Safari of Chrome) - Kan op je **beginscherm gezet worden** als een app-icoon - **Werkt ook offline** als je het goed instelt - Ziet eruit en werkt zoals een gewone app *Wil je een Mobiele app op deze manier maken, laat AI je dan de details verder uitleggen,*
      ### 📄 Klassen - **Class User** - Properties: `$id`, `$username`, `$passwordHash` - Constructor en `verifyPassword($plainText)` - **Class UserDatabase** - Maakt verbinding via `PDO` - Methodes: `addUser()`, `findUserByUsername()` - **Class Task** - Properties: `$id`, `$user_id`, `$description`, `$completed` - Methodes: `toggleCompleted()`, `getDescription()`, `isCompleted()` - **Class TaskManager** - Methodes: `addTask()`, `getTasksByUser()`, `deleteTask()`, `toggleTask()` - Alle database-interacties via `PDO` met prepared statements ### 🧠 Reflectie - Waarom werken we met meerdere klassen in plaats van één grote? - Wat gebeurt er als een niet-ingelogde gebruiker naar de takenpagina navigeert? - Hoe zorgt jouw systeem ervoor dat taken niet tussen gebruikers verwisseld kunnen worden? ### 📅 Bonus voor je portfolio Zet dit project op **GitHub**. Voeg screenshots toe en schrijf een README-bestand waarin je uitlegt wat het systeem doet. Dit laat aan stagebedrijven of werkgevers zien dat jij zelfstandig een werkend OOP-project kunt bouwen! ### ✨ Gebruik AI AI gebruik op de juiste manier, zoals geleerd tijdens de lessen, is toegestaan en wordt zelfs aangemoedigd. Het is wel verplicht om de AI log in te leveren en je moet je code kunnen uitleggen! ### 📄 Inleveren - AI log - alle hulp van AI inleveren! - SQL export. - Alle bestanden nodig voor jouw website. - Reflective in PDF - (Optioneel) Link naar je GitHub repository \-- # OOP Inheritance ## 1 Inheritance (Overerving) ### 🌟 Leerdoelen - Je weet wat inheritance (overerving) betekent in OOP. - Je kunt een class maken die eigenschappen en methodes **erft** van een andere class. - Je ziet waarom inheritance handig is: minder herhaling, meer overzicht. ### 💡 Uitleg #### Wat is inheritance? Inheritance betekent dat je een nieuwe class maakt die eigenschappen en methodes **overneemt** van een andere class. Dit heet overerving. De 'ouderclass' noem je ook wel de *superclass*, en de 'kindclass' de *subclass*. #### Voorbeeld ```php naam . " ademt.\n"; } } class Hond extends Dier { public function blaf() { echo $this->naam . " zegt: Woef!\n"; } } $rex = new Hond(); $rex->naam = "Rex"; $rex->adem(); // komt uit Dier $rex->blaf(); // komt uit Hond ?> ``` 👉 De class `Hond` **erft** de methode `adem()` van `Dier`, maar voegt ook zijn eigen gedrag toe: `blaf()`. ### 🛠️ Opdracht – Maak je eigen dier met overerving 1. **Bestand: dier.php** Maak een class `Dier` met: - een property `$naam` - een methode `beweeg()` die `"{$this->naam} beweegt."` toont 2. **Bestand: vogel.php** Maak een class `Vogel` die `extends Dier`: - een methode `vlieg()` die `"{$this->naam} vliegt!"` toont 3. **Bestand: test.php** - Maak een object `$mus` van de class `Vogel` - Stel zijn naam in op `"Mus"` - Roep zowel `beweeg()` als `vlieg()` aan ### 🧠 Reflectie - Wat gebeurt er als je `vlieg()` oproept op een `Dier`-object? - Kun je uitleggen waarom `Vogel` de methode `beweeg()` kan gebruiken zonder die zelf te schrijven? ### 📄 Inleveren - `dier.php`, `vogel.php`, `test.php` - Reflectie in `reflectie-les7-.txt` # Kennis Check Blok 8 ## Cyber Security #### Hoofdstuk 1: Wat is Cyber Security? 1\. Wat is de primaire focus van Cyber Security? - a) Het beschermen van websites tegen computer-bugs - b) Het beschermen van computersystemen tegen aanvallen en misbruik. - c) Het ontwikkelen van nieuwe softwareprogramma's. - d) Het beheren van netwerkinfrastructuur.
      ✅ Antwoord b) Het beschermen van computersystemen tegen aanvallen en misbruik.
      2\. Welke van de volgende cyberaanvallen omvat het misleiden van iemand om wachtwoorden af te geven, vaak via nep-e-mails? - a) Malware - b) DDoS-aanval - c) Phishing - d) SQL-injection
      ✅ Antwoord c) Phishing
      Welke term wordt gebruikt voor software die ontworpen is om ongevraagd advertenties te tonen en je naar bepaalde webwinkels stuurt? - a) Adware - b) Spam - c) Malware - d) Commerceware
      ✅ Antwoord c) Adware
      Welke vorm van malware kan zichzelf verspreiden naar andere bestanden of programma's zodra het op een computer is geïnstalleerd? - a) Worm - b) Spyware - c) Virus - d) Adware
      ✅ Antwoord c) Virus
      #### Hoofdstuk 2: HTTPS en netwerkveiligheid 3\. Wat is het belangrijkste verschil tussen HTTP en HTTPS? - a) HTTPS is alleen voor professionele websites, HTTP voor persoonlijke. - b) HTTPS staat voor HyperText Transfer Protocol Secure en versleutelt de communicatie tussen browser en server. - c) HTTP is sneller dan HTTPS. - d) HTTP gebruikt een SSL-certificaat, HTTPS niet.
      ✅ Antwoord b) HTTPS staat voor HyperText Transfer Protocol Secure en versleutelt de communicatie tussen browser en server.
      4\. Waarvoor biedt HTTPS geen bescherming? - a) Het onderscheppen van ingevulde wachtwoorden door derden. - b) Het veranderen van informatie terwijl deze onderweg is. - c) Het downloaden van virussen of malware. - d) Verbinding maken met de echte website in plaats van een nepserver.
      ✅ Antwoord c) Het downloaden van virussen of malware.
      #### Hoofdstuk 3: Encryptie 5\. Wat is de definitie van encryptie? - a) Het proces van het verbergen van bestanden op een computer. - b) Het omzetten van gegevens zodat ze onleesbaar zijn voor onbevoegden, tenzij men de juiste ‘sleutel’ heeft. - c) Het back-uppen van gegevens naar een externe schijf. - d) Het controleren van de integriteit van gegevens.
      ✅ Antwoord b) Het omzetten van gegevens zodat ze onleesbaar zijn voor onbevoegden, tenzij men de juiste ‘sleutel’ heeft.
      6\. Welk type encryptie gebruikt dezelfde sleutel voor zowel versleuteling als ontsleuteling? - a) Asymmetrische encryptie - b) Hash-encryptie - c) Symmetrische encryptie - d) Kwantumencryptie
      ✅ Antwoord c) Symmetrische encryptie
      #### Hoofdstuk 4: Hashing 7\. Waarom wordt hashing vaak gebruikt voor het opslaan van wachtwoorden? - a) Omdat de wachtwoorden dan eenvoudig terug te rekenen zijn voor de gebruiker. - b) Omdat het een eenrichtingsversleuteling is die niet terug te rekenen is naar het origineel. - c) Omdat het wachtwoorden comprimeert om opslagruimte te besparen. - d) Omdat het helpt bij het snel ophalen van verloren wachtwoorden.
      ✅ Antwoord b) Omdat het een eenrichtingsversleuteling is die niet terug te rekenen is naar het origineel.
      8\. Hoe controleert een systeem een ingevoerd wachtwoord als het opgeslagen wachtwoord gehasht is? - a) Het systeem probeert de opgeslagen hash terug te rekenen naar het originele wachtwoord. - b) Het systeem stuurt een resetlink naar het e-mailadres van de gebruiker. - c) Het systeem zet het ingevoerde wachtwoord om met de hash-functie en vergelijkt het resultaat met de opgeslagen hash. - d) Het systeem vraagt de gebruiker om een tweede authenticatiefactor.
      ✅ Antwoord c) Het systeem zet het ingevoerde wachtwoord om met de hash-functie en vergelijkt het resultaat met de opgeslagen hash.
      #### Hoofdstuk 5: Brute Force-aanvallen en Loginbeveiliging 9\. Wat is een brute force-aanval? - a) Een aanval waarbij een server wordt overspoeld met aanvragen. - b) Een aanval waarbij kwaadaardige software op een systeem wordt geïnstalleerd. - c) Een aanval waarbij systematisch heel veel verschillende wachtwoorden worden geprobeerd om toegang te krijgen. - d) Een aanval waarbij via een formulier een database wordt gehackt.
      ✅ Antwoord c) Een aanval waarbij systematisch heel veel verschillende wachtwoorden worden geprobeerd om toegang te krijgen.
      10\. Welke van de volgende is ***geen*** methode om brute force-aanvallen te voorkomen? - a) Een limiet stellen op het aantal pogingen. - b) Tijdelijk een gebruiker of IP-adres blokkeren. - c) Twee-factor authenticatie toepassen. - d) Het gebruik van $\_GET voor het versturen van inloggegevens.
      ✅ Antwoord d) Het gebruik van $\_GET voor het versturen van inloggegevens.
      #### Hoofdstuk 6: Rainbow tables 11\. Wat is een rainbow table? - a) Een lijst van alle mogelijke wachtwoorden. - b) Een database van gehackte IP-adressen. - c) Een lijst van veelgebruikte wachtwoorden met hun bijbehorende hashes. - d) Een hulpmiddel om SSL-certificaten te genereren.
      ✅ Antwoord c) Een lijst van veelgebruikte wachtwoorden met hun bijbehorende hashes.
      12\. Waarom zijn rainbow tables gevaarlijk voor wachtwoordbeveiliging? - a) Ze zorgen ervoor dat servers overbelast raken. - b) Ze maken het mogelijk om gehashte wachtwoorden snel terug te vertalen naar het origineel als het wachtwoord in de tabel staat. - c) Ze installeren malware op het systeem van de gebruiker. - d) Ze versleutelen de communicatie tussen de gebruiker en de website.
      ✅ Antwoord b) Ze maken het mogelijk om gehashte wachtwoorden snel terug te vertalen naar het origineel als het wachtwoord in de tabel staat.
      #### Hoofdstuk 7: Salting en encryptie 13\. Wat is het hoofddoel van 'salting' bij het hashen van wachtwoorden? - a) Om het hash-algoritme complexer te maken. - b) Om ervoor te zorgen dat hetzelfde wachtwoord elke keer een unieke hash krijgt, wat rainbow tables minder effectief maakt. - c) Om de snelheid van het hashen te verhogen. - d) Om te controleren of een wachtwoord sterk genoeg is.
      ✅ Antwoord b) Om ervoor te zorgen dat hetzelfde wachtwoord elke keer een unieke hash krijgt, wat rainbow tables minder effectief maakt.
      14\. Hoe wordt een gehasht wachtwoord met een 'salt' gecontroleerd bij het inloggen? - a) Het systeem probeert de opgeslagen hash te ontsleutelen met de salt. - b) Het ingevoerde wachtwoord wordt gehasht zonder de salt en vergeleken met de opgeslagen hash. - c) Het ingevoerde wachtwoord wordt opnieuw gehasht samen met dezelfde opgeslagen salt, en het resultaat wordt vergeleken met de opgeslagen hash. - d) De gebruiker wordt gevraagd om de salt handmatig in te voeren. ## OOP
      Wat betekent OOP en hoe verschilt het van procedureel programmeren? OOP staat voor *Objectgeoriënteerd programmeren*. In plaats van functies en variabelen apart te gebruiken, bundel je bij OOP data en gedrag in objecten. Zo kun je code beter organiseren, hergebruiken en opsplitsen in logische blokken .
      Wat is een klasse in OOP? Een klasse is een blauwdruk of sjabloon waarin je beschrijft welke gegevens (*properties*) en functies (*methods*) een object moet hebben .
      Wat is een object? Een object is een concreet exemplaar van een klasse, gemaakt met new. Je kunt meerdere objecten maken van dezelfde klasse, elk met eigen waarden .
      Hoe noem je in OOP een variabele en een functie binnen een klasse? In OOP noem je variabelen **properties**, en functies **methods**
      Wat is encapsulation? Encapsulation betekent dat je de data (properties) van een object beschermt. Je maakt gegevens vaak private en gebruikt methods om ze gecontroleerd te lezen of aanpassen .
      Wat is het verschil tussen public en private properties/methods? - **public**: toegankelijk en aanpasbaar van buiten de class. - **private**: alleen toegankelijk binnen de class zelf. Dit beschermt de interne gegevens.
      Waarom is OOP handig bij grote projecten? Omdat je code makkelijker kunt organiseren in logische blokken (objecten), hergebruiken, uitbreiden en onderhouden. Daardoor is je programma stabieler en schaalbaarder .
      Waarvoor genbruik je '$this' -> in PHP? `$this->` verwijst naar een property of een object uit **dit** object. Met dit object wordt bedoeld het object waar `$this->` in staat.
      ### 🛠️ Opdracht Maak de kennis-check. ### 📤 Inleveren Aan het einde van de kennis-check ontvang je een certificaat. Maak een schermafdruk en lever deze in. # PHP - Debuggen ## 1 Foutafhandeling en Basis Debugging in PHP ### **🎯** Leerdoelen - Je weet wat de verschillende typen PHP-fouten zijn (`Errors`, `Warnings`, `Notices`). - Je kunt foutmeldingen in PHP interpreteren. - Je kunt foutweergave instellen met `error_reporting()` en `ini_set()`. - Je kunt basisprincipes van foutafhandeling toepassen (zoals `isset()`, `empty()`, `file_exists()`). - Je gebruikt debuggingtechnieken zoals `echo`, `print_r()` en `var_dump()`. ### 💡 Uitleg #### 📌 Soorten fouten in PHP - **Parse error:** fout in de code (bijvoorbeeld vergeten ; of haakje). - **Fatal error:** code probeert iets wat niet kan, bijvoorbeeld een functie die niet bestaat. - **Warning:** foutmelding, maar de code gaat door. - **Notice:** melding van iets wat waarschijnlijk fout is (bijv. niet bestaande variabele). #### ⚙️ Foutmeldingen tonen of verbergen ```php ``` ⚠️ Op een live website wil je foutmeldingen verbergen voor gebruikers. Gebruik dan: ```php ini_set("display_errors", 0); ``` #### 🔍 Veelgebruikte foutafhandelingstechnieken - `isset($variabele)` – controleert of een variabele bestaat. - `empty($variabele)` – controleert of een variabele leeg is. - `file_exists("bestand.txt")` – controleert of een bestand bestaat. - `die("Foutmelding")` of `exit()` – stopt het script bij een ernstige fout. #### 🛠️ Debuggen zonder debugger - `echo` – handig om waardes snel te tonen. - `print_r($array)` – toont de inhoud van een array of object. - `var_dump($variabele)` – toont type + waarde (ook handig bij fouten met getallen). ### 🛠️ Opdracht 1 – Debugging oefenen 1. Maak een PHP-bestand genaamd `korting.php` met deze functie: ```php ``` 2. Voeg foutmeldingen toe via `error_reporting()` zodat je de waarschuwing ziet. 3. Gebruik `isset()` en `empty()` om de fout af te vangen. 4. Test wat er gebeurt als je een variabele gebruikt die niet bestaat. 5. Gebruik `var_dump()` en `echo` om te zien wat je fout doet. ### 🧠 Reflectie - Wat is het verschil tussen een warning en een fatal error? - Waarom is het handig om fouten wel te tonen in de ontwikkelfase, maar niet op een live website? - Welke debuggingtechniek vond je het meest bruikbaar? ### 📤 Inleveren - Lever het bestand `korting.php` in. - Lever een korte uitleg in (.txt of .pdf) waarin je aangeeft: - Welke fout(en) je hebt gevonden - Welke techniek je gebruikte om het op te lossen - Wat je ervan geleerd hebt ## 2 Bestanden en Loggen ### **🎯** Leerdoelen - Je kunt bestanden aanmaken, lezen, schrijven en toevoegen met PHP. - Je weet wanneer het handig is om gegevens in bestanden op te slaan in plaats van een database te gebruiken. - Je begrijpt wat logbestanden zijn en waarom ze nuttig zijn. - Je kunt een eenvoudig logsysteem implementeren dat fouten of gebeurtenissen opslaat. ### 💡 Uitleg #### 📁 Waarom bestanden gebruiken? Bestanden kunnen handig zijn voor eenvoudige opslag zoals instellingen, bezoekerslogs of tijdelijke data. In kleine projecten is dit vaak eenvoudiger dan een database. #### 📄 Bestandsfuncties in PHP - `file_put_contents("bestand.txt", "tekst")` – schrijft tekst naar bestand (overschrijft). - `file_get_contents("bestand.txt")` – leest hele bestand in één keer. - `fopen()` + `fwrite()` – uitgebreidere controle (bijv. toevoegen). - `file_exists("bestand.txt")` – controleert of bestand bestaat. - `fclose()` – sluit een bestand (nodig bij `fopen()`). #### 🗒️ Loggen: fouten en gebeurtenissen bijhouden Een logbestand houdt bij wat er gebeurt in een script. Bijvoorbeeld foutmeldingen of bezoekersactiviteit. Voorbeeld – logregel opslaan: ```php ``` `FILE_APPEND` zorgt dat de nieuwe regel onderaan toegevoegd wordt in plaats van het bestand te overschrijven. ### 🛠️ Opdracht 1 – bezoekersteller.php 1. Maak een nieuw bestand `bezoekersteller.php`. 2. Laat het script een teller bijhouden in `teller.txt`: - Bestaat het bestand nog niet? Begin bij 1. - Zo niet? Lees het getal in, verhoog met 1, en schrijf het terug. 3. Toon het aantal bezoeken op het scherm. ### 🛠️ Opdracht 2 – gastenboek.php (uitbreiding) 1. Maak een script waarin een gebruiker een bericht kan achterlaten via een formulier. 2. Sla elk bericht op in `gastenboek.txt` met datum/tijd. 3. Toon de laatste 5 berichten boven het formulier. 4. Gebruik `htmlspecialchars()` om invoer veilig weer te geven. ### 🧠 Reflectie - Wat zijn de voor- en nadelen van gegevens opslaan in een bestand ten opzichte van een database? - Wat gebeurt er als je `file_put_contents()` gebruikt zonder `FILE_APPEND`? - Waarom is loggen belangrijk, zelfs in kleine projecten? ### 📤 Inleveren - Lever je bestanden `bezoekersteller.php` en/of `gastenboek.php` in. - Lever een reflectieverslag in (.txt of .pdf). ## 3 Geavanceerde Functies, Abstractie en Modulaire Code ### **🎯** Leerdoelen - Je begrijpt waarom functies handig zijn (herbruikbaarheid, leesbaarheid, structuur). - Je kunt functies gebruiken om complexe taken te verbergen (abstractie). - Je snapt het verschil tussen globale en lokale variabelen (scope). - Je kunt functies opslaan in aparte bestanden en deze inladen met `include()` of `require()`. ### 💡 Uitleg #### 🔁 Waarom functies gebruiken? - Je hoeft een stuk code maar één keer te schrijven. - Je kunt de code op meerdere plekken gebruiken. - Je maakt je code overzichtelijker en makkelijker te begrijpen. #### 🎩 Abstractie: de details verbergen Een functie kan iets ingewikkelds doen, zonder dat je telkens opnieuw de details hoeft te schrijven. ```php function berekenKorting($bedrag, $percentage) { return $bedrag - ($bedrag * $percentage / 100); } echo berekenKorting(100, 10); // → 90 ``` Je hoeft niet telkens opnieuw de hele berekening te typen. De functie “verbergt” die logica. #### 📦 Variable scope (bereik van een variabele) - Variabelen binnen een functie zijn **lokaal**: ze bestaan alleen daarbinnen. - Variabelen buiten functies zijn **globaal**. - Je kunt met `global` een globale variabele binnen een functie gebruiken, maar dat is niet altijd wenselijk. ```php $x = 5; function testScope() { $x = 10; echo $x; // Toont 10, NIET 5 } testScope(); echo $x; // Toont nog steeds 5 ``` #### 🧩 Modulaire code met `include()` Je kunt functies in een apart bestand zetten, bijvoorbeeld `utils.php`, en die inladen in andere bestanden. ```php // Bestand: utils.php function toonWelkomstbericht($naam) { echo "

      Welkom, $naam!

      "; } ``` ```php // Bestand: index.php include("utils.php"); toonWelkomstbericht("Ali"); ``` Je kunt ook meerdere functies in één bestand zetten, zoals: - `validation.php`: functies voor formuliercontrole - `format.php`: functies voor tekst- of getalopmaak ### 🛠️ Opdracht – utils.php gebruiken 1. Maak een nieuw bestand `utils.php` en schrijf daarin minstens 3 functies: - `formatteerBedrag($bedrag)` → toont bijv. "€ 12,50" - `valideerInvoer($waarde)` → controleert of de waarde niet leeg is - `toonWelkomstbericht($naam)` → toont HTML met de naam 2. Maak een ander bestand `test_utils.php` waarin je `include("utils.php")` gebruikt en de functies test. 3. Gebruik `echo`, `print_r()` en `var_dump()` om het resultaat van de functies te tonen. ### 🧠 Reflectie - Wat zijn de voordelen van functies in aparte bestanden bewaren? - Welke functie vond je het handigst om te schrijven en waarom? - Wat heb je geleerd over het verschil tussen globale en lokale variabelen? ### 📤 Inleveren - Lever de bestanden `utils.php` en `test_utils.php` in. - Lever een reflectiedocument in (.txt of .pdf) waarin je uitlegt wat je hebt gedaan en geleerd. ## 4 Form Validatie en Beveiliging ### **🎯** Leerdoelen - Je kunt formulierinvoer controleren op geldigheid. - Je kent de risico’s van onveilige invoer (zoals XSS). - Je kunt invoer ontsnappen met `htmlspecialchars()`. - Je gebruikt functies als `isset()`, `empty()` en `trim()` om invoer te valideren. ### 💡 Uitleg #### 📨 Waarom valideren? Gebruikers maken fouten. Hackers doen het expres. Daarom controleer je altijd of een formulier goed is ingevuld voordat je ermee werkt. #### 🔐 Veelvoorkomende gevaren - **XSS (Cross-Site Scripting):** iemand vult HTML of JavaScript in een formulier in, dat op jouw pagina wordt getoond. - **Lege velden:** de gebruiker vergeet iets in te vullen. - **Verkeerde types:** een tekst waar een getal moet staan. #### 🧰 Handige functies voor validatie - `isset($_POST["naam"])` – is het veld verzonden? - `empty($_POST["naam"])` – is het veld leeg? - `trim()` – verwijdert spaties voor en na de invoer. - `htmlspecialchars()` – maakt HTML onschadelijk. ```php ``` #### 📋 Simpel formulier ```html
      ``` ### 🛠️ Opdracht 1 – formulier\_validatie.php 1. Maak een PHP-bestand met een formulier waarin je de gebruiker vraagt om: - Naam - Leeftijd - Bericht 2. Controleer of alle velden zijn ingevuld. Toon een foutmelding als iets ontbreekt. 3. Gebruik `htmlspecialchars()` om het bericht veilig weer te geven. 4. Gebruik `is_numeric()` om te controleren of de leeftijd een getal is. #### Extra (optioneel) - Maak je foutmeldingen visueel opvallend met HTML (bijv. ``). ### 🧠 Reflectie - Waarom is het belangrijk om input van gebruikers altijd te controleren? - Wat zou er kunnen gebeuren als je `htmlspecialchars()` niet gebruikt? - Welke fouten kwamen er tijdens het testen naar boven? ### 📤 Inleveren - Lever je bestand `formulier_validatie.php` in (.php). - Lever een reflectiedocument in (.txt of .pdf) met jouw antwoorden. ## 5 Superglobals en Associatieve Arrays ### **🎯** Leerdoelen - Je begrijpt wat superglobals zijn in PHP (`$_GET`, `$_POST`, `$_SESSION`, `$_FILES`). - Je weet wat een associatieve array is en hoe je ermee werkt. - Je kunt formulierdata opslaan en verwerken met behulp van superglobals. ### 💡 Uitleg #### 🌍 Wat zijn superglobals? Superglobals zijn ingebouwde variabelen in PHP die overal beschikbaar zijn. Je gebruikt ze bijvoorbeeld om gegevens uit een formulier op te halen. - `$_POST` – bevat formulierdata die via POST is verzonden - `$_GET` – bevat data uit de URL (bijv. `?pagina=contact`) - `$_SESSION` – bevat gegevens die je wilt onthouden tussen pagina's - `$_FILES` – bevat geüploade bestanden #### 🔑 Associatieve arrays Een associatieve array is een array met 'sleutels' in plaats van indexnummers: ```php $persoon = [ "naam" => "Ali", "leeftijd" => 19, "email" => "ali@example.com" ]; echo $persoon["naam"]; // Toont: Ali ``` Formulieren leveren ook associatieve arrays op via `$_POST`: ```php echo $_POST["naam"]; ``` ### 🛠️ Opdracht 1 – formulier\_superglobals.php 1. Maak een formulier met de volgende velden: - Naam - E-mail - Bericht 2. Verwerk de invoer met `$_POST` en sla de gegevens op in een associatieve array: ```php $data = [ "naam" => $_POST["naam"], "email" => $_POST["email"], "bericht" => $_POST["bericht"] ]; ``` 3. Toon de waarden netjes op het scherm met `htmlspecialchars()`. 4. Gebruik eventueel `print_r($data)` om de hele array te tonen voor debugging. ### 🧠 Reflectie - Wat is het verschil tussen een normale array en een associatieve array? - Waarom is `$_POST` eigenlijk een associatieve array? - Wanneer zou je liever `$_GET` gebruiken in plaats van `$_POST`? ### 📤 Inleveren - Lever je bestand `formulier_superglobals.php` in (.php). - Lever een reflectiedocument in (.txt of .pdf) met je antwoorden. ## 6 Sessies en Cookies ### **🎯** Leerdoelen - Je begrijpt wat sessies en cookies zijn. - Je kunt sessies gebruiken om gegevens tijdelijk op te slaan voor een gebruiker. - Je kunt cookies aanmaken en uitlezen met PHP. - Je kunt de juiste techniek kiezen om gebruikersgegevens te bewaren. ### 💡 Uitleg #### 🧠 Wat is een sessie? Een sessie is een manier om informatie te onthouden zolang een gebruiker actief is op de website. Bijvoorbeeld: je logt in en blijft ingelogd op alle pagina’s. Een sessie start je met: ```php ``` Je kunt sessiegegevens gebruiken zolang de browser open is (of tot je ze verwijdert met `session_destroy()`). #### 🍪 Wat is een cookie? Een cookie wordt opgeslagen in de browser van de gebruiker, meestal voor een langere tijd. Handig om voorkeuren of gebruikersgegevens te onthouden tussen bezoeken. ```php // Cookie instellen setcookie("taal", "NL", time() + 3600); // 1 uur geldig // Cookie uitlezen echo $_COOKIE["taal"]; ``` #### 📌 Verschillen tussen sessies en cookies
      KenmerkSessieCookie
      OpslaglocatieServerBrowser van gebruiker
      LevensduurTijdelijk (tot de browser sluit of je het wist)In te stellen (bijv. 1 uur, 30 dagen)
      ToepassingIngelogde gebruiker, winkelmandjeVoorkeuren, laatst bezochte pagina
      ### 🛠️ Opdracht 1 – sessie\_en\_cookie.php 1. Maak een pagina waar de gebruiker zijn naam kan invoeren via een formulier. 2. Na verzenden: - Sla de naam op in een **sessie** én in een **cookie** (1 uur). - Toon op de pagina: “Welkom terug, \[naam\]!” als de gebruiker opnieuw langskomt. 3. Laat ook zien wat er gebeurt als de gebruiker het formulier overslaat. 4. Gebruik `session_start()` bovenaan het script. #### Extra (optioneel) - Voeg een link toe die de sessie wist (`session_destroy()`). ### 🧠 Reflectie - Wanneer kies je voor een sessie? En wanneer voor een cookie? - Wat gebeurt er als je `session_start()` vergeet? - Waar moet je op letten bij het gebruik van cookies met privacy? ### 📤 Inleveren - Lever het bestand `sessie_en_cookie.php` in (.php). - Lever een reflectiedocument in (.txt of .pdf) met je antwoorden. ## 7 State en Bestandgebaseerde 'Database' ### **🎯** Leerdoelen - Je begrijpt het concept van ‘state’ in webapplicaties. - Je kunt gebruikersgegevens opslaan in een tekstbestand. - Je kunt meerdere records opslaan als gestructureerde regels (bijv. JSON of CSV). - Je kunt gegevens uit zo’n bestand inlezen en tonen aan de gebruiker. ### 💡 Uitleg #### 🧠 Wat is ‘state’? Een webpagina ‘vergeet’ wat er net gebeurd is zodra je hem ververst. Daarom moet je zelf bijhouden wat de toestand (state) is van je applicatie. Je kunt dat doen met sessies, cookies of door gegevens op te slaan in een bestand of database. #### 📁 Bestanden als ‘mini-database’ In plaats van een echte database zoals MySQL, kun je voor simpele toepassingen gegevens bewaren in een tekstbestand. Bijvoorbeeld: als iemand een bericht achterlaat in een formulier, voeg je dat toe aan `data.txt`. #### 📝 Structuur - Elk bericht komt op een eigen regel - Of je gebruikt een JSON-array, met meerdere objecten erin - Of je gebruikt CSV (waardes gescheiden met komma's) ```php // Voeg toe aan tekstbestand $bericht = htmlspecialchars($_POST["bericht"]); file_put_contents("data.txt", $bericht . "\n", FILE_APPEND); // Lees het bestand $inhoud = file("data.txt"); foreach ($inhoud as $regel) { echo "

      " . trim($regel) . "

      "; } ``` ### 🛠️ Opdracht 1 – gastenboek\_met\_bestand.php 1. Maak een formulier waarin iemand een naam en een bericht kan achterlaten. 2. Als de gebruiker op "Verstuur" klikt: - Sla het bericht op in een bestand `gastenboek.txt`. - Voeg ook datum/tijd toe met `date()`. 3. Toon de laatste 5 berichten onder het formulier. 4. Zorg dat de HTML veilig blijft via `htmlspecialchars()`. #### Extra (optioneel) - Laat de berichten in omgekeerde volgorde zien (nieuwste bovenaan). - Sla de data op in JSON-formaat i.p.v. tekstregels. ### 🧠 Reflectie - Wat zijn de voordelen van een tekstbestand boven een database? - Wanneer loop je tegen de beperkingen aan? - Hoe zou je dit uitbreiden zodat iemand ook berichten kan verwijderen? ### 📤 Inleveren - Lever je bestand `gastenboek_met_bestand.php` in (.php). - Lever het bestand `gastenboek.txt` mee met minimaal 3 testberichten. - Lever een reflectie in (.txt of .pdf). ## 8 Inleiding tot PHP Include-logica en Templatebestanden ### **🎯** Leerdoelen - Je begrijpt het nut van het opdelen van HTML/PHP-bestanden in herbruikbare componenten. - Je kunt `include` en `require` gebruiken om logica en opmaak te splitsen. - Je kunt een eenvoudige template-structuur bouwen (header, content, footer). ### 💡 Uitleg #### 🧱 Waarom opdelen in componenten? Als je meerdere pagina’s hebt met dezelfde header of footer, is het onhandig om die steeds te kopiëren. Daarom gebruik je `include()` of `require()` om ze in te laden. ```php

      Welkom op de homepage

      ``` #### 🔁 Verschil tussen include en require - `include()`: Laadt het bestand in. Als het bestand niet bestaat, gaat de rest van de pagina gewoon door. - `require()`: Laadt ook het bestand in, maar als het niet bestaat, stopt de pagina met een foutmelding. #### 📄 Voorbeeldstructuur - `header.php` – HTML <head>, navigatie - `footer.php` – Copyright info, afsluitende HTML - `index.php` – Hoofdpagina die alles samenvoegt ### 🛠️ Opdracht 1 – templatestructuur 1. Maak drie bestanden: - `header.php`: bevat een <header> met de titel van je site en een eenvoudige navigatie (bijv. naar home en contact). - `footer.php`: bevat een <footer> met een copyrightregel. - `index.php`: bevat de pagina-inhoud en gebruikt `include()` om de header en footer in te laden. 2. Zorg dat alles er netjes uitziet (je mag CSS toevoegen). 3. Test wat er gebeurt als je `include("footer.php")` verandert in `require("footer.php")` en het bestand bestaat niet. ### 🧠 Reflectie - Waarom is het handig om componenten zoals header/footer apart te houden? - Wat is het risico als je alles in één bestand zou houden? - Wanneer zou je `require()` verkiezen boven `include()`? ### 📤 Inleveren - Lever `index.php`, `header.php` en `footer.php` in. - Lever een reflectiedocument in (.txt of .pdf) met je antwoorden. ## 9 Validatie en Veiligheid bij Formulieren ### **🎯** Leerdoelen - Je begrijpt waarom inputvalidatie belangrijk is. - Je kunt formulierinvoer controleren met PHP (server-side). - Je kent de risico’s van onveilige invoer (bijv. XSS, SQL-injectie). - Je kunt input veilig maken met functies zoals `htmlspecialchars()` en `filter_var()`. ### 💡 Uitleg #### Waarom valideren? Gebruikers kunnen fouten maken (of expres verkeerde dingen invullen). Als je invoer niet controleert, kan dat leiden tot bugs of zelfs beveiligingsproblemen. #### Soorten validatie - **Client-side**: Met HTML of JavaScript (bijv. `required`, `type="email"`). - **Server-side**: Met PHP (altijd nodig, want je kunt client-side validatie omzeilen). #### Veiligheid: wat kan er misgaan? - **XSS (Cross-Site Scripting)**: Als je niet ontsnapte HTML toont, kan iemand scripts injecteren. - **SQL-injectie**: Als je invoer rechtstreeks in een query zet (komt later aan bod). #### Voorbeeld inputcontrole ```php
      Naam:
      $fout

      "; } else if ($naam) { echo "

      Welkom $naam

      "; } ?> ``` ### 🛠️ Opdracht 1 – formuliercontrole 1. Maak een formulier met de volgende velden: - Naam (verplicht) - Email (verplicht, geldig e-mailadres) - Bericht (optioneel, max. 200 tekens) 2. Controleer de invoer met PHP: - Laat foutmeldingen zien als iets ontbreekt of fout is. - Gebruik `filter_var()` om het e-mailadres te controleren. - Gebruik `htmlspecialchars()` om veilige output te tonen. 3. Toon een nette samenvatting van de ingevulde gegevens als alles goed is. #### Extra (optioneel) - Voeg visuele validatie toe met CSS-klassen (bijv. rode rand bij fout). - Voeg een resetknop toe aan het formulier. ### 🧠 Reflectie - Wat gebeurt er als je geen server-side validatie gebruikt? - Wat is het verschil tussen validatie en het veilig maken van input? - Hoe zou je dit formulier uitbreiden voor een login- of registratiepagina? ### 📤 Inleveren - Lever je formulierpagina in als `formulier_validatie.php`. - Lever een reflectiedocument in (.txt of .pdf). # Unit Testen (py) linked/18663/52557 ## 1 Wat is testen? Waarom is het belangrijk? ### **🎯** Leerdoelen - Je begrijpt wat testen is en waarom we het doen. - Je herkent verschillende soorten testen. - Je kunt een eenvoudige functie handmatig testen. ### 💡 Uitleg Testen betekent controleren of je code het juiste doet. Als je iets verandert, wil je zeker weten dat het nog steeds werkt. Denk aan: - Een rekenmachine die ineens verkeerde antwoorden geeft. - Een webshop die verkeerde prijzen toont. Daarom testen we onze code – om fouten te voorkomen en vertrouwen te krijgen in wat we gemaakt hebben. #### 📚 Testsoorten Er zijn verschillende soorten testen. Hieronder zie je een overzicht:
      TestsoortWat test je?Voorbeeld
      **Unit test**Één functie of klein onderdeelKlopt `bereken_korting()`?
      **Integratietest**Samenwerking tussen onderdelenVoegt `bereken_korting()` + `bereken_verzendkosten()` alles goed op?
      **Systeemtest**Het hele programmaWerkt de volledige webshop van begin tot eind?
      **Acceptatietest**Voldoet het aan de wensen van de gebruiker?Kan de klant een product kiezen en succesvol bestellen?
      In deze lessenserie focussen we op **unit tests**: kleine, duidelijke tests waarmee je functies controleert. ### 🛠️ Opdracht 1 – winkelmandje.py Maak een nieuw Python-bestand aan met de naam `winkelmandje.py` en doe het volgende: 1. Schrijf een functie `bereken_totaalprijs(prijzen)` die een lijst van prijzen optelt. 2. Voorbeeld: `bereken_totaalprijs([2.50, 4.00, 3.25])` moet `9.75` opleveren. 3. Print het resultaat van je functie met verschillende lijsten. 4. Probeer ook een lege lijst – wat gebeurt er? ### 🧠 Reflectie - Welk van de testsoorten vind jij het belangrijkste? Leg in eigen woorden uit waarom! - Wat gebeurt er als je iets fout typt in je functie? - Wat als je functie 3 keer voorkomt in een groter programma – hoe test je dat? - Hoe zou je dit automatisch kunnen controleren? ### 📤 Inleveren - Lever het bestand `winkelmandje.py` in (.py). - Beantwoord de drie reflectievragen in een apart .txt of .pdf bestand. ## 2 Je eerste unit test schrijven ### **🎯** Leerdoelen - Je kunt een eenvoudige test schrijven met de module `unittest`. - Je weet wat `assertEqual()` doet. - Je voert je testbestand uit en controleert of het slaagt. ### 💡 Uitleg In de vorige les heb je een functie gemaakt die de totaalprijs berekent van een lijst met bedragen. Nu ga je leren hoe je automatisch kunt testen of die functie goed werkt. Hiervoor gebruik je de module `unittest`. Je schrijft testfuncties waarin je verwacht wat de uitkomst moet zijn. Als die klopt, krijg je een groene melding. Als die fout is, zie je precies waar het misgaat. #### Voorbeeldtest: ```python import unittest def bereken_totaalprijs(prijzen): totaal = 0 for prijs in prijzen: totaal += prijs return totaal class TestTotaalprijs(unittest.TestCase): def test_drie_bedragen(self): self.assertEqual(bereken_totaalprijs([2.50, 4.00, 3.25]), 9.75) def test_lege_lijst(self): self.assertEqual(bereken_totaalprijs([]), 0) def test_een_bedrag(self): self.assertEqual(bereken_totaalprijs([5.00]), 5.00) # def test_nog_een_bedrag(self): # self.assertEqual(bereken_totaalprijs([5.00, 2.00]), 8.00) if __name__ == '__main__': unittest.main() ``` Je voert het testbestand uit met: ```bash python totaalprijs_test.py ``` ### 🛠️Opdracht 1 Maak regel 9 en 10 actief. Voer het bestand opneuw uit. Wat zie? Kna je verklaren wat er gebeurt? ### 🛠️ Opdracht 2 – totaalprijs\_test.py Je gaat nu je eigen functie `bereken_totaalprijs()` uit les 1 testen. 1. Maak een nieuw bestand aan: `totaalprijs_test.py`. 2. Kopieer je functie `bereken_totaalprijs(prijzen)` uit `winkelmandje.py`. 3. Schrijf een testklasse `TestTotaalprijs` waarin je de functie test met `unittest`. 4. Schrijf minstens drie tests: - Lijst met meerdere bedragen (bijv. `[2.50, 3.50]`) → controleer of totaal klopt. - Lege lijst → verwacht `0`. - Lijst met één bedrag → verwacht dat bedrag. 5. Voer je bestand uit in de terminal met `python totaalprijs_test.py`. ### 🧠 Reflectie - Wat gebeurt er als een test slaagt? En als hij faalt? - Wat zijn de voordelen van automatisch testen vergeleken met handmatig printen? - Hoe weet je zeker dat je test goed geschreven is? ### 📤 Inleveren - Lever een .txt of .pdf-bestand in met het antwoord op de vraag uit Opdracht 1. - Lever het bestand `totaalprijs_test.py` in (.py). ## 3 Testen met lijsten en tekst ### **🎯** Leerdoelen - Je leert functies testen die werken met tekst en lijsten. - Je gebruikt `assertTrue()` en `assertFalse()`. - Je test of een bepaald product in een lijst voorkomt. ### 💡 Uitleg Veel programma's werken met lijsten van gegevens, zoals producten of gebruikers. Het is belangrijk dat je functies goed testen of iets voorkomt in een lijst, of hoeveel elementen erin zitten. Stel, je hebt een lijst met producten: ```python producten = ["kaas", "melk", "brood"] ``` Dan kun je bijvoorbeeld een functie maken die kijkt of een product voorkomt: ```python def zoek_product(lijst, naam): product_gevonden = gezochte_product_naam in product_lijst return product_gevonden ``` En die functie testen met: ```python self.assertTrue(zoek_product(["melk", "brood"], "melk")) self.assertFalse(zoek_product(["kaas", "brood"], "cola")) ``` ### 🛠️ Opdracht 1 – producten\_test.py 1. Maak een nieuw bestand `producten_test.py`. 2. Schrijf een functie `zoek_product(lijst, naam)` die `True` geeft als het product in de lijst staat. 3. Maak een testklasse `TestProductZoeken`. 4. Schrijf drie tests: - Zoek naar een bestaand product → `assertTrue` - Zoek naar een niet-bestaand product → `assertFalse` - Zoek in een lege lijst → `assertFalse` 5. Voer je testbestand uit met `python producten_test.py`. #### Uitbreiding (optioneel) Maak ook een functie `tel_producten(lijst)` die het aantal producten telt, en schrijf daar een test voor met `assertEqual`. ### 🧠 Reflectie - Wat is het verschil tussen `assertTrue` en `assertEqual`? - Waarom is het handig om een lege lijst te testen? - Hoe weet je zeker dat je lijst-functies in alle gevallen goed werken? ### 📤 Inleveren - Lever het bestand `producten_test.py` in (.py). - Lever een reflectiedocument in (.txt of .pdf) met jouw antwoorden op de vragen. ## 4 Fouten en `assertRaises` ### **🎯** Leerdoelen - Je weet wat een foutmelding (exception) is in Python. - Je leert testen of een functie op de juiste manier een fout geeft. - Je gebruikt `assertRaises` in je testcode. ### 💡 Uitleg In Python krijg je een **foutmelding** (ofwel: *exception*) als er iets misgaat, zoals delen door nul of een ongeldig type. Stel je schrijft deze functie: ```python def deel(a, b): return a / b ``` Als je `deel(10, 0)` probeert, krijg je deze fout: ```python ZeroDivisionError: division by zero ``` In een goede functie wil je zulke fouten **voorspelbaar** en **controleerbaar** maken, bijvoorbeeld zo: ```python def deel(a, b): if b == 0: raise ValueError("Delen door nul is niet toegestaan") return a / b ``` Je kunt dan testen of de fout netjes wordt afgehandeld, met: ```python with self.assertRaises(ValueError): deel(10, 0) ``` ### 🛠️ Opdracht 1 – deel\_test.py 1. Maak een nieuw bestand `deel_test.py`. 2. Schrijf een functie `deel(a, b)` die: - Een `ValueError` geeft als `b == 0` - Anders de uitkomst van `a / b` teruggeeft 3. Maak een testklasse `TestDelen` met drie tests: - Deel 10 door 2 → verwacht `5.0` - Deel 9 door 3 → verwacht `3.0` - Deel door 0 → verwacht `ValueError` met `assertRaises` 4. Voer je tests uit met `python deel_test.py`. ### 🧠 Reflectie - Waarom is het belangrijk om ook foutgevallen te testen? - Wat is het verschil tussen een fout en een mislukte test? - Hoe weet je of je functie veilig omgaat met verkeerde input? ### 📤 Inleveren - Lever het bestand `deel_test.py` in (.py). - Lever een .txt of .pdf-bestand in met antwoorden op de reflectievragen. ## 5 Testen van klassen met `setUp()` ### **🎯** Leerdoelen - Je weet wat een klasse is in Python. - Je leert hoe je een klasse test met `unittest`. - Je gebruikt `setUp()` om herhaling in je testcode te voorkomen. ### 💡 Uitleg In grotere programma’s werk je vaak met **klassen**. Die bestaan uit eigenschappen (zoals naam en prijs) en methodes (zoals korting berekenen). Bijvoorbeeld een klasse `Product`: ```python class Product: def __init__(self, naam, prijs): self.naam = naam self.prijs = prijs def prijs_incl_btw(self): return self.prijs * 1.21 ``` Als je zo'n klasse vaak moet testen, wil je niet steeds opnieuw een object aanmaken in elke test. Daarom gebruik je `setUp()`: ```python class TestProduct(unittest.TestCase): def setUp(self): self.product = Product("muis", 10.00) def test_naam(self): self.assertEqual(self.product.naam, "muis") def test_prijs(self): self.assertEqual(self.product.prijs, 10.00) def test_prijs_incl_btw(self): self.assertAlmostEqual(self.product.prijs_incl_btw(), 12.10) ``` ### 🛠️ Opdracht 1 – product\_test.py 1. Maak een nieuw bestand `product_test.py`. 2. Schrijf een klasse `Product` met: - Eigenschappen `naam` en `prijs` - Methode `prijs_incl_btw()` die 21% btw toevoegt 3. Maak een testklasse `TestProduct` waarin je in `setUp()` een `Product` aanmaakt. 4. Voeg minimaal drie tests toe: - Test of de naam klopt - Test of de prijs klopt - Test of de prijs inclusief btw ongeveer klopt (gebruik `assertAlmostEqual`) ### 🧠 Reflectie - Wat is het voordeel van `setUp()` gebruiken? - Wanneer gebruik je `assertAlmostEqual` in plaats van `assertEqual`? - Hoe zou je meerdere producten kunnen testen zonder dubbel werk? ### 📤 Inleveren - Lever het bestand `product_test.py` in (.py). - Lever een reflectiedocument in (.txt of .pdf) met jouw antwoorden op de vragen. ## 6 Edge cases en grenswaarden ### **🎯** Leerdoelen - Je weet wat een edge case is. - Je test functies met bijzondere of extreme invoer. - Je denkt vooraf na over mogelijke problemen in je functie. ### 💡 Uitleg Een **edge case** is een grensgeval of een extreme situatie waarin je functie getest wordt. Zulke gevallen zorgen vaak voor fouten als je er niet vooraf aan denkt. Voorbeelden van edge cases: - Een lege lijst - De waarde `0` - Negatieve getallen - Extreem grote of kleine getallen #### Voorbeeld: verzendkosten berekenen Stel, je schrijft een functie die verzendkosten berekent op basis van het aantal producten: ```python def bereken_verzendkosten(aantal): if aantal <= 0: raise ValueError("Aantal moet positief zijn") elif aantal <= 3: return 2.50 elif aantal <= 10: return 5.00 else: return 0.00 ``` Je kunt dan tests schrijven voor grenswaarden zoals 3, 4, 10 en 11. ### 🛠️ Opdracht 1 – verzendkosten\_test.py 1. Maak een nieuw bestand `verzendkosten_test.py`. 2. Schrijf een functie `bereken_verzendkosten(aantal)` met de volgende regels: - 1 t/m 3 producten → €2,50 - 4 t/m 10 producten → €5,00 - Meer dan 10 producten → gratis - 0 of minder → `ValueError` 3. Schrijf een testklasse met tests voor: - `bereken_verzendkosten(1)` → €2,50 - `bereken_verzendkosten(3)` → €2,50 - `bereken_verzendkosten(4)` → €5,00 - `bereken_verzendkosten(10)` → €5,00 - `bereken_verzendkosten(11)` → €0,00 - `bereken_verzendkosten(0)` → foutmelding (`assertRaises`) ### 🧠 Reflectie - Waarom is het belangrijk om grenswaarden te testen? - Wat zou er gebeuren als je `aantal == 0` niet test? - Ken je een voorbeeld uit de praktijk waar een fout ontstond door een vergeten randgeval? ### 📤 Inleveren - Lever het bestand `verzendkosten_test.py` in (.py). - Lever een reflectiedocument in (.txt of .pdf) met je antwoorden. ## 7 Eindopdracht – Testen in de praktijk ### **🎯** Leerdoelen - Je past toe wat je geleerd hebt over unit testen. - Je denkt zelfstandig na over wat belangrijk is om te testen. - Je levert een werkend testbestand in met meerdere tests. ### 💡 Uitleg In deze les werk je aan een kleine testset voor een programma naar keuze. Je kiest één van de twee scenario's hieronder. Je schrijft zelf de functies én de bijbehorende `unittest`-tests. #### Scenario 1 – Webshop-functies Je maakt een verzameling functies zoals: - `bereken_totaalprijs(prijzen)` - `bereken_korting(prijs, procent)` - `bereken_verzendkosten(aantal)` Je schrijft voor elk van deze functies minstens 2 tests, waaronder minstens 1 edge case per functie. #### Scenario 2 – Quiz-controlefunctie Je schrijft een functie `controleer_antwoord(gegeven, verwacht)` die controleert of het antwoord juist is (hoofdletterongevoelig en spaties tellen niet mee). Voorbeeld: ```python controleer_antwoord(" Python ", "python") → True ``` Schrijf meerdere tests voor deze functie: - Juist antwoord met extra spaties - Hoofdletters door elkaar - Verkeerd antwoord → moet `False` geven ### 🛠️ Opdracht – Kies en test 1. Kies scenario 1 (webshop) of scenario 2 (quiz). 2. Maak een nieuw testbestand (bijvoorbeeld `webshop_test.py` of `quiz_test.py`). 3. Schrijf de functies zoals hierboven beschreven. 4. Maak een testklasse en voeg minimaal 6 goed werkende tests toe (minstens 2 per functie). 5. Zorg dat je ook minstens één foutmelding test met `assertRaises`. ### 🧠 Reflectie - Welke test vond je het lastigst om te schrijven? Waarom? - Wat is volgens jou een goede test? En wat niet? - Hoe zou je deze testset uitbreiden als je meer tijd had? ### 📤 Inleveren - Lever je testbestand in (.py). - Lever een reflectieverslag in (.txt of .pdf). - Als je extra functionaliteit of creatieve toevoegingen hebt gemaakt: geef dat kort aan in je verslag. # Cyber Security 2 Status: moet nog worden aangevuld. 1 is herhaling/uitbreiding van Cyber Security 1 2 en 2 zijn belangijrk voor SD ## 1 Cybersecurity, risico versus impact ### Inleiding In cybersecurity 1 hebben we gekeken naar een aantal soorten cyberaanvallen. We gaan ons lijstje uitbreiden. ### 🛡️ Soorten Cyberaanvallen – Overzicht 1. **Phishing:** iemand probeert jou te misleiden om je wachtwoord af te geven (bv. via een nep-mail van je bank) 2. **Adware:** software dat ongevraagd advertenties toont. 3. **Virus**: speciaal soort malware dat zichzelf kan vermenigvuldigen (net als het Corona virus). 4. **SQL-injection:** via een formulier wordt je database gehackt 5. **Man-in-the-middle:** iemand onderschept je gegevens tussen jou en een website 6. **Trojan Horse**: Lijkt op legitieme software, maar voert op de achtergrond schadelijke acties uit. 7. **Randsomware**: Blokkeert je bestanden of systeem en eist losgeld om weer toegang te krijgen. 8. **Spyware**: Volgt je activiteiten op je apparaat zonder dat je het merkt, vaak om wachtwoorden of surfgedrag te stelen. 9. **Keylogger**: Registreert alles wat je typt, zoals wachtwoorden en privéberichten. 10. **Distributed Denial-of-Service (DDoS)**: Een aanval waarbij een website of server overspoeld wordt met verkeer en daardoor onbruikbaar wordt. 11. **Brute Force Attack**: Het systematisch proberen van alle mogelijke wachtwoorden tot het juiste gevonden is. 12. **SQL Injection**: Aanval via een invoerveld waarin schadelijke databasecode wordt ingevoerd. 13. **Cross-Site Request Forgery (CSRF**): De gebruiker wordt misleid om zonder het te weten een actie uit te voeren, zoals een betaling. #### 🧠🎯 Test je kennis – Cyberaanvallen **Opdracht:** Lees elk voorbeeld en probeer te raden om welke cyberaanval het gaat. Klik op de vraag om jezelf te controleren.
      1. Je krijgt een e-mail van “de bank” met een link waarin je gevraagd wordt opnieuw in te loggen, maar het is een nepwebsite. Phishing
      2. Zodra je een gratis app installeert, verschijnen er overal pop-ups met reclame, zelfs als je de app niet gebruikt. Adware
      3. Een programma op je computer verspreidt zich automatisch naar andere bestanden en computers, net als een griepvirus. Virus
      4. Een website is opeens onbereikbaar omdat duizenden bots tegelijk verzoeken sturen naar de server. DDoS-aanval
      5. Je klikt op een “update”-melding, maar je installeert ongemerkt een programma dat op de achtergrond je bestanden versleutelt en geld vraagt om ze terug te krijgen. Ransomware
      6. Je vult een formulier in op een website, en een hacker gebruikt die invoer om toegang te krijgen tot de database. SQL-injection
      7. Iemand op hetzelfde wifi-netwerk leest mee met de gegevens die jij naar een website stuurt, zonder dat jij het merkt. Man-in-the-middle
      8. Je downloadt een handig ogend programma, maar zodra je het opent blijkt het kwaadaardige acties uit te voeren op je computer. Trojan Horse
      9. Je toetsenbordactiviteit wordt in het geheim vastgelegd zodat iemand je wachtwoord kan achterhalen. Keylogger
      10. Een hacker probeert tienduizenden verschillende wachtwoorden totdat hij de juiste vindt en toegang krijgt tot een account. Brute Force Attack
      11. Een kwaadaardige link zorgt ervoor dat jij zonder het te weten geld overmaakt via een formulier dat je niet hebt ingevuld. Cross-Site Request Forgery (CSRF)
      12. Je surft naar een website en zonder te klikken wordt automatisch schadelijke software op je computer gezet. Drive-by Download
      13. Je bezoekt een vertrouwde website, maar deze is ongemerkt gehackt en stuurt jou door naar een foute pagina. Watering Hole Attack
      14. Een hacker onderschept je login-sessie en gebruikt jouw sessie-ID om toegang te krijgen tot je account. Session Hijacking
      15. Je krijgt een sms van “de pakketdienst” met een link naar een track-and-trace pagina, maar die blijkt nep te zijn. Smishing
      16. Iemand installeert een app op jouw telefoon die in het geheim foto’s, locatie en berichten doorspeelt. Spyware
      17. Je gebruikt overal hetzelfde wachtwoord en een hacker probeert deze combinatie op andere websites. Credential Stuffing
      ### **📚** Uitleg: Wat is het verschil tussen risico en impact? 🔍 **Risico** = Hoe groot is de kans dat het gebeurt? 💥 **Impact** = Wat zijn de gevolgen als het gebeurt? #### 🎮 Voorbeelden - ##### **Fiets wordt gestolen bij school** - *Risico*: Hoog → je laat hem vaak ongeopend buiten staan. - *Impact*: Middel → je baalt, moet lopen, misschien nieuwe kopen. - ##### **Telefoon valt in water** - *Risico*: Laag → je past goed op. - *Impact*: Hoog → je bent alles kwijt: foto’s, apps, schoolwerk. - ##### **Je vergeet een wachtwoord** - *Risico*: Middel → gebeurt wel eens. - *Impact*: Laag → je kunt meestal resetten. ### 🛠️ Opdracht Lees de 6 scenarios en bepaal vervolgens van elke scenario het **risico** en de **impact** en licht je keuze toe. ##### **Scenario 1 Phishing** Stel je voor: je krijgt een e-mail van “de Rabobank” met als onderwerp **“Dringende actie vereist – je account wordt geblokkeerd”**. In het bericht staat dat je onmiddellijk moet inloggen om je rekening te verifiëren. Er staat een link bij die lijkt op de echte site, maar eigenlijk leidt naar een nepwebsite. Zodra je daar je gegevens invult, krijgt een oplichter direct toegang tot je bankaccount. ##### Scenario 2 Ransomware Je opent een bijlage in een e-mail die lijkt te komen van je school, bijvoorbeeld “roosterwijziging.pdf”. Maar zodra je het opent, wordt je scherm zwart en verschijnt er een melding: **“Je bestanden zijn versleuteld. Betaal €300 in bitcoins om ze terug te krijgen.”** Alle documenten, foto’s en schoolopdrachten op je laptop zijn geblokkeerd. Dit is een **ransomware-aanval**: je bestanden zijn gegijzeld en je moet losgeld betalen om ze terug te krijgen. ##### Scenario 3 Adware Je downloadt een gratis spelletje van een onbekende website. Na de installatie verschijnen er ineens overal pop-ups en reclames, zelfs als je de browser niet open hebt. Je wordt telkens doorgestuurd naar webwinkels of vage aanbiedingen. Je computer wordt trager, en sommige advertenties proberen je te laten klikken op gevaarlijke links. Dit is een typische **adware-infectie**: ongewenste software die reclame toont en soms zelfs je surfgedrag volgt. ##### Scenario 4 Brute Force Je hebt een simpel wachtwoord zoals “welkom123” voor je schoolaccount. Een hacker probeert via een script duizenden combinaties van veelgebruikte wachtwoorden, één voor één, totdat jouw wachtwoord wordt geraden. Dit heet een **brute force-aanval**: de aanvaller probeert systematisch allerlei wachtwoorden uit tot hij toegang krijgt tot je account. Als je een zwak of kort wachtwoord gebruikt, ben je hier extra kwetsbaar voor. ##### Scenario 5 DDos aanval Je wilt je favoriete webshop bezoeken, maar de site laadt niet of geeft een foutmelding. Op dat moment voeren hackers een **DDoS-aanval** uit: duizenden computers sturen tegelijk nepverzoeken naar de server van de webshop, waardoor die overbelast raakt en voor echte bezoekers onbereikbaar wordt. De website stort tijdelijk in, terwijl er eigenlijk niets “stuk” is — hij wordt gewoon overspoeld met verkeer. ##### Scenario 6 Man in the Middle Je zit op een openbaar wifi-netwerk in de trein en logt in op een webshop. Wat je niet weet, is dat een hacker op hetzelfde netwerk zit en al het internetverkeer onderschept. Hij leest ongemerkt mee met de gegevens die jij verstuurt, zoals je inlognaam en wachtwoord. Dit is een **man-in-the-middle-aanval**: iemand zit letterlijk “tussen jou en de website in” en vangt alles op wat je verstuurt, zonder dat je het doorhebt.
      **Cyberaanval** **Risico** **Impact** **Uitleg**
      1\. Phishing Laag Hoog Risico laag omdat we meestal de nep-email herkennen, maar als we er toch "*intrappen*" dan is de impact groot want dan kan je (veel) geld verliezen.
      2\. Ransomware
      3\. Adware
      4\. Brute Force
      5\. DDoS
      6\. Man in the Middle
      ### 📤 Inleveren Bepaal van scenario 2 t/m 6 het risico en de impact en leg uit waarom ## 2 SQL Injection in PHP ### 🎯 Leerdoelen - Je begrijpt wat een SQL Injection is en waarom het gevaarlijk is. - Je kunt zelf een simpele SQL Injection uitvoeren op een onveilige PHP-pagina. - Je kunt uitleggen hoe je dit soort aanvallen voorkomt. ### 💡 Uitleg Bij een **SQL Injection** wordt misbruik gemaakt van een fout in je code, waarbij de invoer van een gebruiker direct in een SQL-query wordt gezet. Als je niet oppast, kan een hacker zo gegevens uit je database stelen of zelfs verwijderen. Een klassiek voorbeeld is een inlogformulier waarin de gebruikersinvoer zonder controle in de query komt te staan: ```php query($sql); if ($result->num_rows > 0) { echo "Welkom!"; } else { echo "Ongeldige login."; } ?> ``` Als een aanvaller het volgende invoert: ``` Gebruikersnaam: ' OR '1'='1 Wachtwoord: watdanook ``` dan wordt de SQL-query dit: ``` SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'watdanook' ``` Omdat '1'='1' altijd waar is, kan de aanvaller inloggen zonder wachtwoord te kennen. ### 🛠️ Opdracht – Voer een SQL Injection uit 1. Maak een database `testdb` met een tabel `users`: ```sql CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(255), password VARCHAR(255) ); ``` 2. Voeg een gebruiker toe: ```sql INSERT INTO users (username, password) VALUES ('admin', 'admin123'); ``` 3. Maak een PHP-bestand `login.php` met bovenstaande onveilige code. 4. Maak een formulier met twee velden: `username` en `password`. 5. Voer een SQL-injection uit zoals hierboven uitgelegd. Wat gebeurt er? ### 🛠️ Vervolgopdracht – Beveilig je formulier 1. Pas de code aan zodat je gebruik maakt van **prepared statements**: ```php prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $username, $password); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows > 0) { echo "Welkom!"; } else { echo "Ongeldige login."; } ?> ``` 2. Test of de SQL Injection nu nog werkt. Leg uit waarom het niet meer lukt. ### 🧠 Reflectie - Waarom is SQL-injection zo gevaarlijk voor een website? - Wat had de originele programmeur moeten doen om dit te voorkomen? - Welke techniek moet je gebruiken in PDO om SQL injection te voorkomen. - Wat gebeurt er als je bij de aangepaste (veilige) code toch SQL-injection probeert? - Wat zou een reden kunnen zijn dat een software developer geen gebruik maakt van technieken om SQL injection te voorkomen? ### 📤 Inleveren - Lever je aangepaste code in waarbij SQL injection niet meer mogelijk is. - Maak de reflectie en lever die in (PDF). ## 3 Cross-Site Scripting (XSS) ### 🎯 Leerdoelen - Je weet wat Cross-Site Scripting (XSS) is en hoe het werkt. - Je kunt zelf een XSS-aanval uitvoeren in een onveilige webpagina. - Je kunt uitleggen hoe je je website kunt beschermen tegen XSS. ### 💡 Uitleg #### Wat is XSS? **Cross-Site Scripting (XSS)** is een aanval waarbij een aanvaller kwaadaardige scripts (zoals JavaScript) invoert in een formulier of URL. Deze scripts worden dan uitgevoerd in de browser van een andere bezoeker. Stel: je maakt een gastenboek waar mensen een berichtje kunnen achterlaten. Als je hun invoer niet goed filtert, kan iemand dit invoeren: ``` ``` Iedereen die daarna het gastenboek bezoekt, krijgt dan deze melding te zien – het script wordt uitgevoerd alsof het van jouw site komt. ### 🛠️ Opdracht – Voer een XSS-aanval uit 1. Maak een PHP-bestand `gastenboek.php` met het volgende formulier en afhandelingscode: ```html
      Naam:
      Bericht:
      Bericht ontvangen:"; echo "

      Van: " . $_POST['naam'] . "

      "; echo "

      " . $_POST['bericht'] . "

      "; } ?> ``` 2. Voer nu als bericht het volgende in: ``` ``` 3. Wat gebeurt er? ### 🛠️ Vervolgopdracht – Beveilig je formulier 1. Pas de PHP-code aan zodat gebruikersinvoer wordt ge-escaped: ```php echo "

      Van: " . htmlspecialchars($_POST['naam']) . "

      "; echo "

      " . htmlspecialchars($_POST['bericht']) . "

      "; ``` 2. Voer nogmaals het script in. Wat gebeurt er nu? ### 🧠 Reflectie - Wat maakt XSS zo gevaarlijk voor je bezoekers? - Wat is het verschil tussen `htmlspecialchars()` en `strip_tags()` in PHP? - Hoe zou jij in een groter project XSS voorkomen? ### 📤 Inleveren - Screenshot van de popup bij onveilige invoer - Screenshot van veilige invoer na beveiliging - Toelichting op je reflectie - Bestandsnamen: - `xss-aanval-.jpg` - `xss-veilige-versie-.jpg` - `xss-reflectie-.pdf` ## 4 Cross-Site Request Forgery (CSRF) ### 🎯 Leerdoelen - Je begrijpt wat Cross-Site Request Forgery (CSRF) is en waarom het gevaarlijk is. - Je kunt uitleggen hoe een CSRF-aanval werkt met een voorbeeld. - Je leert hoe je je webapplicaties kunt beschermen tegen CSRF. ### 💡 Uitleg #### Wat is CSRF? **Cross-Site Request Forgery (CSRF)** is een aanval waarbij een gebruiker wordt misleid om een actie uit te voeren op een website waarop hij is ingelogd, zonder dat hij het weet. Bijvoorbeeld: je bent ingelogd op je bankwebsite in tabblad 1. In tabblad 2 bezoek je een foute website die automatisch een formulier verstuurt waarmee geld wordt overgemaakt vanaf jouw bankaccount. #### Voorbeeld ```html ``` Als jij op dat moment bent ingelogd bij de bank, wordt dit verzoek uitgevoerd zonder dat je het merkt! ### 🛠️ Opdracht – Begrijp een CSRF-aanval 1. Maak een simpel PHP-bestand `bank.php` dat zogenaamd een betaling uitvoert: ```php ``` 2. Maak nu een tweede HTML-bestand `aanval.html` dat de aanval uitvoert: ```html ``` 3. Open `bank.php` in een tabblad en daarna `aanval.html` in een ander tabblad. Wat zie je? ### 🛠️ Vervolgopdracht – Bescherm je formulier 1. Gebruik een **CSRF-token** in je formulier: ```php session_start(); if (!isset($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } $token = $_SESSION['csrf_token']; ?>
      ``` 1. Controleer in `verwerk.php` of het token klopt: ```php session_start(); if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) { die("CSRF aanval gedetecteerd!"); } echo "Betaling uitgevoerd."; ``` ### 🧠 Reflectie - Waarom is CSRF gevaarlijker dan je op het eerste gezicht denkt? - Wat is het verschil tussen een CSRF-aanval en een XSS-aanval? - Waarom werkt een CSRF-aanval alleen als je al bent ingelogd? - Hoe kun je in een groot project zorgen dat alle formulieren automatisch CSRF-bescherming krijgen? ### 📤 Inleveren - Screenshot van de onveilige aanval (aanval.html). - Screenshot van de beschermde versie met token. - Toelichting bij je reflectie in PDF. - Bestandsnamen: - `csrf-aanval.jpg` - `csrf-beschermd.jpg` - `csrf-reflectie.pdf` # DigitalSkills-01 ## 01 - Introductie Digital Skills & Portfolio-opbouw Bouw je professionele toekomst met digitale skills! Welkom! Als toekomstige softwareontwikkelaar is je digitale portfolio straks je visitekaartje. In deze module 'Digitale Skills' leer je de essentiële vaardigheden: effectief online werken, samenwerken en jezelf professioneel online presenteren. We bouwen gericht aan jouw portfolio, zodat jij straks vol zelfvertrouwen kunt solliciteren. **Wat kun je verwachten in de module 'Digitale Skills'?** In deze module duiken we in de digitale vaardigheden die essentieel zijn voor jouw succes als toekomstige softwareontwikkelaar. Je kunt de volgende onderwerpen en activiteiten verwachten: ### 🎯 **Wat ga je vandaag doen?** In deze eerste les: - Maak je kennis met het vak Digital Skills. - Start je met het bouwen van je eigen **persoonlijke digitale portfolio**. - Maak je een professioneel **LinkedIn-profiel** aan. - Koppel je LinkedIn aan **Stichting Praktijkleren**, zodat je toegang krijgt tot **LinkedIn Learning**. Deze twee digitale profielen (portfolio & LinkedIn) vormen de basis van jouw ontwikkeling dit jaar! --- ### 🧠 **Waarom is dit belangrijk?** Als software developer is het belangrijk dat je: - Digitale vaardigheden kunt aantonen. - Weet hoe je jezelf professioneel online presenteert. - Kunt laten zien wat je hebt gemaakt, geleerd en wie je bent als developer. --- ### ✅ **Opdrachtstappen** #### ✏️ **1. Start je portfolio** ➡️ **Maak een eerste pagina “Over mij”** met daarin: - Je naam, klas, opleiding - Een korte bio (wie ben je? wat zijn je interesses? wat wil je leren?) - Een foto of afbeelding die jou representeert - 1 persoonlijk leerdoel voor dit schooljaar --- #### 💼 **2. Maak een LinkedIn-profiel** Ga naar [https://www.linkedin.com](https://www.linkedin.com) en maak een account aan met je schoolmail. Vul minimaal in: - Je voor- en achternaam - Opleiding: "Software Developer – ROC v Amsterdam Amstelland College" - Profielfoto (neutrale of professionele foto) - Samenvatting: wie ben je, wat kun je, wat wil je leren? --- #### 🔗 **3. Koppel LinkedIn aan Stichting Praktijkleren** Volg deze stappen om gratis toegang te krijgen tot **LinkedIn Learning**: 1. Ga naar https://link[www.stichtingpraktijkleren.nl](https://www.stichtingpraktijkleren.nl) 2. Volg de instructies om je profiel te koppelen 3. Test of je toegang hebt tot [LinkedIn Learning](https://www.linkedin.com/learning/) > ✅ Heb je hulp nodig? Vraag je docent of check de stap-voor-stap uitleg via de link hierboven. --- ### **✍️** **Wat lever je in via Canvas?** Lever vóór les 2 in (via deze opdracht): 1. 📎 Een **link naar jouw portfolio** of een **screenshot van je Over mij-pagina** 2. 📎 Een **screenshot van je LinkedIn-profiel** (met zichtbare naam, opleiding, profielfoto) 3. ✏️ Een kort reflectieantwoord (mag in Word of als tekst inleveren): - Wat vond je makkelijk of moeilijk aan deze opdracht? - --- Wat wil je als volgende stap toevoegen aan je portfolio of profiel? ## 02 Digitale planning & time management Je leert hoe je je schoolweek overzichtelijk kunt plannen met behulp van een digitale tool en leert nadenken over je prioriteiten en tijdsindeling. **Inleveren :** een reflectiedocument + screenshot in als bijlage ( pdf bestand ) --- ### 🎯 **Leerdoel** Na deze opdracht kun je een persoonlijke digitale weekplanning maken in een tool naar keuze en nadenken over je tijdsindeling en prioriteiten. --- ### ✅ **Stap 1: Kies een plannings-tool** Je kiest zelf een digitale tool om je weekplanning te maken. Mogelijke opties: - **Google Calendar** → [https://calendar.google.com/](https://calendar.google.com/) - **Outlook Agenda** → via je schoolmail - **Trello** → [https://trello.com/](https://trello.com/) - **Todoist** → [https://todoist.com/](https://todoist.com/) Kies een tool die je handig vindt of al kent. --- ### 🗓️ **Stap 2: Plan je komende week** Maak een planning van je komende week (maandag t/m zondag) en voeg minimaal deze onderdelen toe: - Schoollessen (je rooster) - Huiswerk/studietijd - Projecttijd of stage (indien van toepassing) - Vrije tijd / sport / ontspanning - **Minimaal één ‘bufferblok’** (tijd voor onverwachte taken) > 🎯 **Tip:** Houd rekening met je energie: wanneer werk jij het beste? --- ### 🔺 **Stap 3: Geef prioriteit aan je taken** Voeg prioriteiten toe aan je taken met labels of kleurcodes: - ✅ **Must** = Moet gebeuren (hoge prioriteit) - 🔄 **Should** = Belangrijk, maar niet dringend - ✳️ **Could** = Extra’s, handig als je tijd hebt Bijvoorbeeld: - Ma 15:00 – ✅ Wiskunde opdracht afmaken - Di 20:00 – ✳️ Tutorial Python kijken --- ### **✍️** **Stap 4: Reflectie – Inleveren in Canvas** Lever je opdracht in via **Canvas** (als bijlage), met daarin: 1. 📸 Een **screenshot** van je digitale planning 2. 🧠 **Reflectievragen** (typ je antwoorden in een Word- of PDF-bestand): - Wat valt je op aan jouw planning? - Welke taken vond je lastig in te plannen? - Wat ga je de volgende keer anders doen? - Welke tool heb je gebruikt, en zou je die blijven gebruiken? Waarom (niet)? ## 03 Typvaardigheid & sneltoetsen **Waarom een portfolio?** Jouw portfolio laat zien wie jij bent als developer. Het is hét bewijs van wat je kunt en wat je hebt gemaakt. Of je nu een stage zoekt, een baan of aan een project werkt—een goed portfolio helpt je om op te vallen. 💡 Laat zien waar je trots op bent. 🚀 Vergroot je kansen op stage en werk. 👨‍💻 Bouw aan je professionele toekomst! **Kortom:** je portfolio is jouw visitekaartje als software developer. Maak er iets van waar je achter staat! ### **✍️** Opdracht 3 Maak je eigen linkedln profiel aan en koppel je stichting praktijkleren account zodat je de learning cursusen kan gebruiken Inleveren: ## 04 Besturingssystemen & bestandsbeheer Stel je voor dat je een brief schrijft. Je kunt die in Word schrijven, en opslaan als een ".docx"-bestand, of als een ".pdf"-bestand om hem te printen. Die ".docx" en ".pdf" zijn *bestandsformaten*: ze vertellen de computer hoe de informatie in het bestand is georganiseerd. Elk type bestand heeft zijn eigen indeling, zodat de computer weet hoe het geopend en weergegeven moet worden

      https://www.linkedin.com/learning/writing-a-tech-resume/file-format

      ### **✍️** Opdracht 2 Je gaat onderzoek doen naar verschillende soorten bestandsformaten. Je maakt een overzicht in een **spreadsheet** waarin je uitlegt wat elk formaat is, waarvoor het gebruikt wordt, en wat de voor- en nadelen zijn. #### Bestandsformaten: - `txt`, `docx`, `pdf`, `py`, `html`, `css`, `jpg`, `png`, `gif`, `mp4`, `zip`, `csv` Zoek zelf nog naar 8 andere bestandsformaten. Beantwoord per bestandsformaat de volgende vragen (één rij per formaat): 1. **Type data** – Wat voor soort data bevat dit formaat? (Bijv. tekst, audio, video, afbeelding) 2. **Programma’s** – Welke programma’s gebruik je om dit bestand te openen of te maken? 3. **Kenmerken** – Wat zijn belangrijke eigenschappen van het formaat? (Bijv. compressie, kwaliteit, bestandsgrootte) 4. **Gebruik** – Wanneer zou jij dit bestandsformaat gebruiken? #### Eisen: - Je geeft duidelijke uitleg bij elk formaat. - Je gebruikt je eigen woorden (geen copy-paste). - Je beantwoordt alle vragen per formaat. - Je werkt netjes en overzichtelijk. ### Inleveren - 1 .csv bestand - Eén `.csv` bestand. - Bestandsnaam: `voornaam_achternaam_bestandsformaten.csv`

      [https://www.youtube.com/watch?v=aZ\_wB9V6yos](https://www.youtube.com/watch?v=aZ_wB9V6yos)

      ### **✍️** Opdracht 4 ## 05 Digitale identiteit en netiquette ### **✍️** Opdracht 5 ## 06 Cyberveiligheid & privacy ### **✍️** Opdracht 6 ### ## 07 ### **✍️** Opdracht 7 ### ## 08 Herhaling + Voorbereiding op toets ### **✍️** Opdracht 8 ## Toetsweek ### Eind Opdracht