Översikt
Tredje kursveckan! Denna vecka kan du börja fundera på att titta på den första examinationsuppgiften som du ju har tillgång till, men först efter det att du kikat på veckans övningsuppgifter! Nu är du verkligen på gång! Information om veckans upplägg annonseras löpande i kursens Zulip-kanal.
Torsdag med problemlösning
Section titled “Torsdag med problemlösning”Torsdagen i kursvecka 3 visade Mikael, med Mats som bollplank, hur man kan angripa en ny övningsuppgift metodmässigt — med utgångspunkt i övningsuppgiften Hemliga språk (rövarspråket och Ubbi Dubbi).
Om passet
Section titled “Om passet”Torsdagens pass i kursvecka 3 hölls av Mikael, med Mats som bollplank vid sidan om. I stället för att bara lösa övningsuppgiften Hemliga språk (rövarspråket och Ubbi Dubbi) används den som ett exempel på hur man tacklar en ny, till synes stor uppgift rent metodmässigt — särskilt för den som ännu inte kommit igång med veckans övningsuppgifter.
Att hitta och forka övningsuppgiften
Section titled “Att hitta och forka övningsuppgiften”Mikael letar upp övningen bland modul A:s uppgifter (sorterade på skapelsedatum, så den senaste
dyker upp längst upp) och forkar den till sin egen 1dv025/student-grupp på GitLab — samma
förfarande som en student använder för att få en egen kopia av repot. Ett kort återkommande GitLab-
kvirk demonstreras i förbigående: att skriva in ett projektnamn räcker inte för att komma vidare i
fork-dialogen, man måste också aktivt klicka på sökvägen i listrutan.
VS Code-miljön är en personlig preferens
Section titled “VS Code-miljön är en personlig preferens”Innan uppgiften påbörjas pratar Mikael och Mats kort om hur olika deras VS Code-miljöer ser ut —
bland annat hur man i inställningarna kan stänga av de färgade linjerna mellan paneler/rutor
(Settings → sök på “modern” → Experimental Modern UI avaktiveras) om den experimentella vyn
irriterar. Poängen som görs är att detta är rena smaksaker utan påverkan på uppgiften — det finns
inget “rätt” sätt att ställa in sin editor, bara personliga preferenser.
De inbyggda npm-skripten
Section titled “De inbyggda npm-skripten”Innan uppgiften ens öppnas kör Mikael npm run (utan argument) för att se vilka skript som finns
tillgängliga, sedan npm install för att installera beroenden. Han går igenom skripten i tur och
ordning:
npm startkör huvudprogrammet.npm testkör Vitest i watch-läge — testerna körs direkt men terminalen fortsätter sedan ligga kvar och bevaka filändringar (avslutas med Q).npm run test:runkör samma tester en gång och återgår sedan till prompten — det egentliga engångskommandot.npm run lintkör ESLint. En fråga i chatten om huruvida lint fångar syntaxfel lämnas öppen i passet (“det borde det nog göra”) snarare än att besvaras definitivt.npm run format/npm run format:checkför Prettier nämns men hinns inte demonstreras i detalj.
Testtillägg för att köra enskilda tester
Section titled “Testtillägg för att köra enskilda tester”Mikael visar VS Code:s tillägg för att köra enskilda tester grafiskt i stället för att komma ihåg
testnamn för npm run test:match på kommandoraden — installationen strular till en del live i
passet (tillägget dyker inte upp direkt, kräver en omstart av VS Code), men poängen med verktyget
— att kunna peka ut och köra en enskild testfunktion när man arbetar med en större kodmassa — når
ändå fram.
Pólyas fyra faser för problemlösning
Section titled “Pólyas fyra faser för problemlösning”Innan uppgiftsbeskrivningen ens läses tar Mikael en paus för att beskriva sin egen tankeprocess inför ett nytt problem, och refererar till en klassisk problemlösningsmodell i fyra faser (den matematikern George Pólyas, ursprungligen från boken How to Solve It, även om namnet aldrig sägs helt korrekt i passet):
- Förstå problemet.
- Gör upp en plan.
- Genomför planen.
- Kontrollera resultatet (och reflektera över vad som kan förbättras).
Mats kompletterar med att poängtera att den första fasen — att verkligen förstå problemet — ofta är den svåraste delen när man samtidigt lär sig ett nytt programmeringskoncept: man ska förstå uppgiften och lära sig programmera på en gång, och att kasta sig över tangentbordet direkt är ett säkert sätt att misslyckas med båda samtidigt. Att lösa problemet först med papper och penna (eller en whiteboard) innan man skriver någon kod alls är rådet som ges.
Att läsa uppgiftsbeskrivningen utan att fastna i djupläsning
Section titled “Att läsa uppgiftsbeskrivningen utan att fastna i djupläsning”Mikael demonstrerar sin egen läsartaktik: han skummar beskrivningen i stora drag först (“scrolltaktik”) i stället för att direkt djupläsa varje stycke, och läser bara noggrant i de delar han fastnar i. Han liknar det vid att montera en IKEA-möbel — han tittar på delarna och gissar sig fram, och läser manualen först när det går fel. Mats representerar den motsatta strategin (läsa hela manualen innan man börjar) — båda angreppssätten lyfts fram som giltiga, bara olika.
isLetter, isConsonant och isVowel
Section titled “isLetter, isConsonant och isVowel”Mikael identifierar snabbt att isLetter redan är implementerad och kan återanvändas, medan
isConsonant och isVowel är de två hjälpfunktioner han själv behöver bygga. Han noterar också
att encodeRobber/encodeUbbiDubbi är exporterade från modulen medan hjälpfunktionerna är lokala
— ett sätt att snabbt läsa av en fils publika API bara genom att skumma vilka export-nyckelord
som finns.
Bygga en minimal fungerande kodrad
Section titled “Bygga en minimal fungerande kodrad”I stället för att försöka lösa hela uppgiften på en gång skriver Mikael medvetet minsta möjliga
kod som gör något han kan köra och observera: encodeRobber returnerar först bara sin egen
textparameter oförändrad, testat med console.log och en hårdkodad indata. Genom att sedan bygga
vidare stegvis — en for-loop som itererar över strängens tecken, en resultatvariabel som byggs
upp med += (konkatenering) — närmar han sig lösningen i små, verifierbara steg snarare än att
skriva hela funktionen på en gång. Ett litet men läroriktigt misstag demonstreras här: att starta
resultatvariabeln som undefined i stället för en tom sträng ger undefined i utskriften, vilket
direkt avslöjar att variabeln måste initieras korrekt.
If-satser och en bugg på vägen
Section titled “If-satser och en bugg på vägen”När Mikael sedan lägger till en if-sats som anropar isLetter för att filtrera bort tecken som
inte är bokstäver, dyker ett oväntat värde upp i utskriften. Snarare än att gissa sig fram
felsöker han steget: det visar sig bero på att filen inte sparats innan npm start kördes senast
— ett klassiskt, igenkännbart nybörjarmisstag som Mats själv flikar in att han misstänkte direkt.
Bugsökningen används pedagogiskt som exempel på hur man arbetar sig fram till en trolig
felorsak i stället för att bara krångla vidare i koden.
Att inte hinna klart — och varför det räcker ändå
Section titled “Att inte hinna klart — och varför det räcker ändå”Tiden tar slut innan encodeRobber är helt färdiglöst (konsonant-fallet med att dubblera
bokstaven runt ett o hinns bara beskrivas muntligt, inte kodas klart). Mats poängterar att detta
inte är ett misslyckande: att ha förstått och kunnat använda for-loopen, if-satsen, funktioner
med argument och returvärden samt strängkonkatenering under passet räknas som en stor del av
veckans lärandemål redan uppnådd — resten är en mindre mängd återstående arbete jämfört med det.
Jämförelse med facit (solution-branchen)
Section titled “Jämförelse med facit (solution-branchen)”Avslutningsvis växlar Mikael till uppgiftens solution-branch på GitLab för att jämföra sin egen,
ofärdiga lösning med facit. Strukturen visar sig vara påfallande lik det han själv byggt fram:
en tom sträng som startvärde, en for-loop över strängens tecken och en if/else-konstruktion
som antingen dubblerar konsonanten med ett o emellan eller kopierar tecknet oförändrat. Facitets
solution.md innehåller också en diskussion om alternativa lösningar (bland annat
String.prototype.includes) för den som redan känner sig bekväm med grundkonstruktionerna och vill
utforska andra sätt att skriva samma sak.
Stödjande inspelningar
Section titled “Stödjande inspelningar”Titta igenom dessa, de ger dig grunden för det som är veckans fokus.
Kontrollstrukturer
Section titled “Kontrollstrukturer”En presentation som går igenom de tre kontrollstrukturerna sekvens, selektion och iteration men tre separata videor.
PresentationSekvenser
Section titled “Sekvenser”Vad är egentligen en sekvens? Kursledningen repeterar även debuggern i denna inspelning.
Kontrollstrukturer – en överblick
Section titled “Kontrollstrukturer – en överblick”Kontrollstrukturer är grundläggande verktyg vid programmering, och det finns fyra huvudtyper:
- Sekvens – en följd satser som utförs efter varandra.
- Selektion – ett sätt att välja mellan att exekvera olika satser (
if,switch, villkorsoperatorn?:). - Iteration – ett sätt att upprepa en sats ingen, en eller flera gånger (
while,do...while,for). - Rekursion – en funktion som anropar sig själv. Kommer längre fram i kursen.
Sekvens
Section titled “Sekvens”En sekvens är den enklast möjliga kontrollstrukturen: en följd instruktioner som körs i tur och ordning, en efter en.
Instruktion 1Instruktion 2Instruktion 3Instruktion 4Enkel att förstå i isolation – men eftersom en enskild instruktion i sin tur kan innehålla andra kontrollstrukturer (en selektion, en iteration) kan en till synes rak sekvens ändå bli komplicerad att följa i praktiken.
Selektioner
Section titled “Selektioner”Att göra val i koden är en verklig hörnsten inom programmering. Selektioner är bara ett finare ord för val.
if-satsen
Section titled “if-satsen”Ett enkelt val: är villkorsuttrycket true körs satsen (eller satserna) i if-satsens kropp.
let number = 42if (number === 0) { console.log('Talet är lika med 0.')}Ett villkorsuttryck är ett uttryck som resulterar i något JavaScript betraktar som true eller false. Satserna ska alltid omslutas av klammerparenteser, även när det bara är en enda sats – det gör koden tydligare och mer motståndskraftig mot framtida ändringar.
if...else-satsen
Section titled “if...else-satsen”Ett tvåvägsval: precis ett av alternativen körs, beroende på om villkorsuttrycket är sant eller falskt.
let number = 42if (number % 2 === 0) { console.log('Talet är jämt.')} else { console.log('Talet är udda.')}if...else if...else-satsen
Section titled “if...else if...else-satsen”Ett flervägsval för fler än två alternativ. Villkorsuttrycken testas i tur och ordning, och det första som blir true avgör vilken gren som körs – ett avslutande else (utan eget villkor) kan uteslutas om inget alternativ behöver vara “resten”:
let number = 42if (number < 0) { console.log('Talet är mindre än 0.')} else if (number < 50) { console.log('Talet är större än 0 men mindre än 50.')} else { console.log('Talet är större än, eller lika med, 50.')}// OUTPUT: Talet är större än 0 men mindre än 50.switch-satsen
Section titled “switch-satsen”Ett alternativ till en lång if...else if...else-kedja när flera värden ska jämföras mot samma variabel. case-grenar utan egen kropp “faller igenom” till nästa case som har en – praktiskt när flera värden ska hanteras likadant:
let number = 4switch (number) { case 1: case 2: case 3: case 4: case 5: case 6: console.log('För litet!') break case 7: console.log('Rätt gissat') break case 8: case 9: case 10: console.log('För stort!') break default: console.log(number + ' är inte i det slutna intervallet mellan 1 och 10.') break}// OUTPUT: För litet!break avslutar switch-satsen – glöms det bort fortsätter exekveringen rakt in i nästa case, oavsett dess eget villkor.
Villkorsoperatorn (?:)
Section titled “Villkorsoperatorn (?:)”En vanlig if...else-sats kan ibland lämpligen uttryckas mer kompakt med villkorsoperatorn – den enda operatorn i JavaScript som tar tre operander:
const number = 42let output = 'Talet är 'output += number % 2 === 0 ? 'jämt.' : 'udda.'console.log(output)// OUTPUT: Talet är jämt.Motsvarar exakt samma logik som en fullständig if...else-sats, men som ett uttryck snarare än en sats – lämpar sig bäst för korta, tydliga val, inte för mer invecklad förgrening.
Iterationer
Section titled “Iterationer”Inte sällan behöver samma sak göras flera gånger, alltså upprepas. Det händer alltså att du i din kod behöver upprepa dig för att vara extra tydlig!
while-satsen – förtestad upprepning
Section titled “while-satsen – förtestad upprepning”Så länge villkorsuttrycket utvärderas till true körs satserna i loopens kropp. Villkoret testas innan varje varv, så loopen kan köras noll, en eller flera gånger:
let sum = 0while (sum < 500) { sum = sum + 42}console.log(sum) // OUTPUT: 504do...while-satsen – eftertestad upprepning
Section titled “do...while-satsen – eftertestad upprepning”Satserna i loopens kropp körs minst en gång, eftersom villkoret testas efter varje varv:
let i = 10do { console.log(i + ' ') i++} while (i < 10)// OUTPUT: 10 – körs en gång trots att villkoret redan var falsktfor-satsen – bestämd upprepning
Section titled “for-satsen – bestämd upprepning”Ett annat sätt att uttrycka en while-sats, med initiering av räknare, villkorsuttryck och uppdatering av räknaren samlat på en rad:
let output = ''for (let i = 0; i < 10; i++) { output += i + ' '}console.log(output) // OUTPUT: 0 1 2 3 4 5 6 7 8 9Ordningen är: (1) initiera räknaren en gång, (2) testa villkorsuttrycket, (3) kör satserna, (4) uppdatera räknaren och gå tillbaka till steg 2.
Avbryta en loop – break
Section titled “Avbryta en loop – break”break-satsen avbryter en loop omedelbart, oavsett loopens eget villkor:
let output = ''for (let i = 0; i < 10; i++) { if (i === 4) { break } output += i + ' '}console.log(output) // OUTPUT: 0 1 2 3Gå till nästa iteration – continue
Section titled “Gå till nästa iteration – continue”continue-satsen avslutar den aktuella iterationen och hoppar direkt till nästa varv, utan att köra resten av loopens kropp den gången:
let output = ''for (let i = 0; i < 10; i++) { if (i % 3 === 0) { continue } output += `${i} `}console.log(output) // OUTPUT: 1 2 4 5 7 8continue anses av vissa vara “bad practice” – koden kan i regel omformuleras (till exempel med ett inverterat villkor) så att continue inte behövs.
Kommentarer
Section titled “Kommentarer”Att kommentera din kod på ett strukturerat sätt är viktigt. Kursledningen ger en inledning till detta här. Missa inte guiden kring JSDoc-kommentarer.
PresentationVad gör koden?
Section titled “Vad gör koden?”Odokumenterad kod kräver att man läser och förstår den i detalj för att inse vad den gör:
function m (a, b) { if (a === 0 || b === 0) { return 0 } if (b < 0) { return -a + m(a, b + 1) } return a + m(a, b - 1)}Ett otydligt namn (m), inga uppgifter om vad parametrarna eller returvärdet betyder, och en funktion som anropar sig själv (rekursion) utan förklaring till varför – allt det gör koden svårare att förstå än den behöver vara.
Vad gör den dokumenterade koden?
Section titled “Vad gör den dokumenterade koden?”Samma funktion, men med ett tydligare namn och en JSDoc-kommentar:
/** * Multiplies two numbers by repeated addition and returning the product. * * @param {number} a - The multiplicand. * @param {number} b - The multiplier. * @returns {number} The product of the two numbers. */function multiply (a, b) { // Base case if (a === 0 || b === 0) { return 0 } // Negative multiplier if (b < 0) { return -a + multiply(a, b + 1) } // Positive multiplier return a + multiply(a, b - 1)}Som bonus använder editorer som VS Code JSDoc-kommentaren för att visa information om funktionen direkt vid anrop, och den kan även användas för att generera automatisk HTML-dokumentation.
Vad är kommentarer?
Section titled “Vad är kommentarer?”Kommentarer används för att förklara kod och göra ett program mer läsbart – även för den som skrev koden från början. De kan också användas för att temporärt hindra kod från att exekveras, vilket är användbart vid felsökning. Det finns tre typer: dokumentationskommentarer (JSDoc), radkommentarer och blockkommentarer.
Dokumentationskommentarer med JSDoc
Section titled “Dokumentationskommentarer med JSDoc”JSDoc är ett märkspråk för att dokumentera moduler, funktioner (parametrar och returvärde), klasser och deras medlemmar. En JSDoc-kommentar inleds med /** och avslutas med */:
/** * Outputs a greeting. * * @param {string} name - The name of the person to greet. */function greet (name) { console.log('Hi, ' + name + '!')}Den enklaste formen är bara en beskrivning utan taggar; JSDoc-taggar som @param och @returns ger mer strukturerad information.
Radkommentarer
Section titled “Radkommentarer”Radkommentarer, som börjar med //, kommenterar resten av raden. De kan stå på en egen rad eller i slutet av en kodrad (en “inline”-kommentar):
// The answer to the ultimate question of life.let meaningOfLife = 42
// Output the variable's value to the console.console.log(meaningOfLife)Det finns delade meningar om inline-kommentarer – en känd synpunkt (Jeff Raskin) är att en kommentar förtjänar minst en egen rad, hellre än att klämmas in efter kod. Lämpligast står en radkommentar på en egen rad, med en tom rad ovanför, om den inte används för att tillfälligt kommentera bort kod.
Blockkommentarer
Section titled “Blockkommentarer”Blockkommentarer, som börjar med /* och slutar med */, kommenterar bort allt däremellan – en del av en rad, eller flera hela rader:
/* This isa multi-line comment.Only code outside of thismulti-line comment will be executed.*/console.log('Here is a /*cat*/ 🐈!')Flera på varandra följande radkommentarer används ofta för samma syfte – att tillfälligt kommentera bort ett kodblock – som ett alternativ till en enda blockkommentar.
Läsanvisningar
Section titled “Läsanvisningar”Under läsanvisningar hittar du veckans kapitel som ska läsas i kurslitteraturen. Planera upp och dela upp läsningen under veckan.
Övningar
Section titled “Övningar”Under Övningsuppgifter hittar du övningsuppgifter som det är lämpligt att du arbetar med under veckan. Försök att göra så många som möjligt!
Guider
Section titled “Guider”Dags att börja komma igång med examinationsuppgiften A2 - Beskrivande statistik! Förfarandet skiljer sig något mot hur du arbetar med övningsuppgifterna så följ guiden!
Målet för veckan är att bekanta dig med uppgiften, mycket mer behöver du inte göra på uppgiften denna vecka. Du har fortfarande många koncept att gå igenom innan du fullständigt kan lösa examinationsuppgiften.
En viktig del i examinationsuppgiften är att du ska skriva dokumenterande kommentarer till alla funktioner i uppgiften. Det finns därför en guide kring just JSDoc.
Seminarier + individuell handledning
Section titled “Seminarier + individuell handledning”Kört fast? Strular Git? Problem med en övningsuppgift? Då ska du definitivt vara med på handledningen där du har möjlighet att fråga kursledning och amanuenser om vad som helst. Om ingen i kursledningen kan svara direkt går det säkert att tillsammans komma fram till en lösning! På campus hittar du salen i schemat och på distans håller kursledningen till i kursens Zoom-rum, där seminariet som vanligt inleds gemensamt.
Examinationsuppgift A1
Section titled “Examinationsuppgift A1”Dags för kursens första examinationsuppgift. Läs mer om examinationsuppgift A1 här.
Utmaningar
Section titled “Utmaningar”Även denna vecka finns ett antal utmaningar att lösa för att hjälpa dig i din lärprocess. Lägg lite tid på att läsa igenom dem.
Studiefrågor
Section titled “Studiefrågor”Här är ett antal frågor som du kan försöka besvara och diskutera tillsammans med en AI-assistent. Tveka inte att lyfta någon av frågorna till handledningen för att fortsätta diskussionen med lärare och studiekamrater.
- Berätta kort om varför man bör dokumentera sin kod med JSDoc.
- Visa exempel på hur man skriver JSDoc-kommentarer.
- Vad innebär det att JavaScript är ett svagt typat språk?
- Visa ett par exempel på hur man bygger if-satser i JavaScript.
- Visa ett par exempel på hur man bygger for-loopar i JavaScript.
- Visa ett par exempel på hur man bygger while-loopar i JavaScript.
- Vad innebär nyckelorden
continueochbreak? - Vilken loop är bäst, for- eller while-loopen?
Här är en utskrift från hur det kan se ut när frågorna ovan diskuterats med en AI-assistent.
Här följer tips till hur du kan prioritera bland kursmaterialet för att komma igång med veckan.
- Just nu förutsätter jag att du kan klona och lösa förra veckans övningsuppgift “Hello World”. Om du inte har gjort det så bör du backa till vecka 2 och lösa den biten.
- Denna veckan finns det ett par (relativt korta) föreläsningar som visar hur man skriver villkor och loopar i JavaScript, man får även insikt i hur en programmerare kan tänka. Titta igenom dem.
- Försök göra de övningsuppgifter som finns. Ta en i taget och se hur långt du kommer. Lyckas du lösa alla blå så skall du vara riktigt nöjd.
