Så mycket sämre – ny videoserie

Vi har börjat spela in en liten filmserie som vi kallar “Så mycket sämre”. Tanken är att vi tar kod som är i ett ok skick och gör den sämre (“så mycket sämre”). Det är ett försök att på ett lite roligare sätt diskutera kodkvalitet.

Kolla in på kanalen Så mycket sämre (borde den heta “Saa mycket saemre“). Oavsett detta, första avsnittet heter Så mycket sämre – avsnitt 1, säsong 2017.

En kort pod om detta finns också: Så mycket sämre

Posted in Uncategorized | Leave a comment

Tankar kring kursbetyg , S01E01

 

Efter att ha funderat länge på ett oväntat dåligt kursbetyg har vi en del reflektioner som vi vill diskutera. Betyget samt en del efterkommande kommentarer har gjort att vi diskuterat kursbetyg en hel del på sistone.

Motsvarande poddcast: https://juneday.podbean.com/e/tankar-kring-kursbetyg-s01e01/

 

Bakgrund till problem med kursvärderingar

Vi börjar med att ta upp två saker vi ser som viktiga när man lär ut programmering.

  • Noggrannhet (t ex kolla returvärdet vid malloc när man skriver C-kod) är, enligt vissa studenter och ibland också lärare, jobbigt eller kanske t o m svårt. Kanske saknar lärarna adekvat kunskap och erfarenhet?
  • Skriva generella program eller delar av program verkar, eftersom det i princip aldrig görs, också svårt. Det upplevs enklare av studenterna om lärare visar speciella lösningar på speciella problem. Vi har sett kod som “parse:ar” 0-2 argument. Koden är komplex vid 2 argument och blotta tanken på 6 argument får en att få rysningar.

Nogrannhet

Vi exemplifierar ovanstående med lite kod:

 char * name = calloc(sizeof(char), length);
 ……
 name = realloc(name, sizeof(char)*length);

Det ser väl ok ut? Men gick det verkligen bra att allokera minnet? Vi måste kolla om det gick bra och vidta en åtgärd om det inte gick bra.

  char * name = calloc(sizeof(char), length);
  if (name == NULL)
  {
      return MEMORY_FAILURE;
  }
 ……
 char * tmp = realloc(name, sizeof(char)*length);
 if (tmp == NULL)
 {
    free(name);
    return MEMORY_FAILURE;
 }

Ok, koden är mer robust. Men den är också mer komplex. Eller är det så att den första kodsnutten är inkorrekt?

Generalitet

Kolla på vår tidigare bloggpost där vi diskuterar en övningsuppgift: https://programmeringspedagogik.wordpress.com/2016/09/21/hur-manga-i-ar-det-i-liverpool/

if (argc == 1)
{
  in_stream = stdin;
}
else if (argc == 2) 
{
  in_stream = fopen(argv[1], "r");
} 
else if (argc == 3)
{   
  in_stream = fopen(argv[1], "r");
  if (strcmp(argv[2], "--long")==0)
  {
  ....
  }
  else 
  {
  ...
  }
}

Det här skalar verkligen inte. Det finns ganska enkla strategier för hur man “parsar” argument given på kommandoraden. Ett enkelt sätt är att loopa igenom alla argument. Vi har skrivit lite om detta på vår wiki: http://virt08.itu.chalmers.se/mediawiki/index.php/Command_line_parser

OBS: felkontroll saknas i koden ovan

Slutkläm

Om man struntar i ovanstående blir det akademiprogrammering av utbildningen. Vi förespråkar det motsatta, dvs skriv generell och robust kod (var noggrann) osv.

Men vi har vissa tvivel eller kanske snarare tankar kring detta. Om man följer de två principerna ovan undrar vi om programmering är svårare att lära sig, kanske t o m svårt? Förmodligen gör det inlärningen av programmering svårare. Men kan vi verkligen ta bort detta moment utan att tappa värde? Vad har sådan här kunskap för värde i fortsatta studier eller yrkesliv. Är det lite som att strunta i hållfasthetslära för arkitekter? Är det verkligen adekvat att lära ut att skriva program som bara funkar under vissa förutsättningar, t e x att det finns en fil som heter people.dat i katalogen där programmet körs istället för att ange filen som argument och läsa stdin om ingen fil anges? Men å andra sidan kan man undra om det är enklare att skita i felhantering och generalitet. Men vad blir då följderna? Dels för kursen och dess betyg, dels för studenterna och deras kunskap.

Vi har sett och jobbat med många som tror sig kunna, men egentligen inte kan, programmera. De slarvar ofta med helheten, t ex felhantering. 

Vi försöker stenhårt att verkligen lära ut grunder, noggrannhet, generalitet osv.

Inom kort kommer vi att diskutera:

  • Sjunker kursbetyget på en kurs om man är noggrann?
  • Hur påverkas synen på läraren av vad man lär ut?
  • Vilka krav kan vi lärare ställa på studenter?

 

Hör gärna av dig, genom at kommentera på denna blogg.

 

Posted in Uncategorized | Leave a comment

Pod om att undvika uppskjuten definition

Ny podd släppt: https://juneday.podbean.com/e/undvik-uppskjuten-definition-sa-langt-det-ar-mojligt/

Podden är baserad på en gammal bloggpost om vikten att undvika uppskjuten definition: https://programmeringspedagogik.wordpress.com/2016/05/15/undvik-uppskjuten-definition-sa-langt-det-ar-mojligt/

 

 

 

Posted in Uncategorized | Leave a comment

Kodstandard i undervisning

Bakgrund

Lyssna gärna på vår podcast i ämnet: https://juneday.podbean.com/e/kodstandard-i-undervisning/

Vi har, när vi förbereder ett Java-projekt i en kurs på GU, läst en hel del på studenters kod. Det är ganska uppenbart att studenterna inte använder kodstandard. Åtminstone inte i en grad där kodstandarden genomsyrar koden. Är detta bra eller dåligt frågade vi oss?

Vi själva, som de Pella-rediga vi är, försöker använda oss av en kodstandard. Numera är det Googles kodstandard vi använder. Blir det enklare för studenterna att vi följer en standard?

Rent generellt är det så klart bra med kodstandard. Men vi kommer inte diskutera kodstandard utifrån det generella. Istället kommer vi diskutera kodstandard i undervisning. Mer specifikt huruvida det är viktigt om vi lärare använder sådan och om det är viktigt att vi kräver av våra studenter att de använder en sådan.

Bör lärare använda kodstandard?

Vad tycker du själv?

Kostar det något för en lärare att faktiskt använda kodstandard? Det kan väl knappast ses som något jobbigt att följa åtminstone delar av en standard?

Tror du att ansträngningen att vara konsekvent påverkar elevernas möjlighet att lära sig läsa och skriva kod?

Kan man vinna något ytterligare på att använda kodstandard? Hur uppfattar studenterna dig om din kod ser olika ut, särskilt om du uppmanar studenterna att följa en standard eller att vara konsekventa.

Bör studenter krävas använda kodstandard?

Det är uppenbart att det är bra att följa och lära sig en standard. Men är det verkligen så pass viktigt för nybörjare och deras inlärning av Java att följa en standard strikt? Vi tycker att man kan slappna av lite granna här och istället uppmuntra dem att följa en standard.

Fundera på om det är ok att:

  • du som lärare inte följer en standard
  • du som lärare  kräver av studenter att följa en standard

Saker vi ser som viktiga när du som lärare skriver kod som ges ut

I kort tycker vi att följande är viktigt:

  • Bra namn på variabler, metoder osv
  • Indentera på ett sätt
  • Bra namn på variabler, metoder osv
  • Skilj på små och stora bokstäver

Bra namn på variabler, metoder osv

Ett skräckexempel på nam är oddOrNot som vi hittade på https://www.javacodegeeks.com/2015/06/java-programming-tips-best-practices-beginners.html. Varför är det inte ett bra namn? Vad borde den heta istället?

Om du vill hålla reda på antalet studenter med hjälp av en variabel. Kalla den då t ex för numStudents. Använd inte b1, num, antal ….  

Indentera på ett sätt

Det är enklare att läsa kod om den ser samma ut. Varför inte bjuda på detta då för studenterna. Om det blir lättare för dem att läsa din kod ser vi inget skäl till att inte göra detta.

Det kan ju dessutom ge ett intryck av att det är olika författare som skrivit koden. Tyvärr har vi sett kod som florerar på internet som dyker upp här och där på olika kurser och i material. Att låna kod må vara hänt (nja, mer om detta senare) men var då konsekvent.

Använd engelska namn

Sluta direkt med att kalla din klass för något av följande:

  • Raenta
  • Ranta
  • Ränta

om det är menar ränta som man förr fick på sina pengar på banken. Kalla hellre klassen för Interest.

Skilj på små och stora bokstäver

Det finns en uppsjö regler i kodstandarder som specar namn. Följande är, enligt oss, viktigast:

  • Klasser, interface och enum skall (ja, skall!) ha namn med stor initial bokstav.
  • Variabler och metoder skall (ja, skall!) liten initial bokstav.
  • Undantag kan gälla konstanter.

Återigen är det enklare att läsa kod som följer en standard. Särskilt har nybörjare svårt att lära sig skillnad på typ och identifierare. Varför då bidra till förvirringen? Ta till exempel följande syntaktisk korrekta kod:

package a;
class a{
  a a;
  a(a a){
    this.a = a;
  }
  a a(){
    return a;
  }
}

Är detta bra kod? Är det lätt för en student att tolka koden?

 

Posted in Uncategorized | Leave a comment

Arv Series – S01E02

Ok, det är dags att diskutera följande:

Lägg till en “default-konstruktor”

Detta är värt att diskutera!

Kolla (eller kanske lyssna?) på vår podcast om detta: https://juneday.podbean.com/e/arv-series-s01e02/

Låt oss utgå ifrån följande klass och arvshierarki (nej, vi gillar inte detta arv i sig). Här är ett “UML-liknande diagram” över vår struktur:

       
       +----------------+
       |   Person       |
       +----------------+
       |  name: String  |
       +----------------+
       | Person(String) |
       +----------------+
           ^
          /
         /
    +--------------------------+
    |   Employee               |
    +--------------------------+
    |  email: String           |
    +--------------------------+
    | Employee(String, String) |
    +--------------------------+

 

net/Person.java

package net;

public class Person {

 String name;

 public Person (String name) {
   this.name = name;
 }
}

net/Employee.java

package net;
package net;

public class Employee extends Person {

  String email;

  public Employee (String name, String email) {
    this.name = name;
    this.email = email;
  }

  public String toString() {
      return super.toString().toUpperCase() + "<" + email + ">";
  }
}

Detta ser la ok ut, eller?
Hmmm: om du tycker att det är konstigt att vi inte har private som åtkomstmodifierare (access modifier) så håller vi med, vi håller oss till vad böcker brukar lära ut!

Problem #1: Vad an default-konstruktor?

En default-konstruktor är något vi “får gratis” (på köpet) av Javs kompilator . Om vi inte har skrivit någon enda konstruktor så skapar javac en åt oss, en så kallad default-konstruktor, typ enligt följande

  public Person () { ; }

Om vi skriver en egen konstruktor, t ex med tom parameterlista:

  public Employee () { ; }

så får vi ingen konstruktor “på köpet”. Men den konstruktor vi skrivit är ej heller en default-konstruktor.

Alltså, om vi skriver

  public Employee () { ; }

… så kan vi inte kalla den “default-konstruktor” då vi inte får den “på köpet av Javac”.

Problem #2: Kompilerar inte

Om vi inte lägger till en konstruktor med tom parameterlista,  så kompilerar det inte. Kompilator klagar enligt följande (eller liknande):

 
 net/Employee.java:7: error: constructor Person in class Person cannot be applied to given types;
 public Employee (String name, String email) {
 ^
 required: String
 found: no arguments
 reason: actual and formal argument lists differ in length
 net/Employee.java:16: error: constructor Person in class Person cannot be applied to given types;
 public Employee () { ; }
 ^
 required: String
 found: no arguments
 reason: actual and formal argument lists differ in length

Vad är då lösningen?

Dålig lösning

Enkelt!!!! Enligt de flesta böcker vi läst ach lärare vi hört gör du följande i Person.java:

public Person () { ; }

But no….. Det här leder till problem. Tänk dig följande:

    Employee empoli = new Employee();
    System.out.println("empoli: " + empoli);

Vad händer nu då?

javac net/Person.java  net/Employee.java net/EmployeeTest.java  && java net.EmployeeTest 
Exception in thread "main" java.lang.NullPointerException
	at net.Employee.toString(Employee.java:13)
	at java.lang.String.valueOf(String.java:2994)
	at java.lang.StringBuilder.append(StringBuilder.java:131)
	at net.EmployeeTest.main(EmployeeTest.java:12)

Varför hände detta då? Jo, för att vi i vår design tillåter icke-initierade objekt att skapas genom vår konstruktor:

  public Employee () { ; }

Varför har då så himla många böcker och vaför säger lärare att vi skall göra så här?????

Varför rekommenderar författare och lärare (som vi som skriver denna blog/pod) studenter att skriva konstruktorer med tom parameteerlista? Vi vet ärligt talat inte varför detta görs.

Ibland görs det implicit när man visar kod. Ibland görs det explicit:

// Filen Person.java

class Person {
  protected String namn, adress;   // Obs! protected
  protected int född;              // Obs! protected

  protected Person() {} // måste finnas för subklassernas skull

  .......
}

http://www.cse.chalmers.se/~skanshol/Java_dir/losn8/kap04/ex4-3.txt

Kommentar: det kan absolut finnas skäl till en konstruktor med tom parameterlista, t ex vid reflection, men att säga att det behövs för “subklassernas skull” är direkt fel. Vi skulle nog gå så långt att vi säger att det kan medföra skada för studenternas förståelse för arv och Javas regler.

Om du som lärare läst eller kansker använder boken ovan finns det en risk att detta förs vidare till studenter/elever då du litade på författaren (av olika skäl).

Problem #3: Åtkomstsmodifierare

I vårt fall hade vi inga åtkomstsmodifierare så vi fick alltså default (package private). Detta gör att ärvande klasser, t ex Manager.

package net.ext;

import net.Employee;

public class Manager extends Employee {

  public Manager (String name, String email) {
    this.name = name;
    this.email = email;
  }

}

Om vi kompilerar får vi följande fel:

net/ext/Manager.java:8: error: name is not public in Person; cannot be accessed from outside package
 this.name = name;
 ^
net/ext/Manager.java:9: error: email is not public in Employee; cannot be accessed from outside package
 this.email = email;
 ^
2 errors

Ok…. vad är felet? …. felet är att javac lägger till ett anrop till basklassens konstruktor med tom parameterlista. Om vi själva anropar en kontruktor i basklassen gör javac inget implicit anrop. I kort kan man säga att koden ovan ser ut så här:

package net.ext;

import net.Employee;

public class Manager extends Employee {

  public Manager (String name, String email) {
    super();
    this.name = name;
    this.email = email;
  }

}

Anropet till super (markerat med fetstil) läggs till i byte-koden[1] av kompilatorn.

Vi använder en konstruktor (sker implicit) med tom parameterlista och sedan manuellet sätter värden på variablerna i bas-klassen.

Men hur skall man göra då?

Bättre att istället använda existerande konstruktor.

Skriv om enligt följande:

  • inga klasser har konstruktorer med tom parameter-lista
  • anropa alltid explicit en existernade konstruktorer i basklassen, m h a super

Disclaimer:

Eftersom vi i övrigt anser:

  • arv mellan Person, Employee och Manager inte kan motiveras i ett riktigt system
  • i och med att det inte finns publika åtkomstsmetoder kommer man inte åt värdena
  • det enda som skiljer Employee och Person är att Employee har ytterligare data kan man inte programmera mot superklassen (Person) utan att casta ned till underklassen (Employee) för att komma åt det som skiljer dem

 

[1]

javap -c net.ext.Manager
Compiled from "Manager.java"
public class net.ext.Manager extends net.Employee {
 public net.ext.Manager(java.lang.String, java.lang.String);
 Code:
 0: aload_0
 1: invokespecial #1 // Method net/Employee."<init>":()V
 4: aload_0
 5: aload_1
 6: putfield #2 // Field name:Ljava/lang/String;
 9: aload_0
 10: aload_2
 11: putfield #3 // Field email:Ljava/lang/String;
 14: return
}

Posted in Uncategorized | Leave a comment

Arv Series – S01E01

Ok, dags för en av våra favorit-hat-grejer. Arv, enligt gängse uppfattning.

Här hittar du motsvarande pod(d)cast: https://juneday.podbean.com/e/arv-series-s01e01/

Vi har sett i bok efter bok, kurs efter kurs och hört av lärare efter lärare att arv är bra på grund av att ….. Men vi har aldrig förstått vurmen för arv, i alla fall inte så som det används i  alltför många exempel. Vi har nu tagit på oss den ganska stora kostymen och drar igång en serie om just arv. Blygsamt, som vanligt!

Vi startar med att diskutera och motivera denna serie om arv. Skall vi kalla serien för Arvssynden?

Saker vi tar upp under seriens gång är:

  • När är arv mindre bra – exempel från en så kallad verklighet
  • Alternativ till Arv
  • Man sparar så mycket kod med arv
  • När arv motverkar polymorfism (kräver typecast)
  • När är arv bra

I dag fokuserar vi på att snacka om våra invändningar mot arv. Detta utan att ens prata kod. Vi gör detta genom att diskutera arvshierarkier som:

                  +-------------+                 +---------+                 
                  |             | *            1  |         |                 
                  |    Fruit    |---------------<>|  List   |                 
                  |             |                 |         |                 
                  +-------------+                 +---------+                 
                   /\   /\   /\
                  /__\ /__\ /__\
                   /    |     \
                 /      |       \
               /        |         \
             /          |           \
           /            |             \
    +---------+     +---------+       +---------+       
    |         |     |         |       |         |       
    |  Apple  |     |  Orange |       |  Grape  |       
    |         |     |         |       |         |       
    +---------+     +---------+       +---------+       

Saxat från: http://courses.washington.edu/css343/zander/Code/fruituml

Eller följande:

                  +-------------+                  
                  |             |                 
                  |  Employee   |                 
                  |             |                               
                  +-------------+               
                   /\   /\   /\
                  /__\ /__\ /__\
                   /    |     \
                 /      |       \
               /        |         \
             /          |           \
           /            |             \
    +---------+     +----------+       +---------+       
    |         |     |          |       |         |       
    | Project |     |Developer |       | System  |       
    | Manager |     |          |       | Admin   |     
    +---------+     +----------+       +---------+      

Eller varför inte den här:

animal

som kommer från: http://cse.csusb.edu/dick/cs202/abstraction.html. Hittar ingen licens men eftersom det är ett universitet utgår vi ifrån att vi får använda i utbildningssyfte. OBS: bilden ovan visar förmodligen Abstrakt basklass eller inteface vilket gör bilden mer begriplig.

Posted in Uncategorized | Leave a comment

En bild säger mer än tusen ord

Ny podcast En bild säger mer än tusen ord. Detta är första delen i en, vad vi hoppas på, serie om ordspråk vi finner i bästa fall konstiga och i de flesta fall rent ut sagt dumma. Vi börjar med en gemensam favorit: “En bild säger mer än tusen ord”.

Borde vi gjort en bild istället för en pod och en blog?

Här är en bild från vår planering av podden (eller poden?):

 

20170306_141806

Planering av pod(d)en

Och här en bild när vi spelar in:

20170306_150156

Inspelning, på pedagogen på Göteborgs Universitet

Som ni redan förstått så säger ju bilderna mer än våd pod(d) så varför lyssna?

Om någon betvivlar våra akademiska meriter så säger den här bilden mer än tusen ord, d v s mer än sisådär 3-4 “papers”:

20170306_144506

 

Posted in Uncategorized | Tagged , , , , | Leave a comment