Python Workshop

av Peder Bergebakken Sundt

Programvareverkstedets

s.ntnu.no/spy20

A-genda

  • Installere Python
  • IDLE
  • Litt om programering
  • Litt om språket      
  • Top-down - & Bottom up
  • 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 egne moduler
  • Argumentlister
  • God humor                     

Installere Python

Det finnes mange implementasjoner og versjoner av python standarden. Vi bruker her 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 

Mye av industrien bruker fremdeles Python 2

selv om Python 3 er her og har tatt over.

Vi skal her bruke Python 3.

 

Støtte for Python 2  gikk ut i starten av 2020.

Dette ble kunngjort i 2008.

 

Hvis noen her bruker Python 2 kan jeg peke ut forskjellene

IDLE

 

IDLE er en enkel teksteditor for

å redigere Pythons .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

live-demo

 

Andre teksteditorer

  • Det finnes mange editorer man programere med
  • Dette kurset tilpasset jeg for IDLE, fordi
    et er raskt å sette opp sammen med Python
  • Hvis du bruker/er kjent med en annen editor fra før,
    kan du gjerne bruke den under kurset!
     
  • IDLE er ikke en veldig god brukeropplevelse i lengden.
  • Jeg anbefaler derfor at du prøver andre editorer etter kurset.
    • Jeg har lenket noen guider på nettsiden.
    • Min anbefaling er teksteditoren: VSCode

Litt om programmering

 

Datamaskinen

En halv-kompleks kalkulator som utfører de

regne- og logikkoperasjonene vi ber den om.

Dette kaller vi for instruksjoner

Programmer

 

Programmer er ei liste av instruksjoner vi vil

datamaskinen skal utføre.

 

Programmer kan sammenlignes med kokeoppskrifter:
en rekke emd instruksjoner

for kokken å utføre

Programmeringsspråk

Et formelt definert språk for å formidle

instruksjoner på en måte som

både mennesker og datamaskinen forstår.

Datamaskiner er dumme

Datamaskinen gjør akkurat det du

ber den om å gjøre.

Hvis den gjør feil, er det 99% av tiden feil i din kode.

 

Den siste prosenten er feil i noen andre sin kode.

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. 

 

 

Bruksområder

 

Python er brukt mange steder i industrien:

  • Automatisering
  • Maskinlæring
  • Dataanalyse
  • Data visualisering
  • Webutvikling
  • Mye mer!

Eksempler:

Visualisering av geodata

 

Dataanalyse i Jupyter med Scipy

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')

Generering av kart

Python er kjent for hvor mye du får til med lite kode

Webutvikling

Dette er et REST API illustrert med swagger

Python som språk

Python er et språk som tolkes

av maskinen under runtime.

 

Det har dynamiske typer:

språket ikke er veldig strengt

 

Dette gjør at du slipper å ta hensyn til

mange smådetaljer som Python bare håndterer for deg

 

Python miljøet oppmuntrer også

en ren og oversiktlig  kodestil

  • Vi starter med en del kodeeksempler for å få en oversikt av språket
  • Deretter jobber vi oss opp fra grunnen

Top-Down og

Bottom-Up

  • Python kjører filer med .py filtypen
  • Denne .py fila kan lages med hvilken som helst simple teksteditor
    • notepad vil fungere. Alt som lar deg formatere teksten er ikke simpel.
    • Word fungerer desverre ikke
  • Vi skriver da programmene våre i .py filer

Kjøring av kode

Et kode eksempel

Her finner vi ut hvilket av to tall som er størst

 

 

 

 

 

 

 

Kansje ikke veldig intuitivt som en start...

a = 5
b = 6

if a > b:
    resultat = a
else:
    resultat = b

print("Maximum av", a, "og", b, "er", resultat)

Et kode eksempel

Vi kan legge til kommentarer!

# vi skal finne maksimum av disse to tallene:
# a og b er verdier vi lagrer
a = 5
b = 6

if a > b: # Hvis a er større enn b, sett resultatet til a
    resultat = a
else:     # Hvis ikke, sett resultat til b
    resultat = b

# print() er en funksjon som skriver tekst ut til brukeren
print("Maximum av", a, "og", b, "er", resultat)

Kommentarer er deler av

koden som blir ignorert. 

Kontrolflyt graf

(CFG)

a = 5
b = 6

if a > b:
    resultat = a
else:
    resultat = b

print(resultat)

Løkker og CGF

Løkker lar deg kjøre en blokk med kode flere ganger

min_liste = [] # tom list

for i in range(1, 5): #løkke
    print("i =", i)
    min_liste += [i*2, i*3]
    print(min_liste)

print("ferdig")

Kjøring med debugger

Mange kodeeditorer støtter å kjøre

programmet ditt med en debugger

 

Jeg skal nå bruke en debugger som heter PuDB

for å visualisere kodeflyten i de forrige eksemplene.

 

# Denne funksjonen pauser kodekjøringen
# og gir deg en debugger
breakpoint()

Takeaway:

 

  • Programmer kjøres fra toppen til
    bunnen, én linje av gangen
  • De fleste programmer består av:
    • Lagring av verdier ( = )
    • Sammenlikning av verdier ( > )
    • Kodeflyt ( if, else og løkker )
    • Sideeffekter ( print )

Bottom-Up

 

Herfra starter vi med det mest

grunnlegende av det grunnlegende,

for så å jobbe oss opp i kompleksitet.

 

Prøv gjerne mens du følger med

i et interaktivt skall!

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 med = tegnet.

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 derimot kommentarer i rødt
a = 1 # kommentarer går til slutten av linja
# a = 2 # denne linja kjøres ikke
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))

Innrykk skrives med TAB tasten!

Du kan også bruke 4 mellomrom

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
>>> ... # kjør uttrykket ditt!
False
>>> a = 5# endre a til en ny verdi
>>> ... # kjør uttrykket ditt igjen
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

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:

  1. Bekreft først at 'import requests' feiler
  2. Installer requests:    (med cmd eller powershell)





     
  3. 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() # setter første bokstav i hvert ord til uppercase
'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 posisjon
'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 # Bemerk at originale strengen er ikke endret på.
'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()) # Lokale variable
'1 og 2'
>>> f"{a} og {b}" # Snarvei, kalles f-strings
'1 og 2'
>>> f"{a} og {b+3}" # f-string støtter utrykk
'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

den samme blokken med kode for hvert element i lista.

 

 

 

 

 

"for each item(i) 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 strenge 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 this while condition 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 har 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 brukes ikke i praksis,
jeg viser det frem bare for forståelse

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

>>> gen = (i * 2 for i in range(5))
>>> gen # exp er en generator
<generator object <genexpr> at 0x7fb6ae445f48>
>>> list(gen)
[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
fib\left(0\right)=0 \newline fib\left(1\right)=1 \newline fib\left(n\right)=fib\left(n-1\right)+fib\left(n-2\right)

Ø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 typene feil som du forventer!

value = None
while value == None:
    try:
        value = int(input("Enter a number: "))
    except ValueError: # int() hever denne feiltypen
        print("Not a valid number!")
        # Denne fanger ikke f.eks.  MemoryError,
        # som heves når maskinen er tom for RAM

print("The double is:", value*2)

None

Unngå å returnere None når funksjonen din feiler.

Da må de som bruker funksjonen huske å sjekke mot dette.

Det er bedre å heve en Exception de enklere kan håndtere.

Takk for meg

 

s.ntnu.no/spy20

Se under Ressurser ;)

 

Practice Python

Beginner Python Excercises

eller

Kodetips:

Du leser kode oftere enn du skriver kode.

  • Hold derfor koden ryddig og forståelig!
  • Skriv kommentarer ofte!
  • Bruk fornuftige variabel- og funksjonsnavn!

 

Prøv å kjør dette:

>>> import this