Programmeringsteknik

Användarvänlighet
Informativa utskrifter Enkel inmatning
Programmerarvänlighet
Vettiga namn Kommentarer
Konsekvent språk Konsekvent typografi
Felhantering
Strukturering
Lämplig uppdelning i klasser Lämplig uppdelning av metoder och funktioner
Temporära variabler så lokalt som möjligt     Återanvändbara funktioner/metoder/klasser
In- och utdata till metoder och funktioner Flexibelt/utbyggbart program
Ingen kodupprepning Ingen hårdkodning
Följande punkter är nödvändiga (måste alltid åtgärdas)
Uppfyller kraven i lydelsen Detaljförståelse

Användarvänlighet

Informativa utskrifter

Programmet ska tala om för användaren vad programmet gör i varje steg och vad för inmatningen som förväntas. Ett dåligt exempel kan se ut så här.

Ge tal1  : 26
och tal2 : 54
29 31 37 41 43 47 53

Man ska inte behöva titta i en manual eller ännu värre själva programkoden för at förstå vad som händer. Att köra programmet måste vara självinstruerande.

Hej och välkommen till primtalsprogrammet. Programmet
skriver ut alla primtal i ett intervall du definierar.

Ange lägre gränsen i intervallet: 26
Ange högre gränsen i intervallet: 54
De primtal som finns mellan 26 och 54 är:
29 31 37 41 43 47 53

Det senare exemplet är mycket lättare att förstå när man kör programmet.

Enkel inmatning

Anmärk på programmet om inmatningen onödigt krånglig.

...
Vill du boka en biljett?ja
Varifrån åker du? Arlanda
Vart ska du åka? Kastrup
Vilken månad ska du åka? Mars
Vilken dag ska du åka? 25
Vill du boka returbiljett?ja
Vilken månad ska du tillbaka? April
Vilken dag ska du tillbaka? 5
Det går tyvärr inget flyg den 25 mars.
Försök igen

Vill du boka en biljett?ja
Varifrån åker du? Arlanda
Vart ska du åka? Kastrup
Vilken månad ska du åka? Mars
...


Förutom att vara väldigt sen med att kläcka ur sig att det inte finns något flyg den önskade resdagen så verkar det inte finnas något sätt att boka en mängd biljetter. Att boka en klassresa med det systemet skulle vara väldigt enerverande.

Programmerarvänlighet

Vettiga namn

Programmet ska ha intuitiva namn på variablerna. För den som skrivit programmet är allt ofta självklart inte för den som granskar.

Nedanstående programkod är ganska svår att tyda

        namn = 0
	kalle=0
        while kalle < len(pelle):
            if pelle[kalle] > namn:
	         namn = pelle[kalle]
	    kalle+=kalle       
Här följer samma kod med andra variabelnamn.
        max = 0
        i=0
	while i < len(vektor):
            if vektor[i] > max:
	       max = vektor[i]
	    i+=1

Man ser nu lättare vad koden gör, koden sparar undan det högsta värdet i vektorn till variablen max. Fortfarande är det inte optimalt bra namn på vektorn. Vad för slags värden innehåller den? Är det löner, skottstatistik eller vad?

Generellt brukar bra namn på funktioner och metoder oftast vara verb som beskriver vad de gör. Klaser och variabler är ofta substantiv som beskriver vad klassen/variabeln är.

Det ska sägas att det är väldigt svårt att komma på bra namn.

Kommentarer

Alla klasser, metoder och funktioner måste kommenteras. Berätta syftet med klassen/metoden/funktionen. Det ska räcka att läsa kommentar och metodhuvud för att förstå hur en metod ska användas man ska alltså inte behöva titta i koden.

In och utdata till metoder och funktioner måste kommenteras. Det gäller både returvärden, parametrar och eventuella instansvariabler metoden använder sig av. Alltså om metoden använder sig av instansvariabler ska detta kommenteras.

Konsekvent språk

Var konsekvent i ditt språkval. Alla variabel/metodnamn på ett språk. Alla kommentarer på ett språk. Det är OK att ha engelska variabel/metodnamn och kommentera på svenska. Undvik svengelska (sejva svenska språket)

Konsekvent typografi

Håll dig till samma typografi i hela programmet. t.ex. skriv ihop ord genom att inleda med stor bokstav därefter små. Variabel- och metodnamn inleds med med liten bokstav och klasser inleds med stor bokstav. Och detta ska gälla för hela programmet.
    class EnBraKlass(object):
    class EnTillBraKlass(object):

    def enMetodSomTarTreParametrar(x,y,z):
    ettHeltal = 12

Felhantering

För betyg fyra krävs att programmet kan hantera fel som uppstår. Ofta behövs en slinga, t.ex. vid inmatning för att programmet ska kunna gå vidare.

Ange täljare: 1000
Ange nämnare: 0
Oj oj, nämnare får inte vara noll försök igen.
Ange nämnare: 10

1000 delat med 10 blir 100

Strukturering

Lämplig uppdelning i klasser

Undvik att ha all kod i en enda klass. Försök ha fler klasser för olika uppgifter.

Lämplig uppdelning av metoder och funktioner

Sträva efter att ha specialiserade metoder och funktioner som bara gör en sak.

    lasFranFil():
        filnamn = raw_input("Vad heter filen?")
	in=open(filnamn,"r")
	list =in.readLines()
	vek=[]
        for element in list:
	     if type(element)==type(0):
	     vek=vek+[element]
	return vek
    

Koden ovan gör flera saker; frågar efter en fil, läser in allt data från filen, gör om datat till heltal, stoppar in heltalen i en heltalsvektor och returnerar denna. Det är bättre att dela upp dessa uppgifter på flera metoder och funktioner så att anropen blir:

    filNamn = fragaFil()
    fildata = laesFranFil(filnamn)
    intresseantaTal = konvertera(fildata)
Programmet blir mer flexibelt. Metoden frågaFil kan skrivas om till ett grafiskt GUI där man klickar på rätt fil. Metoden laesFranFil kan användas i andra sammanhang då man vill läsa från fil. Man kan skicka fildatat till en ny metod som kontrollerar data innan man anropar konvertera.

Temporära variabler så lokalt som möjligt

Deklarera tillfälliga variabler så lokalt som möjligt. Det är ett grovt fel att ha loop-variabler som instansvariabler. I koden nedan antas infil vara en instansvariabel av typen fil initierad att läsa från tangentbordet.

    lasFranFil(self):
        filnamn = raw_input("Vad heter filen?")
        self.in =open(filnamn,"r")
        self.list = in.readLines()
	return self.list
    

Notera att metoden sätter om instansvariabel infil att peka på en ny fil som läser från fil. Övriga metoder och funktioner som använder infil kommer att påverkas. Även om programmet fungerar ändå (ingen annan metod använder infil) kan man få allvarliga problem om man försöker utöka programmet. Även list verkar vara deklarerade som instansvariabler helt i onödan då den returneras.

Återanvändbara funktioner/metoder/klasser

En del uppgifter kan separera i klasser som kan återanvändas i andra program.

Specialicerade metoder och funktioner kan man använda i andra sammanhang jämför avsnittet om metoder och funktioner ovan

In- och utdata till metoder och funktioner

Var noga med in och utdata till metoder och funktioner. En del metoder och funktioner som t.ex. bara skriver ut på skärmen kan vara parameterlösa metoder och funktioner. Övriga metoder har in och utadata. Om metoden använder instansvariabler ska detta kommenteras.

Flexibelt/utbyggbart program

Skriv ditt program så att det lätt att utöka och bygga ut.

Ingen kodupprepning

Ett vanligt nybörjarfel när man programmerar är att använda taktiken klippa och klistra. Det leder dock till kod som är väldigt svår att underhålla. Om man ändrar på ett ställe måste man göra samma ändring på flera parallellställen.

Ingen hårdkodning

Undvik att hårdkoda värden så gott det går. Om du behöver använda siffervärden kan man deklarera dessa som konstanter.
    ANTALSPELARE = 4
    PI = 3.14

Följande punkter är nödvändiga

Uppfyller kraven i lydelsen

Programmet måste uppfylla kraven i p-uppgiftslydelsen. Det är inte tillåtet att förenkla uppgiften. Om du vill göra några förändringar bör du förankra det med kursledaren först. Du måste kunna visa en bekräftelse (ett ebrev t.ex.) på att kursledaren godkänt kravförändringar.

Detaljförståelse

Vid redovisningen ska man kunna redogöra för alla detaljer i koden. Handledaren ska kunna ta bort en rad och man ska kunna förklara vad som händer.