Python - Intro

Thu 26 May 2022

Introduksjon til programmering i python.

Syntax

Vi har allerede sett et eksempel på python syntax når vi skrev og kjørte det første programmet vårt. Det som skiller python syntax fra endel andre språk er at den tvinger oss til å ha et spesifikt format på koden vår. Siden vi bruker en IDE, Visualstudio Code, får vi hjelp til å holde oss innenfor det nødvendige formatet når vi skriver. Men det kan være nyttig å nevne noe av reglene alikevel. Den viktigste av reglene er indentering, det vil si at vi kravene til mellomrom i starten av en linje.

def test():
print("Hello world")

Om skriver inn kodesnutten over i visualstudio code vil du se at du får en rød strek, en indikasjon på at dette ikke er korrekt. Du vil også se nede editoren at det kommer opp en fane "Problems", og om du trykker på den vil den forsøke å forklare deg hvor problemet ligger: Expected indented block. La oss indentere koden vår slik som vi har fått tips om.

def test():
  print("Hello world")

Nå ser vi at editoren vår er fornøyd. Dette er en av fordelene ved å bruke en editor som visualstudio code, vi får hjelp og tips underveis.

Hvor mange mellomrom du bruker når du indenterer spiller ingen rolle, men det må være lik indentering når du først har valgt. Det vanlige er 4 eller 2 mellomrom.

I tillegg til indentering kan det være nyttig å kommentere direkte i koden. Kommentering er et konsept som de aller fleste programmeringsspråk har, og det er så enkelt som at vi kan skrive tekst i filen som oversees av tolkeren (eller kompilatoren).

# Skriv ut tekst v.h.a en gjenbrukbar funksjon
def test():
  print("Hello world") # Bruk den innebygde print() funksjonen for å skrive tekst.

#print("Hello world")

Her ser vi tre forskjellige måter å bruke kommentar på. Et hashtegn er pythons tegn for å indikere at 'her kommer en kommentar'. Kommentarer kan stå på en egen linje eller bak kode som kjøres. Vi kan også bruke hashtegnet for å kommentere vekk kode som vi ikke ønsker å kjøre.

Det er stort sett det vi trenger å vite om syntaks på nåværende tidspunkt.

Variabler

Kort fortalt er variabler en kontainer for å lagre verdier. Så fort en variabel har fått tildelt en verdi så kan de brukes i koden vår. Dersom vi prøver å bruke en variabel uten at den har fått tildelt en verdi vil programmet kræsje når vi kjører det.

# Define some variables
x = 5
name = "Kristian"

# Use our variables
print(x)
print(name)
print(y)

Her ser vi at variablen x får tildelt verdien 5, og variablen name får tildelt verdien "Kristian". Her ser vi også et eksempel på bruk av typer. Variable x blir tildelt et heltall, mens variablen name blir tildelt en string. I python, og de fleste andre programmeringsspråk, indikerer vi at noe er en streng ved å bruke '' eller "". Når vi skal bruke en variabel referer vi til den ved navnet, altså uten '' eller "".

la oss prøve å kjøre koden:

5
Kristian
Traceback (most recent call last):
  File "/Users/adrock2nd/Utvikling/git/pythonkurs2022/helloworld.py", line 7, in <module>
    print(y)
NameError: name 'y' is not defined

Når vi kjører koden over vil vi se at programmet skriver ut "5" og "Kristian" før det kræsjer. Grunnen til at det kræsjer er at vi forsøker å bruke variablen y, uten at denne har blitt definert.

Når vi programmerer kan det være nyttig å se hva som kommer av feilmeldinger. De er ofte beskrevet godt nok til at det er enkelt å fikse. Her ser vi at det er en feil på linje 13, og det er at y ikke er definert. Vi ser også at visualstudio code har oppdaget denne feilen før vi kjørte koden. La oss fikse koden vår.

# Define some variables
x = 5
name = "Kristian"

# Use our variables
print(x)
print(name)

# Define y variable properly before we use it
y = 15
print(y)

la oss prøve å kjøre koden vår igjen:

5
Kristian
15

Som dere ser så liker jeg å bruke engelsk i variabelnavn og i kommentarer, men dette er helt valgfritt. Men tenk gjerne litt på om det er andre som skal lese koden din på et senere tidspunkt. Kanskje er det et prosjekt flere jobber på, eller et prosjekt som kan være aktuelt å dele som åpen kildekode en gang i fremtiden. Du vil uansett tjene på å bruke beskrivende variabelnavn selv om python ikke tvinger deg til det. Det er dog noen få regler man må forholde seg til når det gjelder variabelnavn.

  • Et variabelnavn må starte med en bokstav eller understrek ** Som impliserer at det ikke kan starte med et tall
  • Et variabelnavn kan kun inneholde alfanumeriske karakterer og understrek (A-z, 0-9, og _)
  • Variabelnavn er casesensitive.

La oss se noen eksempler på variabelnavn.

aaa = 10
aAa = 15
aaA = 20

print(aaa, aAa, aaA)

vil gi oss:

10, 15, 20

Her ser dere også at jeg har kortet ned koden litt ved å skrive ut alle variablene i samme linje istedenfor å ha en linje utskrift for hver linje.

Vi kan korte ned ytterligere. Mest for å vise at python er fleksibelt og lar deg velge flere forskjellige stiler når du programmerer.

aaa, aAa, aaA = 10, 15, 20
print(aaa, aAa, aaA)

vil gi oss:

10, 15, 20

Så lenge du bruker en kodeeditor som visualstudio code vil du få grei veiledning på det meste som har med variabler å gjøre, f.eks om du forsøker å bruke et ugyldig variabelnavn, glemmer å definere en variabel eller noe annet festlig.

Typer

Vi har nå sett på bruk av variabler, og at vi kan lagre data i de. Vi har til nå lagret tall og tekst i variablene våre. Tall og tekst i denne sammenheng er eksempel på to typer som brukes ofte i programmering. Det finnes mange flere typer, og man kan også lage sine egne. Forskjellige typer kan ha forskjellige egenskaper, og her ser vi en oversikt over de typene som er innebygget i python.

Text Type:          str
Numeric Types:      int, float, complex
Sequence Types:     list, tuple, range
Mapping Type:       dict
Set Types:          set, frozenset
Boolean Type:       bool
Binary Types:       bytes, bytearray, memoryview
None Type:          NoneType

Det er ikke alle disse typene vi kommer til å bruke, men endel av de vil vi stifte bekjentskap med idag. Python har heldigvis en innebygd funksjon som gjør at vi kan sjekke hvilken type vi har med å gjøre.

x = 5
print(type(x))

vil gi oss:

<class 'int'>

Vi har nevnt innledningsvis at pyhon er et dynamisk typert språk. Det betyr at python forsøker å automatisk finne typen avhengig av hvilken verdi vi har tildelt variablen. I eksempelet over har python korrekt satt datatypen til 'int', som er forkortelse for Integer (heltall) basert på tallet 5.

Vi kan også spesifisere typen dersom vi ønsker det.

x = int(5)
print(type(x))

vil gi oss:

<class 'int'>

La oss set på hvordan de andre typene kan brukes.

var_str = str("Hello World")
var_int = int(20)
var_float = float(20.5)
var_complex = complex(1j)
var_list = list(("apple", "banana", "cherry"))  
var_tuple = tuple(("apple", "banana", "cherry"))    
var_range = range(6)    
var_dict = dict(name="John", age=36)    
var_set = set(("apple", "banana", "cherry"))    
var_frozenset = frozenset(("apple", "banana", "cherry"))    
var_bool = bool(5)  
var_bytes = bytes(5)    
var_bytearray = bytearray(5)    
var_memoryview = memoryview(bytes(5))

print(var_str, var_int, var_float, var_complex, var_list, var_tuple, var_range, var_dict, var_set, var_frozenset,
var_bool, var_bytes, var_bytearray, var_memoryview, sep='\n')

vil gi oss:

Hello World
20
20.5
1j
['apple', 'banana', 'cherry']
('apple', 'banana', 'cherry')
range(0, 6)
{'name': 'John', 'age': 36}
{'apple', 'banana', 'cherry'}
frozenset({'apple', 'banana', 'cherry'})
True
b'\x00\x00\x00\x00\x00'
bytearray(b'\x00\x00\x00\x00\x00')
<memory at 0x7feab8c1bdc0>

Nå skal vi kikke litt nærmere på de mest bruktene typene: int/float, string, bool, list, tuple, set og dict.

int / float / complex

Dette er integer, flyttal og komplekse tall. Int kan være 0, eller et annet negativt eller positivt tall av vilkårlig lengde, uten desimaler. Legg til desimaler så får du float. 1.0 vil altså være av typen float, selv om verdien er den samme som 1, som er int. Float kan også være vitenskaplige tall, f.eks 35e3. Complex er komplekse tall hvor den imaginære delen betegenes med en 'j'.

var_int = 1
var_float = 1.0
var_complex = 1j

print(var_int, var_float, var_complex, sep=', ')
print(type(var_int), type(var_float), type(var_complex), sep=', ')

som gir oss:

1, 1.0, 1j
<class 'int'>, <class 'float'>, <class 'complex'>

Vi kan også konvertere mellom typene. Å konvertere mellom datatyper kalles casting, og er mer vanlig i programmeringsspråk som ikke er dynamisk typerte. I python vil data konverteres / castes automatisk og vi slipper å tenke altfor mye på det.

var_int = 1    # int
var_float = 1.0  # float
var_complex = 1j   # complex

a = float(var_int) #convert from int to float:
b = int(var_float) #convert from float to int:
c = complex(var_int) #convert from int to complex:

print(a, b, c, sep=', ')
print(type(a), type(b), type(c), sep=', ')

som gir oss:

1.0, 1, (1+0j)
<class 'float'>, <class 'int'>, <class 'complex'>

Merk at vi ikke kan konvertere komplekse tall.

Det siste vi skal se på under tall er hvordan vi kan generere tilfeldige tall. Dette er kan være nyttig i mange forskjellige sammenhenger.

import random

print(random.randrange(1,7))

når vi kjører denne koden vil den gi oss et tall i området 1 - 6. Inkludert 1 og 6. Dette er altså det vi trenger av kode for å simulere ett terningkast ved hjelp av python. Om du kjører programmet flere ganger vil du se at du får et nytt resultat for hver kjøring.

Dette eksempelet er også vårt første møte med bruk av en python modul. I linjen 'import random' importerer vi den innebygde modulen 'random'. Denne modulen inneholder flere funksjoner, blant annen en funksjon som heter 'randrange' som da gir oss tilfeldige heltall. Vi skal komme tilbake til funksjoner ganske snart.

Det som også er greit å vite når en generer tilfeldige i python (og de fleste andre programmeringsspråk) er at vi egentlig jobber med det som kalles pseudotilfeldige tall. Funksjonen som generer de tilfeldige tallet baserer seg på et seed, og generer resultatet på bakgrunn av dette. Dette betyr at dersom vi bruker samme seed vil vi alltid få det samme resultatet, altså ingen tilfeldigheter.

import random

random.seed(0)
print(random.randrange(1,7))

vil gi oss tallet 4 hver gang vi kjører programmet, fordi vi har låst seed til å være 0. Setter du seedverdien til 3 vil du få tallet 2 hver gang.

Grunnen til at vi fikk forskjellige tall i første eksempelet vårt er fordi at standard seed bruker systemets klokke, som altså vil endre seg litt for hver gang du kjører. Tenk millisekunder.

Python som programmeringsspråk er åpen kildekode, som betyr at hvem som helst kan lese koden og se hvordan ting fungerer, slik som f.eks hvordan tilfeldige tall genereres. Når vi vet hvordan disse pseudotilfeldige tallene genereres, og vi vet at dersom seedverdien er lik så får vi samme resultat, så må vi være forsiktig / unngå å bruke denne funksjonen til å generere hemmeligheter som vi ikke vil andre skal finne ut av. Eksempelvis må vi være forsiktige med å bruke disse funksjonene i kryptografiske operasjoner.

string

Dette er vanlig tekst, og som vi har sett flere eksempler på allerede indikeres en streng v.h.a fnutter, eller dobbelfnutter. Om vi bruker tre fnutter (enkel eller dobbel) kan vi definere en lenger tekst over flere linjer.

print("Hello")
print('Hello')
print("""Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.""")

som gir:

Hello
Hello
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua

strenger er egentig et tabell (array) med bokstaver (chars). Dersom du har vært bort i andre programmeringsspråk har du kanskje brukte char som egen datatype, men dette har vi ikke i python. Så en char er en string med lengde 1.

var_string = "Hello, World!"
print(var_string[1])

som gir:

e

Her forventer noen kanskje at resultatet skulle bli 'H', men python (og mange andre programmeringsspråk) benytter seg av det som kalles 0'indeksering. Så det første elementet i en tabell (som en string egentlig er) er altså å finne på [0].

var_string = "Hello, World!"
print(var_string[0])

som gir:

H

Veldig mange programvarefeil skyldes at utvikleren har bommet på indekseringen.

La oss se på litt andre operasjoner som er vanlige å bruke på strenger.

var_string = "Hello, World!"
var_string2 = "What a nice day"

print(len(var_string)) # Get the length of the string
for x in var_string: # Loop through the string and print each character
  print(x)
print("ello" in var_string) # Check if the substring 'ello' exist in our text
print("python" in var_string) # Check if the substring 'python' exist in our text
print(var_string.upper()) # Make everything uppercase
print(var_string.lower()) # Make everything lowercase
print(var_string + " " + var_string2) # Concatenate two strings with a whitespace between

som gir oss:

13
H
...
!
True
False
HELLO, WORLD!
hello, world!
Hello, World! What a nice day

booleans

Dette er kanskje en av de enklere typene å håndtere. En boolsk verdi er enten 'True' eller 'False'. Vi kan evaluere hvilket som helst uttrykk i python og få tilbake en av de to boolske verdiene. Vi har også allerede sett noen eksempler på dette når vi testet om en substring var endel av en lenger string.

print(10 > 9)
print(10 == 9)
print(10 < 9)

som gir oss:

True
False
False

Det nyttige med booleans er når vi bruker det for å bestemme hvilken deler av koden vår som skal kjøres. La oss gjenbruke eksempelet med å lete etter en substring i teksten vår.

var_string = "Hello World!"
if ('ello' in var_string): # The values between ( and ) will evaluate to True or False, in this example True
  print("We found 'ello' in our string")
else:
  print("We did not find 'ello' in our string")

som gir oss:

We found 'ello' in our string

men om vi prøver å søke etter noe som ikke eksisterer

var_string = "Hello World!"
if ('python' in var_string): # The values between ( and ) will evaluate to True or False, in this example False
  print("We found 'python' in our string")
else:
  print("We did not find 'python' in our string")

vil vi få:

We did not find 'python' in our string

Vi begynner å få mer og mer avansert pythonkode og funksjonalitet, men jeg håper det fortsatt føles greit å lese koden.

Før vi avslutter med bool må vi se litt på hvor det kan gå gærnt. Jeg nevnte at vi kan evaluere alle uttrykk og få tilbake en av de to boolske verdiene.

print(bool("Hello World!"), bool(10), bool(["apple", "cherry", "banana"]), sep=", ")
print(bool(False), bool(None), bool(0), bool(""), bool(()), bool([]), bool({}), sep=", ")

som gir oss:

True, True, True
False, False, False, False, False, False, False

de aller fleste verdier som vi evaluerer på denne måten vil bli True, men det er altså noen unntak. Om vi ikke passer på kan vi da få kode som aldri vil bli brukt, og dermed er unødvendig.

if (10):
  print("Always true")
else:
  print("This will never happen")

som da gir oss:

Always true

operatorer

Er ikke en type i så måte, men det kan være nyttig å se på disse nå. Operatorer brukes til å utføre operasjoner på verdier og variabler. Vi har syv typer operatorer i python. Vi skal gå veldig raskt igjennom noen av de typene vi har nå, og så blir vi kjent med flere av de litt underveis.

Arithmetic operators    (+, -, *, /, %, **, //)
Assignment operators    (=, +=, -=, *=, /=, %=, //=, **=, &=, |=, ^=, >>=, <<=)
Comparison operators    (==, !=, >, <, >=, <=)
Logical operators       (and, or, not)
Identity operators      (is, is not)
Membership operators    (in, not in)
Bitwise operators       (&, |, ^, ~, <<, >>)

La oss gå raskt igjennom comparison operatorene:

==  Equal:                    x == y    
!=  Not equal:                x != y    
>   Greater than:             x > y
<   Less than:                x < y 
>=  Greater than or equal to: x >= y    
<=  Less than or equal to:    x <= y

La oss gå raskt igjennom de logiske operatorene:

and     Returns True if both statements are true:                   x < 5 and  x < 10   
or      Returns True if one of the statements is true:              x < 5 or x < 4  
not     Reverse the result, returns False if the result is true:    not(x < 5 and x < 10)

La oss gå raskt igjennom de logiske operatorene:

is         Returns True if both variables are the same object:     x is y   
is not     Returns True if both variables are not the same object: x is not y

La oss gå raskt igjennom membership operatorene:

in         Returns True if a sequence with the specified value is present in the object:     x in y 
not in     Returns True if a sequence with the specified value is not present in the object: x not in y

Det er de viktigste operatorene for denne gang. Men her er en fullstendig liste for de som ønsker å se eksempel på bruk av alle operatorene:

[TODO: Sett inn bilde av https://cheatography.com/nouha-thabet/cheat-sheets/python-operators-and-booleans/ her]

Lists

Lister brukes til å lagre flere verdier i samme variabel. Lister er en av fire innebygde datatyper som kan brukes til å lagre en samling av data. De tre andre er tupler, set og dictionaries som vi skal se på etterpå. En liste er en ordnet samling, som betyr at elementene i listen har en rekkefølge, og når vi legger nye elementer til i listen vår så legges disse til på slutten av listen. For at vi skal kunne holde orden på rekkefølgen er elementene i listen indeksert, 0, 1, 2 og så videre. Dette betyr også at vi kan ha flere like elementer, duplikater, i listen vår. Vi kan ha forskjellige typer data i en listen, og til og med mikse typer i samme liste.

alist = ["apple", "banana", "cherry"]
alistwithduplicates = ["apple", "banana", "cherry", "apple"]
alistwithints = [1, 2, 3, 4, 5, 6]
alistwithmixedtypes = [1, True, "apple"]

print(alist, alistwithduplicates, alistwithints, alistwithmixedtypes, sep="\n")
print(len(alist), type(alist), sep="\n")

Om vi kjører denne koden får vi:

['apple', 'banana', 'cherry']
['apple', 'banana', 'cherry', 'apple']
[1, 2, 3, 4, 5, 6]
[1, True, 'apple']
3
<class 'list'>

Vi kan arbeide med elementene i listen ved å bruke indekseringen.

alist = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(alist[1])
print(alist[2:5])

alist[1] = "blackcurrant" # Replace element at index 1
print(alist)

alist.append("raspberry") # Append element at end of list
print(alist)

alist.remove("blackcurrant") # Remove a specific element
print(alist)

alist.pop() # Remove last element
print(alist)

alist.clear() # Remove all elements in list
print(alist)

Når vi kjører dette får vi:

banana
['cherry', 'orange', 'kiwi']
['apple', 'blackcurrant', 'cherry', 'orange', 'kiwi', 'melon', 'mango']
['apple', 'blackcurrant', 'cherry', 'orange', 'kiwi', 'melon', 'mango', 'raspberry']
['apple', 'cherry', 'orange', 'kiwi', 'melon', 'mango', 'raspberry']
['apple', 'cherry', 'orange', 'kiwi', 'melon', 'mango']
[]

En vanlig oppgave er å loope igjennom lister.

print("Example 1: Process items, one by one.")
alist = ["apple", "banana", "cherry"]
for x in alist:
  print(x)
print("Example 2: Process items, by using index numbers.")
alist = ["apple", "banana", "cherry"]
for i in range(len(alist)): #Generates a iterable [0, 1, 2]
  print(alist[i])
print("Example 3: Process items, by using a while loop.")
alist = ["apple", "banana", "cherry"]
i = 0
while i < len(alist):
  print(alist[i])
  i = i + 1

Når vi kjører denne koden får vi:

Example 1: Process items, one by one.
apple
banana
cherry
Example 2: Process items, by using index numbers.
apple
banana
cherry
Example 3: Process items, by using a while loop.
apple
banana
cherry

Vi kan sortere lister.

print("Example 1: Sort strings ascending.")
stringlist = ["orange", "mango", "kiwi", "pineapple", "banana"]
stringlist.sort()
print(stringlist)

print("Example 2: Sort integers ascending.")
intlist = [100, 50, 65, 82, 23]
intlist.sort()
print(intlist)

print("Example 3: Sort strings descending.")
stringlist = ["orange", "mango", "kiwi", "pineapple", "banana"]
stringlist.sort(reverse = True)
print(stringlist)

print("Example 4: Sort integers descending.")
intlist = [100, 50, 65, 82, 23]
intlist.sort(reverse = True)
print(intlist)

Som gir oss følgende resultater:

Example 1: Sort strings ascending.
['banana', 'kiwi', 'mango', 'orange', 'pineapple']
Example 2: Sort integers ascending.
[23, 50, 65, 82, 100]
Example 3: Sort strings descending.
['pineapple', 'orange', 'mango', 'kiwi', 'banana']
Example 4: Sort integers descending.
[100, 82, 65, 50, 23]

Da er vi snart ferdig med lister, men først skal vi se kjapt på hvordan vi kopierer, og hvordan vi slår sammen lister.

# This will not work cause it only creates a reference to the originallist. Every changes made to originallist will
# also be visible in the reference copylist.
originallist = ["apple", "banana", "cherry"]
copylist = originallist
print(copylist)

# If you want to make a separate copy of the list you can use the method .copy().
originallist = ["apple", "banana", "cherry"]
copylist = originallist.copy()
print(copylist)

Jeg viser et feil og et korrekt eksempel på kopiering fordi det kan virke intuitivt å bruke den feile måten å gjøre dette på, og man skjønner ikke nødvendigvis at det er feil før senere. Begge eksempelene over er helt korrekte om vi ser på selve syntaksen, og koden vil kjøre OG gi oss forventet output:

['apple', 'banana', 'cherry']
['apple', 'banana', 'cherry']

Det er først når vi gjør skal gjøre endringer på originalen eller kopien at vi vil oppdage at noe ikke er helt som forventet. Det typiske er at man ikke oppdager slike type feil før senere i programmet, og da kan det være vanskelig å huske hvor feilen kan ha blitt innført.

Det siste vi skal se på er hvordan vi kan slå sammen to lister.

print("Example 1: Using the + operator to concatenate two or more lists.")
list1 = ["a", "b", "c"]
list2 = [1, 2, 3]
list3 = list1 + list2
print(list3)

print("Example 2: Using a for-loop to appending items one-by-one.")
list1 = ["a", "b" , "c"]
list2 = [1, 2, 3]
for x in list2:
  list1.append(x)
print(list1)

print("Example 3: Using the .extend() method which's purpose is to add elements from one list to another list.")
list1 = ["a", "b" , "c"]
list2 = [1, 2, 3]
list1.extend(list2)
print(list1)

Og for ordens skyld tar vi med resultatene:

Example 1: Using the + operator to concatenate two or more lists.
['a', 'b', 'c', 1, 2, 3]
Example 2: Using a for-loop to appending items one-by-one.
['a', 'b', 'c', 1, 2, 3]
Example 3: Using the .extend() method which's purpose is to add elements from one list to another list.
['a', 'b', 'c', 1, 2, 3]

Vi har sett på noen metoder for å jobbe med lister, så da tenker jeg vi avslutter listedelen med å vise alle de innebygde metodene:

append()    Adds an element at the end of the list
clear()     Removes all the elements from the list
copy()      Returns a copy of the list
count()     Returns the number of elements with the specified value
extend()    Add the elements of a list (or any iterable), to the end of the current list
index()     Returns the index of the first element with the specified value
insert()    Adds an element at the specified position
pop()       Removes the element at the specified position
remove()    Removes the item with the specified value
reverse()   Reverses the order of the list
sort()      Sorts the list

Tuples

Tupler er den andre av de fire innebygde datatypene som kan brukes for å lagre data. De andre var lister, set og dictionaries. Tupler er en samling som er ordnet, d.v.s at rekkefølge betyr noe, rekkefølgen kan ikke endres etter at vi har opprettet tuplet. Tupler kan heller ikke endres, så når vi først har opprettet tuplen så får vi ikke lagt til eller fjernet elementer i det.

Vi kan veldig enkelt oppsummere med at forskjellen mellom tupler og lister er at vi kan endre elementer i en liste, men ikke i et tuppel. Bortsett fra det gjelder de fleste egenskapene vi gikk igjennom for lister.

atuple = ("apple", "banana", "cherry")
atuplewithdups = ("apple", "banana", "cherry", "apple", "cherry") # Duplicates allowed.
atuplewithmixedtypes = ("abc", 34, True, 40, "male")

print(len(atuplewithdups)) # How long is the tuple?
print(type(atuplewithdups)) # What kind of object is this recognised as?

print(atuplewithdups[1]) # Tuples are indexed, with 0 as the first index.
print(atuplewithdups[1:3]) # We can use range of indexes. start at index 1 (included) and end at index 3 (not included).

if "apple" in atuplewithdups:
  print("Yes, 'apple' is in the fruits tuple") # We found a match.

for x in atuple:
  print(x) # Looping over atuple is not hard.

ajoinedtuple = atuple + atuplewithdups
print(ajoinedtuple) # Combining two tuples are not hard.

Og resultatene:

5
<class 'tuple'>
banana
('banana', 'cherry')
Yes, 'apple' is in the fruits tuple
apple
banana
cherry
('apple', 'banana', 'cherry', 'apple', 'banana', 'cherry', 'apple', 'cherry')

Siden en av egenskapene til tupler er at de ikke kan endres må man være litt kreativ for å få det til.

# Tuples are unchangeable, but here is a little trick to modify the content anyway.
aunchangeabletuple = ("apple", "banana", "cherry")
print(aunchangeabletuple)
temporarylist = list(aunchangeabletuple)
temporarylist[1] = "kiwi"
aunchangeabletuple = tuple(temporarylist)
print(aunchangeabletuple)

Og resultatene:

('apple', 'banana', 'cherry')
('apple', 'kiwi', 'cherry')

Dersom man ønsker å legge til eller fjerne elementer fra et tuppel kan man bruke en variant av trikset over ved at man tar veien innom en liste, utfører ønsket operasjoner og så tar resultatet tilbake til det opprinnelige tuppelet.

Før vi oppsummerer tupler så skal vi se på en liten ting til. Vi har så langt lagt inn verdier i tuplene våre, noe som kalles packing. Men har vi først pakket noe kan vi i noen tilfelle pakke det ut igjen.

fruits = ("apple", "banana", "cherry")
(green, yellow, red) = fruits

print(green)
print(yellow)
print(red)

Som gir oss:

apple
banana
cherry

Da har vi sett på det vi trenger av tupler for denne gang, og kan avslutte med å vise de innebygde metodene vi har i tupler.

count()    Returns the number of times a specified value occurs in a tuple
index()    Searches the tuple for a specified value and returns the position of where it was found

Sets

Set er den tredje av de fire innebygde datatypene som kan brukes for å lagre data. De andre var lister, tupler og dictionaries. Set er en samling som uordnet, ikke kan endres (det vil si at du kan ikke endre elementer i samlingen, men du kan legge til / fjerne elemeenter) og den er ikke indeksert. I motsetning til lister og tupler er det heller ikke tillatt med duplikater i et set.

aset = {"apple", "banana", "cherry"}
print(aset) # Sets are unordered, so you cannot be sure in which order the items will appear.

aset = {"apple", "banana", "cherry", "apple"}
print(aset) # Duplicates will be ignored.

print(len(aset)) # Length of the set.

asetwithdifferenttypes = {"abc", 34, True, 40, "male"}
print(asetwithdifferenttypes) # As with list and tuples, we can mix types in our set.

print(type(aset)) # What kind of object is this recognised as?

Og resultatene:

{'cherry', 'banana', 'apple'}
{'cherry', 'banana', 'apple'}
3
{True, 34, 'male', 40, 'abc'}
<class 'set'>

Siden settet vårt ikke er indeksert kan vi ikke bruke indekser for å hente ut elementer slik vi har gjort tidligere.

aset = {"apple", "banana", "cherry"}
for x in aset:
  print(x) # Looping a set is not hard.

print("banana" in aset) # Check if banana is present in our set.

aset.add("orange")
print(aset) # Now with an added orange.

anotherset = {"pineapple", "mango", "papaya"}
aset.update(anotherset)
print(aset) # Now updated with tropical fruits.

aset.remove("banana")
print(aset) # Now without the yellow fruit.

# This does almost the same as the update(), but returns a new object instead of updating existing object.
newset = {"a", "b" , "c"}
newerset = {1, 2, 3}

newestset = newset.union(newerset)
print(newestset)

Og resultatet:

cherry
banana
apple
True
{'cherry', 'banana', 'apple', 'orange'}
{'cherry', 'papaya', 'apple', 'orange', 'pineapple', 'banana', 'mango'}
{'cherry', 'papaya', 'apple', 'orange', 'pineapple', 'mango'}
{1, 2, 3, 'c', 'b', 'a'}

Så da gjenstår det bare å liste ut alle de innebygde metodene vi har i et set.

add()                           Adds an element to the set
clear()                         Removes all the elements from the set
copy()                          Returns a copy of the set
difference()                    Returns a set containing the difference between two or more sets
difference_update()             Removes the items in this set that are also included in another, specified set
discard()                       Remove the specified item
intersection()                  Returns a set, that is the intersection of two other sets
intersection_update()           Removes the items in this set that are not present in other, specified set(s)
isdisjoint()                    Returns whether two sets have a intersection or not
issubset()                      Returns whether another set contains this set or not
issuperset()                    Returns whether this set contains another set or not
pop()                           Removes an element from the set
remove()                        Removes the specified element
symmetric_difference()          Returns a set with the symmetric differences of two sets
symmetric_difference_update()   inserts the symmetric differences from this set and another
union()                         Return a set containing the union of sets
update()                        Update the set with the union of this set and others

Dictionaries

Dicts er den fjerde av de fire innebygde datatypene som kan brukes for å lagre data. De andre var lister, tupler og set. Dictionaries er en samling som er ordnet, kan endres og bruker et nøkkel:verdi par istedenfor indekser. Det er ikke lov med duplikater i en dictionary. Det som er verdt å merke seg her er at dictionary i python 3.6 og tidligere ikke var ordnet, men de er altså ordnet i python versjon 3.7 og nyere.

Som nevnt så er items i en dictionary et par, nøkkel:verdi som er slik ut.

adict = {
  "brand": "Ford",
  "electric": False,
  "year": 1964,
  "colors": ["red", "white", "blue"]
}
print(adict) # As with list, tuples and set, we can mix types in our dcitionary.
print(len(adict)) # Length of the dictionary.
print(type(adict)) # What kind of object is this recognised as?

Gir oss:

{'brand': 'Ford', 'electric': False, 'year': 1964, 'colors': ['red', 'white', 'blue']}
4
<class 'dict'>

Når vi skal jobbe med elementer i en dictionary.

adict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
x = adict["model"] # Get the value of model.
x = adict.get("model") # Get the value of model.

x = adict.keys() # Get all existing keys in the dictionary.
print(x) # Existing keys before a change.
adict["color"] = "white"
print(x) # Existing keys after we added a new key:value pair.

x = adict.values() # Get all existing values in the dictionary.
print(x) # Existing value before a change.
adict["year"] = 2020
print(x) # Existing values after we modified a value.

x = adict.items() # Get a list of the key:value pairs as tuples in a list.
print(x)

if "model" in adict:
  print("Yes, 'model' is one of the keys in the adict dictionary") # Check if model is present in our dict.

adict.pop("model") # Remove the item with the specified key 'model'.
print(adict)

Når vi kjører denne koden får vi:

dict_keys(['brand', 'model', 'year'])
dict_keys(['brand', 'model', 'year', 'color'])
dict_values(['Ford', 'Mustang', 1964, 'white'])
dict_values(['Ford', 'Mustang', 2020, 'white'])
dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 2020), ('color', 'white')])
Yes, 'model' is one of the keys in the adict dictionary
{'brand': 'Ford', 'year': 2020, 'color': 'white'}

Vi har også flere måter å iterere de forskjellige delene av en dict på.

adict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}

for x in adict: # Loop over all the keynames in the dict.
  print(x)

for x in adict.keys(): # Loop over all the keynames in the dict.
  print(x)

for x in adict: # Loop over all the values in the dict.
  print(adict[x])

for x in adict.values(): # Loop over all the values in the dict.
  print(x)

for x, y in adict.items(): # Loop over both keys and values in the dict.
  print(x, y)

Som gir oss følgende output:

brand
model
year
brand
model
year
Ford
Mustang
1964
Ford
Mustang
1964
brand Ford
model Mustang
year 1964

Det tror jeg det er det vi trenger å vite om dictionaries for nå og vi lister ut de innebygde metodene som finnes i en dictionary. Som dere ser så er det endel av funksjonene vi ikke har brukt tid på akkurat nå.

clear()         Removes all the elements from the dictionary
copy()          Returns a copy of the dictionary
fromkeys()      Returns a dictionary with the specified keys and value
get()           Returns the value of the specified key
items()         Returns a list containing a tuple for each key value pair
keys()          Returns a list containing the dictionary's keys
pop()           Removes the element with the specified key
popitem()       Removes the last inserted key-value pair
setdefault()    Returns the value of the specified key. If the key does not exist: insert the key, with the specified value
update()        Updates the dictionary with the specified key-value pairs
values()        Returns a list of all the values in the dictionary

Funksjoner

Funksjoner er en samling av instruksjoner som kun blir kjørt når vi kaller på de. Vi kan definere de funksjonene vi trenger, og kalle på de når vi har bruk for de. I python definerer vi en funksjon ved hjelp av nøkkelordet 'def', og de som er kjent med andre programmeringsspråk kan ha hørt om metoder, som er det samme.

def greet_function():
    print("Hello from a function")

greet_function()

som vil gi:

Hello from a function

Vi kan sende inn informasjon til funksjonen vår ved hjelp av argumenter.

def greet_function(firstname, lastname): # The function takes 2 parameters, firstname and lastname.
    print("Hello " + firstname + " " + lastname + " from a function")

greet_function("Kristian", "B") # Here we are sending 2 arguments to the function.

som gir:

Hello Kristian B from a function

Når vi har en funksjom som forventer 2 argumenter, men kun sender 1 så vil vi få en feilmelding.

def greet_function(firstname, lastname): # The function takes 2 parameters, firstname and lastname.
    print("Hello " + firstname + " " + lastname + " from a function")

greet_function("Kristian") # Here we are sending 1 argument to the function.

som gir oss som forventet en feilmelding:

Traceback (most recent call last):
  File "/Users/adrock2nd/Utvikling/git/pythonkurs2022/helloworld.py", line 3, in <module>
    greet_function("Kristian") # Here we are sending 1 argument to the function.
TypeError: greet_function() missing 1 required positional argument: 'lastname'

Vi kan bruke funksjoner til å utføre et stykke arbeid for oss og så returnere resultatet ved hjelp av nøkkelordet 'return'.

def square_function(x):
  return x * x

print(square_function(3))
print(square_function(5))
print(square_function(9))

som gir oss:

9
25
81

Når vi har definert en funksjon så må den ha et innhold, det vil si at følgende kode vil gi deg feilmelding siden funksjonen 'mock_function' ikke har noe innhold.

def mock_function():

print(mock_function)

Det kan være tilfeller der vi ønsker å definere funksjonene våre tidlig, men ikke har innholdet klart ennå. Da kan vi bruke nøkkelordet 'pass' som ikke gjør noenting, men er nok til at funksjonen har fått innhold og at feilmeldingen dermed forsvinner.

def mock_function():
    pass

print(mock_function)

Helt til slutt om funksjoner så kan det nevnes at en funksjon kan kalle seg selv, det vil si at en funksjon kan være rekursiv.

def fibonacci(n):
    if n <= 1: # If the number is 0, then the answer is 0. If the number is 1, then the answer is 1.
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2) # Each successive fibonacci number is found by adding up the two numbers before it.

print('Fibonacci sequence:')
for i in range(5):
    print(fibonacci(i))

Som gir oss:

Fibonacci sequence:
0
1
1
2
3

Det er fortsatt mer vi kunne sagt om funksjoner, men nå har vi dekket det aller mest grunnleggende, og forhåpentligvis nok til å komme videre.

Løkker

Det siste temaet vi skal innom i denne "kort introduksjon til python" økten er løkker. Som vi vet er det mye datamaskinen kan gjøre, blant annet repeterende oppgaver. I python kan dette blant annet gjøres ved hjelp av løkkestrukturene 'for' og 'while'.

### Example 1
print("While loop: Example 1")
i = 1 # Variables need to be ready and set before we enter the loop.
while i < 6: # Execute a set of statements while some condition are true.
  print(i)
  i += 1

### Example 2
print("While loop: Example 2")
i = 1 # Variables need to be ready and set before we enter the loop.
while i < 6: # Execute a set of statements while some condition are true.
  print(i)
  if i == 3:
    break # We can break / exit out of the loop, even if the initial condition are still true.
  i += 1

### Example 3
print("While loop: Example 3")
i = 0 # Variables need to be ready and set before we enter the loop.
while i < 6: # Execute a set of statements while some condition are true.
  i += 1
  if i == 3:
    continue # We can stop the current iteration of the loop, and continue with the next interation.
  print(i)

### Example 4
print("While loop: Example 4")
i = 1 # Variables need to be ready and set before we enter the loop.
while i < 6: # Execute a set of statements while some condition are true.
  print(i)
  i += 1
else: # We can run a block of code once when the condition no longer is true.
  print("i is no longer less than 6")

Som vanlig kan vi kjøre eksempelene våre:

While loop: Example 1
1
2
3
4
5
While loop: Example 2
1
2
3
While loop: Example 3
1
2
4
5
6
While loop: Example 4
1
2
3
4
5
i is no longer less than 6

og det var det vi trenger å vite om 'while' konstruksjonen. La oss gå videre til 'for' løkken. I motsetning til 'while' så vil 'for' løkken iterere over en sekvens, og ikke være avhengig av at et gitt utsagn skal være true. I en 'for' løkke itererer vi til sekvensen er slutt.

### Example 1
print("For loop: Example 1")
fruits = ["apple", "banana", "cherry"] # In addition to being a list, fruits are also an 'iterable' object.
for x in fruits: # In contrast with 'while' loop, we do not need to set the index variable beforehand.
  print(x)

### Example 2
print("For loop: Example 2")
for x in "banana": # Strings are also an 'iterable' object.
  print(x)

### Example 3
print("For loop: Example 3")
fruits = ["apple", "banana", "cherry"]
for x in fruits:
  if x == "banana":
    break # We can stop the loop before it has looped through all the items in the 'iterable'.
  print(x)

### Example 4
print("For loop: Example 4")
fruits = ["apple", "banana", "cherry"]
for x in fruits:
  if x == "banana":
    continue # We can stop the current iteration of the loop, and continue with the next iteration.
  print(x)

### Example 5
print("For loop: Example 5")
for x in range(6): # We can use range() to define number of iterations, in  this example values from 0 - 5.
  print(x)

### Example 6
print("For loop: Example 6")
for x in range(2, 6): # We can tweak range, in this example values from 2 - 5.
  print(x)

### Example 7
print("For loop: Example 7")
for x in range(2, 30, 3): # We can tweak range more, in this example increment with 3 step. Givin values 2, 5, 8 ...
  print(x)

### Example 8
print("For loop: Example 8")
for x in range(6):
  print(x)
else: # We can run a block of code once we are done looping all our iterations.
  print("Finally finished!")

### Example 9
print("For loop: Example 9")
adjectives = ["red", "big", "tasty"]
fruits = ["apple", "banana", "cherry"]

for x in adjectives: # Outer loop, the 'iterable' is the list adjectives.
  for y in fruits: # Inner loop, the 'iterable' is the list fruits.
    print(x, y)

### Example 10
print("For loop: Example 10")
for x in [0, 1, 2]:
  pass # For loop can not be empty, but if we dont have content inside, use the 'pass' keyword to avoid errors.

Eksempelkoden vår er som vanlig kjørbar:

For loop: Example 1
apple
banana
cherry
For loop: Example 2
b
a
n
a
n
a
For loop: Example 3
apple
For loop: Example 4
apple
cherry
For loop: Example 5
0
1
2
3
4
5
For loop: Example 6
2
3
4
5
For loop: Example 7
2
5
8
11
14
17
20
23
26
29
For loop: Example 8
0
1
2
3
4
5
Finally finished!
For loop: Example 9
red apple
red banana
red cherry
big apple
big banana
big cherry
tasty apple
tasty banana
tasty cherry
For loop: Example 10

Da! Har vi sett på de viktigste grunnprinsippene i programmering i python. De aller fleste av disse prinsippene finner vi i de fleste programmeringsspråk, men da med noe annerledes syntaks.

Tagged as : python intro
Tagged as : python intro