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+1bara 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
answerpå framsidan, - och stoppar sedan värdet
42i 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,2och 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
lentar 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 änendmy_string[:end]från första tecknet, inkludera tecknen på alla index mindre änendmy_string[start:]alla tecken från indexstarttill 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 änendmy_list[:end]från början, inkludera alla värden med index mindre änendmy_list[start:]från indexstarttill 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
randomoch ser till att det hamnar i namnrymdenrandom - Funktionen
randint(heltal1, heltal2)i modulenrandomkommer 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)