Lektion 2: Att skriva program#
Syfte: Skriva program i en utvecklingsmiljö (t.ex. IDLE
, VS Code
eller Spyder
).
Innehåll: Funktionerna input
och print
. Datatypen bool
. if
-, while
- och for
-satserna.
Arbetsform: Arbeta gärna tillsammans med någon men skriv egen kod. Diskutera med varandra!
Uppskattad arbetstid: 4 timmar.
Redovisning: Ingen obligatorisk redovisning men diskutera med handledare om det är något du är osäker på!
Utvecklingsmiljön IDLE#
Hittills har vi kört Python i ett kommandofönster där vi skrivit enskilda kommandon som utförts direkt. Normalt skriver man dock sina Python-satser i en fil som man kan editera, spara och köra upprepade gånger. Det går att använda vilken texteditor som helst men det underlättar om den har särskilt stöd för Python-kod.
Med Python-installationen kommer en utvecklingsmiljö kallad IDLE som bland annat innehåller en editor.

Den kan startas antingen genom att man skriver idle
eller idle3
(beroende på system) i ett kommandofönster eller klickar på IDLE-ikonen
i den Python 3-katalog som skapades vid installationen. Om du installerat Anaconda på Windows kan du starta Anaconda Prompt
och där skriva idle
.
(Bilderna i detta dokument är gjorda på Mac - det kan se aningen annorlunda ut på andra system.)
När IDLE startas öppnas ett eget kommandofönster som man kan skriva
Python-satser i som då utförs direkt precis som tidigare:
Om man klickar på File
-knappen och väljer NewFile
öppnas ett nytt
fönster,
varefter det kommer att se ut ungefär så här:
I rutan med titeln ”untitled” kan man nu skriva Pythonsatser. Dessa satser utförs först när man begär det med ett särskilt kommando. Man säger att man ”kör” filen.
print
-satsen#
När man skriver direkt i ett kommandofönster skrivs svaren ut direkt. Så
är inte fallet när satserna på en fil utförs. För att se resultatet
använder man print
-funktionen.
Skriv (eller kopiera) följande rader i det fönster som har öppnats:
print('Välkommen till Python-världen')
print('Programmering är roligt', '!'*10)
Innan programmet körs måste det sparas med Save
i File
-menyn:

Ge filen namnet ex1.py
. Filer med Python-kod kan heta vad som helst
men måste ha ändelsen .py
.
Kör nu programmet med kommandot Run Module
som finns under
Run
-menyn!
Observera att man nu måste använda print
-funktionen för att få se
några resultat!
Inläsning med input
#
I stället för att skriva in värden till variabler i koden kan man låta programmet fråga den som kör programmet vad värdet ska vara.
Exempel:
namn = input('Vad heter du? ')
print(f'Välkommen {namn}!')
Lägg in dessa två rader i filen, spara och testkör!
Funktionen input
skriver alltså ut texten mellan parenteserna
(”argumentet”) som en ledtext till den som kör programmet. Därefter
väntar programmet på att användaren skriver en rad och trycker på
retur-tangenten. Hela raden som skrivits placeras som värde i
namn
-variabeln.
Observera att input
alltid returnerar svaret som en sträng även om vi
skrivit något som skulle kunna tolkas som ett tal. Om vi vill kunna
använda svaret i en uträkning måste det alltså konverteras till int
eller float
Exempel:
I USA brukar man ange bilars bränslekonsumtion i miles per gallon i stället för liter per mil. Följande kod hjälper till med att konvertera mellan dessa värden (1 mile = 1609m, 1 US gallon = 3.785 l):
mpg = float(input('Ange miles per gallon: '))
lpm = 10./(mpg*1.609/3.785)
print(f'Detta svarar mot {lpm} liter per mil')
Provkör detta!
Svaret innehåller besvärande många siffror. Funktionen round
kan
användas för att runda till ett lämpligt antal decimaler. Lägg till
raden lpm = round(lpm, 2)
före print
-satsen så blir värdet
korrekt avrundat till 2 decimaler.
Visual Studio Code#
Visual Studio Code är en open
source-miljö från Microsoft som har mer avancerade funktioner än IDLE och rekommenderas varmt.
Du kan installera VS Code separat, men en version följder med Anaconda-installationen. I datasalarna är det viktigt att du använder Anandonda-versionen av VS Code för att allt ska fungera. Starta den genom att starta Anaconda Navigator
och sen klicka på VS Code
.

Om du öppnar/sparar en fil med filändelsen .py kommer VS Code
automatiskt att fråga om du vill installera Pythontilläggen. Det kan ta några minuter men är helt klart värt det. Du kan arbeta vidare under tiden. Med Pythontilläggen kan du köra Pythonprogram direkt i VS
Code. Annars kan du köra dem från terminalfönstret, genom att antingen
skriva python filnamn
(Windows) eller python3 filnamn
(Mac).
Spyder#
Spyder
är en annan bra Python-miljö, som följer med Anaconda. Du kan starta den via Anaconda Navigator
.

Du kan välja att använda det program du tycker bäst om. En avancerad editor/miljö är bara ett hjälpmedel! Ett Pythonprogram är alltid en ren textfil.
Övningar#
Skriv och testkör ett program som läser in ett temperaturvärde i grader Fahrenheit och skriver ut motsvarande temperatur i Celsius med 1 decimal. Omvandlingsformeln är:
\[C = \frac{F-32}{1.8}.\]Svar
f = float(input("Grader Fahrenheit: ")) c = round((f-32)/1.8, 1) print('motsvarar', c, 'grader Celsius')
Skriv och testa ett program som läser in ett kapital (i kronor, heltal), en räntesats i procent (flyttal) och ett antal år (heltal) och räknar och skriver ut vad kapitalet blir med ränta på ränta.
Svar
k = int(input('Kapital: ')) r = float(input('Ränta: ')) n = int(input('Antal år: ')) result = k*(1+r/100)**n print('Beloppet blir: ', round(result)) # Ger heltalsavrundning
Skriv och testa ett program som läser in två flyttal p och q och skriver ut rötterna till andragradsekvationen \(x^2 + px + q\) = 0. Testkör lösningen med \(p = -3\) och \(q = 2\) samt \(p = q = -1\). Prova också \(p = q = 1\).
Svar
import math p = float(input('p: ')) q = float(input('q: ')) discriminant = p*p - 4*q d = math.sqrt(discriminant) print('x1 = ', (-p + d) / 2.0) print('x2 = ', (-p - d) / 2.0)
if
-satsen#
Hittills har alla satser utförts en efter en i tur och ordning. Ofta vill man dock att programmet ska göra olika saker beroende på något villkor. För detta kan man använda en så kallad if
-sats.
Exempel:
Läs in två tal och skriv ut vilket som är störst.
x = float(input('Ge det första talet: '))
y = float(input('Ge det andra talet: '))
if x > y:
print('Det första talet är störst.')
print('Det här skrivs också om det första talet är störst.')
else:
print('Antingen är det andra talet störst')
print('eller så är båda talen lika stora.')
print('Nu vet du en del om relationen mellan talen.')
Kopiera och provkör!
Observera:
Kolontecknen (
:
) efter villkoretx > y
och efterelse
.Indenteringen, d.v.s indragningen av
print
-satserna. Indenteringen ska göras med 4 blanksteg. Troligtvis gör lägger din editor automatiskt till detta efter en sats som slutar med kolon. Annars kan du smidigt göra det med hjälp av Tab-tangenten.
Båda punkterna är väsentliga för if
-satsens funktion!
Om villkoret är sant, d.v.s om x
är större än y
, så utförs de
indenterade satserna fram till else:
(två satser i detta fall). Om
villkoret inte är sant, d.v.s om x
är mindre än eller lika med y
, så
utförs de indenterade satserna efter else:
. Den sista satsen, som inte är indenterad och därför inte en del av else
-grenen, utförs oavsett.
Övning#
Modifiera programmet som löste andragradsekvationen så att det skriver ut rötterna om dessa är reella men texten
'Komplexa rötter'
annars.Svar
import math p = float(input('p: ')) q = float(input('q: ')) discriminant = p*p - 4*q if discriminant < 0: print('Komplexa rötter') else: d = math.sqrt(discriminant) print('x1 = ', (-p + d) / 2.0) print('x2 = ', (-p - d) / 2.0)
Satsen elif
#
Grenarna (satserna som följer raderna med kolon) kan innehålla
godtyckliga satser, till exempel if
-satser.
Exempel:
Antag att vi vill undersöka om ett tal är större än eller lika med eller mindre än 0.
if x > 0:
print('Positiva fallet')
# flera satser
else:
if x == 0:
print('Fallet 0')
# flera satser
else:
print('Negativa fallet')
# flera satser
print('Efter alla fall')
Detta kan uttryckas klarare med hjälp av elif
som kan utläsas ”else if”:
if x > 0:
print('Positiva fallet')
# flera satser
elif x == 0:
print('Fallet 0')
# flera satser
else:
print('Negativa fallet')
# flera satser
print('Efter alla fall')
Logiska uttryck#
Ett logiskt uttryck är ett uttryck som kan vara sant eller falskt. I Python
kallas denna datatyp för bool
och de två värdena skrivs True
och
False
.
Villkoren i if
-satserna ovan är exempel på logiska uttryck. Dessa
konstruerades med hjälp av relationsoperatorerna <
, >
och ==
.
Operator |
Betydelse |
---|---|
==
|
lika |
!=
|
ej lika |
<
|
mindre än |
<=
|
mindre än eller lika |
>
|
större än |
>=
|
större än eller lika |
Operanderna måste vara jämförbara, t.ex. båda tal eller båda strängar.
Python har också de logiska operatorerna and
, or
och not
.
Exempel: Satsen
teenager = age > 12 and age < 20
sätter variabeln teenager
till True
om variabeln age
är större än 12 men mindre än 20.
Anmärkning: I Python kan detta formuleras kortare:
teenager = 12 < age < 20
Ytterligare ett exempel:
day = input('Vad är det för dag idag? ');
if day == "lördag" or day == "söndag":
print("Helg")
else:
print("Arbetsdag")
while
-satsen#
En annan vanlig situation är att man vill upprepa en följd av satser flera gånger - en så kallad loop eller slinga.
Exempel:
Följande program beräknar \(n! = 1·2·3· \ldots ·n\) är för ett inläst värde på \(n\):
print('Beräkning av n!')
n = int(input('Ange n: ')) # input returnerar en sträng
prod = 1
i = 1
while i <= n:
prod *= i
i += 1
print(f'{n}! = {prod}')
Så länge villkoret efter while
är sant, d.v.s. så länge i
är mindre
än eller lika med n
så upprepas de indenterade satserna. Variabeln
prod
ackumulerar produkten och variabeln i
räknar antalet.
Liksom i if
-satsen är både kolon och indentering väsentliga!
Exempel: Läs in tal till en lista. Be användaren mata in positiva tal och spara dem i en lista. Avbryt när 0 matas in.
numbers = [] # En tom lista
print('Mata in positiva tal. Avbryt med 0')
x = int(input('Första: '))
while x > 0:
numbers.append(x)
x = int(input('Nästa: '))
print('Inmatad lista: ', numbers)
break
-satsen#
Normalt avslutas en while
-loop när villkoret blir falskt men det går
också att avbryta med en så kallad break
-sats.
Exempel: Gissa vilket tal datorn tänker på.
import random # paket med slumptalsfunktioner
number = random.randint(1, 100) # Slumptal mellan 1 och 100
while True: # "Evighetsloop"
guess = int(input('Gissa: '))
if guess < number:
print('För litet!')
elif guess > number:
print('För stort!')
else:
print('Rätt!')
break # Avbryter loopen
print('Klart för den här gången.')
Anmärkning: I första hand ska man försöka skriva koden så att det
syns på while
-villkoret när loopen ska avbrytas (det är alltid
möjligt!) och endast använda break
om det gör koden väsentligt enklare
och tydligare!
Övningar#
Lägg till kod till exemplet som låter användaren mata in en lista ovan. Den nya koden ska använda en
while
-loop för att räkna antalet jämna tal i den inmatade listan.Svar
n = 0 i = 0 while i < len(numbers): if numbers[i] % 2 == 0: n += 1 i += 1 print('Antal jämna tal: ', n)
Skriv kod som ber användaren mata in ett positivt tal. Så länge det inmatade talet inte är positivt ska frågan ställas om igen tills användaren gör rätt. Skriv ut texten ”OK” när inläsningen lyckats.
Svar
x = float(input('Ge ett positivt tal: ')) while x <= 0: x = float(input('Ej positivt! Försök igen: ')) print('OK')
Modifiera koden i övningen så att programmet skriver ”Äntligen!” istället för ”OK” om det krävdes mer än 3 försök.
Svar
x = float(input('Ge ett positivt tal: ')) tries = 1 while x <= 0: x = float(input('Ej positivt! Försök igen: ')) tries += 1 if tries <= 3: print('OK') else: print('Äntligen!')
Skriv om koden i gissningsleken så att den inte använder
break
!Svar
import random number = random.randint(1, 100) guess = int(input('Gissa: ')) while guess != number: if guess < number: print('För litet!') else: print('För stort!') guess = int(input('Gissa: ')) print('Rätt!') print('Klart för den här gången')
for
-satsen#
Ett annat sätt för att upprepa kod är att använda for
-satsen. I själva
verket blir koden lite enklare i flera av exemplen och övningarna ovan
med denna sats.
Exempel: Beräkning av \(n! = 1·2·3· \ldots ·n\)
Med for-loop |
Med while-loop |
---|---|
prod = 1
for i in range(1, n+1):
prod *= i
|
prod = 1
i = 1
while i <= n:
prod *= i
i += 1
|
Uttrycket range(1, n+1)
kommer successivt ge värdena \(1, 2, \ldots,
n\) till den s.k. loopvariaben, som här heter i
. Vi behöver alltså inte en sats som ökar på i
. Vi behöver inte heller hålla reda på när iterationen ska avbrytas. Observera att det sista värdet (n+1
)
inte antas.
Anropet range(n)
kommer gå igenom talen \(0, 1, \ldots, n-1\).
Beräkningen ovan går alltså också att göra med koden:
prod = 1
for i in range(n):
prod *= (i + 1)
for
-satsen kan generellt användas för att gå igenom värdena i en lista med
konstruktionen
for variabel in lista:
Loopvariabeln (här variabel
) kommer successivt anta de olika värdena i listan.
Exempel: Att gå igenom listan numbers
för att räkna antalet jämna
tal blir med for
-satsen (while
-varianten till höger):
Med for-loop |
Med while-loop |
---|---|
n = 0
for x in numbers:
if x % 2 == 0:
n += 1
|
n = 0
i = 0
while i < len(numbers):
if numbers[i] % 2 == 0:
n += 1
i += 1
|
Övningar#
Skriv kod som läser in ett tal \(x\) och ett heltal \(n\) och som beräknar \(x^n\) med multiplikationer, d.v.s utan att använda operatorn
**
eller funktionenpow
. Observera att \(n\) kan vara negativt!Svar
x = float(input('Ge ett tal: ')) n = int(input('Ge ett heltal: ')) p = 1 for i in range(0, abs(n)): p *= x if n < 0: p = 1/p print(f'{x}^{n} = {p}')
Skriv kod som givet en lista med tal skapar en ny lista med kvadraterna av talen.
Svar
numbers = [2, 4, 1, 9, 7] squares = [] for x in numbers: squares.append(x*x) print(numbers) print(squares)
Nästlade for
-satser#
Loopkroppen i en for
-sats (gäller även while
-satser) kan innehålla
vilka satser som helst, d.v.s. även nya for
-satser.
Exempel: Antag att vi har en lista med förnamn och en lista med efternamn och vill generera en ny lista med alla möjliga kombinationer av förnamn och efternamn. Programmet
firstnames = ['Bo', 'Eva', 'Ola']
surnames = ['Ek', 'Strand']
result = []
for fn in firstnames:
for sn in surnames:
result.append(fn + ' ' + sn)
print(result)
ger utskriften
['Bo Ek', 'Bo Strand', 'Eva Ek', 'Eva Strand', 'Ola Ek', 'Ola Strand']
För varje förnamn (fn
) kommer koden alltså gå igenom alla möjliga
efternamn sn
och lägga till kombinationen i result
-variabeln.
Övning#
Givet en lista med positiva heltalsvärden, t.ex.
[10, 15, 24, 17, 9, 8, 3]
. Skriv kod som ritar ut ett liggande stapeldiagram där varje stapel innehåller lika många*
tecken som värdet i listan anger. I detta fall skall alltså utskriften bli:********** *************** ************************ ***************** ********* ******** ***
Tips: Anropet
print('*', end='')
undertrycker radframmatningen. Nästaprint
kommer alltså fortsätta på samma rad.Svar
values = [10, 15, 24, 17, 9, 8, 3] for v in values: for i in range(v): print('*', end='') print() # Byt rad
Anmärkning: Med list-operatorer kan detta resultat åstadkommas enklare. Vi återkommer till det senare i kursen.
Kommentarer och kodlayout#
Programkod ska läsas av människor och inte bara av datorer. För att underlätta för människan ska man skriva kommentarer, dvs text som bara är till för det mänskliga ögat och ignoreras av datorn.
I Python använder man #
-tecknet för att markera att resten av raden är
en kommentar. Se till exempel lösningsförslaget till föregående övning. Vi kommer längre fram ta upp
principer för kommentering.
I Python är kodlayouten inte bara för människan utan påverkar även
betydelsen av koden. Indenteringen som användes i if
- och
while
-satserna ovan är exempel på detta!
I dokumentet PEP 8 – Style Guide for Python Code finns ett regelverk som gäller för denna kurs.
De viktigaste punkterna är:
Indenteringen ska ske med 4 blanksteg per nivå
Inga rader längre än 79 tecken. Ett
\
sist på raden indikerar att satsen fortsätter på nästa rad. (Det går att dela upp satser på flera rader om man delar på ”vettiga” ställen.)Två blanka rader mellan funktionsdefinitioner (se nästa avsnitt).
Blanktecken efter kommatecken.
Inget blanktecken efter
(
eller före)
.Blanktecken kring tilldelningsoperatorerna
Räkna med att assistenter vägrar, med rätta, att titta på kod som inte uppfyller dessa basala läslighetskrav!