Nytt podcast-avsnitt om cirkulära definitioner

Vi har spelat in ett nytt avsnitt i vår pod-serie. Denna gång behandlar vi cirkeldefinitioner vilket vi gör utgående från en “gammal” bloggpost “Undvik cirkeldefinitioner“.

“Detta kan naturligtvis låta som en självklarhet men faktum är att vi funnit många exempel på cirkeldefinitioner i såväl kurslitteratur som föreläsningbilder (egna och andras!).

En utmaning här är att inom programmering florerar en stor mängd programmeringstekniska termer och begrepp, varav många endast låter sig förklaras i termer av ytterligare programmeringsbegrepp.”

Pod-avsnittet hittar du här: Undvik cirkeldefinitioner

Posted in Uncategorized | Leave a comment

Ny podcast om hur man (eventuellt) tar fram kurser

Utifrån en gammal blogpost (Arbeta bakifrån från lärmålet) och en wiki-sida (Arbeta bakifrån från lärmålet) diskuterar vi en av våra principer som vi strävar mot när vi tar fram kurser.

Som vanligt har vi en pod om detta: Arbeta bakifrån från lärmålet.

Diskutera gärna med oss här på bloggen. Kommentera detta inlägg direkt här under.

 

Posted in Uncategorized | Leave a comment

Åh nej, inte arrayer igen

Bakgrund

Problemet så som vi ser det är att många böcker, övningar, lärare och exempel på nätet visar på kod som använder arrayer. Och, vad är det för fel med det då tänker du säkert. Vi ställer följande fråga till dig istället:

När valde du att använda array istället för en List (eller liknande) senast? 

Lyssna på vår podcast om denna blog: https://juneday.podbean.com/e/om-arrayer-i-java-undervisning/

Varför skall vi babbla om detta då? Vi får ibland frågor från gamla studenter. Jättekul. Och tack för att ni fortfarande står ut med oss. I veckan har vi fått två frågor (se nedan). Vi har dessutom blivit ombedda att föreläsa om hur man använder List i Java. Så då passar vi på att snacka lite om arrayer. Med array menar vi

    int[] numbers = new int[]{5,3,4,1,9};

Varför arrayer över huvud taget?

Vi börjar med att backa lite granna. Det är nog uppenbart för alla att vi behöver något stöd i språket för att lagra (potentiellt) flera element (av samma typ). T ex kan man ju tänka sig att det är bra om ett epost-program kan lagra alla användarens kontakter på ett ställe (via en variabel) i stället för på flera. Vi vill ju inte ha ett epost-program som säger “Du har nu 100 kontakter och vi kan inte lägga till flera!”. Tänk dig att skriva motsvarande kod:

Contact c1;
Contact c2;
....
Contact c100;

Nej, så klart är detta helt kasst. Mycker bättre med arrayer då.. väl?

 Contact[] contacts = new Contact[100];

Men är arrayer den bästa lösningen på detta? Du kommer ju inte undan ovanstående problem med begränsat antal kontakter då arrayer har en fix storlek i Java. Jo visst, du kan vid behov skapa en ny och lite större array och kopiera över elementen…..men nej, tänk inte ens tanken.

Alternativ till arrayer?

List

Är det inte betydligt enklare att använda någon form av Lista, t ex ArrayList. Om man har en List istället för en array är det ju bara att “add:a” element allt eftersom. Vi kan “till och med” ta bort element på ett enkelt sätt. Typ så här:

 List<Contact> contacts = new ArrayList<>();

Är detta svårare? Finns det några skäl att inte använda ovanstående istället för array?

Enligt oss: nej, nej

Enum

En student visade ett program skrivet i Java där han/hon lagrat veckodagar i en array.  Vi sade att det verkar ganska osannolikt att det kommer komma en ny veckodag så att storleken är fix känns ok. Men vi rekommenderade enum istället och diskuterade detta lite granna. Det tog inte många sekunder innan studenten insåg att enum är ett betydligt bättre sätt att hantera veckodagar.

Samma student frågade senare om hur man kan spara årets dagar i en array eller enum. Vårt svar blev en fråga. Varför i hela friden skule du vilja det? Eftersom studenten inte kunde svara på detta enades vi om att frågan inte var en fråga 🙂 Det finns ju t ex Calendar till detta. Hur skulle vi göra i vår array om det är skottår? Och så vidare. Sluta nu! Det får vara stopp här!

Är arrayer aldrig användbara?

Menar vi att arrayer är något som man aldrig behöver använda? Nej, det finns ett par saker som vi tar upp i kapitel (So when should we use arrays?) en av våra böcker om java. Boken är inte riktigt klar ännu, men vi jobbar på det. I kapitlet tar vi upp att arrayer behövs i följande fall:

  1. när ett API “tvingar” dig, t ex main-metoden
  2. om du skriver en metod med variabelt antal argument
  3. du vill använda syntaxen new String[]{“abba”, “europe”, “ace of base”} eller bara “abba”, “europe”, “ace of base” , typ så här:
    List <String> strings =
        Arrays.asList ("abba", "europe", "ace of base");

Några kommentarer kring punkterna ovan

  1. I fallet med main-metoden är det ju enkelt att bara visa och förklara hur man läser från args. Det är ju inte vi som skapar arrayen. Det sköter JVM:en åt oss. I resten av fallen, och faktiskt i fallet med main-metoden, kan man enkelt göra om en List till en array och vice versa.
  2. Visar du över huvud taget detta i en grundkurs? Vi går inte igenom det i vår grundkurs (Programming with Java). Men om du går igenom varargs kanske det är läge att gå inte mer på arrayer.
  3. Jo, men detta är ju så himla enkelt att visa och lära ut som ett idiom. Men behöver inte frossa i arrayer.

Varför lär man ut array då?

Men, måste man inte kunna array för att förstå List? Hmm, vi tror inte det. En av oss (Henrik) använde detta för många år sedan som argument till att lägga tid på arrayer. Men om man går igenom main-metoden så har man ju pratat lite om arrayer och vi hävdar att studenterna därmed har en tillräcklig grund för att förstå List. Så nej, vi behöver inte lägga tid på array för att kunna lära ut List.

I fallet med den av oss (Henrik!!!!) som lärde ut array så var det dels tanken om att det var att kunna array innan man lär sig List. Men framför allt tog Henrik upp array för att alla andra gör det. Jävligt dåligt skäl när man tänker efter.

Varför bry vi oss?

Så sluta upp med att lägga timme efter timme och sida efter sida på arrayer. Lägg den tid du sparar på att diskutera hur man löser problem/uppgifter på ett lämpligt sätt. Och lägg nu inte timme efter timme på List och t ex LinkedList. Dessa är bara exempel på bra klasser som finns i Javas API. Så i kort:

  1. lägg inte tid på djupdyk i en (icke relevant) klass eller konstruktion
  2. lär ut hur man löser problem
  3. lär ut hur man läser ett API

Kanske borde vi lärare fundera på vad vi måste stryka till förmån för array. Om vi tänker så är det mycket enklare att stryka array. Så. Borta. Finns inte mer. Tack.

.. å så lite slutgnäll

.. men vänta, en sak till. Vi vill passa på att klanka ned lite på följande kod som man ofta ser:

ArrayList<Member> members = new ArrayList<>();

Känns väl ok. Men behöver du verkligen använda det som är ArrayList-specifikt? Förmodligen inte. Skriv då istället.

List<Member> members = new ArrayList<>();

På detta sätt kan du enkelt byta ut ArrayList mot t ex LinkedList utan att ändra i din kod… ja, mer än raden ovan.

List<Member> members = new LinkedList<>();

Slutord

Ja, då har vi väl gnällt färdigt för idag? Känns som att det är dags för en positiv blog-post. Tänkte att vi skriver lite om vår pedagogik nästa gång.

 

Posted in Uncategorized | Leave a comment

Getters och setters – tänk efter innan

Efter en “gansk” tuff hösttermin startar vi upp på nytt med bloggen och, nytt för i år, med en pod. Shit, vad hippa ni är tänker ni säkert. Men det är inte så hipt med poddar längre så vi vågar oss på att försöka. Tänkte att vi skall försöka skriva 2-4 blogposter och motsvarande podar per månad. Men alla som jobbat med oss vet att vi har svårt att göra mer än en sak i taget så det lär väl spricka direkt.

I vår första pod (Juneday – Getters och Setters) disukterar vi getters och setters som vi om skrivit om på vår wiki. Dessa metoder, get respektive set, verkar vara något som man “bara skall skriva”. Är det verkligen så? Finns det nackdelar?

Vi ger ett enkelt exempel. Om du i Java har en private instansvariabel name:

private String name;

så verkar det som att man enligt många böcker, bloggare/poddare och lärare måste lägga till:

public String getName() {
  return name;
}

public void setString(String name) {
  this.name = name;
}

Men vad har vi då vunnit med att göra name private? Är det bra eller ens nödvändigt att kunna ändra namnet på ett objekt?

Detta och mer saker diskuterar vi på vårt första podavsnitt, Juneday – Getters och Setters.

Vår hållning och rekommendation är att vi alla skall sluta skriva getters och setters bara för att man “skall” gör det. Det finns säkert ramverk som kräver det för att något skall funka… men som grundregel är det här med getters och setters en ganska kass ide, så sluta skriv getters och setters nu! 

 

Posted in Uncategorized | Leave a comment

Hur många ‘i’ är det i “Liverpool”?

Det var ett bra tag sedan vi skrev något här så det är minst sagt dags igen. Vi har idag publicerat en engelsk blog-post som vi vill referera till här. I kort handlar den om meningslösheten (ja, den är i stort sett meningslös och kanske till och med skadlig) i en viss typ av övningar. De flesta av oss, så kallade, pedagoger har säkerligen stött på, använt eller skrivit en sådan uppgift.

Som titeln antyder rör det sig om följande uppgift, eller fråga:

Hur många ‘i’ är det i “Liverpool”?

Vad vi klagar på i uppgiften ovan är:

  • finns det någon student som inte kan lösa denna uppgift utan ett datorprogram? (uppgiften är tråkig och meningslös)
  • du löser en väldigt specifik uppgift med ett likaledes specifikt program (uppgiften och lösningen är icke generell)

Vi går, så klart, också igenom hur man skulle kunna, med uppgiften ovan som grund, skapa en vettig uppgift med progression. Här är delar av våra förslag (på engelska):

  1. Write a program (with a main function) that counts the number of ‘i’ in “Liverpool”
  2. Put the code doing the count in a separate function.
  3. Make the function general – any letter in “Liverpool”
  4. Make the function more general – any letter in any text
  5. Make the function even more general – any (sub)string in any string
  6. Make use of existing API functions
  7. Make the function robust
  8. Put the function in one file and the main function in another
  9. Write tests
  10. Write a function printing out the lines containing the string “liverpool”. This is not general – but a useful start.
  11. Write a function printing out the lines, in a file, containing any string., using the function above. This is not general enough – still rather useful.
  12. Write a function printing out the lines, as read from stdin (a stream) or a file, containing any string

Läs gärna den engelska blog-posten och kommentera här på svenska eller “där” på engelska.

 

Posted in Uncategorized | Leave a comment

Undvik för svåra övningar

Det är vad vi anser viktigt att stärka studenternas självkänsla och tro på sin kapacitet att praktisera de kunskaper som lärts ut. Därför är det problematiskt att skapa situationer där studenterna kör fast och inte känner att de ens vet vad de ska börja när de ställs inför en uppgift. Programmering är av sin natur en färdighet i att lösa generella problem med hjälp av ett programmeringsspråk. En styrka hos datorer är dessas förmåga att utföra matematiska operationer mycket snabbt. Därför är det naturligt att många av de problem som löses med datorer mer eller mindre är av matematisk natur.

Emellertid så är en kurs i programmering mycket fokuserad på regler för hur kod skrivs i ett programmeringsspråk. Dessa regler för hur man uttrycker sig i programmeringsspråket förklaras och beskrivs vidare i en stor uppsättning programmeringstermer. Det gör att studenter som aldrig tidigare programmerat ställs inför två begreppsvärldar. Dels en begreppsvärld för att beskriva typiska programmeringstekniker och koncept. Dels en begreppsvärld för hur dessa tekniker och koncept uttrycks i ett specifikt programmeringsspråk.

Först när man nått så långt i lärprocessen att man behärskar ett visst programmeringskoncept och hur detta koncept uttrycks i det språk som används i undervisningen, kan man använda konceptet för att lösa ett verkligt problem. För att få vana och känna trygghet i denna färdighet måste detta naturligtvis övas i stor omfattning.

Vad som händer om man ger en uppgift som matematiskt eller logiskt är för komplicerad för studenterna är att fokus förskjuts från de programmeringskoncept som skall övas in. I stället läggs fokus på att förstå vad uppgiften går ut på och hur detta i allmänhet ska lösas, oaktat om man använder datorer eller papper och penna för att lösa problemet. Kör studenterna fast eller misslyckas att förstå problemet eller/och hur det kan lösas, skapas en känsla för att programmering är något mycket matematiskt och konceptuellt svårt och att studenternas egen förmåga inte räcker till. Av dessa skäl anser vi att man noga bör överväga vilken nivå av svårighetsgrad de problem som skall lösas med programmering bör ligga på.

En annan aspekt som lett oss fram till denna princip är att det måste finnas en relation mellan vad man lär ut och vad man förväntar sig att studenterna ska klara av att utföra. Om lejonparten av kursen läggs vid rena programmeringskoncept och programmeringsspråkliga konstruktioner så bör uppgifterna reflektera detta. Om undervisningen inte omfattar matematik och problemlösning, så kan man inte förvänta sig att detta är något som studenterna skall klara av eller lära sig själva.

Stor tid och mycket reflektion bör därför under kursens konstruktion ägnas åt att slå fast förkunskapskrav vad gäller matematik och kompetens i problemlösning. Antar man studenter utan särskilda krav på matematik och problemlösningsförmåga så måste detta faktoriseras in i utformningen av kursen. I den mån matematik och problemlösning ändå förväntas ingå i lärmålen för kursen måste detta också läras ut och tränas under kursen på ett sätt så att förkunskapskraven matchar vad man förväntas ha med sig för att nå kursens lärmål.

Det är också viktigt för att studenterna skall ha rätt förväntningar av kursen utifrån vad de har med sig i form av kunskaper och färdigheter. Uppfyller man formellt kraven för att antas som student på kursen förväntar man sig inte att moment i kursen skall ställa krav på ytterligare kunskaper.

Särskilt viktigt är detta vid examinering av studenternas kunskaper och färdigheter vid slutet av kursen. Det bör finnas ett ett-till-ett-förhållande mellan vad som examineras och vad som lärts ut och tränats på under kursen, med reservation för att vissa förkunskaper krävs utöver vad som lärs ut under kursen.

Genom att gå igenom denna process vid skapandet av kursen och skapandet av examinationen av kursen, så kan man också transparent och öppet motivera övningar och examensfrågor på ett sätt som föregriper kritik och en känsla av att nivån på övningar och prov var försvår i förhållande till de förväntningar som studenten kunnas skaffa sig.

Denna ansträngning och analys ger värdefull indata till hur förkunskapskrav skall sättas, vilka färdigheter som skall läras ut och övas samt hur övningsuppgifter samt prov skall utformas.

Posted in pedagogik, Principerna | Tagged , , | Leave a comment

Ge vägledande övningar

Ett sätt att stärka studenternas självförtroende är att ge dem övningar och uppgifter som är relativt avancerade men samtidigt ge dem så mycket hjälp på traven att de med mycket liten extern hjälp kan lösa dem. Det handlar om att analysera syftet med övningarna. Övningar som är så svåra att studenterna inte förstår vad de går ut på för av förklarliga skäl med sig en rad problem. Studenterna får en känsla av att ämnet är för svårt eller att de inte lärt sig något.

Ett syfte med övningar kan vara att träna in nya färdigheter genom repetition som skapar en vana och trygghet. Det är bra för rena mekaniska färdigheter som exempelvis inom programmering att använda rätt syntax (som att inte glömma semikolon osv). Ett annat syfte kan vara att utmana studenterna att tänka i egna banor och finna egna lösningar.

Observera att inget av dessa syften uppnås om en uppgift är så svår att studenterna inte förstår vad de ska göra och inte kommer igång med uppgiften.

En strategi som vi prövat är att använda övningsuppgifterna som ett tillfälle att vägleda och repetera ett moment. Detta sker genom att frågan är formulerad på ett sätt som avslöjar de detaljer och delar i lösningen som behövs samtidigt som begrepp repeteras och förklaras i sjävla övningstexten. Det kan se ut så här:

En metod i Java har ju en returtyp, ett namn och så eventuella parametrar som anges inom parenteser. I metodens kropp, som deklareras inom ett block som börjar med { och slutar med }, så sker själva arbetet som metoden skall utföra. Om metoden ska returnera ett värde, så måste ju metoden ha en sats med nyckelordet return där det värde som metoden tagit fram returneras. Värdet har som bekant samma typ som metodens returtyp. Skriv en metod med returtypen int, som tar två paramterar int a och int b. Metoden skall heta add och returnera värdet av a+b.

Jämför detta med denna variant av exakt samma uppgift:

Skriv en metod som tar två heltal som argument och returnerar summan av talen

Den senare versionen är mycket enklare för läraren att skriva men förutsätter att studenterna själva klarar av att översätta underförstådda begrepp som metod, argument, heltal, returnerar, summan och hur dessa ska omsättas i Java-kod. Det vill säga uppgiften förutsätter just de färdigheter som syftet var att studenterna skulle öva på.

Vi har i våra undersökningar av kurslitteratur och kurser hittat mängder av övningar av den senare typen. Ibland får man känslan av att så lite information som möjligt ges av den enda anledningen att det skall vara lite svårare för studenterna. Det gäller att vi inte glömmer bort att studenterna är här för att lära sig och vi är här för att lära dem. Att göra lärandet svårare kan knappast tjäna någon större pedagogisk funktion.

För de studenter som är mogna att ge sig an de mer kortfattade övningarna inte skall känna sig understimulerande måste man ofta arbeta med olika svåra övningar där övningar som är lite svårare eller som kräver mer förkunskaper kan markeras som frivilliga och lite mer utmanande.

Posted in pedagogik, Principerna | Tagged , | Leave a comment