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 Utskrifter

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

Kodexempel: utskrifter

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: utskrifter

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 betygnivå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.

Problem med att skriva backslash

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 tabboch inte mellanslag som du skall använda.
  • 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.

Läraren bestämmer sedan om och hur denna uppgift skall lämnas in/visas upp.

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: escapetecken

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. Pyton 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: beräkningar

# 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

# Deklarera variabler
a = 4
b = 3

# För att addera a 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 konvera 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: konkatenering

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 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 mäst 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å.

2.6.7 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

2.6.8 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

Ange ditt namn: Sebastian
Hej Sebastian

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: Inmatning

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

Ange ditt namn: Johan
Ange din ålder (heltal): 42
Ange din längd i meter: 1.75
Hej Johan. Har du redan blivit 42 år och är 1.75m lång.

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 instä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 intepretator 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 intepretatorn 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 depareras 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 i vklass eller på mail.

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.

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(sek, 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.

2.9 Slutuppgift på momentet

Det finns två uppgifter som eleven kan göra, den första behöver alla elever göra för att bli klara med detta momentet. Den uppgiften kommer också finnas i två varianter, en grunduppgift som visar på grundläggande kunskaper inom detta moment och en fördjupande del där den första delen byggs på till en något större applikation.
Vid redovisning skall denna uppgift döpas enligt följande; klassens namn_Ditt namn_moment02a.py

Den andra uppgiften är helt skild ifrån den första och testar på lite andra saker än den första uppgiften. Om den andra uppgiften lämnas in så skall även den första uppgiften lämnas in.
Vid redovisning skall denna uppgift döpas enligt följande; klassens namn_Ditt namn_moment02b.py

Väljer du att lämna in bägge uppgifterna så kan du också packa dem och lämna in endast en fil, då skall denna fil heta klassens namn_Ditt namn_moment02.zip. När denna fil packas upp så skall varje fil vara namngiven enligt tidigare instruktioner.

Lämna sedan in lösningen på angivet sätt i Vklass eller på Drive, allt beroende på hur din lärare har bestämt.

Viktigt att påpeka är att varje elev genomför och lämnar in sin egen uppgift. Givetvis kan ni samarbeta men att två elever lämnar in identiska filer brukar inte handla om samarbete utan om plagiering och det är inte tillåtet att lämna in någon annans lösning på en uppgift.

Inlämningsuppgift moment02a

Uppgiften är att skapa en applikation som beräknar area och omkrets av en cirkel genom att användaren anger radien för en specifik cirkel.

  • Be användaren ange radien för en cirkel, du väljer själv om användaren skall få mata in radien som heltal eller decimaltal (var tydlig vad som förväntas av användaren).
  • Gör korrekta beräkningar, ge pi närmevärdet 3,14.
  • Gör utskrift på lämpligt sätt, radie, area och omkrets skall skrivas ut. Area och omkrets skall skrivas ut med två decimaler, radien styrs av inmatningen men bör inte skrivas ut med fler än två decimaler.
  • Tänk på att det skall vara lätt att använda ditt program även för användare som inte känner till uppgiften.

Hjälp med cm2 [klicka för att visa]

Om du vill skriva ut en snyggare enhet för area så kan du använda exemplet nedan.

Kodexempel

print("Rektangelns area är 12cm\u00b2")

Utskrift

Rektangelns area är 12cm2

Fördjupning av uppgiften [klicka för att visa]

Ta en säkerhetskopia på den lösta grunduppgiften och jobba sedan vidare med samma uppgift.

Fördjupningsuppgiften kommer vara lite annorlunda då vi skall blanda in saker som kommer först i nästa moment. Du kommer dock få se två exempel som du efter att ha provkört bör förstå hur koden fungerar och vad som händer. När du har förstått dessa nya delar så vill jag att du löser fördjupningsuppgiften med hjälp av dessa två exempel.

Selektion

En selektion innebär att man i koden kan göra olika val och se till att olika saker händer beroende på någonting.

svar = "ja"
if(svar == "ja"):             # om villkoret är sant ...
    print("Du svarade rätt!")
else:                         # ... annars
    print("Du svarade fel.")

Stränghantering

När vi tvingar användaren att mata in ett svar så kan vi behöva styra hur svaret skall se ut. Vill vi ha ett positivt svar på svenska så kan det skrivas JA, Ja eller ja. När vi vill använda detta så vill vi begränsa alternativen så att vi kanske bara jämför med J oavsett vilken av de tre alternativen som användaren tidigare har skrivit in.

svar = "ja"

# Tar fram första bokstaven i svaret
# 0 står för indexet/positionen för den bokstav vi letar efter
svar = svar[0];

# Gör om första bokstaven till versal (stor bokstav)
svar = svar.upper()

print (svar)

Dags att presentera vad du skall göra i tilläggsuppgiften. Den består av två delar som du skall bygga på uppgiften som du redan har gjort.

  1. Du skall bygga ut räknaren så att användaren får välja om hen vill kunna mata in radien som ett heltal eller ett decimaltal. Matar användaren in radien 3, skall radien skrivas ut som 3 i svaret och matar användaren in 3.2 skall 3.2 skrivas ut i svaret när radien presenteras. Värdet för area och omkrets skall fortsatt presenteras med två decimaler.
  2. Istället för att använda ett närmevärde för PI så skall du använda den inbyggda konstanten. [Länk: PI]

Att tänka på inför inlämning

Innan du lämnar in uppgiften kolla att följande saker är gjorda;

  • Filen med källkod har rätt namn, klass_namn_moment02a.py (eller zip om du lämnar in bägge uppgifterna)
  • Applikationen körs utan error.
  • Källkoden är kommenterad. Lägg fokus på kommentarer på svåra eller nya delar.
  • Skapa ett huvud i källkoden där du som en kommentar skriver ditt namn och klass, vilken uppgift som du har löst och sedan en kort utvärdering av lösningen/ditt arbete. Jag är extra intresserad över hur du har tänkt när du fått ta olika beslut.

Exempel på kodhuvud

# Anders Andersson, 18TEx
# Moment02, grunduppgift + tillägg 1
# Det var en utmanade uppgift och jag klarade inte av sista tillägget.
# Det som var mest utmanande var hur jag skulle konvertera det som matades in...
# ....

Inlämningsuppgift moment02b

Här kommer nu den lite svårare inlämningsuppgiften.

Du skall skapa en tidsomvandlare där användaren skall få mata in hur många sekunder som skall omvandlas till timmar, minuter och sekunder. Inmatning och utskrift skall ske på lämpligt sätt.

Exempel som jag testar vid inlämning

Inmatning: 96s -> Utskrift: 0h1m36s
Inmatning: 180s -> Utskrift: 0h3m0s
Inmatning: 3661s -> Utskrift: 1h1m1s

Fördjupning av uppgiften [klicka för att visa]

Även denna uppgift har en fördjupande nivå med flera uppgifter. Du skall bygga vidare samma program så att följande funktionalitet finns med.

  1. Snygga till så att alla utskrifter sker med två siffror, 00h05m09s. Tips: [Länk: Skriv ut int med två siffror]
  2. Gör ett tillägg till programmet så att användaren på lämpligt sätt kan ange timmar, minuter och sekunder och att utskriften blir i enbart sekunder.
  3. Skapa möjlighet att mata in två tider och skriv ut differensen mellan dessa tider.

Inlämningsinstruktioner för denna uppgift är de samma som för den första uppgiften.