Slutprojekt: leverans
Koden du lämnar ifrån dig
Ditt program fungerar. Det var det svåra, och det är gjort.
Det som återstår är en osynlig tröskel som finns i alla projekt: stunden när koden slutar vara enbart din. Innan den kan du arbeta i valfri ordning, döpa variabler till vad du vill och lämna felsökningsutskrifter kvar med löftet att ta bort dem snart. Ingen ser det utom du, och det fungerar.
Men nu ska du leverera. Läraren ska bedöma koden. Kanske ska en klasskompis använda programmet. Kanske är det ett portföljprojekt du visar upp om ett år. Perspektivet förändras: koden ska vara begriplig för någon som inte var med när du skrev den, inklusive dig själv om sex månader, när du inte längre minns varför du löste det på just det sättet.
Slarv vid leverans kan bli dyrt. 2012 förlorade finansföretaget Knight Capital 440 miljoner dollar på 45 minuter, för att en uppdatering inte lagts ut på alla servrar. Gammal kod vaknade till liv och skickade miljontals felaktiga order.
Det är vad clean code handlar om. Inte eleganta algoritmer eller optimering, utan kod som kommunicerar sin avsikt tydligt och inte lämnar frågetecken hos läsaren. Det är den sista formen av respekt för din kod: ta hand om den innan du lämnar ifrån dig den.
I den här delen skriver du alltså inget nytt. Du gör om det som redan finns, så att det går att läsa. Det är refaktorering, samma sak som du gjorde med Brawl i Din första funktion, och det är sista gången du rör projektet innan det lämnas in.
Det är också här du betalar av din Teknisk skuld En medveten genväg i koden som fungerar nu men gör framtida arbete dyrare. Precis som ett lån är den ibland värd att ta, den låter dig komma vidare i dag mot att någon får betala i morgon. Det farliga är inte att ta lånet, utan att glömma bort att man gjort det. , alltså de genvägar du tog medvetet under bygget för att komma vidare. Du mötte begreppet i Låsskärmen, där lösenordet låg i klartext för att gränssnittet skulle bli klart först. Gå igenom projektet och leta efter dina egna lån: en variabel du tänkte döpa om, en funktion som växte sig för stor, ett värde du hårdkodade “tills vidare”. Det som inte hinns med skriver du i stället ned under Om jag hade mer tid, för en känd skuld är oändligt mycket mindre farlig än en bortglömd.
Namngivning, den billigaste dokumentationen
Det snabbaste sättet att göra kod läsbar kostar noll extra rader: välj beskrivande namn.
# Svårläst, vad gör det här?
def b(x, y):
r = x - y
if r < 0:
r = 0
return r
# Tydligt, svaret finns i namnen
def beräkna_skada(attack, försvar):
skada = attack - försvar
return max(0, skada) Samma logik, samma antal rader. Den andra versionen kräver inga kommentarer, namnen är kommentaren. Det gäller variabler, funktioner, parametrar och filer. Kod som är omöjlig att läsa är omöjlig att underhålla, och system som ingen kan underhålla misslyckas på oförutsägbara sätt. Du läste om det i Verkstaden byggs: namnen du väljer idag är en del av hur du bygger saker som fungerar för fler än dig själv.
När ett tal återkommer i koden ger du det ofta ett namn: en Konstant En variabel vars värde inte ska ändras under programkörning. I Python namnges konstanter med versaler och understreck: MAX_FÖRSÖK = 3. Python hindrar dig inte från att ändra dem, konventionen är ett löfte till läsaren. som MAX_FÖRSÖK = 3 säger mer än en ensam trea längre ner. Men ibland är det bästa inte att namnge talet, utan att räkna ut det. I ditt Caesar-chiffer skrev du % len(alfabet), inte % 29. Skillnaden är att len(alfabet) fortsätter stämma även om du lägger till ett tecken i alfabetet, medan en hårdkodad 29 blir fel i tysthet. En konstant är ett löfte att talet inte ändras. len() behöver inget löfte, det räknar om sig självt.
En gemensam stil, PEP 8
Du har följt en stil genom hela kursen utan att vi satt namn på den: snake_case för variabler och funktioner, VERSALER_MED_UNDERSTRECK för konstanter, fyra mellanslag för indrag, en tom rad mellan funktioner. Det är inte slump, det är PEP 8 Pythons officiella stilguide. Beskriver konventioner för namngivning, indrag och mellanrum, så att Python-kod ser likadan ut oavsett vem som skrivit den. , Pythons officiella stilguide.
Poängen med en gemensam stil är inte att just den är objektivt rätt, utan att när alla följer samma slipper läsaren lägga energi på formen och kan fokusera på innehållet. VS Code kan formatera din kod efter PEP 8 automatiskt, så att indrag och mellanrum blir konsekventa utan att du tänker på det. Sök på “format document” i kommandopaletten.
Funktioner som gör en sak
En funktion som gör mer än en sak är egentligen två funktioner som råkar dela ett namn. Det märks tydligast när du försöker testa dem: du kan inte testa del A utan att köra del B också.
# Gör för mycket, ökar och ritar om och sparar och avgör vinst
def knapp_klickad():
global poäng
poäng += 10
poäng_etikett.config(text=f"Poäng: {poäng}")
spara_poäng(poäng)
if poäng >= 100:
visa_vinstskärm()
# Bättre, separata ansvarsområden
def öka_poäng():
global poäng
poäng += 10
def uppdatera_poäng_visning():
poäng_etikett.config(text=f"Poäng: {poäng}")
def knapp_klickad(): # koordinerar, delegerar
öka_poäng()
uppdatera_poäng_visning()
spara_poäng(poäng)
if poäng >= 100:
visa_vinstskärm() Den andra versionen är samma uppdelning du använt genom hela projektet: logik för sig, visning för sig, och en funktion som koordinerar. Kan du beskriva vad en funktion gör och behöver ordet “och” för att göra det, är det två funktioner.
Kommentarer som förklarar varför
Koden visar vad som händer. Kommentaren förklarar varför det händer på det sättet, beslutet bakom koden, inte en upprepning av koden i prosa.
# Dålig kommentar, upprepar koden
ålder += 1 # ökar ålder med 1
# Bra kommentar, förklarar beslutet
resultat = (position + steg) % len(alfabet) # modulo håller oss innanför
# alfabetet, som en klocka som
# börjar om vid tolv
# Bra kommentar, förklarar varför undantaget hanteras
except FileNotFoundError:
inventory = [] # första körningen, ingen sparfil finns ännu Checklista inför leverans
Gå igenom det här innan sista pushen:
- Funktionalitet: kör programmet som din målgrupp skulle, skriv fel, tryck på fel knapp, lämna fält tomma. Kraschar det? Ger det obegripliga felmeddelanden?
- Namngivning: läs igenom variabel- och funktionsnamn. Kan du förklara vad de gör utan att läsa koden runt omkring?
- Död kod: sök efter
print()du inte lade dit avsiktligt, utkommenterade block och funktioner som aldrig anropas. Felsökningsutskrifter du glömt kvar syns i terminalen när användaren kör programmet. Sådan Död kod Kod som aldrig körs: funktioner som aldrig anropas, grenar som aldrig kan nås, utkommenterade block som lämnats kvar. Förvirrar läsaren och ska tas bort, Git-historiken finns om du ångrar dig. ska bort, Git-historiken finns om du ångrar dig. - Kommentarer: finns det ett
# TODOeller# FIXA SENARE? Lös det, eller ta bort kommentaren och acceptera begränsningen medvetet. - Git-historiken: är commit-meddelandena meningsfulla? Återspeglar historiken ett progressivt arbete? En enda commit med meddelandet “klar” är inte en historik, det är en fil.
- README.md: är den komplett med målgruppsanalys och skiss? Kan din målgrupp förstå den?
Prova i VS Code
De här tre stegen är att titta, inte att bygga. De tar några minuter och visar dig vad du har.
Kör en global sökning i ditt slutprojekt (Ctrl+Shift+F, Mac ⇧⌘F) efter
print(. Hur många av träffarna är felsökningsutskrifter du glömt kvar?Välj en funktion i koden. Täck för funktionskroppen och läs bara namnet och parametrarna. Förstår du vad funktionen gör utan att se koden?
Kör
python -m py_compile main.pyi terminalen. Visas inga fel är syntaxen korrekt. Det testar inte logiken, men det är ett snabbt nollkoll inför leverans.
Bedömning
Bedömningen sker i ett samtal, inte som en skriftlig inlämning. Du visar programmet körandes och läraren ställer tre typer av frågor.
Designfrågor: varför valde du det här projektet? Vem designade du för, och hur påverkade det ett konkret beslut i gränssnittet?
Kodfrågor: välj en funktion du är nöjd med och förklara den. Vilket mönster från Mönsterkortet implementerar den? Vad tar den emot, och vad returnerar den?
Reflektionsfrågor: vad skulle du göra annorlunda om du började om? Vad var den svåraste tekniska utmaningen du löste, och hur löste du den?
Läraren tittar också på Git-historiken. Hur många commits, hur tidigt arbetet startade, och om meddelandena visar vad som faktiskt förändrades. En Git-historik berättar mer om hur ett projekt gick till än koden gör.
Uppgift: Städa och lämna ifrån dig
Detta ska lämnas in
Projektets andra och sista inlämning: den städade koden och en färdig README.md.
Gå igenom checklistan ovan på ditt slutprojekt. Dokumentera varje punkt: vad hittade du, vad ändrade du?
Välj en funktion du är nöjd med och en du vet kan bli bättre. Refaktorera den sämre till något du är nöjd med. Committa den för sig, med meddelandet
Refaktorering: [vad du ändrade].Fyll i din
README.md. Den har vuxit i tre steg, från målgruppsanalysen i designfasen till noteringarna under bygget. Det här är formen den ska ha när du lämnar ifrån dig den:
# [Programmets namn]
(En kort beskrivning, skriven för din målgrupp och inte för en programmerare.)
## Målgrupp
(Personen du designade för, och ett designval du gjorde just för hen.)
## Gränssnittsskiss
(Bild på pappersskissen. Skriv en rad om var koden avvek från skissen och varför.)
## Så använder du programmet
(Hur man startar det och vad som händer sedan.)
## Vilket spår och vilken nivå
(Fönster eller terminal, och varför. Grunden, en utbyggnad eller en kombination,
och vad du i så fall byggde till.)
## Mönster jag använde
- Presentatören:
- (fler mönster du känner igen från Mönsterkortet)
## Det som var svårast
(Vilket steg fastnade du på, och hur löste du det?)
## Om jag hade mer tid
(Tre saker du skulle förbättra.) - Gör en sista genomkörning av programmet som din målgrupp, och sedan din sista
git push. Det här är leveransen.
Vad händer om
Du visar en klasskompis koden utan att förklara något, kan de förstå vad en specifik funktion gör bara av att läsa den? Det är det ultimata testet på läsbarhet. Det är inget betyg, det är information om vad som fortfarande behöver bli tydligare.
Motivera & reflektera
Motivera ett namnbyte eller en refaktorering du gjorde. Varför är den nya versionen lättare för någon annan att läsa? Koden visar vad du byggde, motiveringen visar att du förstod varför, och båda påverkar bedömningen.
Nästa nivå
Gör programmet startbart utan Python. Så länge ditt program är en .py-fil kan bara den som har Python installerat köra det. Vill du ge det till någon i din målgrupp behöver det bli en fil de kan dubbelklicka på.
Verktyget heter PyInstaller och installeras med pip install pyinstaller. Sedan räcker ett kommando:
pyinstaller --onefile --windowed main.py Resultatet hamnar i mappen dist. --onefile packar allt till en enda fil, --windowed säger att inget terminalfönster ska öppnas bakom ditt grafiska program, och det utelämnar du om ditt program är en terminalmeny.
Var beredd på att det inte är helt smärtfritt. Filen blir stor, ofta tiotals megabyte, eftersom hela Python följer med. Windows Defender flaggar ibland nybyggda exe-filer som misstänkta, helt felaktigt, just för att de är nya och osignerade. Och en fil byggd på Windows kör bara på Windows, en byggd på Mac bara på Mac, så du kan inte bygga åt en kompis med annat operativsystem.
Lyckas du: lägg inte filen i ditt repo, den hör inte hemma i versionshanteringen. Lägg dist/ och build/ i din .gitignore i stället, och skriv i din README hur man bygger den. Det är så riktiga projekt gör.