Python Workshop
av Peder Bergebakken Sundt og Torje Hoås Digernes
Programvareverkstedets
s.ntnu.no/py18
A-genda
- Installere Python
- IDLE
- Litt om programering
- Litt om språket
- Feilmeldinger
- Løkker
- Iteratorer
- Liste utrykk
- Lese filer
- Operatorer
- Flytkontroll
- Typer
- Funksjoner
- Strenghåndtering
TODO: TID
TODO: TID
TODO: TID
- Gjøre øvelser!
- Gjøre øvelser!
- Gjøre øvelser!
Ikke-genda
- Objekter
- Klasser
- Polimorfi
- Lage moduler
- Argumentlister
- God humor
Installere Python
Det finnes mange implementasjoner og versjoner av python standarden. Vi skal her bruke CPython
https://www.python.org/
Windows og MacOS brukere kan
laste ned Python 3.7 fra nettsiden
Linux og MacOS kan bruke en pakkebehandler
til å installere python3
Implementert av de samme folkene
som bestemmer Python standarden.
Interaktiv gjennomgang av installasjon
Python 2 og Python 3
Disse to versjonene har noen små forskjeller.
I denne workshoppen vil de nesten ikke merkes.
Workshoppen bruker Python 3.
Python 2 er på vei ut.
Hvis noen her bruker Python 2:
Si ifra! Så peker vi ut forskjellene
IDLE
IDLE er en enkel teksteditor for
å redigere Python sine .py filer.
Den følger med Python, men er veldig primitiv.
Den har to moduser:
IDLE / Editor
Her skriver man fullverdige python programmer
Programmet kan så kjøres via IDLE eller ved å dobbeltklikke på fila som er lagret
IDLE / Interaktivt skall
Du skriver og kjører en linje kode av gangen
Skallet gir deg resultatet for hver linje.
Tilstand blir bevart.
>>> 3 + 4
7
>>> print("dette er en test")
dette er en test
>>> print("na" * 8 + ", Batman!")
nananananananana, Batman!
IDLE demo
Litt om programmering
Datamaskinen
En kompleks kalkulator som utfører
regne- og logikkoperasjonene vi ber den om.
Dette kaller vi instruksjoner
Programmer
Programmer er ei liste av instruksjoner vi vil datamaskinen skal utføre.
Programmer kan sammenlignes med kokeoppskrifter:
en rekke instruksjoner for kokken å utføre
Programmeringsspråk
Et godt definert språk for å formidle
instruksjoner på en måte som
både mennesker og datamaskinen forstår
Litt om Python
Python er en av de enkleste og mest brukte
programmeringsspråkene i verden.
Det finnes mange resurser på nettet om
bruk av språket.
Python
Python er brukt mange steder i industrien
- Automatisering
- Maskinlæring
- Kompleks dataanalyse
- Data visualisering
- Webutvikling
- Tolking av naturlig språk
Eksempler
import snowy, numpy as np
def create_falloff(w, h, radius=0.4, cx=0.5, cy=0.5):
hw, hh = 0.5 / w, 0.5 / h
x = np.linspace(hw, 1 - hw, w)
y = np.linspace(hh, 1 - hh, h)
u, v = np.meshgrid(x, y, sparse=True)
d2 = (u-cx)**2 + (v-cy)**2
return 1-snowy.unitize(snowy.reshape(d2))
def create_island(seed, freq=3.5):
w, h = 750, 512
falloff = create_falloff(w, h)
ns = sum(
n1 = 1.000 * snowy.generate_noise(w, h, freq*1, seed+0)
n2 = 0.500 * snowy.generate_noise(w, h, freq*2, seed+1)
n3 = 0.250 * snowy.generate_noise(w, h, freq*4, seed+2)
n4 = 0.125 * snowy.generate_noise(w, h, freq*8, seed+3)
elevation = falloff * (falloff / 2 + n1 + n2 + n3 + n4)
mask = elevation < 0.4
elevation = snowy.unitize(snowy.generate_sdf(mask))
return (1 - mask) * np.power(elevation, 3.0)
snowy.save(create_island(10), 'island.png')
Python som språk
Python er et språk som tolkes
av maskinen i sanntid.
Det har dynamiske typer, som betyr
språket ikke er veldig strengt
Du slipper å ta hensyn til så mange smådetaljer som Python håndterer for deg
Python oppmuntrer en ren og oversiktlig kodestil
Utrykk
Hver linje kode inneholder ett eller flere utrykk.
Utrykk er en beregning som returnerer en verdi
>>> 2 + 3
5
>>> 3 * 4
12
>>> sum((1, 2, 3))
6
>>> sqrt(16)
4.0
Variabler
Vi kan lagre verdier til navn.
Disse navnene kalles variabler.
>>> 2 + 2
4
>>> hei = 2 + 2
>>> hei
4
>>> hei = hei + 2
>>> hei
6
>>> hei * 2
12
Kommentarer
Vi kan skrive kommentarer i koden for
å forklare og hjelpe oss med å holde oversikt.
# Dette er en kommentar
# De fleste teksteditorer har grønne kommentarer
# IDLE viser kommentarer i rødt
a = 1 # kommentarer går til slutten av linja
# a = 2
print(a) # Dette vil skrive ut 1 til brukeren
Vi kan "kommentere ut" kode som ikke brukes
Blokker / indentering
Python bruker indentering (innrykk) for å separere
kode inn i "blokker". Dette brukes i flytkontrol og
funksjoner, som vi dekker i dag.
import random
# Denne "if" strukturen har to blokker:
if random.random() > 0.5:
print("Hei")
else:
print("Hallo")
out = []
# de to neste linjene tilhører denne "for" løkken
for i in range(5):
i_squared = i**2
out.append(i_squared)
print(sum(out))
Operatorer
For å kunne utføre aritmetikk og logikk,
trenger vi operatorer å regne med:
>>> 3 + 4 # plusse sammen tall
7
>>> 3 - 4 # trekke to tall fra hveradre
-1
>>> 3 * 4 # gange sammen tall
12
>>> 3 / 4 # dele to tall på hverandre
0.75
Operatorer
Et par mer avanserte operatorer:
>>> 2 ** 3 # to opphøyd i tredje
8
>>> 10 % 3 # Modulo: Resten av 10 delt på 3
1
Disse brukes ikke ofte og kan raskt oppsøkes på nettet etter behov
Sammenliknings-operatorer
>>> 2 > 3 # større enn
False
>>> 2 < 3 # mindre enn
True
>>> 4 >= 4 # lik eller større
True
>>> 4 <= 4 # lik eller mindre
True
>>> 2 == 3 # lik
False
>>> 2 != 3 # ulik
True
>>> 4 == 4 # lik
True
En vanelig misforståelse
>>> a = 1
>>> b = 2
>>> a == b # sammenlikning
False
>>> a = b # tilordning, bemerk ingen returverdi
>>> a == b # sammenlikning
True
>>> a
2
>>> b
2
== og = er to forskjellige operatorer!
Python vil av og til hindre deg i å gjøre denne feilen
Operator presedens
Operatorene har en definert rekkefølge,
likt som i matematikken:
>>> 1 + 3 * 4
13
>>> (1 + 3) * 4
16
Den er for det meste intuitiv, men kan
overstyres med parenteser
and, or
"and" og "or" brukes til å kombinere sammenlikninger:
#
>>> True and True
True
>>> True and False
False
>>> False and True
False
>>> False and False
False
>>> True or True
True
>>> True or False
True
>>> False or True
True
>>> False or False
False
Øvelse: uttrykk
Lag et uttrykk som sjekker om en
ukjent verdi er mellom 4 og 10
>>> a = 3 # definer verdien a
>>> a == 5 # kjør uttrykket
False
>>> a = 5# endre a til en ny verdi
>>> a == 5 # kjør uttrykket på nytt
True
Tips:
Trykk ALT+P for å kopiere forrige linje kjørt i IDLE.
Trykk gjentatte ganger for eldre linjer
Trykk opp-tasten istedet hvis du bruker terminal
>>> a = 3
>>> 4 <= a and a <= 10
False
>>> a = 5
>>> 4 <= a and a <= 10
True
>>> a = 12
>>> 4 <= a and a <= 10
False
Utgangspunkt
Løsning
Kombinere and og or
med andre utrykk
>>> a = 1
>>> b = 2
>>> a > b
False
>>> a > b or b > a
True
>>> False or True
True
Flytkontroll
Programmer trenger en måte å ta beslutninger,
og kunne tilpasse handlingene sine ut ifra disse.
>>> a = 2
>>> b = 3
>>> if a == b:
... print("equal")
... else:
... print("not equal")
...
not equal
if
Blokken under kodeordet "if" kjøres kun hvis utrykket
evalueres til True
>>> if False:
... print("something happened")
>>> if True:
... print("something happened")
something happened
>>>
else
Blokken under "else" kjøres kun hvis blokken under
det tilsvarende "if" kodeordet ikke ble kjørt
>>> if True:
... print("The if block was run")
... else:
... print("The else block was run")
...
The if block was run
>>> if False:
... print("The if block was run")
... else:
... print("The else block was run")
...
The else block was run
elif
"elif" er en forkortelse for "else: if"
"elif" lar oss teste flere muligheter på en enkel måte:
if a == 1:
print("one")
else:
if a == 2:
print("two")
else:
if a == 3:
print("three")
else:
print("unknown")
if a == 1:
print("one")
elif a == 2:
print("two")
elif a == 3:
print("three")
else:
print("unknown")
Øvelse: Karakterer
Lag et program som tar inn et testresultat
mellom 0 og 100, og skriver ut en tilsvarende
karakter mellom A og F
Utgangspunkt:
(Finn opp mengden poeng som bestemmer
de ulike karakterene)
# Skriv dette som ei fil med IDLE
# (trykk File -> New File eller CTRL+N hvis du er i skallet)
# Husk å lagre fila!
from random import random
result = round(100*random()) # en verdi mellom 0 og 100
print(result)
Øvelse: Karakterer
Lag et program som tar inn et testresultat
mellom 0 og 100, og skriver ut en tilsvarende
karakter mellom A og F
Løsningsforlsag:
from random import random
result = round(100*random()) # en verdi mellom 0 og 100
print(result)
if result >= 90:
print("A")
elif result >= 80: #trenger ikke teste om result er under 90
print("B")
elif result >= 70:
print("C")
elif result >= 60:
print("D")
elif result >= 50:
print("E")
else:
print("F")
Typer
Verdier kan være av forskjellige typer
Typen bestemmer hvordan informasjonen blir
lagret i minne og behandlet av operasjoner.
>>> type(5)
<class 'int'>
>>> type(5.0)
<class 'float'>
>>> type("Hei på deg")
<class 'str'>
Bool
Boolske verdier betegner sannheter.
De fleste sammenlikninger evalueres til en boolverdi
>>> True
True
>>> if True: print("test")
...
test
>>> if False: print("test")
...
>>> 3 > 2
True
Bool brukes i "if" spørringer
Tall
Heltall blir lagret som typen "int", kort for "integer"
Desimaltall blir lagret som typen "float": flyttall
>>> type(5) # heltall er av typen "integer"
<class 'int'>
>>> type(5.0) # flyttall er av typen "float"
<class 'float'>
Med Python 3 trenger du for det meste ikke bry deg om forskjellen mellom float og int.
Strenger
Tekst er lagret i form av strenger, kalt "str" i python
(programmerere likte korte navn på 90 tallet)
>>> 'test' == "test" # typen fnutter er ikke viktig
>>> "hei " + "på " + "deg!" # strenger kan kombineres
'hei på deg!'
>>> "ha" * 3 # strenger kan bli gjentatt
'hahaha'
>>> type("hei")
<class 'str'>
Lister
Ei liste kan inneholde flere elementer av
arbitrere typer
>>> mylist = [123, 456, 789]
>>> mylist[0] # indekser starter på 0
123
>>> mylist[1]
456
>>> mylist.append("hei") # lister kan endres
>>> mylist
[123, 456, 789, 'hei']
>>> mylist[1:3] # lister støtter "slicing"
[456, 789]
Den største gotcha'en med lister er nullindeksering.
De fleste programeringsspråk bruker dette
Ordbøker
Python kaller ordbøker "dict", kort for dictionary.
Ordbøker "oversetter" fra en verdi til en annen:
fra en nøkkel til verdi
>>> mylist = [5, 6, 7]
>>> mylist[1] # fra lister henter vi verdier via indeksen
6
>>> mydict = {"hei":1, "hallo":"min verdi"}
>>> mydict["hei"] # oppslag gjøres med en "nøkkel", ikke via indeks
1
>>> mydict["hallo"]
'min verdi'
>>> mydict[33] = "ny verdi" # du kan legge inn nye verdier
>>> mydict
{'hei': 1, 'hallo': 'min verdi', 33: 'ny verdi'}
>>> mydict["hei"] = 2 # eller overskrive eksisterende verdier
>>> mydict
{'hei': 2, 'hallo': 'min verdi', 33: 'ny verdi'}
Operatorer og typer
De forskjellige typene oppfører seg forsjellig
for de ulike operatorene.
>>> 2 + 2 # + betyr addering for tall
4
>>> "a" + "a" # + betyr sammenslåing for strenger
'aa'
>>> 2 + "a" # her kan ikke python bestemme seg for oppførsel
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Bool-aktig
De fleste typer har en eller annen form for "sannhet"
>>> bool(0) # integer 0 er usann-aktig
False
>>> bool(1) # alle andre heltall er sanne
True
>>> bool(99)
True
>>> bool(-1)
True
>>> bool([]) # tomme lister er usanne
False
>>> bool([1, 2]) # lister med innhold er sanne
True
>>> bool("") # tomme strenger er usanne
False
>>> bool("hei") # strenger med innhold er sanne
True
De fleste typer er "usanne" hvis de er tomme
Tuple
"tuple" fungerer på samme måte som "list",
men de er "immutable": De kan ikke bli endret på.
>>> foo = [1, 2, 3] # liste
>>> foo.append(99)
>>> foo
[1, 2, 3, 99]
>>> bar = (1, 2, 3) # tuple
>>> bar.append(99)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
"There would only exists about 5 good programmers in the world, if it where not for Google."
Funksjoner
Funksjoner tar null eller flere verdier
inn og returnerer en verdi
>>> abs(3) # absoluttverdi
3
>>> abs(-3)
3
>>> max([5, 7, 2])
7
>>> min([5, 7, 2])
2
Du "kaller" funksjonen "foo" ved å skrive:
>>> foo()
Moduler
Python: "batteries included"
Moduler
Moduler er "samlinger" eller "biblioteker"
med ferdige funksjoner og verdier
som du kan importere og ha nytte av
>>> import math # hente modulen "math"
>>> math.pi # bruke verdien "pi" i "math"
3.141592653589793
>>> math.sqrt(25) # square root
5.0
Det følger med mange moduler med python.
Det finnes også mange moduler du kan
laste ned fra nettet og bruke i ditt program
Delvis import
Vi er ikke tvungen til å hente inn hele modulen:
Det kan være kortere å hente kun enkelte funksjoner.
>>> import math
>>> math.sqrt(16)
4.0
>>> from math import sqrt
>>> sqrt(16) # trenger skrive ikke "math."
4.0
vs
De fleste mener den siste er mer "ryddig"
Kule innebygde funksjoner og moduler
Du trenger man ikke pugge alle nå,
men det er fint å vite at de eksisterer.
Google er din venn fra nå av.
abs
Returnerer absoluttverdien til et tall
>>> abs(-2)
2
>>> abs(-1)
1
>>> abs(0)
0
>>> abs(1)
1
>>> abs(2)
2
print og input
Ikke veldig nyttid i det interaktive skallet, men
veldig nyttig i større programmer
navn = input("Hva heter du? ") # spør om tekst fra brukeren
print("Hei " + navn + "!") # skriver tekst ut til brukeren
Print støtter flere parametre, som blir
slått sammen med en separator (mellomrom):
navn = "Robert"
print("Hei på deg", navn)
print(1, 2, 3)
print(1, 2, 3, sep="-") # endrer separator til en strek
Hei på deg Robert
1 2 3
1-2-3
min og max
min og max returnerer det minste
og det største elementet i ei liste
>>> mylist = [2, 2, 3, 1, 4, 0, 2]
>>> max(mylist)
4
>>> min(mylist)
0
sorted
Du kan bruke funksjonen "sorted" til å lage en
sortert kopi av ei liste
>>> mylist = [2, 2, 3, 1, 4, 0, 2]
>>> sorted(mylist)
[0, 1, 2, 2, 2, 3, 4]
>>> mylist
[2, 2, 3, 1, 4, 0, 2]
>>> mylist2 = [[3,"a"], [2, "b"], [1, "c"]] # ei liste av lister
>>> sorted(mylist2) # listene sorteres i leksikal rekkefølge
[[1, 'c'], [2, 'b'], [3, 'a']]
Øvelse: Sortere input
Skriv et program som spør brukeren om tre tall.
Skriv de ut igjen i sortert rekkefølge
mylist = [
int(input("Tall 1: ")),
int(input("Tall 2: ")),
int(input("Tall 3: "))
]
print(sorted(mylist))
Oversette typer
De fleste typer har en eller flere funksjoner
som oversetter en verdi fra en type til en annen:
>>> a = "123"
>>> type(a)
"<class 'str'>"
>>> int(a) # oversette strengen til heltall:
123
>>> type(int(a))
"<class 'int'>"
age = int(input("Hvor gammel er du? "))
Øvelse: Avrunding
Du får en flyt-verdi du vil runde ned til nærmeste heltall
mitt_tall = 55.3
# din kode her
print(mitt_tall) # dette skal skrive ut 55
mitt_tall = 55.3
mitt_tall = int(mitt_tall)
print(mitt_tall) # dette skal skrive ut 55
round
round() avrunder et flyttall til det nærmeste heltallet
>>> round(2.0)
2
>>> round(2.3)
2
>>> round(2.8)
3
>>> int(2.8)
2
Nøyaktighet med float
Datamaskinen må gjøre avrundinger
grunnet et begrenset antall siffer.
Dette blir rart for oss, fordi maskinen lagrer tall som
binærtall (0 og 1) , og ikke de desimaltallene vi forventer:
>>> 0.1*3 # binær avrunding
0.30000000000000004
>>> round(2.5) # merk at round() ikke alltid runder opp ved 0.5
2
>>> # dette er fordi 0.5 ikke kan
>>> # representeres nøyaktig med 0 og 1
Disse småfeilene er sjeldent av stor betydning.
map
map() kjører en gitt funksjon på hvert element i ei liste,
og returnerer ei ny liste med alle resultatene
>>> mylist = [-3, -2, -1, 0, 1, 2, 3]
>>> map(abs, mylist)
<map object at 0x7fa5f3aaa748>
>>> list(map(abs, mylist)) # oversette "map object" til ei liste
[3, 2, 1, 0, 1, 2, 3]
>>> list(map(str, mylist))
['-3', '-2', '-1', '0', '1', '2', '3']
"map object" kommer vi til å snakke om senere
math
En modul med en rekke kule matte funksjoner og verdier
>>> import math
>>> math.pi
3.141592653589793
>>> math.factorial(5)
120
>>> 1*2*3*4*5
120
>>> math.factorial(int(input("Give a number: ")))
Give a number: 6
720
Google: "python math module"
for ei fin oversikt over funksjonene og verdiene i modulen
os.path
Brukes for å se på filer i filsystemet
Resten av os modulen har
mange andre kule formål
>>> import os.path
>>> filnavn = "C:/Users/Bob/min_fil.txt"
>>> os.path.dirname(filnavn)
'C:/Users/Bob'
>>> os.path.basename(filnavn)
'min_fil.txt'
>>> os.path.exists(filnavn)
True
>>> os.path.isdir(filnavn)
False
>>> os.path.isfile(filnavn)
True
datetime
>>> from datetime import date
>>> today = date.today()
>>> today.isoformat() # ISO 8601 standardformatet
'2018-08-30'
>>> my_birthday = date(today.year, 2, 20) # 20. februar
>>> if my_birthday < today:
... my_birthday = my_birthday.replace(year=today.year + 1)
...
>>> my_birthday.isoformat()
'2019-02-20'
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
174
Google vet mer
random
For å introdusere tilfeldige valg
>>> import random
>>> random.random() # tilfeldig tall mellom 0 og 1
0.14072062696326082
>>> random.random()
0.47548683533973257
>>> random.random()
0.940841472800279
>>> random.choice([1, 2, 3])
3
>>> random.choice([1, 2, 3])
2
>>> random.choice([1, 2, 3])
1
>>> random.choice([1, 2, 3])
2
Noen kule moduler
Disse trenger du ikke pugge.
Bare vit at sannsynligheten for at det du trenger
allerede finnes som en modul er stor.
Google er din venn.
csv
Brukes for å lese og skrive excel dokumenter
>>> import csv
>>> with open('eggs.csv', newline='') as csvfile:
... spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
... for row in spamreader:
... print(', '.join(row))
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam
Det finnes et "enklere" alternativ: Pandas
Pandas må lastes ned. Vi kommer til å snakke mer om Pandas på del 2 av kurset.
urllib3
Brukes for å hente og sende data til og fra nettsider
>>> import urllib3
>>> http = urllib3.PoolManager()
>>> resp = http.request('GET', 'http://www.vg.no/robots.txt')
>>> print(resp.data.decode("utf-8"))
user-agent: Googlebot-News
disallow: /annonsorinnhold/
disallow: /innstikk/
Det finnes et "enklere" alternativ: requests
requests må lastes ned, men er enklere å bruke. Google har mange fine guider.
concurrent.futures
Brukes for å kjøre funksjoner i parallel "tråder"
from concurrent.futures import ThreadPoolExecutor
import shutil # brukes til å håndtere filer
with ThreadPoolExecutor(max_workers=4) as e:
e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
e.submit(shutil.copy, 'src4.txt', 'dest4.txt')
Øvelse: Installere en modul
Ofte må vi installere python moduler vi har behov for.
En ofte brukt modul er requests:
- Bekreft først at 'import requests' feiler
- Installer requests: (med cmd eller powershell)
- Bekreft at 'import requests' fungerer
Denne prosessen kan variere fra platform til platform
Workshop del 2
Morgendagens kurs kommer til å gå igjennom tre viktige biblioteker for databehandling i stor detalj:
- Numpy
- Pandas
- Matplotlib
Lage egne funksjoner
Ikke alt er innebygd i Python. Du kan lage egne
funksjoner og redusere mengden koden du må skrive
def input_int(prompt): # prompt er input argument
return int(input(prompt))
#return brukes for å returnere en verdi
print(input_int("Gi et nummer: ") * 2)
Gi et nummer: 5
10
Funksjonsparametre
Funksjoner kan ta inn et vilkårlig antall parametre/argumenter inn:
def min_kule_funksjon(arg1, arg2, arg3):
print("Jeg fikk", arg1, arg2, "og", arg3, "inn!")
min_kule_funksjon(1, 2, 3)
min_kule_funksjon("hei", "på", "deg")
Jeg fikk 1 2 og 3 inn!
Jeg fikk hei på og deg inn!
Returverdi
Funksjoner kan returnere en verdi
def tail(liste):
return liste[1:]
#summerer alle tallene i liste med unntak av første element:
mylist = [4, 4, 3, 3]
print(sum(tail(mylist))) # skriver ut tallet 10
Øvelse: is_odd
Lag en funksjon som bestemmer om
et tall er odde eller ikke
Utgangspunkt:
def is_odd(number):
pass
print("5 is odd:", is_odd(5)) # Skal skrive False
print("6 is odd:", is_odd(6)) # Skal skrive True
print("7 is odd:", is_odd(7)) # Skal skrive False
None
None er en spesiell verdi. Funksjoner som ikke returnerer en verdi vil returnere None
>>> def i_do_nothing():
... pass # python krever kode i hver blokk. Pass gjør ingenting
...
>>> i_do_nothing()
>>> foo = i_do_nothing()
>>> print(foo)
None
>>> None # Det interaktive skallet skuler None
>>> 1 # andre verdier skrives ut
1
Unpacking
Lister og tupler kan "pakkes ut" til variabler
>>> a, b, c = (1, 2, 3)
>>> a
1
>>> b
2
>>> c
3
>>> 1, 2, 3 # python velger tuple hvis ingen parenteser presiseres
(1, 2, 3)
>>> a, b, c = "hei", "på", "deg"
Returnere flere verdier
Vi kan utnytte "unpacking" til å returnere flere verdier
def my_function(value):
return value*2, value/2
a, b = my_function(4)
print(a) # Skriver ut 8
print(b) # Skriver ut 2.0
Standardparametre
Noen parametre kan ha et standardvalg satt.
Disse kalles også "named parameters"
def min_kule_funksjon(arg1, arg2, foo=1, bar=2):
print(arg1, arg2, foo, bar)
min_kule_funksjon(1, 2) # skriver ut: 1 2 1 2
min_kule_funksjon(1, 2, 3) # skriver ut: 1 2 3 2
min_kule_funksjon(1, 2, 3, 4) # skriver ut: 1 2 3 4
min_kule_funksjon(1, 2, bar=4) # skriver ut: 1 2 1 4
Øvelse: bytte verdier
Gitt to variabler, bytt verdiene på de
Utgangspunkt:
a = 1
b = 2
# din kode her
print(a, b) # dette skal skrive ut 2 1
a, b = b, a
temp = a
a = b
b = temp
Dokumentasjon på nett
- Hard documentation
- Soft Documentation
- Video tutorials
- Talks
Det finnes mye annet også
Strengehåndtering
Det finnes mange funksjoner for å
behandle strenger i Python
>>> min_hilsen = "Hei " + "på " + "deg!"
>>> min_hilsen
'Hei på deg!'
>>> min_hilsen.lower() # oversetter bokstavene til små bokstaver
'hei på deg!'
>>> min_hilsen.upper() # oversetter bokstavene til store bokstaver
'HEI PÅ DEG!'
>>> "petter".capitalize()
'Petter'
Indeksering
>>> min_hilsen = "Hei " + "på " + "deg!"
>>> min_hilsen
'Hei på deg!'
>>> min_hilsen[0] # indeksering
'H'
>>> min_hilsen[1]
'e'
>>> min_hilsen[2]
'i'
Slicing
>>> min_hilsen = "Hei " + "på " + "deg!"
>>> min_hilsen
'Hei på deg!'
>>> min_hilsen[:5] # Implisitt fra starten
'Hei p'
>>> min_hilsen[5:] # implisitt til slutten
'å deg!'
>>> min_hilsen[2:6] # eksplisitt start og slutt
'i på'
Slicing fungerer på samme måte for elementene i lister
Splitt og join
>>> min_hilsen = "Hei " + "på " + "deg!"
>>> min_hilsen
'Hei på deg!'
>>> min_hilsen.split() # "split" deler strengen opp i ei liste av ord
['Hei', 'på', 'deg!']
>>> min_hilsen.split()[:-1]
['Hei', 'på']
>>> "".join(["a", "b", "c"]) # "join" samler ei liste av strenger
'abc'
>>> " test ".join(["a", "b", "c"]) # separatoren kan bestemmes
'a test b test c'
>>> "#".join(min_hilsen.split())
'Hei#på#deg!'
split er ofte brukt til å tolke strenger.
join er nyttig for å konstruere strenger fra elementer.
Øvelse: Sortere ord
Skriv et program som tar inn ei setning fra brukeren
og som skriver ut ordene i sortert rekkefølge.
sentence = input("Input a sentence: ")
words = sentence.split()
words = sorted(words)
output = " ".join(words)
print(output)
replace
Bytter ut alle instanser av en søkestreng med
en annen annen strenge, og returnerer en ny kopi.
>>> min_strenge = "Hei på deg!"
>>> min_strenge.replace("Hei", "halla")
'halla på deg!'
>>> min_strenge.replace("å", "aa")
'Hei paa deg!'
>>> min_strenge.replace("Hei", "Hei'du").replace("deg", "deg'du")
"Hei'du på deg'du!"
>>> min_strenge # merk den originale er ikke endret.
'Hei på deg!'
Format strings
Python har en rekke forskjellige måter å
formatere strenger på. De fleste bruker
"format" eller f-strenger:
>>> str(1) + " og " + str(2) # manuelt og tungvindt
'1 og 2'
>>> "{} og {}".format(1, 2) # positional
'1 og 2'
>>> "{a} og {b}".format(b=2, a=1) # named
'1 og 2'
>>> a = 1
>>> b = 2
>>> "{a} og {b}".format(**locals()) # named from local namespace
'1 og 2'
>>> f"{a} og {b}" # shorthand, called f-strings
'1 og 2'
>>> f"{a} og {b+3}" # which supports expressions
'1 og 5'
Spesialtegn i strenger
Python og de fleste andre språk støtter
"escape" koder for å spesifisere spesielle tegn i strenger.
I python bruker vi "backslash" for escape koder.
>>> print("hei\npå\ndeg!") # \n betyr newline
hei
på
deg!
>>> print("Dette er et hjerte: \u2764") # alle unicode tegn er støttet
Dette er et hjerte: ❤
>>> print("For å skrive en backslash \\")
For å skrive en backslash \
>>> print("For å skrive en fnutt: \" ")
For å skrive en fnutt: "
\ er ikke /
Guider på google
Vi kan ikke lære alle funksjonene på en dag.
Let rundt på Google etterhvert som behovene
dukker opp, og lær etter behov!
Løkker
if og else er kult, men ikke spesielt kraftig.
Med løkker kan vi kjøre ei blokk
med kode gjentatte ganger!
>>> for i in [1, 2, 3]:
... print("Element", i)
...
Element 1
Element 2
Element 3
for
"for" løkken itererer gjennom en liste og kjører
blokken med kode for hvert element i lista.
"for each item in x, do the following"
>>> for i in [1, 2, 3]:
... print("The double of", i, "is", i*2)
...
The double of 1 is 2
The double of 2 is 4
The double of 3 is 6
Øvelse:
Fordobbling av input
Ta inn ei liste av mellomromm-separerte tall og
skriv ut hvert tall fordobblet.
Eksempelkjøring:
numbers = input("Skriv inn liste av tall: ")
for number in numbers.split():
print(int(number) * 2)
Skriv inn liste av tall: 1 2 3
2
4
6
while
blokken under while vil fortsette å kjøre
så lenge utrykket i while er sant.
"do that while this is true"
>>> value = 2
>>> while value < 10000:
... value = value*2
...
>>> value
16384
Øvelse: Meny
Lag en meny som gir brukeren valg mellom noen funksjoner og muligheten til å avslutte programmet.
Menyen skal "gjenta" seg frem til brukeren avslutter.
Eksempelkjøring:
Velg enten foo, bar eller stop
Valg: foo
Dette er foo
Velg enten foo, bar eller stop
Valg: bar
Dette er bar
Velg enten foo, bar eller stop
Valg: foo
Dette er foo
Velg enten foo, bar eller stop
Valg: stop
Avslutter...
Øvelse: Meny
def foo():
print("Dette er foo")
def bar():
print("Dette er bar")
stop = False
while not stop:
print("Velg enten foo, bar eller stop")
valg = input("Valg: ")
if valg == "foo":
foo()
elif valg == "bar":
bar()
elif valg == "stop":
stop = True
else:
print("Jeg forstår ikke")
print() # tom linje
print("Avslutter...")
Uendelige løkker
while kan kjøre uendelig, er du uheldig
>>> while True:
... print("This is not a good idea")
...
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
This is not a good idea
Hvis dette skjer kan du som regel stoppe programmet ved å trykke CTRL+C,
eller lukke vinduet, eller via CTRL+ALT+DELETE
er du uheldig
range
range er en funksjon som lager ei liste med tall i serie
Merk: nullindeksering
>>> range(10)
range(0, 10)
>>> list(range(10)) # oversette til liste for lestbarhet
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for i in range(10):
... print("Verdien av i er", i)
...
Verdien av i er 0
Verdien av i er 1
Verdien av i er 2
Verdien av i er 3
Verdien av i er 4
Verdien av i er 5
Verdien av i er 6
Verdien av i er 7
Verdien av i er 8
Verdien av i er 9
range(start, stop, step)
range støtter flere argumenter, som er med
på å bestemme hvordan den skal lage lista
>>> list(range(3, 7))
[3, 4, 5, 6]
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(2, 10))
[2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(2, 10, 3))
[2, 5, 8]
>>> list(range(10, 0, -1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Øvelse: Sum av kvadrater
Skriv et program som beregner summen av
alle kvadrattall fra 1² til 15²
summen av 1 + 4 + 9 + 16 + ... + 225
sum = 0
for n in range(1, 16):
sum += n * n
print(sum) # skriver ut 1240
numbers = []
for i in range(1, 16):
numbers.append(i * i)
print(sum(numbers))
Iterable
Ikke bare tupler og lister har elementer i seg.
Det er mange typer og objekter som
inneholder flertall elementer.
Hvis typen er "iterable", kan du iterere
over elementene med en for løkke:
>>> val = range(3)
>>> val
range(0, 3)
>>> type(val) # verdien er av typen "range"
"<class 'range'>"
>>> for i in val: print(i)
...
0
1
2
Iterable til liste
list() vil hente alle elementene fra en iterable
og konstruere ei liste fra den.
Det samme gjelder tuple()
>>> val = range(3)
>>> val
range(0, 3)
>>> list(val)
[0, 1, 2]
>>> tuple(val)
(0, 1, 2)
Generatorer
Generatorer er en type iterable, som beregner
den neste verdien i det øyeblikket Python spør om den.
range() er en generator. Den lager ikke hele lista, med elementer, den lager bare et element av gangen.
Dette tillater:
# Ei liste med alle disse elementene ville brukt mer minne
# enn datamaskinen har tilgjengelig
for i in range(9999999999999999999999999999999999999999):
print(i)
Manuell iterering
Vi kan iterere manuelt med iter() og next()
Dette viser jeg frem bare for forståelsen
>>> iterable = range(3)
>>> iterator = iter(iterable)
>>> next(iterator)
0
>>> next(iterator)
1
>>> next(iterator)
2
>>> next(iterator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Iterering takeaway:
- Vi vet ikke antall elementer det er i den iterable.
- Elementene kan bli generert fortløpende
>>> mylist = [1, 2, 3]
>>> for i in mylist:
... mylist.append(i)
... print(i)
...
1
2
3
1
2
3
1
2
3
1
Listeutrykk
Mange vil påstå att den største
styrken til python er listeutrykk.
Listeutrykk produserer en generator.
Denne generatoren kan vi lage ei liste av
>>> exp = (i * 2 for i in range(5))
>>> exp # exp er en generator
<generator object <genexpr> at 0x7fb6ae445f48>
>>> list(exp)
[0, 2, 4, 6, 8]
>>> (i * 2 for i in range(5)) # generatoren
<generator object <genexpr> at 0x7fd66f3dff48>
>>> [i * 2 for i in range(5)] # rett til liste
[0, 2, 4, 6, 8]
Listeutrykk syntax
Listeutrykkene
>>> out = []
>>> for x in range(5):
... for y in range(5):
... if x > y:
... out.append( x + y )
...
>>> out2 = [x+y for x in range(5) for y in range(5) if x>y]
>>>
>>> out == out2
True
Øvelse: filter
Lag et program som filtrerer bort
de tallene i ei liste som er større en 10
ved hjelp av listeutrykk
Utgangspunkt:
mylist = list(range(20))
print(list(...))
mylist = list(range(20))
print(list(i for i in mylist if i <= 10))
Øvelse: Sum av kvadrater
Skriv et program som beregner summen av
alle kvadrattall fra 1² til 15²
(dvs: summen av 1 + 4 + 9 + 16 + ... + 225)
ved hjelp av listeutrykk.
>>> sum(i*i for i in range(1, 16))
1240
Inline if
Av og til er if og else blokker litt for mye å skrive.
De kan gjøres inline:
>>> for i in (-1, 2, 6, -7):
... print(i, "er", "positiv" if i>=0 else "negativ")
...
-1 er negativ
2 er positiv
6 er positiv
-7 er negativ
Listeutrykk vs map
To måter å gjøre samme jobben:
De fleste som liker Python synes
listeutrykk er enklere å forstå.
Map kan gi høyere ytelse
>>> mylist = [1, 2, 3, 4, 5]
>>> def double(x):
... return x * 2
...
>>> [double(i) for i in mylist]
[2, 4, 6, 8, 10]
>>> list(map(double, mylist))
[2, 4, 6, 8, 10]
Øvelse: Fibonacci
Skriv et program som beregner alle fibonaccitallene:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55....
a, b = 0, 1
while True:
print(a)
a, b = b, a+b
Øvelse: Fizzbuzz
Lag et program som skriver ut tallene fra 1 til 100,
men alle tall som er delbar på 3 erstattes med "fizz",
og tall delbar på 5 erstattes med "buzz".
Hvis delbar på begge: "fizzbuzz"
>>> for i in (1, 2, 3, 4, 5, 6, 7):
... print(i, "% 3 ==", i%3)
...
1 % 3 == 1
2 % 3 == 2
3 % 3 == 0
4 % 3 == 1
5 % 3 == 2
6 % 3 == 0
7 % 3 == 1
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
Eksempel
output
Nyttig forkunnskap
Øvelse: Fizzbuzz
for i in range(1, 101):
if i % 15 == 0:
print("fizzbuzz")
elif i % 3 == 0:
print("fizz")
elif i % 5 == 0:
print("buzz")
else:
print(i)
print("\n".join(
"fizzbuzz" if i%15==0 else
"fizz" if i%3==0 else
"buzz" if i%5==0 else
str(i)
for i in range(1,101)))
print(*("fizz"*(i%3==0) + "buzz"*(i%5==0) or i
for i in range(1,101)), sep="\n")
Øvelse: Palindrom
Et palindrom er det samme om man leser fra
høyre eller fra venstre. Det største palindromet
laget av produktet av to tosifrede heltall er:
9009 = 91 x 99
Lag et program som finner det største palindromet
som er et produkt av to tresifrede tall.
Øvelse: Palindrom
biggest = 0
for x in range(1, 1000):
for y in range(1, 1000):
if str(x*y) == str(x*y)[::-1]:
if x*y > biggest:
biggest = x*y
print(biggest)
all_products = (x*y for x in range(1, 1000) for y in range(1, 1000))
def is_palindrome(num):
return str(num) == str(num)[::-1]
print(max(i for i in all_products if is_palindrome(i)))
#skriver ut 906609
Lese filer
Python kan lese fra og skrive til filer.
Å lese filer kan være nyttig for databehandling.
handle = open("myfile.txt", "r") # åpne i "read" modus
data = handle.read()
handle.close() # lukke filhåndtaket
# "data" er en strenge som inneholder hele filen
print(data)
Linje for linje
Vi kan lese fila linje for linje:
# "with" kjører file.close() for oss når vi er ferdig
with open("myfile.txt", "r") as file:
for line in file:
print(line)
Dette er grunnen til å huske å lukke filer.
Bruk "with"!
Skrive til fil
Python kan skrive data til filer.
result = []
for i in range(10):
result.append( i * 2 )
with open("output_file.txt", "w") as file:
for i in result:
file.write(str(i)) # krever at data er en strenge
file.write("\n") # husk linjeskift!
Feilmeldinger
Feilmeldinger
Enkelte handlinger i Python er ugyldige.
Disse vil oftest resultere i en
feilmelding som stopper programmet
>>> 5 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> foo = 3
>>> foo
3
>>> fooo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'fooo' is not defined
Disse kalles "Exceptions"
Traceback
Når en Exception intreffer vil Feilmeldingen
fortelle deg hva som gikk feil og hvor feilen skjedde
Traceback (most recent call last):
File "hei.py", line 7, in <module>
print(foo(99))
File "hei.py", line 2, in foo
return bar(my_number * 2 + 3)
File "hei.py", line 5, in bar
return my_number / 0
ZeroDivisionError: division by zero
# hei.py
def foo(my_number):
return bar(my_number * 2 + 3)
def bar(my_number):
return my_number / 0
print(foo(99))
Traceback
Kode
"Programmet krasjer"
Når en Exception blir hevet, stanser programmet
1
2
Traceback (most recent call last):
File "hei.py", line 4, in <module>
1 / 0
ZeroDivisionError: division by zero
# hei.py
print(1)
print(2)
1 / 0
print(3)
print(4)
Konsoll
Kode
Feilhåndtering
For å forhindre programstans kan vi "fange" Exceptions.
Til dette har vi "try" og "except" nøkkelordene:
def dangerous_function(input):
a = input + 3
b = input - 3
return a / b
try:
print(dangerous_function(1))
print(dangerous_function(2))
print(dangerous_function(3))
print(dangerous_function(4))
except ZeroDivisionError:
print("Someone divided by zero")
print("Still running!")
-2.0
-5.0
Someone divided by zero!
Still running!
Konsoll
Kode
Ikke gjem feil
Det er fristende å "gjemme" feil, men dette gjør
det vanskelig å "debugge" koden: å fikse feil.
Dette vil forhindre tracebacks, og
oppmuntrer ustabil kode.
Ikke gjem feilen, håndter den!
try:
my_dangerous_function()
except:
pass # ignore it
# todo: fix this later
print("Everything is fine") # it isn't
Fange enkelte feil
En try-except trenger ikke håndtere alle feil.
De burde kun håndtere de feilene som er forventet.
value = None
while value == None:
try:
value = int(input("Enter a number: "))
except ValueError: # int() hever denne feilen
print("Not a valid number!")
# Denne blokkerer ikke MemoryError f.eks,
# som heves når maskinen er tom for RAM
print("The double is:", value*2)
None
Unngå å returner None når funksjonen din feiler.
Da må de som bruker funksjonen huske å sjekke mot dette.
Det er bedre å heve en exception
s.ntnu.no/py18
Se under Ressurser
Practice Python
Beginner Python Excercises
eller
Kodetips:
Du leser kode oftere enn du skriver kode.
Hold koden ryddig og forstålig.
Skriv kommentarer!
Bruk fornuftige variabel- og funksjonsnavn.
Prøv å kjør dette:
>>> import this
Python
By pbsds
Python
- 721