Till KTH:s startsida Till KTH:s startsida

Ändringar mellan två versioner

Här visas ändringar i "Perfekt program" mellan 2015-01-28 11:56 av Linda Kann och 2015-01-28 11:57 av Linda Kann.

Perfekt program

Krav för perfekt program

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

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

Man ska inte behöva titta i en manual eller ännu värre, i själva programkoden för att förstå vad som händer. Programmet måste vara självinstruerande.

Hej och välkommen till primtalsprogrammet. Programmetskriver ut alla primtal i ett intervall du definierar. Ange undre gränsen i intervallet: 26Ange högre gränsen i intervallet: 54De primtal som finns mellan 26 och 54 är: 29 31 37 41 43 47 53

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

Enkel inmatning Inmatningen ska inte vara onödigt krånglig.

...Vill du boka en biljett? jaVarifrån åker du? ArlandaVart ska du åka? KastrupVilken månad ska du åka? MarsVilken dag ska du åka? 25Vill du boka returbiljett? jaVilken månad ska du tillbaka? AprilVilken dag ska du tillbaka? 5Det går tyvärr inget flyg den 25 mars. Försök igenVill du boka en biljett?jaVarifrån åker du? ArlandaVart ska du åka? KastrupVilken 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.

Vettiga namn Programmet ska ha intuitiva namn på variablerna. För den som skrivit programmet är allt självklart, men inte för andra.

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 + 1 Här följer samma kod med andra variabelnamn.

max = 0 i = 0 while i < len(lista): if lista[i] > max: max = lista[i] i = i + 1 Man ser nu lättare vad koden gör, nämligen sparar undan det högsta värdet i listan till variablen max. Fortfarande är inte namnet på listan optimalt. Vad för slags värden innehåller den? Är det löner, skottstatistik eller vad?

När det gäller en funktion eller metod brukar ett bra namn oftast vara ett verb som beskriver vad den gör eller vad den returnerar. Booleska funktioner (som returnerar True/False) bör ha ett namn som talar om hur läget är i det fall den returnerar True, t ex

Namnet på en klass kan vara ett substantiv som beskriver vad objektet representerar. Variabler och attribut är också substantiv.

Att komma på bra namn kräver en del arbete!

Kommentarer Alla klasser och funktioner måste kommenteras. Syftet med klassen/funktionen ska framgå. Det ska räcka att läsa kommentaren för att förstå hur en funktion ska användas (man ska inte behöva sätta sig in i hela koden).

In- och utdata till funktioner måste kommenteras. Det gäller både returvärden och parametrar. Om funktionen är en metod och den ändrar något attribut ska detta också kommenteras.

Kommentarerna ska inte förklara hur Python fungerar . man kan förutsätta att den som läser källkoden redan vet hur man programmerar.

Konsekvent språk Språkvalet ska vara konsekvent. Alla variabel-, klass- och funktionsnamn 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 Programmet ska ha en genomgående typografi. Namn som är sammansatta av flera ord kan t ex skrivas ihop genom att inleda varje nytt ord med stor bokstav, eller genom att skilja orden åt med understrykning. Variabel- och metodnamn brukar inledas med med liten bokstav och klasser med stor bokstav.

class Pussel def normeraKoordinater(x, y, z) Lämplig uppdelning i klasser Data som hör ihop (t ex namn, födelsedata och adressuppgifter för en person) kan samlas genom att dom får vara attribut i en klass. Funktioner som hör ihop kan bli metoder i en klass.

Lämplig uppdelning i funktioner/metoder Bäst är det med specialiserade funktioner som bara gör en sak. Här är ett exempel på hur man inte ska skriva:

def lasFranFilen(): filnamn = raw_input("Vad heter filen?") infil = open(filnamn,"r") lista = infil.readLines() lista2 = [] for element in lista: if type(element) == type(0): lista2.add(element) return lista2 Koden ovan gör flera saker; frågar efter en fil, läser in alla data från filen, stoppar in heltalen i en heltalsvektor och returnerar denna. Det vore bättre att dela upp dessa uppgifter på flera funktioner så att funktionsanropen blir:

filnamn = fragaFilNamn() fildata = laesFranFil(filnamn) intresseantaTal = samlaHeltal(fildata) Programmet blir då mer flexibelt: Funktionen fragaFilNamn kan skrivas om till ett grafiskt GUI där man klickar på rätt fil. Funktionen 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 samlaHeltal.

Temporära variabler så lokalt som möjligt Se till att tillfälliga variabler skapas så lokalt som möjligt. En variabel som bara används inuti en slinga i en metod ska inte vara ett attribut i klassen, utan en lokal variabel i metoden.

Återanvändbara funktioner/klasser Programmet ska delas upp i klasser som går att återanvända i andra program. T ex kan en klass som representerar ett spelkort användas i olika kortspelsprogram.

Funktioner ska om möjligt vara skrivna så att dom går att använda i andra sammanhang. Ett knep är att se till att alla indata ges som parametrar. Ett annat är att specialisera funktionerna, så att varje funktion bara gör en liten del.

In- och utdata till funktioner Var noga med in och utdata till funktionerna. En del funktioner som t.ex. bara skriver ut på skärmen kan vara parameterlösa och inte returnera något. Övriga funktioner bör ha alla indata som parametrar och utdata som returvärden.

Flexibelt/utbyggbart program Skriv ditt program så att det lätt att utöka och bygga ut. Några exempel: I ett program som samlar data om Pokémon ska man kunna lägga till fler Pokémon utan att gå in och ändra i programmet. Om ett program läser in från fil ska det vara lätt att byta till en annan fil. Om man vill lägga till en beräkning så ska det vara enkelt att stoppa in en funktion för det, utan att behöva ändra på många ställen i programmet.

Ingen kodupprepning Ett vanligt nybörjarfel när man programmerar är att använda taktiken klippa och klistra när samma sak ska göras på flera ställen i programmet. Detta 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. Detta går i regel att skriva om med en slinga eller en funktion med parametrar och returvärde.

Ingen hårdkodning Förekommer talet 5 på flera ställen i programmet? Om man behöver använda siffervärden kan dessa definieras som konstanter.

ANTALSPELARE = 5; PI =3.14;