2. Moment02 - Grunderna

Info

Till detta moment finns en sida med lösningsförslag och videoklipp.

2.1 Introduktion

Vi har tidigare skrivit lite korta kodexempel men mest för att visa hur det fungerar att köra individuella koder mot Pythons interpretator i Terminalen och hur vi kan köra filer med instruktioner både i terminalen och från PyCharm. Behöver du repetera och eventuellt installera om någon av delarna så hittar du den informationen här.

2.2 Utskrift

Att skriva ut text i Python gör vi med utskriftsfunktionen print().

Kodexempel: utskrift

print("Hello World")

Utskrift

Hello World

Inne i parentesen, inom dubbelfnuttar (" ") så skrivs den texten som vi vill få utskriven. Det går också att ange enkelfnuttar (' ') för att skriva ut samma sak.

Kodexempel: utskrift

print('Hello World')

Utskrift

Hello World

Som du ser så kommer det inte göra någon skillnad vid utskriften, varför vi väljer att använda den ena eller den andra kommer vi att återkomma till senare.

2.2.1 Kommentarer

Det finns två stora frågor när det gäller kommentarer;

  1. Hur man kommenterar i det aktuella språket.
  2. Hur mycket behöver jag kommentera?

När vi kommenterar kod så görs detta ofta på olika sätt, dels så är det vanligt att skriva kommentar på en rad men sedan är det också effektivt att blockommentera, vilket innebär att du kommenterar ett större block av kod och då kan det ofta behöva skrivas kommentar på flera rader.

Att kommentera bort kod är också användbart då du utvecklar och/eller testar kod. Kod som du har "kommenterat bort" kommer inte köras när du testar koden.

Kodexempel: kommentarer

# Kommentera en rad görs med "hashtag-tecknet"
print("Hello World")        # Det går också att kommentera efter koden vad koden gör

# Bortkommenterade utskrifter
# print("Detta är en rad med utskrift")
# print("Detta är en annan rad med utskrift")

Utskrift

Hello World

Om du vill kommentera bort en större mängd kod, eller skriva ett större block med kommentarer så finns det ett speciellt sätt att göra detta på. Då kan du skapa en större sträng som du väljer att inte skriva ut. Men det är också en teknik som du kan använda om du vill skriva ut ett större textblock och ha bättre koll på formatering såsom radbrytning.

Kodexempel: kommentarer

"""
  Om vi vill kommentera på flera rader så
  görs detta med tre raka dubbelfnuttar för att starta kommentaren
  men också för att avsluta kommentaren.
  """

print("""Men det går också att använda denna tekniken för att
        skriva ut en formaterad
    text om man nu vill det.
Här gäller det att börja och sluta med tre enkel- eller dubbelfnuttar.
""")

Utskrift

Men det går också att använda denna tekniken för att
        skriva ut en formaterad
    text om man nu vill det.
Här gäller det att börja och sluta med tre enkel- eller dubbelfnuttar.

Hur mycket kommentarer behöver du skriva i din kod? Grundtanken är att kommentarer skall hjälpa dig och andra att förstå koden. Att skriva en kommentar för varje rad som utför något enkelt kommando gör att koden snabbt blir överkommenterad. Jag brukar ha två saker som riktmärke för kommentarer.

  • Kommentera de delar som är nya och som du tränar på i just detta momentet.
  • Om du av någon anledning inte kodade en rad på tre månader och fick se en gammal kod du har skrivit, då skall den vara så välkommenterad så att du själv direkt förstår, och kommer ihåg, vad koden gör och hur du skall rätta den ifall det behöver göras.

Allt eftersom du blir duktigare på att koda så kommer det bli naturligt för dig hur mycket du skall kommentera. Håller du dig till de två riktlinjer som finns ovan så kommer du och de som ser din kod få den hjälp som ni behöver.

För betygssättning så behöver du och din lärare vara överens om vad som skall gälla för olika betygsnivåer.

2.2.2 Escapetecken

Kodexempel: escapetecken

print("Detta är en helt vanlig utskrift.")

# Att skriva ut 'enkel-' eller "dubbelfnuttar" är enkelt när jag kan välja hur texten skall markeras i print()
print("Denna text har 'enkelfnuttar' i sig.")
print('Denna text har "dubbelfnuttar" i sig, då måste vi använda enkelfnuttar för att rama in strängen')
print() # Skriver ut en tom rad

# Det blir lite svårare när vi både skall skriva ut 'enkel-' eller "dubbelfnuttar" i en text.
# option+shift+7 ger backslash på en mac.
print("Om vi måste blanda 'enkelfnutt' och \"dubbelfnutt\" så använder "
      "vi oss av ett backslash '\\' för att \n markera att det tecken som "
      "i normala fall avslutar en sträng skall skrivas ut.")
# Lägg också märke till att jag nu skrev tre texter i samma parentes.
# Det fungerar att slå ihop text vid utskrift på detta sätt.
# \n i koden skapar en radbrytning i utskriften

"""
Andra användbara escapetecken är
\\ för att kunna skriva ut backslash (\)
\n för att skapa en "new line" (radbrytning) i text
\t för att skapa en tabb(texten flyttas in en bit)
"""

Utskrift

Detta är en helt vanlig utskrift.
Denna text har 'enkelfnuttar' i sig.
Denna text har "dubbelfnuttar" i sig, då måste vi använda enkelfnuttar för att rama in strängen

Om vi måste blanda 'enkelfnutt' och "dubbelfnutt" så använder vi oss av ett backslash '\' för att
markera att det tecken som i normala fall avslutar en sträng skall skrivas ut.

Skriva ut backslash i Windows10/11

Det kan ta en stund att få ordning på alla specialtecken som används i programmering som du normalt sätt inte använder dig av. För att skriva ut backslash så använder du följande tangenter.

Utskrift

Problem med att skriva backslash (macOS)

På vissa datorer kommer hjälpmenyn upp om du trycker på den kombination som som skall ge backslash. Du löser detta genom att;

  • Klicka på äpplet (övre vänstra hörnet) > Systeminställningar > Tangentbord > Kortkommandon
  • Markera delen som heter Programkortkommandon.
  • Klicka ur rutan för Visa hjälpmenyn

2.2.4 Uppgift

Efter varje del så finns det en uppgift som du skall göra för att träna på, och visa att du behärskar, de delar som du precis har gått igenom.

Denna första övningen behandlar utskrifter, kommentarer och escapetecken.

Uppgift: m02u01

Skapa programkoden som skapar följande utskrift.

Utskrift

Jag heter <mitt namn> och jag läser programmering på Alströmergymnasiet.
Jag tycker att det verkar "kul" med programmering.

Dessa tre rader
har jag skrivit med
en enda print().

Följande saker har jag kommenterat i min kod:
  * Hur jag skrev ut dubbelfnuttarna på andra raden
  * Hur jag kunde skriva ut tre rader med en print().
  * Hur jag använde mig av tab, för att göra denna listan.

Saker att notera

  • <ditt namn> skall bytas ut mot ditt för och efternamn.
  • Tabbarna i slutet av utskriften kan vara olika långa beroende på inställningar, men det är tabb och inte mellanslag som du skall använda.
  • Du får endast använda trippla dubbelfnuttar (""") när du skapar kodhuvudet (se nästa punkt), ingen annan gång i denna uppgiften.
  • Innan du är klar så skapar du ett kommentarsblock längst upp i filen och där skriver du ditt namn, din klass, vilken uppgift det är du har löst och gärna ett datum då du blev färdig. Ta för vana att skapa detta huvud för varje uppgift, det måste du ha när du senare lämnar in en uppgift och då skall du dessutom skriva en kort utvärdering av uppgiften.

Uppgifter av denna typen skall inte lämnas in. När du är färdig så kika gärna i mitt hjälpavsnitt och jämför din lösning med min och reflektera över likheter och eventuella skillnader. Det viktigaste när vi programmerar är att vi skaffar oss flera olika verktyg som vi sedan kan använda när vi löser våra uppgifter.

2.3 Variabler

Variabler används ofta i programmering för att inte programmen skall bli helt statiska. Det är variabler, inmatade eller sådana som finns/skapas i våra program, som gör att vi kan styra ett program att lösa olika problem, ta emot och sammanställa data eller vad det nu är vad vi vill göra med vårt program.

Kodexempel: variabel

age = 17
print(age)

Utskrift

17

Innan vi börjar använda variabler så finns det några saker vi behöver tänka på.

  • Variabelns namn får inte börja med en siffra, tal1 är ok men inte 1tal
  • Variabelns namn får inte innehålla ett mellanslag, my age är inte godkänt som variabelnamn.
  • Variabelns namn är case sensitive vilket innebär att Python skiljer på gemener och versaler (stora och små bokstäver), tal och Tal är alltså två olika variabler.
  • Variabler får inte ha samma namn som de reserverade orden i Python. Ett reserverat ord är ett ord som har särskild betydelse för Python och kan därför inte användas. De reserverade orden är [is, if, in, def, del, or, elif, from, for, and, else, while, import, not, except, raise, assert, return, global, class, try, break, not, lambda, continue, finally]

Sedan finns det några saker till att tänka på när vi skapar variabelnamn, dessa är inte absoluta krav men de underlättar för dig när du utvecklar program och det gör att koden du skriver blir snyggare vilket kan innebära ett högre betyg på kursen.

  • Skapa variabelnamn där du vet vad det står för, att läsa en programkod och se variablerna a, b och c säger inte så mycket när vi bara ser dessa. Att döpa variablerna till r, o och a kan i sammanhanget vara bättre men först när du ser variabelnamnen radie , omkrets och area som du på riktigt vet vad variablerna innehåller. Ge variabler namn så att du förstår vad de innehåller.
  • Var konsekvent i din namngivning. Att blanda gemener och versaler huller om buller kommer ge dig problem då du inte minns hur en specifik variabel skrivs.
  • Att skriva långa variabelnamn kan hjälpa dig att veta vad en variabel skall lagra, men det kan också bli väldigt långa namn som är svåra att läsa i koden, t.ex. envariabelihopslagenavfleraord. Det finns i grova drag tre alternativa skrivsätt att ta hand om variabelnamn som är ihopsatta av flera ord.
    • PascalCase, EnVariabelIhopslagenAvFleraOrd, där varje ord börjar med versal. Detta är ett relativt enkelt skrivsätt att läsa och används som standard i flera andra programmeringsspråk, t.ex. C#.
    • camelCase, enVariabelIhopslagenAvFleraOrd, fungerar på samma sätt som den ovan fast första bokstaven i namnet skrivs med gemen. Ännu vanligare än PascalCase och används bl.a. i java.
    • snake_case, en_variabel_ihopslagen_av_flera_ord, vilket skiljer sig från de andra alternativen då orden separeras med underscore. Detta är det rekommenderade skrivsättet för Python när det gäller variabler och senare också metoder.
  • Var konsekvent i valet av språk för dina variabelnamn. Det är ok att döpa en variabel till ålder men risken är stor att det kommer bli problem för någon som inte har den svenska teckenuppsättningen på sin dator att kunna hjälpa dig eller köra ditt script. Vissa löser detta genom att ta bort prickar och ringar på å/ä/ö och döper då variabeln till alder medan andra väljer ett engelskt variabelnamn age. Att välja engelska som grundspråk för din namngivning och kommentarer ger dig större chans att få hjälp om du publicerar ett problem på nätet. Du får välja vilken variant du vill men du skall vara medveten om riskerna. Oavsett så vill jag att du är konsekvent genom varje applikation.

2.4 Datatyper

För att datorn skall kunna hantera variabler och dess innehåll så kommer varje variabel vara av en viss datatyp. En datatyp kan t.ex. vara ett tal, en textsträng eller en bokstav. I många programmeringsspråk så deklarerar programmeraren vilken typ en viss variabel skall ha och sedan måste den variabeln vara av denna typen genom hela programmet. Python fungerar inte så, här deklareras inte variabeln när den skapas utan variabeln skapas när den får ett värde och kommer då ta samma datatyp som värdet den får. En variabel i Python kan också byta datatyp när programmet körs. Det finns för- och nackdelar med detta sätt, fördelen är att det är enkelt att skriva koden men en svårighet kan vara ifall variabeln har en annan typ än vad du förväntar dig. Som vanligt gäller det att vara noggrann när du kodar. Om en variabel har en annan datatyp än vad du förväntar dig så är sannolikheten stor att detta kommer skapa problem och programmet ger ett felmeddelande istället för att slutföra sin uppgift.

Att ge ett värde på en variabel kallas att den tilldelas ett värde och i Python, och faktiskt de flesta programmeringsspråk, så görs detta med ett likhetstecken (likamedtecken). Det är viktigt att tilldelningen sker i riktning från höger till vänster, vänder du på det så kommer du få ett error (SyntaxError: can't assign to literal).

Kodexempel: tilldela en variabel ett värde

test = 17
print(test)
test = "Johan"
print(test)
test = 1.2    # Notera punktnotation för decimaltal
print(test)

Utskrift

17
Johan
1.2

Innan vi går in på de olika datatyperna så är det faktiskt ganska enkelt att se att i koden ovan så har vi tre olika datatyper, ett heltal, en text och en ensam bokstav. Tyvärr är det inte alltid lika enkelt att vid utskrift se vilken datatyp som används. Vi kikar på ett exempel.

Kodexempel: vilken datatyp?

test = 1
print(test)
test = "1"
print(test)

Utskrift

1
1

Som du ser, inte helt enkelt. I detta fall så är det dessutom viktigt ifall vi vill addera ett tal till vår variabel så kommer det endast vara möjligt i ett av alternativen. Vilket tror du att det är?

Det finns en funktion för att kolla vilken datatyp en variabel har och det är type(variabelns_namn) och när du skriver ut detta med funktionen print() så kommer datatypen att skrivas ut.

Kodexempel: vilken datatyp?

test = 1
print(type(test))
test = "1"
print(type(test))
test = 1.2
print(type(test))

Utskrift

<class 'int'>
<class 'str'>
<class 'float'>

2.4.1 Standarddatatyper i Python

Det finns en begränsad mängd datatyper i Python och vi skall göra det ännu enklare och just nu bara visa på de viktigaste och de datatyper som du kommer klara dig väldigt bra på i denna kursen. Skall du göra avancerade matematiska beräkningar kanske du behöver använda ytterligare någon datatyp, men isf tar vi det då. Pythons dokumentation över inbyggda typer.

Namn Exempel Not
int 1, 7, -9 int står för integer och lagrar heltal
float 0.0, 4.5, -9.7 flyttal, lagrar decimaltal, notera decimalpunkt enligt engelskspråkig standard
string "Hello world", "Johan", 'j' String/strängar. Alla texter och tecken. Markeras med dubbelfnutt(") eller enkelfnutt (')
boolean true, false Boolesk variabel, lagrar sant eller falskt, ofta ett resultat av ett uttryck som (1 < 2)

2.5 Aritmetik

Beräkningar i alla dess former är något som datorn är bra på och som vi ofta får programmera. De flesta beräkningssätten känner du igen och de kommer från matematiken men några av dem är beräkningar som du kanske har glömt bort från de tidiga åren i grundskolan. Jag visar de olika aritmetiska operatorerna som du behöver kunna.

Kodexempel: aritmetik

# Variabler som tilldelas ett värde
a = 9
b = 4

# Det går att beräkna och skriva ut svaret samtidigt ...
# + används för addition
print(a + b)

# ... eller så gör du beräkningen och lagrar denna i en ny variabel ....
c = a + b
print(c)         # ... som skrivs ut

# - används för subtraktion
print(b - a)

# * används för multiplikation
print(a * b)

# / används för division
print(a / b)

# Heltalsdivision, alltså där vi bara får heltalet som svar skrivs med // ...
print(a // b)    # 9 klubbor skall delas på 4 personer, varje person får två var...

# ... för att få fram resten (det som blir över) använder vi % (modulus)
print(a % b)     # ... och det blir 1 över (rest)

# Ifall vi vill använda oss av upphöjt med (a^2) skriver vi **
print(a ** 2)    # Vi behöver inte bara räkna med variabler, det går bra med tal också

# Roten ur är ju samma sak som upphöjt med 0.5
print(a ** 0.5)

Utskrift

Här har jag dolt utskriften för att du själv skall kunna fundera på vad som skrivs ut.

Klicka för att visa utskrift!

13
13
-5
36
2.25
2
1
81
3.0

Troligtvis är det inga konstigheter med dessa beräkningar. Du ser också att när det behövs så görs datatypen om, alla tal som har en decimal är float's samtidigt som de andra är integers.

Inom programmeringen så finns det ofta skrivsätt som är förkortade för att det skall vara enkelt och gå snabbt att skriva kod. Här nedan följer några sådana exempel.

Kodexempel: aritmetik, förkortat skrivsätt

# Deklarera variabler
a = 4
b = 3

# För att addera b till a skriver vi i vanliga fall ...
a = a + b

# ... men det går också att skriva kortare
a += b

# På samma sätt med övriga räknesätt
a -= b      # vilket är samma som a = a - b
a *= b      # vilket är samma som a = a * b
a /= b      # vilket är samma som a = a / b
a %= b      # vilket är samma som a = a % b
a //= b     # vilket är samma som a = a // b
a **= b     # vilket är samma som a = a ** b
# De tre sista kanske inte är så vanligt att man använder....

2.5.1 Uppgift

I denna uppgift skall du utföra ett antal beräkningar. Det kan kännas som att uppgiften inte hänger ihop, men följ punkt för punkt så blir det enklare. Vissa delar av denna uppgiften skall vi återanvända i senare uppgifter.

Uppgift: m02u02

  1. Skapa fyra variabler, ge dem följande namn och värde;
    • a får värdet 9
    • b får värdet 2
    • f får värdet "4 komma 0"
    • namn tilldelas <ditt namn>
  2. Beräkna a multiplicerat med b, skriv ut svaret och sedan datatypen.
  3. Beräkna a multiplicerat med f, skriv ut svaret och sedan datatypen.
  4. Beräkna a dividerat med b, skriv ut svaret och datatypen. Skriv en kommentar varför du tror att datatypen blir den som den blir.
  5. Skriv ut ditt namn och sedan datatypen.
  6. Beräkna heltalsdivisionen mellan a och b, skriv ut svaret och sedan datatypen.
  7. Beräkna resten mellan a och b, skriv ut svaret och sedan datatypen.
  8. Kommentera uppgift 6 & 7, varför blir svaret och datatypen som den blir?
  9. Beräkna roten ur a, skriv ut svaret och sedan datatypen.
  10. Beräkna kvadraten av b, skriv ut svaret och sedan datatypen.
  11. Beräkna kvadraten av f, skriv ut svaret och sedan datatypen.
  12. Kommentera uppgift 9, 10 & 11, varför blir svaret och datatypen som den blir?
  13. Addera slutligen b till a enligt det korta skrivsättet. Skriv sedan ut detta svar.

2.6 Utskrifter

I den förra uppgiften så gjorde vi en mängd beräkningar och sedan skrev vi bara ut svaret på det sätt som hade gjort vår matematiklärare helt galen. För att få till snyggare utskrifter måste vi lära oss att bygga upp dessa på ett bra sätt. Det finns några olika sätt att göra detta på och vi skall kika på hur de fungerar.

2.6.1 Utskrifter med kommatecken

Första tekniken vi skall kolla på använder sig av kommatecken.

Kodexempel: utskrift med kommatecken

namn = "Johan"
kurs = "Programmering01"
print("Jag heter", namn, "och läser kursen", kurs)

Utskrift

Jag heter Johan och läser kursen Programmering01

Detta är troligtvis det enklaste sättet att göra en utskrift och den fungerar bra i detta fallet. I samband med kommatecknet läggs också ett mellanslag till vilket du behöver ha koll på, gör du ett eget mellanslag inne i strängen så kommer dubbla mellanslag skrivas ut.

Det går också att skriva ut andra datatyper med denna tekniken.

Kodexempel: utskrift med kommatecken

kurs = "Programmering01"
poäng = 100
betygetB = 17.5
print("Kursen", kurs, "omfattar", poäng, "poäng och om jag når betyget B kommer jag få", betygetB, "poäng.")

Utskrift

Kursen Programmering01 omfattar 100 poäng och om jag når betyget B kommer jag få 17.5 poäng.

Det kan finnas olika anledningar att inte vilja skriva ut på detta sättet, det kanske är så att vi vill undvika mellanslag mellan en variabel och en enhet, 125% eller att vi vill formatera ett tal på ett visst sätt, 17.5 vs 17.50. Då får vi ta till ett annat sätt.

2.6.2 Utskrifter med plustecken

Plustecken använder vi när vi skall addera två tal men vi kan också använda plustecken för att addera två strängar. Denna teknik kallas att konkatenera två strängar. Ordet härstammar från catena som betyder ihopkedjning.

Kodexempel: utskrift med plustecken

namn = "Johan"
kurs = "Programmering01"
print("Jag heter " + namn + " och läser kursen " + kurs)

Utskrift

Jag heter Johan och läser kursen Programmering01

Här behöver du lägga märke till att det behövs mellanslag i din sträng för plustecknet lägger inte till egna mellanslag.

Det gick ju enkelt att använda sig av variabler med datatypen String men när vi skall göra samma sak med numeriska datatyper måste vi passa på att typkonvertera dem eftersom det bara går att konkatenera strängar. Typkonvertera i Python är enkelt, det vi gör är att runt variabeln sätta en parentes och ange vilken metod vi skall anropa för att konvertera variabelns värden. Metoden heter typ samma som den skall konvertera värdet till. Vill du konvertera till en sträng så heter metoden str(), vill du konvertera till en int så heter metoden int() och vill du konvertera till en float (decimaltal) så heter metoden float(). Mer om metoder kommer i senare moment, mer om konvertering kommer i detta moment.

Kodexempel: utskrift med plustecken

kurs = "Programmering01"
poäng = 100
betygetB = 17.5
print("Kursen " + kurs + " omfattar " + str(poäng) + " poäng och om jag når betyget B kommer jag få " + str(betygetB) + " poäng.")

Utskrift

Kursen Programmering01 omfattar 100 poäng och om jag når betyget B kommer jag få 17.5 poäng.

2.6.3 Bygga upp sträng innan utskrift

Det är ju inte bara för att kunna formatera det lilla extra som gör detta sätt smidigt. Senare när du lär dig jobba med villkor och loopar så är det troligt att du vill bygga upp en sträng som skrivs ut först när alla beräkningar är klara. Om den tekniken skall användas så behöver du kunna konkatenera strängar.

Kodexempel: bygga upp sträng

kurs = "Programmering01"
poäng = 100
betygetB = 17.5

# Bygger upp sträng inför utskrift
s = "Kursen " + kurs
s += " omfattar " + str(poäng)
s += " poäng och om jag når betyget B kommer jag få "
s += str(betygetB) + " poäng."

# Skriver ut strängen
print(s)

Utskrift

Kursen Programmering01 omfattar 100 poäng och om jag når betyget B kommer jag få 17.5 poäng.

Som du ser så är det ingen skillnad i slutresultatet (utskriften) men det kommer underlätta att bygga upp utskrifter på detta sätt.

2.6.4 Utskrift utan radbrytning

Vi har tidigare lärt oss att print() avslutas med en radbrytning, men det finns faktiskt ett sätt att skriva ut någonting och låta utskriften hänga i luften för att sedan skriva vidare med ett nytt print()-kommando.

Kodexempel: utskrift utan radbrytning

kurs = "Programmering01"
poäng = 100
betygetB = 17.5

# Skriver ut text men radbryter inte utskriften.
print("Kursen " + kurs + " omfattar ", end="")
print(poäng, end="")
print(" poäng och om jag når betyget B kommer jag få ", end="")
print(str(betygetB) + " poäng.")    # Här radbryter vi utskriften (vilket vi iof inte måste)

Utskrift

Kursen Programmering01 omfattar 100 poäng och om jag når betyget B kommer jag få 17.5 poäng.

2.6.5 Formatering

Vi skall kolla på ett annat sätt att blanda strängar och variabler vid utskrift. I detta exempel så skapar vi först en formaterad sträng som visar hur utskriften skall se ut och sedan så placerar vi in variablerna i den strängen, det finns här också möjlighet att formatera varje variabel för sig själv, speciellt användbart är detta om vi skriver ut numeriska värden.

Kodexempel: utskrift med formatering

kurs = "Programmering01"
poäng = 100
betygetB = 17.5

print("Kursen {} omfattar {} poäng och om jag når betyget B så kommer jag få {} poäng.".format(kurs, poäng, betygetB))

När jag skapar strängen så markerar jag med måsvingar var de olika variablerna skall placeras in. Här har jag inte angivit några siffror i måsvingarna och då kommer variablerna placeras in i den ordning som jag har skrivit dem. Om jag skall ange en siffra inom måsvingen {0} så numreras de i ordning, hur de är skrivna i format()-metoden, med start på index 0. Index 0 är ett vanligt sätt att räkna inom programmering eftersom de första binära talet är 0. Om vi lägger med våra index så blir koden;

Kodexempel: utskrift med formatering

kurs = "Programmering01"
poäng = 100
betygetB = 17.5

print("Kursen {0} omfattar {1} poäng och om jag når betyget B så kommer jag få {2} poäng.".format(kurs, poäng, betygetB))

Utskriften i bägge fallen blir:

Utskrift

Kursen Programmering01 kurs omfattar 100 poäng och om jag når betyget B så kommer jag få 17.5 poäng.

Detta sätt att formatera utskriften är också effektivt då vi vill formatera text eller ange ett visst antal decimaler i vår utskrift.

Kodexempel: utskrift med formatering

namn1 = "Anna"
namn2 = "Beatrice"
namn3 = "Carl Gustav"

poäng1 = 17.5
poäng2 = 8
poäng3 = 19

# Utskrift som är oformaterad
print("{0} {1}".format(namn1, poäng1))
print("{0} {1}".format(namn2, poäng2))
print("{0} {1}".format(namn3, poäng3))

print()
# Utskrift med 12 positioner för strängen
print("{0:12s} {1:5.1f}".format(namn1, poäng1))
print("{0:12s} {1:5.1f}".format(namn2, poäng2))
print("{0:12s} {1:5.1f}".format(namn3, poäng3))

Utskriften skall simulera en resultatlista för ett matteprov. Den första utskriften är gjord helt utan formatering.

Den andra utskriften har två formateringsinstruktioner;

  • {0:12s} innebär att det först är index 0 (alltså den första variabel som angivits) och den skall formateras som en sträng och denna sträng skall få 12 teckens utrymme. Är strängen för kort så fylls det ut med mellanslag, är strängen för lång så kommer den knuffa allt annat framför sig.
  • {1:5.1f} innebär först att det är index 1 (andra angivna variabeln) och att det skall formateras med 5 tecken (5) varav 1 decimal (.1) och datatypen skall vara en float (f).

På detta sätt kan man bygga upp utskrifter som behöver formateras. Att lära sig alla dessa koder utantill är inte så enkelt, eller användbart, så det viktigaste är att kunna hitta information om hur det skall göras när det behövs. Här har du en bra länk med instruktioner och exempel.

Utskrift

Anna 17.5
Beatrice 8
Carl Gustav 19

Anna          17.5
Beatrice       8.0
Carl Gustav   19.0

2.6.6 Formatering med f-string

I avsnitt 2.6.5 så byggde vi först upp en formaterad sträng, en formatmask, som vi sedan placerade in variablers värde i. Sedan version 3.6 av Python finns det en ny typ av formatering, det som kallas f-string. Den stora fördelen med detta sätt är att vi bygger in variabler direkt i vår formatmask så det blir lättare och tydligare att hantera blandningen mellan formatmasken och variblerna.

Jag visar samma exempel som i tidigare avsnitt med det nya sättet.

Kodexempel: utskrift med formatering

kurs = "Programmering01"
poäng = 100
betygetB = 17.5

print(f"Kursen {kurs} omfattar {poäng} poäng och om jag når betyget B så kommer jag få {betygetB} poäng.")

Den stora skillnaden här är att variablerna placeras innanför måsvingarna, {}, vilket gör det tydligare vilken variabel som skall placeras på vilken position i strängen. Vi slipper också numrera variablerna ifall de inte skrivs i ordning.

Om vi vill formatera texten genom att välja ett visst antal decimaler eller hur mycket plats en kolumn skall få ta så kan vi använda samma typ av formatering som vi såg i det tidigare exemplet med listan av resultat från matteprovet.

Kodexempel: utskrift med formatering

namn1 = "Anna"
namn2 = "Beatrice"
namn3 = "Carl Gustav"

poäng1 = 17.5
poäng2 = 8
poäng3 = 19

# Utskrift som är oformaterad
print(f"{namn1} {poäng1}")
print(f"{namn2} {poäng2}")
print(f"{namn3} {poäng3}")
print()

# Utskrift med 12 positioner för strängen
print(f"{namn1:12s} {poäng1:5.1f}")
print(f"{namn2:12s} {poäng2:5.1f}")
print(f"{namn3:12s} {poäng3:5.1f}")

Själva formatmasken fungerar på samma sätt som jag beskrev tidigare.

Utskriften blir då på följande sätt.

Utskrift

Anna 17.5
Beatrice 8
Carl Gustav 19

Anna          17.5
Beatrice       8.0
Carl Gustav   19.0

2.6.7 Justerad text

När vi vill skriva ut tabeller så är det viktigt att kunna välja hur texten skall skrivas ut. I exemplet ovan med namn och resultat så kan vi se tabellen som tre rader med vardera två kolumner. Text kommer naturligt att vänsterjusteras i sin cell medan tal kommer högerjusteras. Vill vi förändra detta så finns det ett enkelt sätt att göra detta. Då använder vi oss av följande tre tecken, <, ^ och > för att justera åt vänster, centrerat eller åt höger.

Jag visar med ett exempel.

Kodexempel: utskrift med justerad text

namn1 = "Anna"
namn2 = "Bo"
namn3 = "Carl"
namn4 = "David"

ort1 = "Alingsås"
ort2 = "Ås"
ort3 = "Vårgårda"
ort4 = "Västra yttre skogen"

årslön1 = 1200000
årslön2 = 24000
årslön3 = "{0:.0f}kr".format(600000)
årslön4 = "{0:.0f}kr".format(0)

print()
print("|{0:<20s}|{1:<20s}|{2:<.0f}kr|".format(namn1, ort1, årslön1))
print("|{0:^20s}|{1:^20s}|{2:>18s}kr|".format(namn2, ort2, str(årslön2)))
print("|{0:>20s}|{1:>20s}|{2:>20s}|".format(namn3, ort3, årslön3))
print("|{0:20s}|{1:20s}|{2:^20s}|".format(namn4, ort4, årslön4))
print("\nMed f-string")
print(f"|{namn1:<20s}|{ort1:<20s}|{årslön1:18.0f}kr|")

Utskrift

|Anna                |Alingsås            |1200000kr|
|         Bo         |         Ås         |             24000kr|
|                Carl|            Vårgårda|            600000kr|
|David               |Västra yttre skogen |        0kr         |

Med f-string
|Anna                |Alingsås            |           1200000kr|

Här ser man tydligt skillnaden mellan format-metoden och string-f-metoden när vi skall formatera tal. Format-metoden kräver att vi först formaterar talet till en sträng för att sedan kunna ge strängen det utrymme som den vill ha. Du kommer ofta märka att det du vill göra kan göras på olika sätt inom programmeringen och genom att ha fler verktyg så kommer du ha större möjlighet att hitta det mest lämpade verktyget för varje situation.
Tips1: Krångla inte till dina utskrifter som jag har gjort här, låt texter vara vänsterjusterade och tal högerjusterade, allt för att enklare kunna jämföra olika tal.

2.6.8 Sammanfattning

Som du märker så kan vi göra utskriften på flera olika sätt och för att du skall kunna välja det sätt som är mest lämpligt vid varje givet tillfälle så är det bra om du kan använda alla olika sätten. Utgångspunkten är att om du skriver ut det på det sätt som du vill och inte det sätt som det blev så har du gjort rätt. Tänk på att vi lärare kan tala om precis på vilket sätt som vi vill ha utskriften presenterad på.

Om vi ändå skall prioritera vilken av alternativen som är vanligast att använda så brukar de flesta elever använda sig av f-string. Stora delar av materialet i denna kurs är dock uppbyggt innan f-string var så vanligt som det är idag så du kommer ofta springa på format-metoden, även om jag tänker arbeta om materialet allt eftersom.

2.6.9 Uppgift

Uppgift: m02u03

I en affär så köper du 3st pennor som kostar 4kr/st och ett äpple som väger 200g. Äpplen kostar 19kr/kg.

Gör nedanstående utskrift på alla sätt som vi precis har gått igenom.

Utskrift

Jag handlade 3 pennor för 12kr och 1 äpple för 3.80kr vilket totalt blev 15.80kr.

Antalet varor och priser skall vara variabler. Summor, och delsummor, skall vara uträknade på lämpligt sätt.

Kommentera också de olika sätten som du har använt, vilka skall vara;

  • Utskrift med kommatecken.
  • Utskrift med plustecken (konkatenering).
  • Utskrift genom att sträng byggs upp före utskrift.
  • Utskrift med öppen print() utan radbrytning.
  • Utskrift med formatmetoden.
  • Utskrift med f-stringmetoden.

2.6.10 Reflektion på uppgiften

Troligtvis har du märkt att beräkningar av datatypen float kan ge lite slumpmässigt felaktiga utskrifter. När vi förväntar oss ett värde med två decimaler så blir istället svaret två korrekta decimaler följt av en mängd nollor innan det slutligen finns ett, som det verkar, slumpmässigt tal. För er som har läst en hel del matematik verkar ju detta helt ologiskt, men det finns naturligtvis en förklaring på detta fenomen. Vi skall kika på en film där orsaken behandlas.

Där har du förklaringen, du behöver inte kunna den utantill men du måste förhålla dig till den. I de uppgifter vi jobbar med i denna kursen så spelar det inte så stor roll om den 6:e, 8:e eller 10:e decimalen är lite felaktig men det kan vara viktigt i andra sammanhang. Det finns alltid lösningar om det måste vara exakt och det gås igenom i slutet av filmklippet.

2.7 Input

Dags att lära oss nästa teknik som gör att våra program blir lite mer levande och användbara. Hittills har alla våra variabler fått hårdkodade (skrivna i koden) eller beräknade värden. Nu skall vi börja kommunicera med användaren och låta hen mata in data som vi skall använda oss av.

2.7.1 Läsa in från konsollen

Att läsa in något som matas in från konsollen är inte speciellt svårt, det är dock viktigt att vara tydlig med att ge användaren förutsättningar att förstå vad det är vi är ute efter att hen skall mata in. Det är också här vi kan skapa stora problem ifall vi inte är tydliga, förstår inte användaren vad som skall matas in ökar sannolikheten att fel saker matas in och då kommer uträkningen bli fel eller ännu värre så kraschar vårt program.

Kodexempel: inmatning

# funktionen input skriver ut strängen och väntar sedan på en inmatning
name = input("Ange ditt namn: ")
print("Hej", name)

Utskrift

Utskrift

Lägg märke till att alla inmatningar gör du i konsollen, alltså den delen där du ser hur själva programet körs.

2.7.2 Typkonvertering

Att få en sträng inmatad var ju enkelt men på samma sätt som vi behöver konvertera ett tal till en sträng för att kunna fixa en utskrift så behöver vi konvertera en inmatad sträng till ett heltal eller ett decimaltal för att sedan kunna räkna med dem. Det är också här det är kritiskt att användaren matar in det som vi förväntar oss. Vi kommer senare ta hand om felaktiga inmatningar och ge användaren ytterligare chanser att göra rätt, men det kikar vi på senare i kursen. Just nu så är vi extra tydliga så att användaren vet vad vi förväntar oss att få inmatat.

Kodexempel: typkonvertering

name = input("Ange ditt namn: ")
age = int(input("Ange din ålder (heltal): "))
height = float(input("Ange din längd i meter: "))
print("Hej {0}. Har du redan blivit {1} år och är {2:.2f}m lång.".format(name, age, height))

Utskrift

2.7.3 Uppgift

Uppgift: m02u04

Du skall jobba vidare med uppgift m02u03 så att den blir mer användbar. Tidigare har du givit variablerna för antalet pennor och äpplen fasta värden i din kod, detta kallas att hårdkoda in värden. Nu skall du istället fråga användaren hur många äpplen och pennor hen vill köpa och ta emot de inmatningar som görs från konsollen.

Kommentera de delar som du ändrar i koden.

Tips

Innan du börjar med denna uppgiften så tar du en kopia av den gamla uppgiften så att du vidareutvecklar kopian och inte originalet. Att ha kvar en fungerande version är alltid att föredra, ibland tänker man så fel att det är enklare att börja om än att felsöka och backa.

Utbyggnad 1 (klicka för att visa uppgiften)

Du skall i påbyggnadsuppgiften också fråga efter priset / st för pennorna och priset / kg för äpplen. Istället för att fråga efter antalet äpple skall du fråga efter vikten på de äpplen du vill köpa. Skriv ut detta på lämpligt sätt.

Utbyggnad 2 (klicka för att visa uppgiften)

Nu vill vi att du dessutom skall skriva ut dina handlade varor som ett kvitto enligt exemplet nedan (eller annan lämplig utskrift).

Utskrift

Penna, 5st á 3kr           15.00 kr
Äpplen, 550g á 22.90 kr    12.60 kr
-----------------------------------
Summa                      27.60 kr

Innan du är klar så vill jag att du reflekterar över vilka fel som kan uppstå i ditt program som inte är av typen körtidsfel (fel som kraschar programmet) utan av typen logiska fel. Vi skall prata mer om olika typer av fel senare i kursen.

2.8 Syntaxfel

Som du säkert har märkt så dyker det ibland upp felmeddelande när vi skriver felaktig syntax som Pythons interpretator kan tolka åt oss. Det gäller att lära sig läsa och förstå dessa felmeddelande så att du på egen hand kan lösa de fel du skapar. Att lära sig lösa sina egna fel påskyndar inlärningsprocessen vilket är viktigt för att du skall bli en duktig programmerare.

Nedan kommer en lista på ett antal mer eller mindre vanliga felmeddelanden och även en text om varför felet uppstår och hur du kan få hjälp att leta efter felet i din kod. Under listan finns det också ett formulär där du kan kopiera dina felmeddelande, som inte redan är listade, så kan vi fylla på listan. Vill du skriva en text om lösningen kopplad till felmeddelandet så går det naturligtvis bra.

2.8.1 Lista av syntaxfel

Lista med syntaxfel

I utgångsläget när du felsöker så kolla på det allmänna felmeddelandet och även den specifika markeringen. Ofta får du tips om var felet har uppstått och om felet är i början av rad 2 så är det inte sällan rad 1 som inte är avslutad på rätt sätt.

Felmeddelande Förklaring / lösning
EOL while scanning string literal Felet innebär att interpretatorn har kommit EOL (end Of Line) utan att hitta ett tecken som stänger strängen (" eller ').
SyntaxError: invalid syntax Kan bero på en mängd saker eftersom felet flaggas som ett allmänt fel. Läs mer på den specifika markeringen vad som kan vara fel. Inte sällan behandlar interpretatorn början på en rad och känner att raden innan inte avslutades som den skulle.
ValueError: cannot switch from manual field specification to automatic field numbering Detta fel får jag när jag försöker skriva ut en formaterad sträng och blandar mellan skrivsätten inne i måsvingarna, ibland skriver jag index och ibland inte, typ {} och {0}.
ValueError: invalid literal for int() with base 10: '12.4' Detta fel får jag när jag försöker göra om ett decimaltal till ett heltal.
SyntaxError: unexpected EOF while parsing Detta fel innebär att interpretatorn har kommit till slutet av filen när den letar efter något tecken som skall stänga ett öppet tecken, ofta är det en parentes () eller måsvinge {} som inte stängts på rätt sätt.
TypeError: unsupported operand type(s) for /: 'str' and 'tuple' Detta fel innebär att det används någon felaktig datatyp. I detta fall så nämns str och tuple. En sträng vet du vad det är, en tuple är en typ av samling av data som kan separeras med kommatecken. Ex tal = 5,98 ses som två tal, 5 och 98 som lagras i en samling. Menade du 5.98 så är det decimalpunkt som skall användas.

Hittat annat meddelande du vill lägga till listan?

Om du har något bra felmeddelande som du vill lägga till i listan så skicka mig ett meddelande via Google Chat.

2.8.2 Uppgift

Uppgift: m02u05

Ta nedanstående kod och klistra in i en ny fil och lös sedan felen så att du får en fungerande applikation. Kommentera alla fel du hittar i koden och även lösningen som du genomför.

Vissa rader kan vara utan fel och några rader har flera fel. Du är klar när programmet går att köra.

Vill du ha tips på hur många fel det är så klicka här.

8 fel är inplanterade i koden. Men du behöver inte räkna alla fel, när programmet fungerar som det är tänkt så är du färdig med rättningen.

Kodexempel: Rätta felaktig kod

# Skriv en kommentar för varje fel du identifierar och löser.
# Beskriv vad som var fel och hur du har löst det.
exchange_rate dollar_to_sek = 8,82
print(Detta är ett program där vi kan växla mellan SEK & dollar)
1sek = input("Hur många SEK vill du växla till dollar: )
dollar = 1sek / exchange_rate_dollar_to_sek
print("Du ville växla {0} SEK vilket blir {1} dollar.".format(1sek, dollar)

Tips

Följande saker är bra att tänka på när du felsöker kod;

  • Lös ett problem i taget.
  • Kör din kod och försök leta efter det syntaxfel som meddelas i konsollen.
  • Du kommer oftast meddelas ett fel i taget, upprepa proceduren tills programmet fungerar som det var tänkt och alla fel är rättade.
  • Vill du provköra en del av programmet så kommentera bort den kod som du inte vill köra. Då kan du också välja att göra utskrifter av variablers innehåll för att se att det du tror händer verkligen händer.

2.9 Slutuppgift på momentet

Någon form av slutuppgift kommer avrunda momentet.

Vi skall också genomföra en diagnos i slutet av momentet för att du skall kunna testa dig själv och se vad du kan.