Föreläsningsöversikt Fö 1.2¶
- Programmering i Python
Föreläsningsöversikt Fö 1.2¶
- Programmering i Python
- Python som miniräknare
- Värden och datatyper
- Variabler
- Strängar och listor
- Funktioner
- Mer om strängar och listor
Scream if you want to go faster¶
Fallskärm: Korta videos om Python¶
- Inspelade av Jody Foo, som också utformat den här kursen
- https://web.microsoftstream.com/channel/5bf65e11-e261-45aa-ab27-0ec34e2b10e4
- (mindre kort kort URL)
Sats (eng. statement)¶
- Pythontolken är ett program, som vilket annat program som helst. Programmet läser Pythonkod, tecken för tecken, rad för rad, och utför de instruktioner som står i Pythonkoden.
- Varje sådan instruktion kallas för en sats.
- Satser kan vara enkla eller sammansatta och gemensamt uttrycker de ett program, som Pythontolken utför.
- I de enklaste fallen; ett program ungefär som en miniräknare.
Python som miniräknare¶
- De mest grundläggande operationerna i nästan alla programmeringsspråk är de aritmetiska operationerna.
- De fyra räknesätten är representerade som binära operatorer:
+
,-
,*
,/
In [24]:
1-1
Out[24]:
0
Värden och literaler¶
- När vi själva beräknar $1+1$ så vet vi att det är det numeriska värdet 1 som skall adderas till det numeriska värdet 1 och resultatet blir det numeriska värdet 2.
- För datorn är dock
1+1
bara en serie tecken. 1
är inget värde i sig det är bara hur vi signalerar till Python att det numeriska värdet 1 skall användas.- Den här typen av representationer kallas för literaler (eng. literals).
- De är den "bokstavliga" beskrivningen av ett värde.
Datatyper¶
- Alla värden in Python har en datatyp, och datatypen hos ett värde kan inte ändras.
- (Python är strikt typat.)
- Ett värdes datatyp avgör vad vi kan göra med värdet och vad som händer när vi använder det i olika sammanhang.
- En literal representerar alltså ett specifikt värde, som har en specifik datatyp.
- Vi kommer lära oss att känna igen typen av olika literaler under de första labbarna, de vi sett hittills är
int
— Heltal (eng. integer)float
— Flyttal (eng. floating point number), det vanligaste sättet att representera decimaltal digitalt. (Ni kommer höra mycket mer om detta i TANA21/22 Beräkningsmatematik, tills dess kan ni tänka "decimaltal och ofta lite, lite fel")
Sidospår: Objekt och klasser¶
Ibland kommer ni höra objekt istället för värde eller klass istället för datatyp.
Vi kommer återvända till klasser och objekt längre fram i kursen men för tillfället kan vi betrakta dessa som synonymer till datatyp och värde.
Uttryck (eng. expression)¶
- Vad vi såg i miniräknarexemplen var ett antal enkla matematiska uttryck.
- Passande nog kallar vi dessa satser för uttryck även inom programmering.
- Mer generellt: Ett uttryck är en sats som kan evalueras (beräknas) till ett värde.
- (Dvs. alla uttryck är satser, men inte alla satser är uttryck.)
- Värdet av ett uttryck behöver inte vara numeriskt, men mer om det senare.
Flyttal och heltal?¶
- Pythontolken kommer automatiskt se till att resultatet av att evaluera ett uttryck har rätt datatyp under vissa omständigheter.
- Ofta är det givet: Antag att $x, y \in \mathbb{Z}$, vi vet att
- $x+y \in \mathbb{Z}$
- $x-y \in \mathbb{Z}$
- $x \cdot y \in \mathbb{Z}$
- men vad gäller för $x/y$?
- Eftersom vi inte vet om kvoten mellan $x$ och $y$ är ett heltal kommer Pythontolken ta det säkra före det osäkra och värdet av en division är alltid ett flyttal.
- Detta kallas mer generellt för typinferens.
In [ ]:
2/1
Fler aritmetiska operatorer?¶
- Potensoperatorn:
**
- (Ett vanligt misstag är att använda hatt-operatorn
^
som har helt annan betydelse i Python - bitwise XOR för den som kan sin digitalteknik.)
- (Ett vanligt misstag är att använda hatt-operatorn
- Golvdivision, division avrundat nedåt (eng. floor division):
//
- (Kallas ofta felaktigt för heltalsdivision då det är ekvivalent med heltalsdivision för positiva heltal, men inte för negativa. Felaktigt beskriven i Skansholm.)
- Modulo, eller "restdivision":
%
- Ekvivalent med resten vid en golvdivision.
Sidospår: Varför golvdivision och inte heltalsdivision?¶
- Golvdivision och Modulo hänger ihop: Givet att $a, b, q, r \in \mathbb{Z}^+$ så gäller att
- För att samma förhållande skall gälla när $a \in \mathbb{Z}^-$, dvs när $a \leq 0$, finns två alternativ:
- Trunkera $q$ (avrunda $q$ mot $0$, detta är vad Skansholm säger att
//
gör). Då blir $r$ negativ och olikheten $0 \leq |r| \lt b $. - Avrunda $q$ mot negativa oändligheten, $\lfloor q \rfloor$. Då fortsätter $r$ att vara positiv och olikheten är oförändrad.
- Trunkera $q$ (avrunda $q$ mot $0$, detta är vad Skansholm säger att
- Donald Knuth m.fl. har argumenterat för att alternativ 2 leder till färre misstag (ett sådant misstag beskrivs på Wikipedia-artikeln för modulo-operationen) och Guido är uppenbarligen på Knuth's sida.
- Detta är ett av de stora tvisteämnena bland folk som skapar programmeringsspråk och därför skiljer det mellan olika språk.
In [ ]:
answer = 42
answer+1
Tilldelning, inte likhet¶
=-tecknet orsakar ofta förvirring för den som är van vid matematik.
- I Python betyder
=-tecknet tilldelning.
answer = 42
- Utläses som tilldela variabeln answer värdet 42
- Mer generellt tilldela variabeln till vänster om
= värdet av uttrycket till höger om
=
Variabel som en låda
-
answer = 42
- Vi kan tänka oss att en variabel är en låda.
- När vi gör tilldelningen ovan händer följande:
- Pythontolken skapar en låda och skriver namnet
answer
på framsidan, - och stoppar sedan värdet
42
i lådan så att vi kan använda det igen.
- Pythontolken skapar en låda och skriver namnet
Ordningen spelar roll¶
- Vi kan inte vända på en tilldelning som vi kan göra med en matematisk likhet:
In [33]:
answer = answer + 42
hej = hej + 1
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[33], line 3 1 answer = answer + 42 ----> 3 hej = hej + 1 NameError: name 'hej' is not defined
In [34]:
print(answer = answer+1)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[34], line 1 ----> 1 print(answer = answer+1) TypeError: 'answer' is an invalid keyword argument for print()
In [26]:
42 = answer
Cell In[26], line 1 42 = answer ^ SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?
Tilldelning är en sats¶
- Tilldelningsoperationen kan inte evalueras till värde i sig.
- Tilldelning är alltså inte ett uttryck.
- Repetition: Alla uttryck är satser, men inte alla satser är uttryck — tilldelning är en sådan sats.
En variabel är verkligen variabel¶
- Det är tillåtet att när som helst ändra värdet av en variabel i Python.
In [37]:
answer = 1.3
In [ ]:
answer = 42
answer / 2
Bara aritmetik?¶
- Vadå "bara"?
- Bra sätt att börja för den med mattevana.
- Programmering är egentligen mycket mer, speciellt när vi börjar tala om värden som inte är atomära.
Strängar, datatypen str
¶
- Eng. string, från "to string something together"; "a string of beads" → "a string of characters"
- Representerar text och strängliteraler skrivs med citationstecken (enkla
'
eller dubbla"
, så länge man är konsekvent)."abcd"
,'efgh'
- Man bör inte blanda citationstecken i samma fil, men...
- Examinatorn har personligen den fula ovanan att använda
'
för strängar med bara ett tecken, och"
för längre strängar.
- Examinatorn har personligen den fula ovanan att använda
- Python har inte en separat datatyp för tecken,
"a"
är identiskt med'a'
och båda är strängar. - Strängar och heltal är dock helt olika saker, alltså är strängen
'42'
inte samma sak som heltalet42
.
Vilka uttryck kan vi bygga med strängar?¶
+
— utför konkatenering av strängar- Testa andra operatorer, vad händer med
-
,*
och/
?
Listor, datatypen list
¶
- En ordnad samling av objekt.
- Jmf. med kataloger från när vi pratade katalogstrukturer.
- Kan innehålla vilken annan typ av objekt som helst och vi kan blanda fritt i samma lista.
- Listliteraler skrivs med hakparenteser, en tom lista:
[]
- En lista med heltalen
1
,2
och strängen'a'
:[1, 2, 'a']
Funktion¶
- En funktion i Python är en namngiven samling med satser.
- Mer generellt än de operatorer vi sett hittills.
- Kan ta allt från inga till obegränsat många argument, på samma sätt som kommandon i skalet.
- Används till alla möjliga saker, och vi skapar våra egna funktioner för att bygga nya abstraktioner.
Funktionsanrop¶
- En typ av uttryck, då de kan evalueras till någon form av värde.
- Jmf. $f(x)=x^2$, att evaluera $f(a)$ är att beräkna värdet av funktionen i punkten $a$.
- Funktionen
len
tar ett objekt som kan sägas ha en längd, t.ex. en sträng eller en lista, och returnerar den längden. - Vi anropar en funktion genom att skriva dess namn följt av parenteser. Mellan parenteserna skriver vi eventuella argument till funktionen.
- Dvs. när funktionsanropet
len(s)
evalueras så kommer resultatet vara längden av strängens
.
In [48]:
the_length = print('hej')
print(the_length)
hej None
Några viktiga inbyggda funktioner¶
str
— omvandlar ett objekt till en strängint
— omvandlar ett objekt till ett heltalround
— avrundar ett talabs
— ger beloppet av ett talmin
— ger det minsta värdet av två talmax
— ger det största värdet av två talsum
— ger summan av en samling
In [50]:
print(str(42) + "42")
4242
Definiera nya funktioner¶
def
och return
¶
- Antag att vi vill definiera en funktion som kan beräkna arean av en triangel.
- För att göra detta använder vi den särskilda
def
-satsen.
In [52]:
def triangle_area(height, width):
area = (height*width)/2
return area
triangle_area(3, 7)
Out[52]:
10.5
- Nu blev det mycket på en gång...
Anatomilektion¶
Vårt exempel¶
Funktionsdefinition¶
Funktionsdefinition - header¶
Funktionskropp¶
Funktionsanrop¶
Retursats¶
Mer om strängar¶
Osynliga tecken¶
- Vissa tecken är "osynliga", t.ex. tab och radbrytningar
- För att skriva dem används följande teckenkombinationer
- tabtecken:
"\t"
- radbrytning:
"\n"
- tabtecken:
Varje tecken i en sträng har ett index¶
- Index är heltal.
- Numreringen börjar på 0
- Tänk att vi börjar på "nollte" position och läser ett tecken framåt för att få ut första tecknet, osv.
- Strängen
"hejsan"
:
h |
e |
j |
s |
a |
n |
---|---|---|---|---|---|
0 |
1 |
2 |
3 |
4 |
5 |
Åtkomst av tecken på en viss position i en sträng¶
- Vi kan använda följande notation för att komma åt ett tecken på en viss position i en sträng
my_string[index]
my_string[0]
är det första tecknet i variabeln my_string.- Negativa index kan användas för att titta "bakifrån"
my_string[-1]
ger det sista tecknet i variabelnmy_string
Längden på en sträng¶
- För att ta reda på hur många tecken en sträng innehåller kan funktionen
len()
användas. - Exempel
In [ ]:
namn = "Alfred"
# tilldela variabeln namnlängd värdet som len(namn)
# returnerar
namnlängd = len(namn)
# skriv ut värdet i variabeln namnlängd
print(namnlängd)
Delsträngar¶
my_string[start:end]
från indexstart
, inkludera tecknen på alla index mindre änend
my_string[:end]
från första tecknet, inkludera tecknen på alla index mindre änend
my_string[start:]
alla tecken från indexstart
till slutet av strängen
h |
e |
j |
s |
a |
n |
---|---|---|---|---|---|
0 |
1 |
2 |
3 |
4 |
5 |
In [ ]:
my_string = "hejsan"
my_string[1:4]
Ett värde som en sträng¶
- Vi kan använda funktionen str() för att få en strängrepresentation av vilket värde som helst.
- Exempel:
In [ ]:
3+3
In [ ]:
str(3) + str(3)
In [ ]:
str(True)
Mer om listor¶
Datatypen list¶
- Används för att lagra en sekvens av värden (element i listan).
- Listor är också värden, dvs en lista kan innehålla listor (som i sin tur kan innehålla listor osv)
- Syntax:
studenter = ["Ada", "Bertil", "Cecilia"]
- Det går bra att blanda datatyper i en lista:
diverse = [5, 3.0, "rosa", [100, 200, 300]]
- Precis som med strängar använder vi index för att komma åt ett värde på en viss position.
- Index för listor börjar också på 0
Del-listor¶
- Vi kan även plocka fram delar av en lista
my_list[start:end]
från indexstart
, inkludera alla värden med index mindre änend
my_list[:end]
från början, inkludera alla värden med index mindre änend
my_list[start:]
från indexstart
till slutet av listan
'h' |
'e' |
'j' |
's' |
'a' |
'n' |
---|---|---|---|---|---|
0 |
1 |
2 |
3 |
4 |
5 |
In [ ]:
my_list = ['h', 'e', 'j', 's', 'a', 'n']
my_list[1:4]
Operatorer som kan användas med listor¶
- Operatorn
+
kan användas för att slå ihop två listor till en ny lista. Ordningen spelar roll!
In [ ]:
frukter1 = ["äpple", "päron"]
frukter2 = ["apelsin", "banan"]
alla_frukter1 = frukter1 + frukter2
alla_frukter2 = frukter2 + frukter1
In [ ]:
print(alla_frukter1)
In [ ]:
print(alla_frukter2)
Ändra på ett värde i en lista¶
- Vi kan ändra värdet på en viss position i en lista med en tilldelningssats:
In [ ]:
values = [1, 2, 3, 4]
print(values)
In [ ]:
# ändra värde på index 2
values[2] = "hoppsan"
print(values)
Lägga till nytt värde till slutet på en lista¶
In [ ]:
frukter = ["apelsin"]
print(frukter)
In [ ]:
frukter = frukter + ["banan"]
print(frukter)
Lägga till nytt värde till början på en lista¶
In [ ]:
frukter = ["apelsin"]
print(frukter)
In [ ]:
frukter = ["banan"] + frukter
print(frukter)
Metoden list.append()¶
- Användning av operatorn
+
med listor ändrar inte på operanderna- nedanstående uttryck kommer beräknas, men resultatet sparas inte
In [ ]:
characters1 = ["a", "b", "c"]
characters1 + ["d"]
print(characters1)
- Metoder är ett slags funktioner som man hänger på ett objekt med hjälp av punktnotation
- Mer om metoder i Tema 4-6
- Metoden
list.append(value)
lägger till value till en lista
In [ ]:
tcharacters1.append("d")
print(characters1)t
Moduler¶
Moduler¶
- Specialiserade funktioner m.m. kan göras tillgängliga t.ex. genom att importera moduler i sin Python-kod.
- Varje fil med Python-kod kan användas som en modul.
- Det finns ett antal moduler som ingår i Pythons så kallade standardbibliotek (Python Standard Library).
- Moduler i standardbiblioteket finns alltid tillgängliga i alla Python-installationer utan att behöva installera något extra.
Moduler¶
- Tillhandahåller ytterligare funktionalitet, t.ex. funktioner för speciella tillämpningar
- Exempel på moduler som följer med Python
random
: har t.ex. funktioner som returnerar slumpvärdensys
: funktioner m.m. som har med systemet att göra (lägre abstraktionsnivå)os
: funktioner m.m. som har med operativsystemet att göra (högre abstraktionsnivå)
Import av modul och exempel på användning¶
- För att få tillgång till en modul behöver den importeras med en import-sats, som oftast inleds med nyckelordet
import
. - Standard är att lägga alla importsatser i början av textfilen.
In [ ]:
import random
# funktionen random() i modulen random returnerar ett slumpmässigt
# flyttal mellan 0.0 och 1.0
slumpvärde1 = random.random()
print(slumpvärde1)
In [ ]:
# funktionen randint(heltal1, heltal2) i modulen random returnerar ett
# slumpmässigt heltal från heltal1 till och med heltal2.
slumpvärde2 = random.randint(10, 90)
print(slumpvärde2)
Import, namnrymder, punktnotation¶
import random
- Ovanstående laddar in innehållet i modulen
random
och ser till att det hamnar i namnrymdenrandom
- Funktionen
randint(heltal1, heltal2)
i modulenrandom
kommer man då åt genom att skriva
random.randint(heltal1, heltal2)
In [ ]:
# import-exempel 1
import random
list_of_names = ["Ada", "Bea", "Cecilia", "Dolores"]
def random_greeting1(names):
# random.choice() väljer ut ett slumpmässigt element från
# en sekvens
name = random.choice(names)
print("Hello " + name + "!")
def random_greeting2(names):
# random.randint() slumpar fram ett heltal från ett slutet
# intervall
random_index = random.randint(0, len(names)-1)
print("Hello " + names[random_index] + "!")
In [ ]:
random_greeting1(list_of_names)
In [ ]:
random_greeting2(list_of_names)
In [ ]:
#import-exempel 2
from random import *
list_of_names = ["Ada", "Bea", "Cecilia", "Dolores"]
def random_greeting1(names):
# choice() från modulen random väljer ut ett slumpmässigt
# element från en sekvens
name = choice(names)
print("Hello " + name + "!")
def random_greeting2(names):
# randint() från modulen random slumpar fram ett heltal från
# ett slutet intervall
random_index = randint(0, len(names)-1)
print("Hello " + names[random_index] + "!")
In [ ]:
random_greeting1(list_of_names)
In [ ]:
random_greeting2(list_of_names)