Förberedelsematerial 1
Innan du börjar med Pythonuppgifterna kapitel 1-3 och inför Storseminarium 1 ska du gå igenom materialet nedan, vilket bör ta ca en timme. Du bör också genomföra det tillhörande quizet längst ner på sidan, som testar dina kunskaper på materialet. Quizet finns endast till för att du ska kunna skatta dina egna kunskaper, och är inget du bedöms på.
Innehåll
- Aritmetiska operationer
- Litteraler och uttryck
- Lite om Variabler
- Heltal och flyttal
- Strängar
- Listor
- Villkorssatser
- Funktioner
- Quiz
Aritmetiska operationer
Vi ska börja med att arbeta med aritmetiska operationer i Python. Detta kan göras enklast genom att jobba i den interaktiva Python tolken i terminalen. För att starta Python tolken skrivs följande i terminalen tryck sedan på enter-tangenten.
$ python3
Vi kan när som helst avsluta tolken med att trycka ctrl
och d
tillsammans (ctrl + d
).
När vi har aktiverat Python tolken kan vi skriva in och köra Python kod direkt i terminalen. Vi kan demostrera det med en enkel addition, vi skriver in nedanstående, tryck sedan på enter-tangenten för att utföra instruktionen.
>>> 3+4
Vi borde få en utskrift 7
i terminalen. Med detta inser vi att Python kan användas som en miniräknare, men vi vill inte begränsa oss till addition. Nedanför följer några vanligt förekommande matematiska operatinoer i Python.
- addition:
+
- subtraktion:
-
- multiplikation:
*
- division:
/
- division avrundat nedåt till närmaste heltal:
//
- modulo (rest vid nedrundningsdivision):
%
När vi använder //
för positiva tal så “kapar vi bort” eller trunkerar eventuella decimaler vid divisionen och vi kallar ofta lite slarvigt den här operationen för heltalsdivision. Vid “vanlig” division gäller att
$$\frac{17}{4}=4.25$$
Motsvarande heltalsdivision (17//4
) ger oss istället resultatet $4$.
Lite krångligare blir det med negativa tal (det är först då som skillnaden mellan heltalsdivision och nedrundningsdivision blir meningsfull). Hur det fungerar kan man dock reda ut om man skulle behöva det.
Med modulo (%
) så får vi resten vid en nedrundningsdivision enligt ovan, dvs. 17 % 4
ger oss värdet $1$.
Vi får alltså ut restvärdet vid nedanstående heltalsdivision:
$$\require{color} \frac{17}{4} = 4 \text{ rest } \colorbox{lightgreen}{1}$$
Resten är $1$ eftersom:
$$4 \times 4 + 1 = 17$$
Den matematiskt nyfikne kan notera att följande identitet gäller:
x == (x // y) * y + (x % y)
Matematik: Kongruensräkning
Modulo används oftast vid så kallad kongruensräkning där vi oftast använder följande notation:
$$17 \equiv 1 \pmod{4}$$
Kongruensräkning är vi förvånansvärt vana vid, även om ingen kanske påpekat det för oss. Det är nämligen kongruensräkning vi använder när vi arbetar med t.ex. klockan. Om klockan är 19 och vi vill veta vad klockan är om 20 timmar så säger den vanliga matematiken att klockan är 39. Med kongruensräkning kan vi dock visa att:
$$39 \equiv 15 \pmod{24}$$
I Python kan vi skriva detta som:
>>> (19 + 20) % 24
15
Litteraler och uttryck
Vi har redan arbetat med både litteraler och uttryck. En litteral är en direkt representation av ett värde t.ex 3
medan ett uttryck är allt som beräknas till ett värde, t.ex 3 + 4
. Här följer några exempel:
5 - 3
uttryck med två litteraler (5
och3
) och en operator (-
)-9 + (2 * -3) ** 2
uttryck med fyra litteraler (9
,2
,3
och2
igen) och fem operatorer (-
,+
,*
,-
igen och**
)42
uttryck med en litteral"kompis"
uttryck med en litteral
En viktig insikt här är att ensamma litteraler per definition också är uttryck eftersom de bara är en textuell, litteral, representation av ett värde.
Lite om Variabler
En variabel kan förstås som en symbol som refererar till ett värde. För variabelnamn används substantiv, och skrivs i små bokstäver. Om flera ord används skriver man _
mellan orden , denna konvention kallas snake case.
Vi kan tilldela en variabel ett värde med en tilldelningssats t.ex:
|
|
Detta är vad vi kallar en tilldelningssats, vi tilldelar värdet av litteralen 2
till zaphod_num_arms
, vilket vi gör med tilldelningsoperatorn =
. Vi har alltså sparat värdet $2$ i datorns arbetsminne, och kan referera till värdet med variabelnamnet zaphod_num_arms
.
Fortsatt bestämmer sig Zaphod för att skaffa en tredje arm, för att förbättra sin skidboxningsteknik. Vi kan justera för detta med:
|
|
Vi har alltså ändrat på värdet som vår variabel pekar på, från $2$, till $3$, genom att addera värdet av litteralen 1
till det tidigare sparade värdet $2$, och slutligen sparar vi det i samma variabel i vänsterledet. Kom ihåg, =
är tilldelningsoperatorn. I andra sammanhang vill vi kunna spara textdata, t.ex ett efternamn:
|
|
eller ett decimaltal:
|
|
Vi vill kunna göra olika saker beroende på vilken typ av data vi jobbar med. T.ex textdata som zaphod_efternamn
vill vi kunna göra om till versaler, men samma operation på zaphods_promillehalt
vore orimligt. (Vad skulle det innebära att skriva 2.7
med versaler?) Därför finns det ett behov av att kunna bestämma hur vi sparar data, därav så klassificerar vi data i olika datatyper. Några vanliga datatyper som används i Python och som vi kommer att gå igenom nedan är: heltal, flyttal, strängar och listor.
Heltal och flyttal
Med heltal menas alla hela tal, negativa såväl som positiva, ex: -42
och 5
. I Python kan dessa representeras med datatypen integer (int
). Vi kan spara ett heltal i Python genom att tilldela en litteral 42
till vår variabel svaret_på_allt
enligt nadanstående:
|
|
Ibland vill man kunna spara tal med mer precision, det kan handla om valutor $19.90$ kr, $\pi$ ($3.14159265…$) eller som nedan, sannolikheter:
|
|
Observera att vi använder .
som decimaltecken i Python. Datatypen som används för detta är float
, för floating point number, eller på svenska flyttal.
Strängar
Ytterligare en datatyp är sträng (str
), som representerar en följd av symboler, t.ex. "abcABC0123!%&/."
. Vi kan tilldela en variabel ett värde av datatypen sträng på följande sätt:
|
|
När vi skriver värden av datatypen sträng använder vi citationstecknen ("
eller '
) i början och slut för att markera början och slut på teckenföljden.
Varje tecken i följden går att referera till med en siffra, ett index, som börjar på 0
från vänster, och ökar med ett för varje tecken.

Vi kan titta på ett specifikt tecken genom att läsa det index vi är intresserade av med pythons subskriptoperator [ ]
.
|
|
Motsvarar tecknet 'a'
.
Med negativ indexering kan vi läsa “bakifrån”.
|
|
Vilket ger oss tecknet 'k'
.
Vidare kanske vi är intresserade av att titta på en delsträng, utsnitt eller slice, av hela strängen. Vi kan använda subskriptoperatorn även för detta och skriver då:
|
|
Vi kollar på delsträngen som börjar från index start
och inkluderar alla index mindre än stop
. t.ex om vi har:
|
|
och väljer ut:
|
|
så får vi handduk
. Vi kan uppnå samma sak med negativ indexering.
|
|
Om vi utelämnar start
så antar pythontolken att vi vill läsa från början av strängen. Utelämnar vi istället stop
så antar pythontolken att vi vill läsa till slutet av strängen.
>>> "gargleblaster"[:6]
'gargle'
>>> "gargleblaster"[6:]
'blaster'
Fundera på vad som skulle hända om vi utelämnade både start
och stop
.
Typkonvertering
Ibland vill vi ha en strängrepresentation av ett värde. Med funktionen str
kan vi få en strängrepresentation av vilket värde som helst, t.ex:
|
|
ger oss strängen "3.1415"
. Vidare kan vi på motsvarande sätt omvandla mellan olika datatyper. Vi kan konvertera till heltal med int
eller flyttal med float
. T.ex, kan vi omvandla från heltal till flyttal med:
|
|
Vilket ger oss värdet 3.0
.
Listor
Listor (list
) används för att lagra en sekvens av värden som element i listan. En lista kan också vara ett värde, dvs en lista kan innehålla listor (som i sin tur kan innehålla listor, osv. men det återkommer vi till längre fram i kursen).
|
|
Listor kan indexeras på samma sätt som vi redan sätt med strängar:
|
|
motsvarar "Arthur"
. Samt med del-listor ex:
|
|
ger oss ["Zaphod", "Ford"]
. Med listor kan vi även blanda datatyper: strängar, heltal, flyttal, listor o.s.v. Vilket kan se ut så här:
|
|
Vidare kan vi slå ihop listor med +
operatorn. ex:
|
|
skulle ge oss listan "Zaphod", "Ford", "Arthur", "Trillian", "Marvin", "Hjärtat av Guld", 5, 98.7, ["Antal handdukar", 5]
Vi kan dessutom läsa ut längden på listan med den inbyggda funktionen len
.
|
|
som ger oss resultatet 5
.
Alla tecken på en rad efter ett #
-tecken tolkas som kommentarer i Python och ignoreras av pythontolken. Detta innebär att vi kan använda dessa för att t.ex. förklara vår kod eller lämna anteckningar till andra utvecklare. Det är oftast bättre med för mycket än för lite kommentarer i er kod. Ni kommer att märka att man har stor nytta av att skriva kommentarer, det är därför fördelaktigt att ha som vana att kommentera sin kod redan från början i kursen.
Även värt att notera från ovanstående exempel är print
. Detta är ytterligare en inbyggd funktion i Python, som skriver ut ett värde i terminalen. Funktionen print
används ofta när man felsöker sin kod.
Villkorssatser
Används för att bestämma vilka delar av koden som ska köras, nedan visas ett exempel på en if
-sats.
|
|
Efter raden som inleds med if
och avslutas med :
följer ett kodblock. Ett kodblock är ett stycke kod på samma indenteringsnivå och som tillhör någon huvudsats.
Sanningsvärden
(eng. boolean efter George Boole, i Python bool
) är ytterligare en datatyp vi ska bekanta oss med. Ett sanningsvärde kan anta två olika värden, sant (True
) eller falskt (False
).
Men Python kan också tolka andra datatypers “sannighet” (“truthiness”) genom att sätta in ett godtyckligt värde i en kontext där pythontolken förväntar sig ett sanningsvärde. Nästan alla värden förutom värdena None
, []
(den tomma listan), ""
eller ''
(den tomma strängen), 0
och 0.0
ses som sanna. (Det finns några till, men vi har inte gått igenom de datatyperna än, generellt kan man tänka att värden som är “tomma” eller “ingenting” tolkas som False
.)
När sanningsvärdet är True
körs satserna i det tillhörande blocket. När sanningsvärdet är False
hoppar pythontolken över det tillhörande blocket.
|
|
ger oss utskriften
Det är sant.
Det snöar!
Ofta vill vi skriva mer sofistikerade villkorssatser, detta kan vi göra genom att använda jämförelse- och logiska operatorer.
Jämförelseoperatorer
Är operatorer vars beräknade värde alltid är ett sanningsvärde, dvs. True
eller False
. Några vanliga jämförelseoperatorer:
- lika med:
==
,x==y
är sant om förhållandet $x=y$ gäller - inte lika med:
!=
,x!=y
är sant om förhållandet $x\neq y$ gäller - större än:
>
,x>y
är sant om förhållandet $x\gt y$ gäller - mindre än:
<
,x<y
är sant om förhållandet $x\lt y$ gäller - större eller lika med:
>=
,x>=y
är sant om förhållandet $x\geq y$ gäller - mindre eller lika med:
<=
,x<=y
är sant om förhållandet $x\leq y$ gäller - samma som:
is
,x is y
är sant omx
är samma objekt somy
(mer om det längre fram) - finns i:
in
,x in y
är sant omx
förekommer iy
Exempel:
|
|
Logiska operatorer
Används för att kombinera eller negera sanningsvärden. Uttryck med logisk operator beräknas alltid till ett sanningsvärde, dvs antingen True
eller False
precis som jämförelseoperatorer. Skillnaden är att logiska operatorer bara opererar på sanningsvärden.
- and : ger
True
om båda operander är sanna. - or : ger
True
om minst en av operanderna är sanna. - not : ger
True
om operanden ärFalse
, gerFalse
om operanden ärTrue
Exempel: jämförelse och logiska operatorer
|
|
Jag tror att det snöar.
|
|
Jag tror att vi är på en annan planet.
Olika mönster av villkorssatser
En if
-sats kan bestå av flera klausuler. I det enklaste fallet har vi endast en klausul med tillhörande block som nedan.
|
|
Exempel:
|
|
Varje förekomst av nyckelordet if
inleder en ny fristående if
-sats, och alla if
-satser på samma indenteringsdjup kommer kontrolleras oberoende av varandra. Flera sådana oberoende if
-satser kan ha villkor som är sanna och blocken tillhörade dessa kommer att utföras, som i nedanstående exempel.
|
|
Som ger:
Duggan närmar sig!
Bara några timmar kvar, dags att börja plugga på allvar!
Ofta vill vi dock utföra viss kod när villkoret är sant men göra något annat om villkoret är falskt. Detta kan vi åstadkomma genom att lägga till en else
-klausul i if
-satsen. Om villkoret som tillhör if
-klausulen skulle visa sig vara falskt, kommer istället blocket tillhörande else
-klausulen att utföras.
|
|
Exempel: if
-sats med tillhörande else
-klausul.
|
|
Det är långt kvar till duggan...
En if
-sats kan bara ha en if
-klausul och en else
-klausul. Har vi fler än två möjliga utfall med olika villkor kan vi dock använda oss av elif
-klausuler. Dessa används när vi vill kolla alternativa villkor efter varandra: om inte A -> testa B, om inte B -> testa C, om inte C -> gör D. d.v.s i nedanstående exempel utförs alltid bara ett av blocken A, B, C och D.
|
|
Exempel: if
-sats med tillhörande elif
-klausuler och avslutande else
-klausul.
|
|
Det är svalt.
Ett annat sätt att skriva samma sak
|
|
Detta funkar då vi kan veta efter första if satsen att temperature är större än eller likamed -10 vad vi inte vet är om temperaturen är mindre än 10 grader eller inte, osv.
elif läser vi lämpligast som ’eller om'
Funktioner
En funktion är en bit kod som syftar till att utför ett specifikt arbete, ofta bearbetar funktionen någon typ av data och ger tillbaka (returnerar) denna data. Vi kollar på ett vardagligt exempel:
Nedanför har vi definierat en funktion för att baka bröd.

- Vi har valt att namnge vår funktion
baka_bröd
. Funktionsnamnet ska använda verb som beskriver arbetet. - Vad behöver vi för att kunna använda vår funktion? dvs för att baka bröd? Vi behöver ingredienser så som mjöl, vatten och jäst. Data som vi skickar till vår funktion kallas argument och när vi arbetar med det (i funktionen/i lådan) kallar vi det parametrar.
- Självaste bakandet sker efter ett recept, som vi följer steg för steg, vi bearbetar parametrarna (ingredienserna) tills vi har ett färdigt bröd. Denna process utgör funktionskroppen (lådan), dvs det arbete som utförs av funktionen (att baka brödet).
- när funktionen har kört klart, dvs när vi bakat klart, så returnerar funktionen ett värde, ett så kallat returvärde. I vårat fall får vi tillbaka ett bakat bröd från vår funktion.
Okej, men hur skriver vi funktioner i Python? Nedanför står en definition av vår funktion i Python.
|
|
Låt oss bryta ner vårat exempel steg för steg:
Vi börjar med att definiera vår funktion, i Python görs detta med nyckelordet def
(nyckelord - ord som är inbyggda i språket Python och har en speciell innebörd som inte kan ändras). Detta följs av vårat funktionsnamn baka_bröd
, till sist har vi dem argument som vi skickar till funktionen. Dessa skrivs inom parenteser ( )
och avslutas med :
.
|
|
Därefter följer funktionskroppen. Funktionskroppen utgörs av ett kodblock som beskriver vad funktionen faktiskt gör, och motsvarar själva bakningen av brödet. (I exemplet ovan har vi utelämnat de faktiska operationerna.) När alla operationer som krävs för att baka brödet är genomförda så levererar vi det bakade brödet genom att returnera det.
|
|
När vi skrivit instruktioner för datorn om hur man går tillväga för att baka ett bröd, men vi har inte bakat något än. För att använda vår funktion måste vi göra ett funktionsanrop. Vi börjar med att skriva namnet på vår funktion följt utav parenteser med våra argument. Nu kommer datorn att leta efter instruktionerna som vi gick igenom innan, och sätta igång och baka brödet.
|
|
Men eftersom vår funktion har ett returvärde bakat_bröd
, så vill vi antagligen spara det någonstans. Vi använder en variabel, och tilldelar variabeln returvärdet från vår funktion på följande vis:
|
|
Efter att funktionen kört klart ersätts alltså funktionsanropet med returvärdet, vi kan visualisera det som:
|
|
Det här sättet att visualisera vad som händer kallas för substitution och är en värdefull metod för att förstå vad ett stycke kod gör.
obs. Alla funktioner behöver inte ha ett returvärde, i dessa fall returneras ett speciellt “icke-värde”, None
, som används av Python för att beteckna just “inget värde”.
Vi har tidigare sätt hur det finns redan inbyggda funktioner i Python, t.ex: len
och print
. Detta innebär att vi inte behöver definiera dessa själva som vi gjorde med vår egen funktion baka_bröd
. Det är också viktigt att man undvika att skriva över inbyggda funktioner, vilket sker om vi definierar vår egen funktion med samma namn, t.ex:
|
|
Detta skulle göra att vi inte längre kunde använda den inbyggda funktionen print
.
Quiz
Testa din förståelse av materialet med tillhörande quiz
Sidansvarig: Johan Falkenjack
Senast uppdaterad: 2024-08-26