Skjermfilmer, Programmering

Tabellen under gir en oversikt over alle skjermfilmer det refereres til på nettstedet, under menyvalget Programmering.

Under arbeid

Artikkel Beskrivelse og film
 

Aritmetiske operasjoner
Feil og debugging
Feilhåndtering
Filbehandling
Forgreininger med «if»
for-løkker
Funksjoner
Lister
Lokale variabler
Metoder
Nøstede løkker

Strukturere «if»
Variabler
while-løkker

Lister og indekser

Kopiere strukturer

Dictionaries

 

Rekursjon Rekursjon
   
   

Løsningsforslag, mer om lister og dictionaries

Negative indekser i lister

Oppgave 1:

Vi oppretter ei liste som heter kvadrat:

kvadrat = [1, 4, 9, 16, 25, 36]

Så skal vi avgjøre hvilke tall kvadrat[-2] og kvadrat[-6] da refererer til.

Negative indekser regnes fra −1 fra høyre mot venstre, så kvadrat[-2] refererer til 25 og kvadrat[-6] til 1.

Tilbake til oppgaven

Deler av lister

Oppgave 1:

Vi oppretter ei liste som heter kvadrat:

kvadrat = [1, 4, 9, 16, 25, 36]

Så skal vi avgjøre hva kvadrat[1:3], kvadrat[:3], kvadrat[2:] og kvadrat[:5:2] da refererer til.

[a:b:c] gir ei liste som består av elementene med indeks fra og med a inntil b i skritt på c. Utelater vi a, betyr det at vi skal starte på første element i lista. Utelater vi b, betyr det at vi skal slutte på siste element i lista. Utelater vi c, betyr det at vi skal bruke 1 som skrittverdi.

kvadrat[1:3] refererer til ei liste med elementene med indekser fra og med 1 inntil 3 i kvadrat, det vil si [4, 9].

kvadrat[:3] refererer til ei liste med elementene fra begynnelsen inntil indeks 3 i kvadrat, det vil si [1, 4, 9].

kvadrat[2:] refererer til ei liste med elementene fra og med indeks 2 til og med siste element i kvadrat, det vil si [9, 16, 25, 36].

kvadrat[:5:2] refererer til ei liste med elementene fra og med begynnelsen inntil indeks 5 i skritt på 2 i kvadrat, det vil si [1, 9, 25].

Tilbake til oppgaven

Kopiere lister

Oppgave 1:

Vi har funksjonen kvadrer(), som gjør endringer i lista siffer vi sender inn som argument:

kvadrer(siffer)

Så skal vi forklare hvordan vi kan skrive om oppkallet av funksjonen slik at siffer ikke endres.

Vi må sørge for at en egen kopi av siffer overføres til kvadrer() ved å skrive

kvadrer(siffer.copy())

eller

kvadrer(siffer[:])

Bruker vi Python Tutor, ser vi ser vi at siffer i hovedprogrammet og liste i kvadrer() er forskjellige lister:

Illustrasjon av hovedprogram og funksjon som refererer til lister som er forskjellige objekter

Tilbake til oppgaven

Sortere lister

Oppgave 1:

Vi skal skrive Python-kode som oppretter lista kaos = [6, −3, 0, 5, 2, 8] og deretter sorterer lista synkende uten at vi angir reverse = True i sort().

Dette kan vi gjøre ved først å sortere og deretter snu rekkefølgen i lista:

kaos = [6, -3, 0, 5, 2, 8]
kaos.sort()
kaos.reverse()

Tilbake til oppgaven

Lister som inneholder lister

Oppgave 1:

Vi oppretter lista grader, som vist under.

grader_uke_1 = [12, 10, 14, 7, 8, 11, 10]
grader_uke_2 = [10, 7, 9, 6, 6, 8, 15]
grader_uke_3 = [10, 5, 3, 6, 4, 3, 2]
grader = [grader_uke_1, grader_uke_2, grader_uke_3]

Så skal vi avgjøre hva som blir skrevet ut hvis vi kjører følgende kode:

print(grader[1][2])
print(grader[2][1])
print(grader[0])

grader[1][2] betyr at vi skal bruke element nummer 1 i grader, altså grader_uke_2, og element nummer 2 i denne lista, så vi får skrevet ut 9.

grader[2][1] betyr at vi skal bruke element nummer 2 i grader, altså grader_uke_3, og element nummer 1 i denne lista, så vi får skrevet ut 5.

grader[0] har bare én indeks, så dette er hele element nummer 0, som er lista grader_uke_1. Så vi får skrevet ut [12, 10, 14, 7, 8, 11, 10].

Tilbake til oppgaven

Løsningsforslag, funksjoner

Skrive funksjoner

Oppgave 1:

Vi skal skrive en Python-funksjon, cels_til_fahr(), som regner om fra grader Celsius til grader Fahrenheit ved hjelp av formelen $f = {\large \frac{9c}{5}} + 32$, der f er grader Fahrenheit og c grader Celsius. Funksjonen kan bli slik:

def cels_til_fahr(celsius):
    """Konverterer fra grader Celsius til grader Fahrenheit."""
    fahrenheit = 9 * celsius / 5 + 32
    return fahrenheit

Vi skriver så

print(f"{cels_til_fahr(10):.02f}")

i hovedprogrammet. Når vi kjører koden, svarer Python 50.00.

Tilbake til oppgaven

Oppgave 2:

Vi skal skrive en Python-funksjon som finner og returnerer det minste av to tall.

Vi bruker funksjonen i eksempel 4 som mal, endrer funksjonsnavnet fra storst til minst og snur ulikhetstegnet:

def minst(tall_1, tall_2):
    """Finner det minste av to tall."""
    if tall_1 < tall_2:
        return tall_1
    else:
        return tall_2

For å teste funksjonen kan det være lurt å prøve med en variant der tall_1 < tall_2, en variant der tall_1 > tall_2, og en variant der tall_1 == tall_2. Så i hovedprogrammet skriver vi 

print(minst(1, 2))
print(minst(2, 1))
print(minst(1, 1))

Vi får skrevet ut 1 i alle tre tilfeller.

Tilbake til oppgaven

Funksjonsparametere

Oppgave 1:

Vi skal skrive en Python-funksjon som simulerer terningkast, det vil si genererer tilfeldige tall mellom 1 og 6, og returnerer resultatet.

Funksjonen kan se som vist under. I hovedprogrammet før funksjonen importerer vi randint.

from random import randint

def terningkast():
    """Simulerer et terningkast."""
    return randint(1, 6)

Hvis vi i hovedprogrammet skriver

print(terningkast())

vil vi få skrevet ut et vilkårlig tall mellom 1 og 6.

Tilbake til oppgaven

Oppgave 2:

Vi har funksjonen normal(x, my = 0, sigma = 1) som beregner sannsynlighetstetthet i en normalfordeling.

Så skal vi skrive kode som bruker normal() til å beregne sannsynlighetstettheten til 3 i en normalfordeling der sigma er 5, men my beholder standardverdien 0.

Vi kan ikke hoppe over my og bare gi en verdi til sigma, for skriver vi normal(3, 5), er det my som blir satt til 5, men sigma beholder standardverdien 1. Vi navngir derfor parameteren sigma, og skriver

normal(3, sigma = 5)

Tilbake til oppgaven

Lokale og globale variabler

Oppgave 1:

Vi har funksjonen kvadrer(), som vist under:

def kvadrer(y):
    """Kvadrerer y."""
    z = y**2
    return z

Så skal vi avgjøre hva som blir skrevet ut når vi i hovedprogrammet skriver

y = 5
z = 6
y = kvadrer(z)
print(f"y = {y}, z = {z}")

Her er det gjort et forsøk på å forvirre ved å bruke variablene y og z både i funksjonen og i hovedprogrammet. Men variablene i funksjonen er lokale, og vi trenger ikke ta hensyn til dem i det hele tatt. Alt vi trenger å vite er at kvadrer() returnerer den kvadrerte verdien av det vi gir inn som argument. Når z = 6, blir derfor y = kvadrer(6) = 62 = 36, og vi får skrevet ut y = 36, z = 6.

Tilbake til oppgaven

Funksjoner i Python Tutor

Oppgave 1:

Vi har bildet under av kode i Python Tutor, der vi har klikket oss fram så langt at verdien til returvariabelen er beregnet, men funksjonen ikke har returnert. Så skal vi tegne en skisse av hvordan vi tror høyre side av bildet i Python Tutor ser ut.

Oppgave i Python Tutor

Høyre side ser slik ut:

Løsningsforslag i Python Tutor

Vi ser at kvadrer er en variabel med en pil som peker til en funksjon. Vi ser også at vi har variablene y = 5 og z = 6 i hovedprogrammet, slik de er blitt opprettet i linje 6 og 7.

Videre ser vi at kvadrer() er en funksjon med lokale variabler y = 6 og z = 36. y er 6 fordi parameteren y fikk verdien 6 fra argumentet z i funksjonskallet. z er 36 fordi z er beregnet som y2 = 62 = 36. Returverdien er 36 fordi returverdien er verdien til z.

Tilbake til oppgaven

Lagre funksjoner i moduler

Oppgave 1:

Vi skal først skrive funksjonen fakultet(), slik den er vist, inn i ei tom fil, og lagre fila med navnet kombinatorikk.

Vi åpner ei ny fil i Thonny ved å velge «Fil» – «Ny», og limer inn koden under:

def fakultet(n):
    """Beregner n!"""
    if n == 0:
        return 1
    else:
        produkt = 1
        for m in range(1, n + 1):
            produkt *= m
        return produkt

Så velger vi «Fil» – «Lagre» eller «Fil» -«Lagre som», og oppgir kombinatorikk som navn. Thonny lagrer fila med navnet kombinatorikk.py, der py betyr at det dreier seg om ei fil med Python-kode.

Så skal vi åpne ei ny fil, importere fakultet() fra kombinatorikk, bruke fakultet() til å beregne fakultetet til 5, og skrive ut resultatet.

Vi åpner ei ny fil i Thonny, og skriver inn kode tilsvarende dette:

from kombinatorikk import fakultet

print(fakultet(5))

Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til fakultet som kombinatorikk.fakultet:

import kombinatorikk

print(kombinatorikk.fakultet(5))

Når vi kjører koden, får vi skrevet ut 120.

Tilbake til oppgaven

Funksjoner som kaller funksjoner

Oppgave 1:

Vi skal åpne fila kombinatorikk og legge til funksjonen kombinasjon(), slik den er vist, og lagre fila igjen.

Vi velger «Fil» – «Åpne» i Thonny, og klikker på kombinatorikk.py. Så legger vi til koden til kombinasjon() under funksjonen fakultet(). Hele fila ser nå slik ut:

def fakultet(n):
    """Beregner n!"""
    if n == 0:
        return 1
    else:
        produkt = 1
        for m in range(1, n + 1):
            produkt *= m
        return produkt

def kombinasjon(n, k):
    """Beregner antall kombinasjoner av k blant n"""
    return int(fakultet(n) / (fakultet(k) * fakultet(n - k)))

Vi har her brukt 2 tomme linjer mellom de to funksjonene, det er i henhold til stilguiden PEP 8, men det har ingen betydning for virkemåten.

Vi lagrer så fila igjen ved å velge «Fil» – «Lagre», eller trykke <ctrl>s.

Så skal vi åpne ei ny fil, importere kombinasjon() fra kombinatorikk, bruke kombinasjon() til å beregne antall kombinasjonsmuligheter når 7 elementer velges fra en mengde på 34, og skrive ut resultatet.

Vi åpner ei ny fil i Thonny, og skriver inn kode tilsvarende dette:

from kombinatorikk import kombinasjon
 
print(kombinasjon(34, 7))

Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til kombinasjon som kombinatorikk.kombinasjon:

import kombinatorikk

print(kombinatorikk.kombinasjon(34, 7))

Når vi kjører koden, får vi skrevet ut 5379616.

Tilbake til oppgaven

Oppgave 2:

Vi skal skrive en funksjon som beregner sannsynligheten for få k «kron» i n flipp med en mynt, basert på at $P(k) = {\large \binom{n}{k}} \cdot (0{,}5)^n$.

Vi har kalt funksjonen sanns_kron(), men den kan hete hva som helst. Før funksjonen importer vi kombinasjon() fra modulen kombinatorikk, fordi vi trenger den til å beregne ${\large \binom{n}{k}}$.

Koden kan se slik ut:

from kombinatorikk import kombinasjon

def sanns_kron(n, k):
    """Beregner sanns. for k kron i n flipp med en mynt"""
    return kombinasjon(n, k) * 0.5**n

Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til kombinasjon som kombinatorikk.kombinasjon:

import kombinatorikk

def sanns_kron(n, k):
    """Beregner sanns. for k kron i n flipp med en mynt"""
    return kombinatorikk.kombinasjon(n, k) * 0.5**n

Hvis vi i hovedprogrammet skriver

print(sanns_kron(7, 5))

 får vi skrevet ut 0,1640625 når vi kjører koden,

Tilbake til oppgaven

Oppgave 3:

Vi skal utvide funksjonen fra oppgave 2 slik at den beregner sannsynligheten for at en hendelse med sannsynlighet p skal inntreffe k ganger i n forsøk, basert på at $P(k) = {\large \binom{n}{k}} \cdot p^k \cdot {(1-p)}^{(n-k)}$. Funksjonen skal hete binomisk(), og ligge i fila kombinatorikk under fakultet() og kombinasjon().

Vi velger «Fil» – «Åpne» i Thonny, og klikker på kombinatorikk.py. Så legger vi til koden til den nye funksjonen, som kan se slik ut:

def binomisk(n, k, p):
    """Beregner sanns. for k i n forsøk med sannsynlighet p"""
    return kombinasjon(n, k) * p**k * (1 - p)**(n - k)

Vi lagrer så fila igjen ved å velge «Fil» – «Lagre», eller trykke <ctrl>s.

Så skal vi åpne ei ny fil, importere binomisk() fra kombinatorikk, bruke binomisk() til å beregne sannsynligheten for at en hendelse med sannsynlighet 0,2 skal inntreffe 4 ganger i 8 forsøk, og skrive ut resultatet med 5 desimaler.

Vi åpner ei ny fil i Thonny, og skriver inn kode tilsvarende dette:

from kombinatorikk import binomisk
 
print(f"{binomisk(8, 4, 0.2):.5f}")

Vi kan alternativt velge å importere hele modulen kombinatorikk. Da må vi referere til binomisk som kombinatorikk.binomisk:

import kombinatorikk
 
print(f"{kombinatorikk.binomisk(8, 4, 0.2):.5f}")

Når vi kjører koden, får vi skrevet ut 0,04588.

Tilbake til oppgaven

Rekursjon

Oppgave 1:

Vi skal skrive en rekursiv funksjon som beregner summen av de n første leddene av den harmoniske rekka ${\large\frac{1}{1}} + {\large\frac{1}{2}} + {\large\frac{1}{3}} + \dots + {\large\frac{1}{n}}$

Vi baserer oss da på at

S1 = 1

og

$S_n = {\large \frac{1}{n}} + S_{n-1}$

Denne definisjonen kan vi kode direkte:

def harmonisk(n):
    """Beregner 1/1 + 1/2 + ... + 1/n"""
    if n == 1:
        return 1
    else:
        return 1/n + harmonisk(n - 1)

I hovedprogrammet skriver vi 

print(f"{harmonisk(10):.5f}")

Når vi kjører koden, får vi skrevet ut 2,92897.

Tilbake til oppgaven

Oppgave 2:

Vi har en rekursiv funksjon, summer():

def summer(n):
    if n == 1:
        return n
    else:
        return n + summer(n - 1)

Så skal vi gjøre en analyse av koden med penn og papir, og forklare hva som blir skrevet ut når vi i hovedprogrammet skriver

print(summer(3))

Først kalles summer() opp fra print() med argument 3. Deretter kaller summer() seg selv rekursivt to ganger med argumenter lik henholdsvis 2 og 1. Deretter vil vi få returverdier på henholdsvis 1, 2 + 1 = 3 og 3 + 3 = 6, så vi får skrevet ut 6.

Så skal vi forklare hva skjer hvis vi i stedet skriver

print(summer(-3))

I dette tilfellet vil vi få en uendelig kjede av rekursive kall fordi grunnbetingelsen n = 1 aldri blir nådd. Etter noe tid vil kjøringen av koden avsluttes med en feilmelding om for stor rekursjonsdybde.

Tilbake til oppgaven

 

Løsningsforslag, lister og dictionaries

Lister

Oppgave 1:

Vi har lista demo, som ser slik ut:

demo
"a" "b" "c" "d" "e"
Så skal vi avgjøre hvordan lista vil se ut etter at vi har kjørt følgende kode i Python:

demo[1] = demo[2]
demo[3] = demo[4]

Vi husker at indeksering starter på 0, så elementet med indeks 1 er "b", elementet med indeks 2 er "c", elementet med indeks 3 er "d", og elementet med indeks 4 er "e".

Så først erstattes "b" med "c", og lista ser slik ut:

demo
"a" "c" "c" "d" "e"
Deretter erstattes "d" med "e", og lista ser slik ut:
demo
"a" "c" "c" "e" "e"

Vi kontrollerer ved å skrive kode som først oppretter demo, deretter gjør endringene, og til slutt skriver demo ut:

demo = ["a", "b", "c", "d", "e"]
demo[1] = demo[2]
demo[3] = demo[4]
print(demo)0

Vi får skrevet ut ['a', 'c', 'c', 'e', 'e'].

Tilbake til oppgaven

Oppgave 2:

Vi har lista demo, med 5 elementer, og skal forklare hvorfor vi får feilmeldingen "IndexError: list index out of range" når vi skriver

print(demo[5])

Siden indeksering starter på 0, refererer demo[5] til et sjette element som ikke finnes, og vi får derfor en feilmelding.

Tilbake til oppgaven

Oppgave 3:

Vi oppretter variabelen diverse slik:

diverse = [3, "2", 1.0]

Så skal vi avgjøre hvilken datatype følgende da har:

    • diverse. Dette er ei liste.
    • diverse[0]. Dette er element 0 i lista diverse, som er et heltall.
    • diverse[1]. Dette er element 1 i lista diverse, som er en streng.
    • diverse[2]. Dette er element 2 i lista diverse, som er et flyttall.

For å sjekke kjører vi koden

diverse = [3, "2", 1.0]
print(type(diverse))
print(type(diverse[0]))
print(type(diverse[1]))
print(type(diverse[2]))

Tilbake til oppgaven

Opprette lister

Oppgave 1:

Vi skal skrive kode for å opprette følgende:

    • Ei liste som heter lottotrekning og inneholder tallene 2, 9, 10, 15, 16, 22 og 26.
    • Ei liste som heter basis og inneholder 10 tall som alle er lik 1.
    • Ei liste som heter hurra og inneholder 3 strenger som alle er "hipp".
    • Ei liste som heter lottotall og inneholder tallene fra og med 1 til og med 34.

Etterpå skal vi bruke print() for å sjekke at listene er blitt riktige.

I lottotrekning er det ikke noe system i tallene, så vi må opprette lista ved å ramse opp innholdet:

lottotrekning = [2, 9, 10, 15, 16, 22]

I basis skal alle tallene være lik 1, så vi kan opprette lista ved å angi et element som er 1, og så indikere at dette skal gjentas 10 ganger:

basis = [1] * 10

hurra følger samme mønster som basis, så vi skriver:

hurra = ["hipp"] * 3

I lottotall skal tallene være en følge fra 1 til 34, så lista kan vi opprette ved å bruke list() og range():

lottotall = list(range(1, 35))

For å sjekke innholdet, skriver vi

print(lottotrekning)
print(basis)
print(hurra)
print(lottotall)

Tilbake til oppgaven

Liste-metoder

Oppgave 1:

Vi skal skrive Python-kode som oppretter lista demo, som ser slik ut:

demo
7 -3 8 4 8

Deretter skal vi skrive Python-kode som

    • Legger til 9 på slutten.
    • Setter inn −4 foran elementet med indeks 3.
    • Fjerner og skriver ut elementet med indeks 1.
    • Fjerner elementet med verdi 4.
    • Utvider lista med lista [6, 3, 5].

Vi oppretter først lista

demo = [7, -3, 8, 4, 8]

For å legge til 9 på slutten skriver vi

demo.append(9)

For å sette inn −4 foran elementet med indeks 3 skriver vi

demo.insert(3, -4)

For å fjerne og skrive ut elementet med indeks 1 skriver vi

print(demo.pop(1))

For å fjerne verdien 4 skriver vi

demo.remove(4)

For å utvide lista med lista [6, 3, 5] skriver vi

demo.extend([6, 3, 5])

<eller

demo += [6, 3, 5]

Etter hver operasjon skriver vi lista ut:

print(demo)

Tilbake til oppgaven

Lister i Python Tutor

Oppgave 1:

Vi skal forsøke å forutse hva som vil skje i Python Tutor når vi kjører koden under, linje for linje.

kvadrattall = []
for n in range(1, 5):
    kvadrattall.append(n**2)

Ved første klikk på «Next >» opprettes kvadrattall som en variabel med ei pil til ei tom liste. Ved andre klikk opprettes n som en variabel med verdi 1. Ved tredje klikk legges n2, det vil si 12 = 1 inn som første element i lista. Ved påfølgende klikk økes verdien til n med 1, og n2 legges til bakerst i lista. Dette fortsetter inntil n har fått verdien 4, og 42 = 16 er lagt til. (Vi husker at sluttverdien i range() ikke tas med, så 4 er siste verdi for n.) Resultatet ser slik ut:

Python Tutor etter ferdig kjøring av koden i oppgaven

Tilbake til oppgaven

Gjennomløpe lister

<>Oppgave 1:

Vi skal skrive Python-kode som oppretter ei liste som inneholder alle oddetall fra og med 1 til og med 19, og skriver dem ut, ett for ett.

For å generere oddetallene skriver vi range(1, 21, 2), som vil generere tall i skritt på 2 fra og med 1 inntil 21. (Det vil gjøre samme nytte å bruke 20 som sluttverdi, men vi holder oss til oddetall for logikkens skyld.) range() bruker vi så som argument til list(). Deretter bruker vi ei for-løkke til å hente ut og skrive ut tallene i lista. Koden kan se ut som vist under. Vi har kalt lista oddeliste, men den kan hete hva som helst.

# Oppretter ei liste med oddetallene fra 1 til 19,
# og skriver dem ut
oddeliste = list(range(1, 21, 2))
for oddetall in oddeliste:
    print(oddetall)

Tilbake til oppgaven

Oppgave 2:

Vi skal endre koden fra oppgave 1 slik at også nummeret på oddetallet skrives ut, sammen med litt forklarende tekst. Vi tar da i bruk enumerate() med startverdi 1, og bruker en f-streng i utskriften. Koden kan se slik ut:

# Oppretter ei liste med oddetallene fra 1 til 19,
# og skriver dem ut nummerert
oddeliste = list(range(1, 21, 2))
for nummer, oddetall in enumerate(oddeliste, start = 1):
    print(f"Oddetall nummer {nummer} er {oddetall}")

Tilbake til oppgaven

Oppgave 3:

Vi skal endre koden fra oppgave 1 slik at den bruker indekser til å skrive ut lista med oddetallene i omvendt rekkefølge.

Vi bruker da range() til å generere indekser som går fra siste indeks ned til første. Koden kan se ut som vist under.

# Oppretter ei liste med oddetallene fra 1 til 19,
# og skriver dem ut i baklengs rekkefølge
oddeliste = list(range(1, 21, 2))
for n in range(len(oddeliste) - 1, -1, -1):
    print(oddeliste[n])

Startverdien til range() blir len(oddeliste) − 1. Vi må trekke fra 1 fordi siste indeks i ei liste med n elementer er n − 1. Sluttverdien blir −1 fordi siste verdi i range() ikke tas med, og vi må ha med tallet 0. Skrittverdien blir −1 fordi vi går nedover i skritt på 1.

Alternativt setter vi startverdien til len(oddeliste) og sluttverdien til 0, og trekker fra 1 når vi bruker indeksen, slik det er vist under.

# Oppretter ei liste med oddetallene fra 1 til 19,
# og skriver dem ut i baklengs rekkefølge
oddeliste = list(range(1, 21, 2))
for n in range(len(oddeliste), 0, -1):
    print(oddeliste[n - 1])

Tilbake til oppgaven

«break»

Oppgave 1:

En student har skrevet koden under, som er ment å la brukeren skrive inn en streng, og så skrive ut en melding om strengen inneholder minst én vokal::

# Leser inn streng og sjekker om den inneholder vokal
streng = input("Streng å søke i: ")
for vokal in "aeiouyæøå":
    if vokal in streng:
        print("Strengen inneholder vokal.")
    else:
        print("Strengen inneholder ingen vokaler.")

Men koden virker ikke som tenkt, og vi skal forklare hva problemet er og skrive koden riktig.

Problemet er at koden for hver enkelt vokal i strengen "aeiouyæøå" skriver ut om akkurat den vokalen finnes i strengen eller ikke. Her må vi i stedet bruke break og else:

# Leser inn streng og sjekker om den inneholder vokal
streng = input("Streng å søke i: ")
for vokal in "aeiouyæøå":
    if vokal in streng:
        print("Strengen inneholder vokal.")
        break
else:
    print("Strengen inneholder ingen vokaler.")

Hvis vi i denne koden finner en vokal i strengen, får vi skrevet ut teksten Strengen inneholder vokal., og gjennomløpet av løkka avbrytes med break. else-blokka blir da ikke utført. Hvis løkka ikke blir avbrutt, men kjøres til siste vokal er sjekket, blir else-blokka utført, og teksten Strengen inneholder ingen vokaler. skrives ut.

Tilbake til oppgaven

Søke i lister

Oppgave 1:

Vi skal skrive kode som oppretter lista ensifrede, som inneholder heltallene fra og med 1 til og med 9, og skriver ut hvor mange av tallene i lista som er delelige med 4.

For å opprette lista bruker vi hintet, og skriver list(range(1, 10)).

Så bruker vi ei for-løkke til å gjennomløpe lista og telle hvor mange tall i lista som er delelige med 4. Koden kan se slik ut:

# Oppretter ei liste med tallene fra 1 til 9,
# og teller antall tall delelig med 4 i lista
ensifrede = list(range(1, 10))
antall = 0
for tall in ensifrede:
    if tall % 4 == 0: # Tallet er delelig med 4
    antall += 1
print(f"Lista inneholder {antall} tall som er delelige med 4.")

Tilbake til oppgaven

Opprette lister med inline-«for»

Oppgave 1:

Vi har koden under, som oppretter ei liste, y, med kvadratet av heltallene fra 1 til 10. 

# Oppretter lista y med tallene 1, 4, 9, ..., 100
y = []
for n in list(range(1, 11))
    y.append(n**2)

Så skal vi skrive om koden slik at den bruker inline-for til å opprette y. Koden kan se slik ut:

# Oppretter lista y med tallene 1, 4, 9, ..., 100
y = [n**2 for n in list(range(1, 11))]

Tilbake til oppgaven

Oppgave 2:

Vi har koden under, som oppretter ei liste, x, med heltallene fra 1 til 10, og ei liste, z, med 5n2 + 3n − 4 for hver n i x.

# Oppretter lista x med tallene 1 ... 10,
# og lista z med 5*n**2 + 3 * n - 4 for hver n i x
x = list(range(1, 11))
z = []
for n in x:
    z.append(5 * n**2 + 3 * n - 4)

Så skal vi skrive om koden slik at den bruker inline-for til å opprette z. Koden kan se slik ut:

# Oppretter lista x med tallene 1 ... 10,
# og lista z med 5n**2 + 3n - 4 for hver n i x
x = list(range(1, 11))
z = [5 * n**2 + 3 * n - 4 for n in x]

Tilbake til oppgaven

Dictionaries

Oppgave 1:

Vi skal skrive kode som

    • Oppretter en dictionary som heter landsprefiks, og inneholder følgende nøkkel-verdi-par: "Afghanistan": 93, "Albania": 355, "Algerie": 213, "Andorra": 0, "Angola": 244.

Vi oppretter landsprefiks som en dictionary ved å angi par med nøkler og verdier mellom krøllparenteser:

landsprefiks = {
    "Afghanistan": 93,
    "Albania": 355,
    "Algerie": 213,
    "Andorra": 0,
    "Angola": 244
}
    • Endrer verdien tilknyttet nøkkelen "Andorra" til 376 og legger til paret "Anguilla": 1264.

Vi bruker metoden update() og skriver:

landsprefiks.update({"Andorra": 376, "Anguilla": 1264})

Alternativt kan vi skrive

landsprefiks["Andorra"] = 376
landsprefiks["Anguilla"] = 1264
    • Slår opp og skriver ut verdien knyttet til nøkkelen "Angola".

Vi bruker metoden get() med "Angola" som nøkkel, og skriver:

print(landsprefiks.get("Angola"))
    • Slår opp og skriver ut meldingen "Ukjent land" ved oppslag med nøkkelen "Argentina".

Vi bruker igjen get(), men tar med "Ukjent land" som en streng get() skal returnere hvis nøkkelen ikke finnes:

print(landsprefiks.get("Argentina", "Ukjent land"))

Tilbake til oppgaven

Telle med dictionaries

Oppgave 1:

Vi har koden under, som bruker funksjonen randint() fra modulen random til å simulere kast med to terninger, og registrere summen av antall øyne på de to terningene.

from random import randint

oyne = randint(1, 6) + randint(1, 6)

Så skal vi skrive Python-kode som gjør en million slike simuleringer og teller opp og skriver ut hvor ofte de forskjellige summene av øyne forekommer. Utskriften skal være sortert på sum øyne.

Vi bruker de samme mekanismene som i eksempelet med å telle forekomster av tegn i en streng. Vi må også ha ei løkke som gjennomløpes en million ganger.

Koden kan se slik ut:

from random import randint

antall = {}  # Tom dictionary
for _ in range(1000000):
    oyne = randint(1, 6) + randint(1, 6)
    # Øk antall forekomster med 1
    antall.update({oyne: antall.get(oyne, 0) + 1})
antall = sorted(antall.items())
print(antall)

Tilbake til oppgaven

Løsningsforslag, mer om Python

Python Tutor

Oppgave 1:

Vi skal legge inn koden under i Python Tutor, og bruke «Next >» til å gå gjennom den skritt for skritt.

for n in range(1, 5):
    if n % 2 == 0:
        print(f"{n} er et partall")
    else:
        print(f"{n} er et oddetall")

Illustrasjon av kjøring i Python Tutor

Mens vi klikker, ser vi at pila i hvert gjennomløp av løkka peker på rad 1 og 2, men bare annen hver gang på rad 3 og 5, avhengig av om n er partall eller oddetall.

Tilbake til oppgaven

Konstanter

Oppgave 1:

Vi skal skrive Python-kode som leser inn et antall nautiske mil, konverterer til kilometer, og skriver ut resultatet med 3 desimaler. Det er oppgitt at 1 nm = 1,852 km, og vi skal representere konverteringsfaktoren som en konstant i koden.

Koden kan se slik ut:

# Leser inn nautiske mil og konverterer til kilometer
NM_TIL_KM = 1.852
nm = float(input("Oppgi antall nautiske mil: "))
km = nm * NM_TIL_KM
print(f"{nm:.3f} nautiske mil er {km:.3f} kilometer.")

Tilbake til oppgaven

Metoder

Oppgave 1:

Vi har Python-koden

hilsen = "GOD MORGEN, ALLE SAMMEN!"

og skal skrive kode som skriver ut hilsen med bare små bokstaver.

Vi leter på referansesiden Python String Methods. og finner ut at metoden vi trenger heter lower(). Så koden blir

print(hilsen.lower())

Tilbake til oppgaven

Import fra moduler

Oppgave 1:

Vi skal skrive Python-kode som bruker funksjonen randint() i modulen random til å simulere terningkast.

Koden kan se slik ut:

from random import randint

print(f"Terningkast {randint(1, 6)}")

Alternativt

import random

print(f"Terningkast {random.randint(1, 6)}")

Tilbake til oppgaven

Oppgave 2:

Vi skal endre koden fra oppgave 1 slik at randint() blir importert med alias rint() og brukt i koden.

Vi legger da til teksten as rint bak randint, og bruker rint() i stedet for randint() i koden.

from random import randint as rint

print(f"Terningkast {rint(1, 6)}")

Hvis vi velger varianten med å importere hele modulen, kan vi bare gi alias til modulnavnet, ikke enkeltfunksjoner i modulen.

Tilbake til oppgaven

Logiske operatorer

Oppgave 1:

Vi skal analysere Python-koden under og avgjøre om den vil skrive ut True eller False

x = -3
y = 4
print( x > 0 or x < y)

Her er to betingelser. Den første, x > 0, er False fordi x = −3. Den andre, x < y, er True fordi x = −3 og y = 4. Siden de to betingelsene er bundet sammen med or, og minst én av dem er True, vil det bli skrevet ut True.

Tilbake til oppgaven

Oppgave 2:

Vi skal analysere to linjer med Python-kode og avgjøre om de vil skrive ut True eller False.

print(True or False and False)

Siden and har høyere prioritet enn or, får vi:
True or False and FalseTrue or FalseTrue
Python vil skrive ut True.

print(True and False or not(False and True))

Siden parenteser beregnes først, deretter not, and og or, får vi:
True and False or not(False and True) → True and False or not(False) → True and False or TrueFalse or TrueTrue
Python vil skrive ut True.

Tilbake til oppgaven

Boolsk algebra

Oppgave 1:

Ved å sette opp sannhetstabeller skal vi bevise:

    • a == True er det samme som a.

a kan enten være True eller False, og vi kan sette opp følgende sannhetstabell:

a True False
a == True True == TrueTrue False == TrueFalse

Vi ser at resultatet er likt i begge tilfeller.

    • not (a or b) er det samme som not a and not b.

a og b kan være henholdsvis True og False, og vi kan sette opp følgende sannhetstabell:

a True True False False
b True False True False
not (a or b) not (True or True)
not TrueFalse
not (True or False)
not TrueFalse
not (False or True)
not TrueFalse
not (False or False)
not False True
not a and not b not True and not True
False and FalseFalse
not True and not False
False and TrueFalse
not False and not True
True and FalseFalse
not False and not False
True and TrueTrue

Vi ser at resultatet er likt i alle 4 tilfeller.

Tilbake til oppgaven

Løsningsforslag, forgreininger og løkker

Forgreininger med «if»

Oppgave 1:

Et krydder som selges i løsvekt, koster kr 0,90 per gram hvis vi kjøper inntil 25 gram og kr 0,80 per gram hvis vi kjøper 25 gram eller mer. Vi skal skrive Python-kode som leser inn vekt og skriver ut gramprisen. Koden kan se slik ut:

# Les inn vekt og skriv ut grampris på krydder
vekt = int(input("Oppgi antall gram: "))
if vekt < 25:
    pris = 0.9
else:
    pris = 0.8
print(f"Grampris er kr {pris}.")

Tilbake til oppgaven

Oppgave 2:

En student har skrevet koden under for å doble verdien til variabelen x hvis x er større enn 0, men la x være uendret ellers:

if x > 0:
    x *= 2
else:
    x = x

En annen student har skrevet koden under for å gjøre det samme:

if x > 0:
    x *= 2
else:
    pass

Vi skal vurdere om én av de to variantene er bedre enn den andre, og om koden eventuelt kan skrives på en enklere måte.

Begge variantene inneholder kode som ikke har noen effekt, så ingen av dem er særlig bra. Men å sette en variabel lik seg selv, slik som x = x, er alltid meningsløst, så den første varianten er kanskje håret dårligere enn den siste.

Det er ikke uvanlig at studenter tar med en else som ikke har noen effekt, slik som her. Grunnen er antakelig at vi ofte bruker else sammen med if, og at de derfor tror at det er et krav å ha med else. Som en plassholder putter de så inn kode som ikke gjør noe. Men hvis vi ikke har meningsfull kode til else-blokka, sløyfer vi bare else. Så en kode som gjør akkurat det samme, kan se slik ut:

if x > 0:
    x *= 2

Tilbake til oppgaven

Oppgave 3:

I koden under er det brukt en innrykket kommentar i stedet for kodeordet pass, og vi skal vurdere om koden er riktig.

radius = int(input("Oppgi radius: "))
if radius >= 0:
# Kommer senere
else:
    print("Radius kan ikke være negativ.")

Koden er ikke riktig. Kommentarer blir ignorert av Python, så slik Python ser det, står det ikke noe på den innrykkede linja. Vi har derved en tom kodeblokk, og vi får en feilmelding.

Tilbake til oppgaven

Strukturere «if»

Oppgave 1:

Vi skal fjerne overflødige betingelser i Python-koden under.

vekt = int(input("Oppgi vekt i gram: "))
if vekt < 25:
    pris = 0.90
elif 25 <= vekt < 50:
    pris = 0.80
elif 50 <= vekt < 100:
    pris = 0.75
elif vekt >= 100:
    pris = 0.70
print(f"Total pris på {vekt} g krydder er kr {pris * vekt:.2f}")

Hvis vi kommer til første elif, vet vi allerede at 25 <= vekt, så denne betingelsen kan fjernes. Hvis vi kommer til andre elif, vet vi allerede at 50 <= vekt, så denne betingelsen kan fjernes. Hvis vi kommer til tredje elif, vet vi allerede at vekt >= 100, så denne betingelsen kan erstattes med else. Koden kan se ut som vist under:

vekt = int(input("Oppgi vekt i gram: "))
if vekt < 25:
    pris = 0.90
elif vekt < 50:
    pris = 0.80
elif vekt < 100:
    pris = 0.75
else:
    pris = 0.70
print(f"Total pris på {vekt} g krydder er kr {pris * vekt:.2f}")

Så skal vi skrive om koden slik at betingelsene sjekkes i omvendt rekkefølge. Koden kan da se slik ut:

vekt = int(input("Oppgi vekt i gram: "))
if vekt >= 100:
    pris = 0.70
elif vekt >= 50:
    pris = 0.75
elif vekt >= 25:
    pris = 0.80
else:
    pris = 0.90
print(f"Total pris på {vekt} g krydder er kr {pris * vekt:.2f}")

Tilbake til oppgaven

Nøstede forgreininger

Oppgave 1:

Vi har koden under, som beregner og skriver ut pris på et kjøp av lysdioder:

# Leser inn antall lysdioder, og skriver ut stykkpris og totalpris
antall = int(input("Hvor mange lysdioder vil du kjøpe? "))
if antall < 10:
    stykkpris = 3.50
elif antall < 100:
    stykkpris = 3.00
else:
    stykkpris = 2.50
print(f"{antall} lysdioder à kr {stykkpris:.02f}, totalt kr {antall*stykkpris:.02f}.")
    1. Vi skal utvide koden med en ytre if som sjekker at antall kjøpte dioder er større enn 0, og skriver ut en feilmelding hvis ikke.
       
      Vi skriver en ytre if, slik oppgaven sier, og legger den eksisterende koden inn i en else, slik at den bare aktiveres hvis antall dioder er større enn 0, markert med gult:
# Leser inn antall lysdioder, og skriver ut stykkpris og totalpris
antall = int(input("Hvor mange lysdioder vil du kjøpe? "))
if antall <= 0:
    print("Antall dioder må være større enn 0.")
else:
    if antall < 10:
        stykkpris = 3.50
    elif antall < 100:
        stykkpris = 3.00
    else:
        stykkpris = 2.50
    print(f"{antall} lysdioder à kr {stykkpris:.02f}, totalt kr {antall*stykkpris:.02f}.")
    1. Vi skal utvide ytre if slik at den også sjekker om antall kjøpte dioder er 1000 eller mer, og i så fall skriver at kjøperen skal kontakte kundeservice.
       
      Vi har nå fått en ny betingelse, og må utvide ytre if med en elif, markert med gult:
# Leser inn antall lysdioder, og skriver ut stykkpris og totalpris
antall = int(input("Hvor mange lysdioder vil du kjøpe? "))
if antall <= 0:
    print("Antall dioder må være større enn 0.")
elif antall >= 1000:
    print("Kontakt kundeservice for et tilbud!")
else:
    if antall < 10:
        stykkpris = 3.50
    elif antall < 100:
        stykkpris = 3.00
    else:
        stykkpris = 2.50
    print(f"{antall} lysdioder à kr {stykkpris:.02f}, totalt kr {antall*stykkpris:.02f}.")

Tilbake til oppgaven

«for»-løkker

Oppgave 1:

Vi skal skrive Python-kode som beregner og skriver ut de 10 første kvadrattallene.

Vi lager ei for-løkke som bruker range() til å gå gjennom heltallene fra og med 1 til og med 10, og for hvert gjennomløp av løkka skriver ut tallet opphøyd i andre, for eksempel slik:

# Skriver ut kvadratet av tallene fra 1 til 10
for n in range(1, 11):
    print(n**2)

Vi husker at sluttverdien i range() ikke tas med, derfor står det 11, ikke 10.

Så skal vi endre koden slik at den bare skriver ut kvadratet av oddetallene i samme tallområde. Det kan vi gjøre ved å legge inn en skrittverdi på 2 i range(), markert med gult under:

# Skriver ut kvadratet av oddetallene fra 1 til 10
for n in range(1, 11, 2):
    print(n**2)

Tilbake til oppgaven

Oppgave 2:

Vi skal analysere hva for-løkkene under skriver ut:

for n in range(5, 1, -2):
    print(n)

Her starter vi med n = 5 og går i skritt på −2 så lenge n > 1, så vi får skrevet ut 5 og 3.

for n in range(-5, 10, 2):
   print(n)

Her starter vi med n = −5 og går i skritt på 2 så lenge n < 10, så vi får skrevet ut −5, −3, −1, 1, 3, 5, 7 og 9.

Tilbake til oppgaven

Oppgave 3:

Vi skal modifisere koden under slik at den skriver ut tallene mellom 1 og 100 som er delelige med 5 i stedet for delelige med 7.

# Skriver ut tallene mellom 1 og 100 som er delelige med 7
for n in range(1, 101):
    if n % 7 == 0:
        print(f"{n} er delelig med 7.")

Vi må erstatte 7 med 5 i uttrykket n % 7. Vi modifiserer også kommentaren og print() litt for å gjenspeile den nye situasjonen. Endringer er markert med gult:

# Skriver ut tallene mellom 1 og 100 som er delelige med 5
for n in range(1, 101):
    if n % 5 == 0:
        print(f"{n} er delelig med 5.")

Tilbake til oppgaven

Oppgave 4:

I koden under er linja med print() bare rykket inn én gang, og vi skal vurdere hvilken effekt dette vil ha på koden i forhold til at den er rykket inn to ganger.

for n in range(1, 101):
    if n % 7 == 0:
        pass
    print(f"{n} er delelig med 7.")

Vi ser på innrykket at print() nå ikke lenger tilhører if-strukturen, men bare for-strukturen. Derfor vil vi feilaktig få utskrift for hvert gjennomløp i løkka, uavhengig av om n er delelig med 7 eller ikke.

Tilbake til oppgaven

«while»-løkker

Oppgave 1:

Vi skal skrive Python-kode som skriver ut alle kubikktall av partall, altså 23, 43, 63, … , som er mindre eller lik 1000.

Vi trenger ei løkke med en løkkevariabel som starer på 2 og øker i skritt på 2. Vi vet imidlertid ikke hvor mange ganger løkka skal gjnnomløpes, så vi kan ikke bruke ei for-løkke. I stedet bruker vi ei while-løkke med en betingelse som gjør at løkka gjennomløpes så lenge variabelen opphøyd i 3 er mindre eller lik 1000. For eksempel slik:

# Skriver ut kubikktall av partall mindre eller lik 1000
n = 2
while n**3 <= 1000:
    print(n**3)
    n += 2

Tilbake til oppgaven

Evige løkker

Oppgave 1:

Python-koden under er ment å skrive ut 2-gangen, altså 2, 4, 6, 8, 10, 12, 14, 16, 18, 20. Men den inneholder en feil som forårsaker ei evig løkke, og vi skal forklare hva feilen er og hvordan den kan rettes.

# Skriver ut 2-gangen
n = 1
while n <= 10:
    print(n * 2)

Problemet er at vi ikke øker verdien til n i løkka. Derved vil n forbli 1, betingelsen n <= 10 er alltid sann, og gjennomløpet av løkka fortsetter evig. Løsningen er å sette inn kodelinja n +=1 etter print().

Tilbake til oppgaven

Nøstede løkker

Oppgave 1:

Vi skal gå gjennom koden under med penn og papir, og skrive opp rekkefølgen de forskjellige linjene vil bli utført i.

Nøstet løkke i Python Tutor

For hver n i den ytre løkka vil m gjennomløpe 1, 2, 3 i den indre løkka, og for hver m vil print() på linje 3 bli utført. Hver gang den indre løkka er ferdig, vil print() på linje 4 bli utført. Siden pila går til linjer med range() også idet sluttverdien nås, vil linjene bli utført i rekkefølge rekkefølge
1, 2, 3, 2, 3, 2, 3, 2, 4, 1, 2, 3, 2, 3, 2, 3, 2, 4, 1, 2, 3, 2, 3, 2, 3, 2, 4, 1..

Dette kan vi verifisere ved å klikke gjennom koden i Python Tutor.

Tilbake til oppgaven

Løsningsforslag, grunnleggende Python

Kom i gang med Python

Oppgave 1:

Vi skal legge inn Python-kode som skriver ut strengen Heisan, alle!, i editoren.

Vi starter Thonny, og skriver

print("Heisan, alle!")

i editoren.

Så skal vi lage ei mappe til Python-filene, og lagre koden der med et velvalgt filnavn. Vi oppretter ei mappe slik vi pleier på vår datamaskin, klikker på «Fil» – «Lagre» i Thonny, navigerer fram til mappa vi laget, skriver inn et passende filnavn, for eksempel heisan, og klikker på «Lagre».

Så skal vi kjøre koden, det gjør vi ved å klikke på den lille, grønne pila over editoren. Python skriver ut Heisan, alle! i kommandofeltet.

Tilbake til oppgaven

Aritmetiske operatorer og regneoperasjoner

Oppgave 1:

Vi skal bruke Python til å regne ut 7 + 42.

I editoren skriver vi

print(7 + 4**2)

Når vi kjører koden, svarer Python 23.

Tilbake til oppgaven

Oppgave 2:

Vi skal beregne 3 + (8 + 2) / 5 * 3 i hodet, eller med penn og papir, og så sjekke resultatet i Python.

Her er operatorer på tre prioritetsnivåer. Parenteser vil bli regnet ut først, deretter vil / og * bli brukt, fra venstre mot høyre, og til slutt vil + bli brukt. Så vi får

3 + (8 + 2) / 5 * 3 → 3 + 10 / 5 * 3 → 3 + 2 * 3 → 3 + 6 → 9

I editoren skriver vi

print(3 + (8 + 2) / 5 * 3)

Når vi kjører koden, svarer Python 9.0. Resultatet er et desimaltall fordi utregningen involverer en divisjon.

Tilbake til oppgaven

Oppgave 3:

Vi skal forklare hvorfor vi får −1 hvis vi skriver -1**2 i Python selv om −1 opphøyd i andre er 1,

Grunnen er at operatoren for eksponentiering har høyere prioritet enn unært minus, så uttrykket blir tolket som -(1**2) = -1.

For å få det riktig må vi sette inn parenteser: (-1)**2.

Tilbake til oppgaven

Variabler

Oppgave 1:

Vi skal regne ut for hånd hvilke verdier for variablene a, b og c som vil bli skrevet ut av Python-koden under.

a = 1
b = 2
c = 3
a = a + b + c
b = a + b + c
c = a + b + c
print(a, b, c)

Det som er viktig å forstå her, er at koden kjører linje for linje fra toppen og nedover, så hvis en verdi endrer seg i ei linje, er det den nye verdien som brukes i neste linje, markert med henholdsvis gult og blått for a og b.

a = a + b + c → a = 1 + 2 + 3 = 6.

b = a + b + c → b = 6 + 2 + 3 = 11.

c = a + b + c → c = 6 + 11 + 3 = 20.

Når vi kjører koden, svarer Python 6 11 20.

Tilbake til oppgaven

Oppgave 2:

Vi skal regne ut for hånd hvilket tall Python-koden under skriver ut:

x = 5
x *= 2
y = x + 3 * x
y += 2
print(y)

I første linje gis x verdien 5.
I andre linje gis x verdien av seg selv multiplisert med 2, altså 5 * 2 = 10.
I tredje linje gis y verdien av x pluss verdien av x multiplisert med 3, altså 10 + 3 * 10 = 40.
I fjerde linje gis y verdien av seg selv addert med 2, altså 40 + 2 = 42.

Når vi kjører koden, svarer Python 42.

Tilbake til oppgaven

Oppgave 3:

Vi skal finne to feil i Python-koden under:

x1 = 5
2x = 11
x3 = 2x + X1
print(x3)

Den ene feilen er at 2x ikke er et gyldig variabelnavn fordi det ikke begynner med en bokstav eller understreking. Den andre feilen er at vi gir en verdi til variabelen x1, men senere refererer til X1, som ikke er samme variabel fordi vi bruker liten x i det første tilfellet og stor X i det andre. Kaller vi 2x for x2, og bruker x1 i stedet for X1, får vi koden under, som skriver ut 16, når vi kjører den.

x1 = 5
x2 = 11
x3 = x2 + x1
print(x3)

Tilbake til oppgaven

Strenger

Oppgave 1:

Vi skal analysere Python-koden under og avgjøre hva den skriver ut.

innledning = "HIPP " * 2
hilsen = (innledning + "HURRA! " ) * 3
print(hilsen)

I første linje blir strengen "HIPP " repetert 2 ganger og tilordnet til variabelen innledning. Vi får derfor at innledning = "HIPP HIPP ".
I andre linje blir variabelen innledning først slått sammen med strengen "HURRA! " til "HIPP HIPP HURRA! ". Deretter blir denne strengen repetert 3 ganger og tilordnet til variabelen hilsen. Vi får derfor at hilsen = "HIPP HIPP HURRA! HIPP HIPP HURRA! HIPP HIPP HURRA! ".
I tredje linje blir så denne strengen skrevet ut.

Tilbake til oppgaven

Oppgave 2:

Vi skal skrive Python-kode som tilordner en streng vi selv velger, til variabelen navn, og et tall vi selv velger, til variabelen alder, og så setter sammen navn og alder med en forklarende tekst i en formatert streng som skrives ut med print(). Koden kan se slik ut:

navn = "Metusalem"
alder = 969
print(f"{navn} er {alder} år.")

Tilbake til oppgaven

Datatyper

Oppgave 1:

Vi skal avgjøre hvilken datatype resultatet får når vi gjør forskjellige aritmetiske beregninger.

Beregninger som bare involverer heltall, resulterer i heltall, med mindre vi utfører divisjon. Derfor blir følgende heltall:
2 * 4, som er 8
7 // 3, som er 2

Mens følgende blir flyttall:
4 / 2, som er 2.0

Beregninger som involverer flyttall, resulterer alltid i flyttall, også heltallsdivisjon. Derfor er følgende flyttall:
2 * 4.0, som er 8.0
2.0 * 4.0, som er 8.0
4.0 / 2.0, som er 2.0
7.0 // 3, som er 2.0

Når vi multipliserer et heltall og en streng, blir resultatet en streng. Derfor er følgende en streng:
2 * "hei", som er "heihei"

Vi kan ikke multiplisere et flyttall og en streng. Det følgende resulterer derfor i en feilmelding: 
2.0 * "hei"

Hvilke datatyper en beregning gir, kan vi kontrollere ved hjelp av Python-funksjonen type(). Skriver vi for eksempel

type(7.0 // 3)

svarer Python <class float>.

Tilbake til oppgaven

Innebygde Python-funksjoner

Oppgave 1:

Det finnes ikke løsningsforslag til denne oppgaven, som bare dreier seg om å eksperimentere.

Oppgave 2:

Koden under bruker 3 kodelinjer på å konvertere to strenger til flyttall og finne det største av de to tallene ved hjelp av funksjonen max(), og vi skal skrive om koden slik at alt utføres i en enkelt kodelinje.

x = float("2.35")
y = float("2.36")
z = max(x, y)

Vi erstatter x i max() med funksjonen som returnerer verdien til x, altså float("2.35"), og tilsvarende for y:

z = max(float("2.35"), float("2.36"))

Tilbake til oppgaven

Innlesing

Oppgave 1:

Vi skal skrive Python-kode som spør etter og leser inn et mobilnummer, og så skriver ut Ringer deg på etterfulgt av nummeret som blir skrevet i inn.

Når vi skal lese inn noe, bruker vi funksjon input(), og vi angir et passende prompt som argument, for eksempel:

mobilnr = input("Hva er mobilnummeret ditt? ")

Her vil strengen brukeren skriver inn, bli tilordnet variabelen mobilnr. Denne kan vi så skrive ut i en formatert streng, for eksempel slik:

print(f"Ringer deg på {mobilnr}")

Alternativt kan vi droppe variabelen mobilnr og bruke returverdien fra input() direkte i et argument til print().

print(f"Ringer deg på {input('Hva er mobilnummeret ditt? ')}")

Men den siste varianten er kanskje i overkant uoversiktlig. Legg også merke til at vi i den siste varianten må bruke enkle anførselstegn på strengen 'Hva er mobilnummeret ditt? ' fordi denne strengen ligger inni en streng avgrenset av doble anførselstegn.

Tilbake til oppgaven

Oppgave 2:

Vi skal skrive Python-kode som først spør etter fornavn, så etter etternavn, og så skriver ut Hei, etterfulgt av fornavn og etternavn.

Denne oppgaven følger malen fra forrige oppgave, vi må bare utvide med å bruke input() to ganger:

fornavn = input("Hva er fornavnet ditt? ")
etternavn = input("Hva er etternavnet ditt? ")
print(f"Hei, {fornavn} {etternavn}!")

Å slå disse tre linjene sammen etter mal fra det vi gjorde i forrige oppgave vil bli veldig uoversiktlig, selv om det teknisk sett ikke er noe i veien for det.

Tilbake til oppgaven

Oppgave 3:

Vi skal skrive Python-kode som leser inn verdien til to heltall, x og y, og så skriver ut tallene og produktet av dem.

Denne oppgaven følger malen fra forrige oppgave, men vi må huske å bruke funksjonen int() til å konvertere strengene vi leser inn til heltall:

x = int(input("Oppgi verdien til x: "))
y = int(input("Oppgi verdien til y: "))
print(f"{x} * {y} = {x * y}")

Tilbake til oppgaven

Kopiere dictionaries

I artikkelen om å kopiere lister ser vi at når vi tilordner ei liste til en annen variabel, blir det ikke utført noen kopiering av innholdet, den andre variabelen blir bare et nytt navn på den samme lista. Det samme er tilfelle med dictionaries.

For å illustrere bruker vi koden fra eksempel 1 i artikkelen om å kombinere dictionaries med dictionaries og lister:

agentbil = {
    "eier": "James Bond",
    "merke": "Aston Martin",
    "motordata": {"effekt": 125, "slagvolum": 2.1, "dreiemoment": 225},
    "dekkdata": {"bredde": 155, "profil": 70, "felg": 12}
}

Så skriver vi

nybil = agentbil

Da blir nybil en referanse til samme dictionary som agentbil, som vi kan se i Python Tutor:

Illustrasjon av flere referanser til samme dictionary

På samme måte som lister, har også dictionaries en copy()-metode, som genererer en ny dictionary. Hvis vi skriver

nybil = agentbil.copy()

blir nybil en ny dictionary, som vi kan se i Python Tutor:

Illustrasjon av grunn kopi av dictionary

Vi ser imidlertid at dictionaries med nøkler "motordata" og "dekkdata" inni agentbil ikke er blitt kopiert, det er bare gjort en grunn kopiering. Vil vi gjøre en dyp kopiering, kan vi bruke funksjonen deepcopy() fra modulen copy, på samme måte som med lister, slik det beskrives i artikkelen om grunn og dyp kopiering. Skriver vi

from copy import deepcopy
 
nybil = deepcopy(agentbil)

blir også dictionaries inni agentbil kopiert, som vi kan se i Python Tutor:

Illustrasjon av dyp kopi av dictionary

Kilder

    • Sweigart A. (2021). Beyond the basic stuff with Python. no starch press

Kombinere dictionaries med dictionaries og lister

Akkurat som vi kan ha lister inni lister, kan vi ha dictionaries inni dictionaries. Eksempel 1 har en dictionary som heter agentbil, der verdiene til nøklene "motordata" og "dekkdata" er egne dictionaries.

Eksempel 1:

agentbil = {
    "eier": "James Bond",
    "merke": "Aston Martin",
    "motordata": {"effekt": 125, "slagvolum": 2.1, "dreiemoment": 225},
    "dekkdata": {"bredde": 155, "profil": 70, "felg": 12}
}

I Python Tutor ser det slik ut:

Illustrasjon av dictionary i dictionary

For å referere til en nøkkel i en dictionary inni en dictionary må vi bruke 2 indekser, én for hver dictionary. For eksempel agentbil["dekkdata"]["bredde"] for å finne dekkbredden til agentbil i eksempel 1.

Vi kan også ha dictionaries i lister. Eksempel 2 har ei liste som inneholder dictionaries som kopler postnummer og sted.

Eksempel 2:

postinfo = [
    {"nummer": 4225, "navn": "Lyngdal"},
    {"nummer": 4586, "navn": "Korshamn"},
    {"nummer": 4590, "navn": "Snartemo"},
    {"nummer": 4596, "navn": "Eiken"}
]

I Python Tutor ser det slik ut:

Illustrasjon av dictionary i liste

For å referere til en nøkkel i en dictionary inni ei liste, må vi bruke 2 indekser, én for lista og én for dictionary. For eksempel vil postinfo[1]["navn"] i eksempel 2 være "Korshamn" fordi element nummer 1 i postinfo inneholder en dictionary med nøkkel-verdi-paret "navn": "Korshamn".

Koden under vil gjennomløpe lista i eksempel 2 og skrive ut informasjon om postnummer og navn.

for sted in postinfo:
    print(f"{sted['navn']} har postnummer {sted['nummer']}.")

Vi kan også lister i dictionaries. Eksempel 3 inneholder en dictionary med forfattere som nøkler og lister med boktitler som verdier.

Eksempel 3:

katalog = {
    "Knut Hamsun": ["Sult", "Markens grøde", "Victoria"],
    "Ernest Hemingway": ["Og solen går sin gang", "Den gamle mannen og havet"],
    "Roald Dahl": ["Charlie og sjokoladefabrikken", "Heksene", "Matilda", "SVK"]
}

I Python Tutor ser det slik ut:

Illustrasjon av lister i dictionary

For å referere til et element i ei liste inni en dictionary, må vi bruke 2 indekser, én for dictionary og én for lista. For eksempel vil katalog["Roald Dahl"][1] i eksempel 3 være "Heksene" fordi element nummer 1 i lista knyttet til nøkkel "Roald Dahl", inneholder "Heksene".

Koden under vil gjennomløpe lista i eksempel 3 og skrive ut informasjon om forfattere og bøker.

for forfatter, titler in katalog.items():
    print(f"{forfatter} har skrevet:", end = " ")
    for tittel in titler:
        print(f"'{tittel}'", end = " ")
    print()

Det er ingen teoretisk grense for hvor mange dictionaries og lister vi kan nøste inni hverandre, men i praksis blir det sjelden bruk for mer enn 2-3 nivåer.

Kilder

    • Matthes A. (2019). Python Crash Course. no starch press

Grunn og dyp kopiering

I eksempel 1 i artikkelen om lister som inneholder lister har vi ei liste som inneholder tre andre lister:

grader = [[12, 10, 14, 7, 8, 11, 10], [10, 7, 9, 6, 6, 8, 15], [10, 5, 3, 6, 4, 3, 2]]

I Python Tutor ser det slik ut:

Illustrasjon av lister i lister

Så skriver vi

grader_kopi = grader

Som vi ser i artikkelen om å kopiere lister, blir da grader_kopi bare en ny referanse til samme liste:

Illustrasjon av flere referanser til samme liste

Men som vi også ser i i artikkelen om å kopiere lister, hvis vi skriver

grader_kopi = grader[:]

eller

grader_kopi = grader.copy()

blir grader_kopi ei ny liste:

Illustrasjon av grunn kopi av liste

Imidlertid ser vi at de tre listene inni grader ikke er blitt kopiert. grader_kopi er blitt ei ny liste, men den refererer til de samme tre listene som grader. Denne måten å kopiere lister på gir nemlig bare det vi kaller grunn kopiering. Selve lista grader blir kopiert, men ikke listene den refererer til.

Det motsatte av grunn kopiering er dyp kopiering. Da kopieres også listene det refereres til, ikke bare det øverste nivået. For å utføre dyp kopiering kan vi bruke funksjonen deepcopy() fra modulen copy. Hvis vi skriver

from copy import deepcopy

grader_kopi = deepcopy(grader)

ser resultatet slik ut:

Illustrasjon av dyp kopi av liste

Nå har vi også fått kopier av de tre listene inni grader.

Kilder

    • Sweigart A. (2021). Beyond the basic stuff with Python. no starch press