I Python finns olika kommandon för att jämföra tal och uttryck. Vi kan exempelvis undersöka om ett tal är större än ett annat genom att använda relationsoperatorn <. Resultatet blir True om det är sant och False om det är falskt. True och False har datatyp bool (för boolean) och det vi tittar på nu kallas booleanska operationer.
Testa följande i rutan nedan och gissa även vad svaret bör bli i förväg
import numpy as np
a=2*np.pi;
b=np.exp(2);
a<b
Det finns fler s.k. relationsoperatorer som är till för att jämföra tal (och uttryck) med varandra, här är några exempel
| Jämförelse | Skrivs i Python |
|---|---|
| $ a<b $ | a<b |
| $ a\leq b $ | a<=b |
| $ a>b $ | a>b |
| $ a \geq b $ | a>=b |
| $ a = b $ | a==b |
| $ a \neq b $ | a!=b |
Det är viktigt att skilja på tilldelningsoperatorn (=) och relationsoperatorn ==. Man kan t.ex. spara värdet på jämförelsen genom att skriva
s = 3==5
Detta jämför först ifall 3 och 5 är samma tal och sparar sedan False i s.
Ifall vi har ett numpy-fält med värden kan vi även göra elementvis jämförelse.
Provkör denna kod i rutan nedan, men gissa först vad output bör bli:
import numpy as np
a1 = 4 > np.array([4,5,2,3,4,5,6])
a2 = np.array([1,1,1,1,1,1,1]) > np.array([4,5,-1,3,0,5,0])
print(a1)
print(a2)
Antag att vi vill veta ifall funktionen $f(x)=x\sin(x)$ är större än $0.5$, i ett antal punkter. Vi kan då köra koden:
import numpy as np
x = np.array([0,np.pi/4,np.pi/2,np.pi])
y = x * np.sin(x)
print(y > 0.5)
För att se när detta sker. Kör koden i rutan nedan.
Oftast har man dock många värden och kanske inte vill titta på individuella True eller False, utan använda dem för att få ut svaret på sin fråga.
Säg t.ex. att vi undrar: För vilka $x$ på intervallet $[0,\pi]$ är $f(x)=x\sin(x)$ större än $0.5$?
Här kan vi spara jämförelsen i ett fält och använda fältet som index för att plocka ut "rätt" x-värden
import numpy as np
x = np.linspace(0,np.pi)
y = x * np.sin(x)
test_index = y > 0.5
print(x[test_index])
Variabeln test_index fylls då med True- och False-värden som anger vilka av y-värdena som uppfyller kriteriet. Eftersom x- och y-värdena parvis hör ihop (dvs. det sjunde y-värdet fås av det sjunde x-värdet) så kan vi köra x[test_index] och då väljs endast de element ut som uppfyller kriteriet.
Kör kodstycket ovan.
Ifall vi i stället undrar över vilka element kriteriet uppfylls för så kan vi använda np.where. Kör följande kodstycke:
import numpy as np
x = np.linspace(0,np.pi)
y = x * np.sin(x)
print(np.where(y > 0.5))
Ifall vi vill göra fler jämförelser så får vi använda oss av "logiskt och" (and) eller "logiskt eller" (or) för att slå samman våra jämförelser.
Använder den logiska operatorn and mellan två jämförelser så blir resultatet True om båda
jämförelserna är sanna (dvs. båda är True) och i annat fall False.
Använder den logiska operatorn or mellan två jämförelser så blir resultatet False endast om båda av
jämförelserna är falska (dvs. båda är False) och i annat fall True. Det räcker alltså att minst en av de två jämförelserna är sann för att vi ska få True.
För att bekanta dig med detta, så gissa vad följande bör ge för resultat och kör sedan koden för att se hur många rätt du fick:
print(3 > 1 and 1 > 0)
print(3 > 1 and 1 < 0)
print(3 > 1 or 1 > 0)
print(3 > 1 or 1 < 0)
print(3 < 1 or 1 < 0)
Ibland kan det vara användbart att skifta värdet på det logiska värdet från True till False, och vice versa. Då
kan man använda negationsoperatorn not
Så not(3<1) ger True eftersom 3<1 ger False.
För att bekanta dig med detta, så gissa vad följande bör ge för resultat och kör sedan koden för att se hur många rätt du fick:
print( not( 3 > 1 and 1 > 0 and 1 < 0 ) )
print( not( (3 > 1 and 1 == 0) or 0 < 1 ) )
True eller False¶Ibland vill man bara tilldela en variabel ett logiskt värde, utan att det hänger ihop med någon speciell jämförelse eller logisk uträkning. Det kan vi göra på följande vis:
a = True
b = False
Vill man ha ett fält av True eller False kan man använda np.ones respektive np.zeros fast ange att datatypen är bool.
Prova detta själv i rutan nedan:
import numpy as np
a = np.ones(15, dtype=bool)
b = np.zeros(10, dtype=bool)
print(a)
print(b)
True och False som tal¶Man kan också använda logiska uttryck i vanliga beräkningar med tal. Då behandlas True som en etta och False som en nolla. Pröva t.ex.
print(7*(3<6))
print(7*(3>6))
En intressant konsekvens av detta är att man kan räkna antalet sanna värden med np.sum vid elementivs jämförelse. Provköra följande kodstycke nedan:
import numpy as np
a1 = 4 > np.array([4,5,2,3,4,5,6])
a2 = np.array([1,2,3,4,5,6,7]) > np.array([4,5,-1,3,0,5,0])
print(a1)
print(a2)
print(np.sum(a1))
print(np.sum(a2))
Det är lite lurigare att göra elementvis and eller or dock. Säg att vi har tre fält a1, a2, a3 och vill veta hur många gånger a1 < a2 < a3 och vilket det första index är då det inträffar, då kan vi inte skriva a1 < a2 and a2 < a3 utan, vi måste använda funktionen np.logical_and för att slå ihop våra påståenden.
Kör denna kod nedan.
a1 = np.array([1,1,1,1,1,1,1])
a2 = np.array([4,5,-1,3,0,5,0])
a3 = np.array([14,2,3,1,-6,7,-1])
a1_mindre_a2_mindre_a3 = np.logical_and( a1 < a2, a2 < a3)
print(a1_mindre_a2_mindre_a3)
antal = np.sum(a1_mindre_a2_mindre_a3)
print(antal)
Vi kan nu använda funktionen np.where för att ange vilka index alla True har. Lägg till denna kod nedan:
index = np.where(a1_mindre_a2_mindre_a3)
print(index)
Att a1 < a2 < a3 sker alltså två gånger och första gången i det första elementet.
En annan anledning till att man skulle vilja göra detta är för att man kan skapa styckvis definierade funktioner, t.ex.
$$f(x) = \begin{cases} \sin(x) & x < 1 \\ \cos(x) & x \geq 1 \\ \end{cases}$$genom att skriva:
import numpy as np
def styckvis_fun(x):
return np.sin(x)*(x < 1) + np.cos(x)*(x >= 1)
Om vi evaluerar funktionen för ett $x$ mindre än $1$ kommer (x < 1) bli True, vilket blir en etta och np.sin(x)*(x < 1) blir därför np.sin(x) medan (x >= 1) blir False, vilket blir en nolla och np.cos(x)*(x >= 1)blir 0.
Skriv kod som ritar denna funktion på intervallet $[0,2\pi]$. Se till att inte rita något i diskontinuiteten. Du bör få något som liknar

Python kan inte bara hantera tal utan även text. Detta kan göras på olika sätt, men ett är att spara texten i form av ett teckenfält (som är en datatyp som heter str). Det görs genom att omge texten av raka apostrofer ', t.ex.
t = 'Hej värld!'
Vi kan plocka ut delar av t på samma sätt som vi plockade ut delar av en lista, t.ex. ger print(t[0:2]) output He.
Längden av en textsträng fås av len, t.ex. ger len(t) 10 (mellanslag räknas som ett tecken).
För att slå ihop text används +, så
a = 'Jag '
b = 'heter'
a + b
ger oss 'Jag heter'.
Gissa vad följande bör ge för resultat och kör sedan koden för att se ifall du fick rätt:
t = 'Hej värld!'
u = 'på dig'
print(t[0:4] + u + t[3:len(t)])
a = 'Det här är kul'
print(a[11:14] + a[2] + a[12] + 'r')
I flera fall vill vi kombinera text och ett tal vi beräknat. Problemet är att vi inte kan använda + mellan text och tal (Python vet inte vad det skulle betyda), så vi måste omvandla talet till text innan + används. Detta görs med funktionen str.
Testa att köra följande kodstycke:
s = 32
t = 'Jag är '
u = ' år'
text = t + str(s) + u
print(text)
Ibland vill man be användaren om input medan programmet körs. Man kan exempelvis be användaren skriva någon text som svar på en fråga, eller interagera med programmet genom att klicka med musen. Vi går bara igenom textinput i denna kurs.
För att be användaren om input används input-kommandot i vilket du skriver vad som ska presenteras för användaren och i vilken variabel svaret ska sparas, på följande vis:
svaret = input(text till användaren)
Här följer ett exempel för att komma igång. Kör det i rutan nedan:
namn = input('Vad heter du? ');
print('Hej på dig, ' + namn + '!')
Datatypen av det som läses in av input är str, vilket innebär att vi inte kan använda det hur vi vill.
På samma sätt som att vi inte kunde använda + när vi hade en text och ett tal för att sammanfoga det kan vi heller inte använda vanliga matematiska operationer med tal och text och förvänta oss att det ska räknas ut. Vi måste därför alltid konvertera input som är tal, innan vi kan använda den i beräkningar.
Vi använder int ifall vi vill omvandla texten till ett heltal och float ifall vi vill omvandla den till ett decimaltal.
se följande exempel (notera funktionen float omkring input):
import numpy as np
r=float(input('Ange cirkelns radie: '));
A=np.pi*r**2;
print('Cirkelns area är ' + str(A))
if-satser)¶Ibland vill man att vissa rader av ett program bara skall köras under vissa villkor, eller att programmet skall utföra olika saker beroende på vilka villkor som är uppfyllda. Då kan man göra en s.k. if-sats. Man använder if-satser så här
if villkor:
kod att köra om villkor ger True
else:
kod att köra om villkor ger False
Här är ett exempel (round avrundar talet), se ifall du förstår hur det fungerar:
n = int(input('Ange ett heltal: '))
if n / 7 == round(n / 7):
print('Talet är delbart med 7')
else:
print('Talet är inte delbart med 7')
Man kan även testa flera villkor och endast köra raderna som gäller ifall just det villkoret är sant. För att göra detta skriver man elif (kort för else if) på de andra villkorsraderna.
Här kommer ett exempel på det (och fråga dig själv, innan du testar, vad som händer ifall din input är 91 som är 7*13):
n = int(input('Ange ett heltal: '))
if n / 7 == round(n / 7):
print('Talet är delbart med 7')
elif n / 9 == round(n / 9):
print('Talet är delbart med 9')
elif n / 13 == round(n / 13):
print('Talet är delbart med 13')
else:
print('Talet är inte delbart med 7, 9, eller 13')
Man kan ha hur många elif som helst, men högst ett else sist i if-satsen.
Vi även skapa vår styckvis definierade funktion med hjälp av if-satser
$$f(x) = \begin{cases} \sin(x) & x < 1 \\ \cos(x) & x \geq 1 \\ \end{cases}$$Försök att göra detta själv.
try-satser)¶Ifall du provar att ange ett flyttal i koden från tidigare kommer du att få ett felmeddelande (det ser kanske lite kryptiskt ut, men det säger bara att du inte angav ett heltal och att programmet därför kraschade):
n = int(input('Ange ett heltal: '))
if n / 7 == round(n / 7):
print('Talet är delbart med 7')
elif n / 9 == round(n / 9):
print('Talet är delbart med 9')
elif n / 13 == round(n / 13):
print('Talet är delbart med 13')
else:
print('Talet är inte delbart med 7, 9, eller 13')
Vi kanske inte önskar att programmet kraschar när någon trycker lite fel och ett sätt att lösa detta är med hjälp av en try-sats. Detta kommando är till för koden att försöka något och ha en "backup-plan" ifall det misslyckas. Man använder det så här:
try:
kod vi vill testa
except:
kod ifall testet misslyckas
Vi provar nu med att försöka omvandla input till ett heltal och anger sedan vad som händer ifall detta misslyckas.
n = input('Ange ett heltal: ')
try: # Vi testar att omvandla n till ett heltal
n = int(n)
print('Du angav ett heltal')
except: # Vi skriver ett meddelande ifall koden under try misslyckas
print('Du angav inte ett heltal')
Ifall vi vill att programmet ska fortsätta att be om ett tal tills omvandlingen fungerar måste vi introducera loopar.
Ibland vill man upprepa delar av ett program så att vissa rader av koden körs flera gånger. I så fall kan man göra en s.k. loop. Det finns huvudsakligen två typer av loopar: while-loopar och for-loopar.
En while-loop upprepar raderna inom loopen fram tills ett givet villkor blir falskt (får värde False). Så länge villkoret är sant (ger värde True) körs koden.
En for-loop upprepar raderna inom loopen ett givet antal gånger. Du kan exempelvis låta for-loopen stega igenom en lista och låta en variabel anta värdena i listan, ett åt gången.
Låt oss börja tala om while-loopen.
while-satser¶Det allmänna utseendet på en while-sats har följande form:
while villkor:
kommandon att köra ifall villkor är "True"
Säg att vi vill skriva ut alla jämna tal som är mindre eller lika med 20. Vi kan då skriva följande kod.
tal = 1
dubbelt = 2 * tal
while dubbelt <= 20:
print(dubbelt)
tal = tal + 1
dubbelt = 2 * tal
Kör denna kod i rutan nedan:
Hur fungerar denna kod?
Först skapar vi en variabel tal och låter den vara 1. Efter det låter vi dubbel vara en variabel som sparar det dubbla värdet.
Vi kommer sedan till while-loopen som ser efter ifall värdet på dubbelt är mindre eller lika med 20. Eftersom detta villkor ger True när dubbelt = 2 så kliver vi in i loopen.
Inuti loopen skriver vi ut värdet på dubbelt, ökar variabeln tal med 1 och beräknar dubbelt en gång till.
När vi nu kommit till slutet av loopen hoppar vi upp igen och gör en ny kontroll med det nya värdet på dubbelt som nu är 4. Eftersom detta villkor ger True så kliver vi in i loopen igen.
Detta upprepas tills dubbelt = 22, eftersom villkoret då ger False och vi hoppar då över raderna nedan och kliver ur loopen.
Ifall vi skriver ut det som sker ser det alltså ut så här:
tal = 1
dubbelt = 2 * 1 (=2)
while 2 <= 20: (True)
print(2) (Skriver ut 2)
tal = 1 + 1 (=2)
dubbelt = 2 * 2 (=4)
while 4 <= 20: (True)
print(4) (Skriver ut 4)
tal = 2 + 1 (=3)
dubbelt = 2 * 3 (=6)
while 6 <= 20: (True)
print(6) (Skriver ut 6)
tal = 3 + 1 (=4)
dubbelt = 2 * 4 (=8)
...
while 20 <= 20: (True)
print(20) (Skriver ut 20)
tal = 10 + 1 (=11)
dubbelt = 2 * 11 (=22)
while 21 <= 20: (False)
Färdiga!
Låt oss ta ett till exempel på en while-sats.
Antag att vi vill summera talen $\frac{1}{k}$ för $k = 1,2,3,...$ och vill undersöka hur många termer som behövs för att summan ska bli större än $4$. Vi vill alltså ha det minsta $n$ sådant att
$$ \sum_{k=1}^{n} \frac{1}{k} > 4$$Vi vet inte på förhand hur många gånger denna loop måste köras och inte kanske inte ens ifall summan kan bli större än $4$.
Vi kan lösa problemet med följande loop:
summa = 0
k = 0
while summa <= 4:
k = k + 1
summa = summa + 1 / k
print(k)
Vi initierar här summa och k till 0 och hoppar sedan in i while-loopen (eftersom 0 <= 4 ger True).
Väl inne i loopen adderar vi 1 till k och låter summa vara summan mellan det förra värdet på summa och 1/k.
Ifall vi skriver ut det som sker ser det alltså ut så här:
summa = 0
k = 0
while 0 <= 4: (True)
k = 0 + 1 (=1)
summa = 0 + 1 / 1 (=1)
while 1 <= 4: (True)
k = 1 + 1 (=2)
summa = 1 + 1 / 2 (=1.5)
while 1.5 <= 4: (True)
k = 2 + 1 (=3)
summa = 1.5 + 1 / 3 (=1.8333333333333333)
...
while 3.9949871309203906 <= 4: (True)
k = 30 + 1 (=31)
summa = 3.9949871309203906 + 1 / 31 (=4.02724519543652)
while 4.02724519543652 <= 4: (False)
Färdiga!
En sak att tänka på: Ifall summan skulle konvergerat innan den nådde $4$ hade while-loopen aldrig avbrutits, vilket hade varit problematiskt (med tillräckligt tunga beräkningar hade det kunnat få datorn att frysa t.ex.).
För att skydda oss från denna typen av problem kan vi lägga till ett villkor som ser till att vi inte är fast i loopen för länge ifall vi inte kommer någon vart:
summa = 0
k = 0
while summa <= 4 and k < 100:
k = k + 1
summa = summa + 1 / k
print(k)
Genom att skriva summa < 4 and k < 100 så skulle koden avbrutits ifall k nått 100 innan summa blivit 4, eftersom vi då hade haft True and False vilket skulle ha gett False.
Som övning: Skriv själv ett program som med en while-sats avgör vilket som är det minsta heltal $n$ sådant att:
Ha också med en koll, så att while loopen aldrig kör för länge (du själv får avgöra vad som är rimligt).
Skriv sedan ut vad som sker när programmet körs, rad för rad (åtminstone för de första varven i loopen).
Vi kan också ange True som villkor för vår while-sats för att få den att aldrig avslutas förrän vi manuellt bryter den (var försiktig med detta dock, så att du inte råkar skapa en loop som aldrig avbryts någonsin). Kommandot som bryter en loop heter break.
Ifall vi kombinerar while True med vårt try kommando från tidigare så kan vi exempelvis låta programmet be användaren om ett heltal ända till det faktiskt får ett heltal.
Kommentarerna är för att förtydliga vad som sker.
while True: # Kommer aldrig avbrytas om vi inte kör break
n = input('Ange ett heltal: ')
try:
# Vi försöker omvandla n, misslyckas detta
# hoppar vi ner till except- koden
n = int(n)
# Denna rad når vi endast ifall
# n=int(n) inte ger felmeddelande.
break # Vi bryter while-loopen
except:
# Vi skriver ett meddelande ifall
# vi inte lyckades omvandla n.
print('Du angav inte ett heltal')
# Koden nedan når vi endast ifall vi kommit förbi
# n = int(n) utan fel och kört kommandot break
if n / 7 == round(n / 7):
print('Talet är delbart med 7')
elif n / 9 == round(n / 9):
print('Talet är delbart med 9')
elif n / 13 == round(n / 13):
print('Talet är delbart med 13')
else:
print('Talet är inte delbart med 7, 9, eller 13')
Som du ser används mellanslag (eller tab) för att ange vilka delar av koden som ligger "innanför" andra.
try och except är inuti while-loopen och n=int(n) är innanför try.
if n / 7 == round(n / 7): är inte innanför while-loopen eftersom den raden är indenterad lika långt till vänster som while, men print('Talet är delbart med 7') ligger innanför if-satsen.
for-loop¶Ifall vi vet hur många gånger några rader kod ska upprepas kan det vara praktiskt att använda en for-loop.
Låt oss titta på ett exempel där vi vill beräkna summan
$$1 + \frac{1}{2} + \frac{1}{3} + \frac{1}{4} + ... + \frac{1}{96} + \frac{1}{97}$$Vi kan nu först skapa vektorn [1,2,3,...,97] exempelvis genom np.arange(1,98,1) (kom ihåg att arange går från och med start till (men utan) slut) och sedan låta en variabel k stega igenom alla värden i vektorn.
Koden ser då ut så här:
import numpy as np
summa = 0
namnare = np.arange(1,98,1)
for k in namnare:
summa = summa + 1 / k
print(summa)
Testkör den nedan.
Ifall vi skriver ut det som sker ser det alltså ut så här:
summa = 0
namnare = np.arange(1,98,1) ( = [1,2,3,4,...,97] )
for k in [1,2,3,4,...,97] :
k = 1
summa = 0 + 1 / 1 (=1)
k = 2
summa = 1 + 1 / 2 (=1.5)
k = 3
summa = 1.5 + 1 / 3 (=1.8333333333333333)
...
k = 96
summa = 5.136346480888775 + 1 / 96 (=5.146763147555442)
k = 97
summa = 5.146763147555442 + 1 / 97 (=5.157072425905957)
print(5.157072425905957)
I vissa fall kan man beräkna samma sak som en for-loop utan att behöva använda den. Ifall vi använder oss av elementvisa operationer (som vi pratade om förra gången) så kan vi t.ex. skriva np.sum(1/np.arange(1,98,1)) för att beräkna samma summa utan en loop. Detta kallas att vektorisera koden.
Variabeln i for loopen behöver givetvis inte börja på 1 eller ens öka med 1 i varje steg. Det behöver inte ens vara tal i vektorn vi stegar igenom, det kan vara flyttal, tecken eller annat.
mening = ''
ordvektor = ['hej', 'på', 'dig']
for ord in ordvektor:
mening = mening + ord + ' '
print(mening)
Kör denna kod i rutan nedan och prova själv sedan att skriva ut vad koden gör rad för rad.
Även om problem kan lösas på många olika sätt med kod så finns det snabbare och långsammare metoder. Ibland är vi intresserade av att veta hur snabb koden är, eftersom det hjälper oss att skriva effektivare kod.
För att mäta tiden det tar för kod att köra i Python kan man använda kommandot time från modulen time.
Funktionen time.time() returnerar antalet sekunder som gått sedan epoch (som är definierat som 1 januari 1970, 00:00:00 (UTC)). Detta innebär att vi kan beräkna tiden det tar för ett kommando att exekvera genom att först spara tiden från time.time() i en variabel, säg, t, sedan köra koden och slutligen köra time.time() - t för att beräkna tiden som förflutit medan programmet kördes (tiden då variabeln t initieras används som referenspunkt).
Vi tittar på hur lång tid det tar att beräkna summan från tidigare.
import time
import numpy as np
t = time.time()
summa = 0
namnare = np.arange(1,98,1)
for k in namnare:
summa = summa + 1 / k
förfluten_tid = time.time() - t;
print(str(förfluten_tid) + ' sekunder')
print(summa)
Det är viktigt att veta vad man faktiskt vill mäta och tydligt specificera vad man mätt när man presenterar resultatet. Vi har i vårt fall inte med kommandona import eller print i tidtagningen; vi är bara intresserade av hur lång tid det tar att initiera våra variabler och köra for-loopen.
I många fall vill man köra koden många gånger och ta ett medelvärde av tiderna man får, men i denna kurs kan du köra koden några få gånger (säg fem) och plocka ut medianen för hand. Testa själv i rutan nedan (du kan exempelvis kopiera och klistra in koden fem gånger).