Göm menyn

Programmeringspraxis

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.

- Antoine de Saint-Exupery

OBS! Detta är inte det första kapitlet, det är ett kapitel som bör läsas parallellt med övriga kapitel.

Detta kapitel beskriver inte hur du skriver kod för att datorn ska förstå den, utan hur du skriver kod så att du och andra människor förstår den.

Som utvecklare så är det sällan mängden kod eller antalet funktioner som utmärker hur duktig man är. Det som särskiljer en duktig programmerare är hur bra hen är på att följa olika programmeringspraxis; goda koncept som bör eftersträvas. Programmeringspraxis som bör följas av pythonutvecklare står definierade i vissa PEP-dokument (Python Enhancement Proposals).

Korrekthet

För att avgöra om en funktion beter sig korrekt måste vi fastställa vad det är den ska göra. Funktionens kontrakt specificerar exakt hur funktionen ska bete sig.

Antingen skriver du kontraktet efter att du skrivit en funktion för att försäkra dig om att funktionen behåller det nuvarande beteendet, alternativt behöver du skriva eller redigera en funktion med fastställt kontrakt. Det är viktigt att funktionen uppfyller exakt den funktionalitet som beskrivs i kontraktet. För att vara säker på att kontraktet uppfylls används tester.

Kontraktet finns definierat i funktionens docstring (se senare avsnitt)

Läsbarhet

En sak att ha i åtanke när du skriver kod är att den kommer att läsas fler gånger än vad den kommer att skrivas. Det är därför viktigt att se till att andra, och även du själv, kan förstå koden vid ett senare skede och göra nödvändiga ändringar.

För att Python-kod ska vara konsekvent finns ett antal riktlinjer som bör följas.

Självdokumenterande kod

Kod som är självförklarande nog att ingen extra dokumentation behövs för att den ska förstås kallas självdokumenterande och är något programmerare bör sträva efter. Detta uppnås främst med hjälp av beskrivande variabel- och funktionsnamn samt väl strukturerad kod.

Några exempel på funktionsnamn: has_been_read, contains_key, is_substring.

Namnformatering

Namn ska formateras enligt vissa riktlinjer. Det är viktigt att dessa riktlinjer följs då det annars blir svårt för andra att arbeta med din kod. Python i sig tar inte hänsyn till vad du använder. En generell regel är att ny kod ska namnges på samma sätt som existerande kod.

Olika språk har olika standarder men för Python gäller följande:

CamelCase

  • Namnet kommer från pucklarna som texten får.
  • Alla ord skrivs ihop där varje ord börjar med stor bokstav.
  • Används för klasser och undantag i Python.
  • Alternativt kan första ordet ha liten bokstav, detta används ej i Python.

snake_case

  • Namnet kommer från de långsmala namn som bildas.
  • Alltid små bokstäver med ord separerade med understreck.
  • Används för variabler, funktioner, metoder och moduler (modulnamn bör endast vara ett ord eller ihopskrivet utan understreck)

CAPITAL_LETTERS

  • Används för variabler vars värde ska vara konstant (så kallade konstanter).

Blankrader

Alla funktioner och klasser på toppnivå (dvs ej indenterade) ska omringas av två blankrader. Undantag kan göras för enradade funktioner. Inre funktioner, klasser och metoder omringas av en blankrad.

Blankrader kan användas i funktioner för att dela upp koden i logiska sektioner.

Kommentarer

"You know you're brilliant, but maybe you'd like to understand what you did 2 weeks from now."

- Linus Torvalds

Om en sats ej är helt självförklarande bör kommentarer användas för att beskriva syftet med, och tanken bakom, satsen. Kommentarer ska alltid vara fullständiga meningar och stämma överens med koden som beskrivs. Kommentarer ska ej användas till att beskriva speciell syntax eller specifika operationer. Kommentarerna kompletterar koden så att de tillsammans gör programmet lätt att förstå.

Onödig kommentar. Förklara istället varför x tilldelas 2.

Typer av kommentarer

Kommentarer är markerade sektioner av koden som ignoreras av interpretatorn. Likt många andra programmeringsspråk har Python två sorters kommentarer.

Docstrings

"A universal convention supplies all of maintainability, clarity, consistency, and a foundation for good programming habits too. What it doesn't do is insist that you follow it against your will. That's Python!"

-Tim Peters on comp.lang.python, 2001-06-16

Python använder så kallade docstrings, vilket är blockkommentarer placerade direkt efter definitionen av funktioner, metoder, moduler eller klasser. Docstrings får några speciella egenskaper som vi inte kommer gå in på, men ska kortfattat förklara vad funktionen gör. I kursen kräver vi väl skrivna docstrings på alla funktioner från och med labb 4 och på tentamen.

Docstrings ska som andra kommentarer vara skrivna i flytande text. För funktioner ska en docstring summera funktionens beteende, dokumentera dess argument, returvärde och sidoeffekter. Finns många argument kan dessa beskrivas med en rad per argument.

Docstring utgör en funktions kontrakt. En funktionen som utför det och endast det som är specifierat i dess docstring kan anses vara korrekt.

Det finns ytterliggare krav enligt standarden som inte behöver uppfyllas i denna kurs För fullständig specifikation, se PEP-257.

Radlängd

För att skriva lättlästa program brukar man begränsa längden som en rad får ha. PEP-8 specificerar att Python-kod maximalt ska vara 79 tecken lång för att behålla läsbarheten. Vidare ska kommentarer och docstrings enbart vara 72 tecken långa enligt specifikationen.

Att det just är 79 tecken som är bredden för koden har troligen sitt ursprung i att terminalfönster som standard har en bredd på 80 tecken samt att markören uppfyller ett tecken. Det finns dock fler anledningar till att ha en radbredd som enbart är 79 tecken i dagsläget. PEP-8 nämner som exempel att det gör det möjligt att ha flera filer öppna vid sidan av varandra.

För att få emacs att hålla reda på radlängden (80 tecken som standard) åt en kan man lägga till följande emacs-lisp kod i filen ~/.emacs (och skapa den om den inte finns):

Det kommer att lägga till en annan bakgrundsfärg på alla tecken efter det 79:e tecknet.

Mellanrum och onödiga tecken

Eftersom att man strävar efter att skriva läsbar kod är det även värt att nämna något om mellanrum i koden och onödiga tecken. Det man kan tänka på med mellanrum i koden är att det inte finns någon regel som inbegriper alla fall. Som riktlinje kan man dock ha att man ska efterlika helt vanlig text. Till exempel, ha ett mellanslag efter ',' och separera gärna långa aritmetiska uttryck på lämpliga ställen. Jämför:

Med:

Vill man kan det hela delas upp på två rader enligt följande:

Notera här att det inte finns med ett '\' i slutet av första raden. Det är för att inget '\' behövs i och med att interpretatorn förstår att eftersom det är en öppen parentes (i ett funktionsanrop) och raden slutar med ',' kommer nästa rad påbörja nästa argument. Därmed är '\' onödigt och införandet av tecknet kan istället förvirra. Det gäller även i det generella fallet, är något eller några tecken onödiga bör utlämnas.

Enkelhet

Koden är inte en plats att briljera med sina kunskaper i ett språks konstigaste funktionaliteter, enkel och tydlig kod är att föredra.

Även om dessa två lösningar gör samma sak är det nedre alternativet mer lättläst. Detta för att det använder en if-sats och inte använder att 0 tolkas som False i Python.

Testbarhet

"If it's hard to document, it's probably wrong. If it's hard to test, it's almost certainly wrong."

- Okänd upphovsman

Testbarhet är måttet på hur enkelt något är att testa (ej i vilken grad det faktiskt testas), det kan vara ett system, ett program eller en individuell funktion. Moduläritet är en viktig del i hur testbart ett program är. Det är ett mått på i vilken grad något är uppdelat i självständiga delar. Detta kan vara funktioner, klasser, moduler eller liknande. Det här leder till att det blir enkelt att testa varje del för sig.

Moduläritet innebär också att varje del har ett specifikt ansvar (eng. separation of concerns). Med specifikt ansvar menar vi att man endast utför en uppgift och inget annat. Kommunikation mellan delar bör ske strikt och kontrollerat.

Länkar

PEP-8 PEP-257

För en kort dikt om hur pythonkod bör skrivas, skriv följande kommando i en Python-interpretator:

Tillhörande quiz

Finnes här


Sidansvarig: Peter Dalenius
Senast uppdaterad: 2016-09-29