Tilbake
1.1

1.1 Variabler, datatyper og konvertering

Tall, tekst og boolske verdier; heltalls- vs. flyttallsdeling; og int()/float()/str()-konvertering — som er første fallgruve ved fil- og input-data.

45 min
9 oppgaver
Variablerdatatyperkonvertering
Din fremgang i kapitlet
0 / 9 oppgaver
Kapitlets plass i kurset
Forkunnskaper: ingen. Dette er bokas første fagkapittel, og du trenger ikke ha programmert før.

Har du aldri sett et program i det hele tatt, kan du gjerne bruke en time på en mykere inngang først:

- Programmering med Python — de aller første stegene, skrevet for videregående.
- Programmering med Python — samme stoff, enda roligere tempo.
- Variabler, datatyper og uttrykk — samme grunnstoff i et parallelt universitetsemne, hvis du vil ha en ekstra forklaring ved siden av denne.

Ingen av dem er nødvendige. Kapitlet her forklarer alt fra bunnen.

Løkke 1 — Å gi noe et navn (~8 min)

På en strømregning står det tre tall: forbruket i kilowattimer, prisen per kilowattime og fastbeløpet. Skal du regne ut hva regningen blir, må du holde de tre tallene fra hverandre mens du regner. Du gir dem navn — «forbruk», «pris», «fastbeløp» — og regner med navnene.

Det er nøyaktig det et program gjør. Et navn som holder på en verdi, kalles en variabel, og å sette en verdi inn i den kalles en tilordning.

Variabel

Et navn som peker på en verdi maskinen husker mens programmet kjører.

Navnet velger du selv. Det må begynne med en bokstav eller understrek, kan inneholde bokstaver, tall og understrek, og skiller mellom store og små bokstaver: pris og Pris er to forskjellige variabler. Norske bokstaver er lov i Python 3, men boka holder seg til aa, oe og aa-frie navn der det er naturlig, fordi eksamensfasitene gjør det.

En variabel har ingen fast type. Den peker på det du sist la i den, og kan senere peke på noe helt annet.

Tilordning med `=`

Setter verdien på høyre side inn i navnet på venstre side. Likhetstegnet i Python betyr altså «gjør slik at», ikke «er lik».

forbruk = 1250 leser du som «la forbruk være 1250». Høyre side regnes ut først, deretter settes resultatet inn i navnet. Derfor gir n = n + 1 mening: den gamle verdien av n brukes til å regne ut den nye.

Sammenligning skrives med to likhetstegn, ==. Det kommer i kap. 1.2.

Augmentert tilordning (`+=`, `-=`, `*=`)

Kortform for «regn på verdien som allerede står der, og legg resultatet tilbake i samme navn».

total += 50 betyr nøyaktig det samme som total = total + 50. Tilsvarende finnes -=, *=, /=, //= og %=.

Variabelen må ha en verdi fra før — total += 50 på et navn som ikke finnes, gir feilmeldingen NameError. Derfor settes startverdien alltid før løkka i tellemønstrene du møter i kap. 1.3.

✏️Eksempel 1: Strømregningen

Forbruket er 1250 kilowattimer, prisen er 1,15 kroner per kilowattime og fastbeløpet er 39 kroner. Hva blir regningen, og hva skjer hvis forbruket senere korrigeres til 1310?

Vi gir de tre tallene navn og regner med navnene:

forbruk = 1250
pris = 1.15
fastbelop = 39
regning = forbruk * pris + fastbelop
print(regning)

Utskrift:

1476.5

Merk at desimaltall skrives med punktum, ikke komma: 1.15. Komma betyr noe annet i Python.

Korrigeres forbruket, tilordner vi på nytt — og må regne ut regningen på nytt. Den gamle utregningen henger ikke igjen:

forbruk = 1250
pris = 1.15
fastbelop = 39
regning = forbruk * pris + fastbelop
forbruk = 1310
print(regning)
regning = forbruk * pris + fastbelop
print(regning)

Utskrift:

1476.5
1545.4999999999998

Første print gir fortsatt den gamle summen. regning husker tallet som ble regnet ut, ikke oppskriften. Dette er den vanligste misforståelsen om tilordning, og den lønner seg å ha sett én gang.

📝Oppgave 1

(Innstegsoppgave — minimal sporing. Sjanger B — kodesporing, altså «hva skriver programmet ut?».) Hva skriver programmet ut?

antall = 4
antall = antall + 3
antall += 2
print(antall)

Løkke 2 — De fire typene (~10 min)

Tallet 7 og teksten «7» ser like ut på skjermen, men maskinen behandler dem helt forskjellig. Det ene kan du regne med; det andre kan du bare sette sammen med annen tekst. Hvilken av delene en verdi hører til, kalles verdiens datatype.

Fire typer dekker nesten alt du trenger i dette faget.

`int` — heltall

Hele tall uten desimaler: 0, 7, -42, 1250. Ingen øvre grense i Python 3 — heltall kan bli vilkårlig store.

Skrives uten fnutter og uten mellomrom som tusenskille: 1250, aldri 1 250.

Regning mellom to heltall gir heltall, med ett unntak: / gir alltid desimaltall.

`float` — flyttall (desimaltall)

Tall med desimaler: 1.15, 3.0, -0.5. Desimalskilletegnet er punktum, ikke komma.

«Flyttall» betyr at komma «flyter» — maskinen lagrer tallet omtrent slik 1.15 ganger en tierpotens, med et begrenset antall siffer. Derfor er flyttall tilnærminger: 0.1 + 0.2 blir 0.30000000000000004, ikke 0.3. Det er ikke en feil i Python, det er avrundingen i et endelig antall bit.

3.0 er et flyttall selv om verdien er hel. Utskriften viser .0-en.

`str` — streng (tekst)

En tekst, skrevet mellom enkle eller doble fnutter: 'Trondheim', "1250". «Streng» er fagordet for tekst i programmering — en streng av tegn.

Fnuttene er ikke en del av teksten. print('sol') skriver sol, uten fnutter.

+ mellom to strenger limer dem sammen: '12' + '7' gir '127', ikke 19. Dette er felle #1 i bokas feilregister, og den vanligste enkeltfeilen i faget.

`bool` — sannhetsverdi

Har nøyaktig to mulige verdier: True (sann) og False (usann). Stor forbokstav, uten fnutter — 'True' med fnutter er en streng, ikke en sannhetsverdi.

Sannhetsverdier oppstår av sammenligninger (5 > 3 gir True) og styrer alle valg i programmet. Hele apparatet rundt dem står i kap. 1.2.

Internt er True tallet 1 og False tallet 0, så True + True gir 2. Det er sjelden nyttig, men det forklarer at man kan telle sanne tilfeller ved å summere dem.

`type(x)`

Forteller hvilken datatype verdien x har akkurat nå. Svaret skrives som <class 'int'>, <class 'float'>, <class 'str'> eller <class 'bool'>.

type regner ikke om noe og endrer ingenting — den bare rapporterer. På eksamen bruker du den aldri i en besvarelse, men når du sporer kode i hodet, er «hvilken type er dette nå?» ofte det spørsmålet som avgjør svaret.

✏️Eksempel 2: Fire verdier, fire typer

Hva er typen til 1250, 1.15, '1250' og 1250 > 1000 — og hva skjer når du plusser to strenger mot to tall?

print(type(1250))
print(type(1.15))
print(type('1250'))
print(type(1250 > 1000))

Utskrift:

<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

Legg merke til den tredje linja: '1250' med fnutter er en tekst som ser ut som et tall. Det er nøyaktig slik tall kommer inn fra en fil eller fra brukeren, og derfor det viktigste tilfellet i hele kapitlet.

Forskjellen viser seg med én gang du regner:

print(12 + 7)
print('12' + '7')

Utskrift:

19
127

Samme operator, to helt ulike resultater. + betyr «legg sammen» for tall og «lim sammen» for tekst.

📝Oppgave 2
Sjanger B

Hva skriver programmet ut? Skriv de tre linjene nøyaktig som terminalen viser dem.

a = '5'
b = 5
print(a + a)
print(b + b)
print(a * 2)

Løkke 3 — Regneoperatorene, og de to som overrasker (~12 min)

Fire av regneoperatorene oppfører seg som på kalkulatoren: +, -, * og potens. To gjør det ikke, og nettopp de to er faste innslag i kodesporingsoppgavene: heltallsdelingen // og resten %.

Et konkret bilde først. En treningsøkt varte 3725 sekunder. Hvor mange hele minutter er det, og hvor mange sekunder blir til overs? Du deler på 60 og ser på heltallsdelen — det er // — og resten er %.

`/` — divisjon

Vanlig divisjon. Gir alltid et flyttall, også når det går opp: 10 / 2 gir 5.0, ikke 5.

Dette er en av de vanligste kildene til rar utskrift. Skriver programmet 5.0 der du ventet 5, har du sannsynligvis delt med / der du mente //.

Deling på null gir feilmeldingen ZeroDivisionError og stopper programmet.

`//` — heltallsdeling

Deler og kaster desimalene, slik at svaret blir et heltall når begge operandene er heltall: 17 // 5 gir 3.

Presist: // runder nedover, mot minus uendelig — ikke mot null. Det betyr at -17 // 5 gir -4, ikke -3. Dette er nøyaktig den detaljen sporingsoppgavene tester, og den eneste måten å huske den på er å lese «nedover på tallinja».

Er én av operandene et flyttall, blir svaret et flyttall uten desimaler: 17.0 // 5 gir 3.0.

`%` — modulo (resten)

Gir resten etter heltallsdeling: 17 % 5 gir 2, fordi 17 er 3 femmere og 2 til overs.

To bruksmåter går igjen på eksamen: sifre (n % 10 gir siste siffer) og partall (n % 2 == 0 er sant når n er et partall).

For negative tall følger % samme regel som //, så resten får samme fortegn som det du deler på: -17 % 5 gir 3. Sammenhengen som alltid gjelder, er at (a // b) * b + (a % b) er a.

Potens

Skrives med to stjerner: 2 ** 10 gir 1024. To heltall gir heltall.

Negativ eksponent gir flyttall: 2 ** -1 gir 0.5. Kvadratrot skrives som x ** 0.5, som er grunnen til at boka nesten aldri trenger math-modulen.

Potens binder sterkere enn alt annet, og sterkere enn minustegnet foran et tall: -2 ** 2 er 4-4, ikke 44.

📜Tidsformelen: sekunder om til timer, minutter og sekunder

Det kanoniske mønsteret for tidsregning i dette faget, og en fast innpakning i programmeringsoppgavene. Tre linjer, i denne rekkefølgen:

sekunder = 3725
timer = sekunder // 3600
minutter = (sekunder % 3600) // 60
rest = sekunder % 60
print(timer, minutter, rest)

Utskrift:

1 2 5

1. Timene er hele antall 3600-sekunders bolker: // 3600.
2. Minuttene finnes i det som er igjen etter timene: først % 3600, deretter // 60.
3. Sekundene er resten etter hele minutter: % 60.

Bruker du / i stedet for // på noen av linjene, får du desimaltall og hele regnestykket sprekker. Motsatt vei: bytter du % og //, får du timer der du skulle hatt sekunder.

Selve utskriftsformen 01:02:05, med nuller foran, hører til formatert utskrift og kommer i Del 3.

✏️Eksempel 3: `//`, `%` og `/` side om side

Hva gir 17 // 5, 17 % 5 og 17 / 5 — og hva skjer med de samme uttrykkene når tallet er negativt?

print(17 // 5, 17 % 5, 17 / 5)
print(-17 // 5, -17 % 5, -17 / 5)

Utskrift:

3 2 3.4
-4 3 -3.4

Første linje er som ventet: 3 hele femmere, 2 til overs, og 3,4 som desimaltall.

Andre linje er den som koster poeng. -17 // 5 er ikke 3-3. Heltallsdelingen runder nedover på tallinja, og nedover fra 3,4-3{,}4 er 4-4. Resten blir da 3, fordi 45+3=17-4 \cdot 5 + 3 = -17.

Kontrollen du kan gjøre på papir: gang svaret fra // med det du delte på, og legg til resten. Får du tilbake det opprinnelige tallet, har du regnet riktig.

📝Oppgave 3
Sjanger B

Hva skriver programmet ut? Pass på fortegnene.

print(29 // 4)
print(29 % 4)
print(29 / 4)
print(-29 // 4)
print(-29 % 4)

📝Oppgave 4
Eksamensnivå, sjanger B

En treningsøkt er logget som 7384 sekunder. Hva skriver programmet ut?

sek = 7384
t = sek // 3600
m = (sek % 3600) // 60
s = sek % 60
print(t, m, s)
print(t + m + s)

Løkke 4 — Rekkefølgen uttrykkene regnes i (~5 min)

Når flere operatorer står i samme uttrykk, må maskinen bestemme hvilken som gjelder først. Reglene er de samme du lærte i matematikken, med potens på toppen.

Presedens (regnerekkefølge)

Rekkefølgen operatorene regnes i, fra sterkest til svakest:

1. Potens — regnes fra høyre mot venstre: 2 ** 3 ** 2 er 2 ** 9, altså 512.
2. Unært minus — minustegnet foran ett tall.
3. *, /, //, % — like sterke, regnes fra venstre mot høyre.
4. + og - — svakest, også fra venstre mot høyre.

Parenteser slår alt. Er du i tvil på eksamen, sett parenteser — de koster ingenting og fjerner hele spørsmålet.

Den ene fella som faktisk brukes i oppgaver: potens binder sterkere enn minustegnet, så -3 ** 2 er 9-9.

✏️Eksempel 4: Fire uttrykk, samme tall

Hva blir 2 + 3 * 4, (2 + 3) * 4, -3 ** 2 og 20 - 6 // 4 * 2?

print(2 + 3 * 4)
print((2 + 3) * 4)
print(-3 ** 2)
print(20 - 6 // 4 * 2)

Utskrift:

14
20
-9
18

Den siste er verdt en gjennomgang. // og * er like sterke og regnes fra venstre:

1. 6 // 4 gir 1.
2. 1 * 2 gir 2.
3. 20 - 2 gir 18.

Den som regner 4 * 2 først og deretter 6 // 8, får 20 — og har brutt regelen om venstre mot høyre.

📝Oppgave 5
Sjanger B

Hva skriver programmet ut?

print(10 - 2 ** 3)
print(-2 ** 2)
print(18 % 5 * 2)
print(18 % (5 * 2))

Løkke 5 — Konvertering: fra tekst til tall og tilbake (~10 min)

Nå kommer kapitlets viktigste avsnitt. Alle data som kommer inn i programmet utenfra — fra en fil, fra tastaturet — kommer inn som tekst. Ingen unntak. Skal du regne med dem, må du gjøre dem om til tall først. Å gjøre om en verdi fra én datatype til en annen kalles konvertering.

En prisliste på fil ser slik ut for maskinen:

Rimi;melk;21.90

Prisen 21.90 er tekst, ikke et tall, helt til du selv gjør noe med den.

`int(s)` — tekst om til heltall

Tar en tekst som ser ut som et helt tall, og gir tallet: int('42') gir 42.

Teksten må inneholde bare et helt tall, eventuelt med fortegn og omkringliggende mellomrom. int(' 42 ') virker; int('42 kr'), int('') og int('3.9') gir alle feilmeldingen ValueError og stopper programmet.

Merk det siste: en tekst med desimalpunktum kan ikke sendes rett til int. Da må du gå veien om float.

`float(s)` — tekst om til desimaltall

Tar en tekst som ser ut som et tall, og gir et flyttall: float('3.14') gir 3.14, og float('7') gir 7.0.

Desimalskilletegnet må være punktum. float('3,14') gir ValueError — en felle når data kommer fra norske regneark.

Tommelfingerregel for fildata: felt som er penger, målinger eller tider konverteres med float, felt som er antall eller årstall med int.

`str(x)` — verdi om til tekst

Motsatt vei: str(7) gir '7', og str(3.5) gir '3.5'.

Nødvendig når du vil lime et tall sammen med tekst med +: 'Pris: ' + str(pris). Uten str får du feilmeldingen TypeError: can only concatenate str.

print gjør denne konverteringen selv for hvert argument, så print('Pris:', pris) virker uten str. Behovet oppstår først når du bygger en tekst.

`int(3.9)` kutter, den runder ikke

Brukt på et flyttall kaster int desimalene og beholder heltallsdelen — mot null, ikke nedover.

int(3.9) gir 3, og int(-3.9) gir -3. Legg merke til at dette er en annen regel enn //, som runder nedover og ville gitt 4-4. To operasjoner som ser like ut, med ulik oppførsel for negative tall.

Vil du runde av på vanlig måte, bruker du round.

`round(x)` og `round(x, n)`
round(2.7) gir 3, og round(3.14159, 2) gir 3.14. Med ett argument er svaret et heltall, med to er det et flyttall.

Python 3 bruker bankers avrunding ved eksakt halv: den runder til nærmeste partall. Derfor gir round(0.5) verdien 0 og round(1.5) verdien 2. Det overrasker de fleste, og er verdt å kjenne til, men det er sjelden avgjørende i en besvarelse.

Vil du bare vise et pent tall på skjermen, er formatert utskrift (Del 3) et bedre valg enn round.

`.isdigit()` — er teksten bare sifre?

Spørres på en streng og gir True eller False: '42'.isdigit() gir True, mens '42.5'.isdigit(), '-42'.isdigit() og ''.isdigit() alle gir False.

Punktumet, minustegnet og den tomme teksten er alle tre «ikke bare sifre». Metoden er altså en test for positive hele tall skrevet uten fortegn, ikke en generell tall-test.

Nytten er å kunne sjekke før du konverterer, slik at programmet slipper å krasje på ValueError. Det er selve grunnmuren i input-valideringen i kap. 1.4.

📜Konverteringsregelen

Bokas mest brukte enkeltregel, og den som forebygger den hyppigste feilen på eksamen:

Alt som kommer utenfra, er tekst. Skal du regne med det, konverterer du først.

I praksis to steg, i denne rekkefølgen:

1. Del opp teksten i felt (kommer i Del 3).
2. Konvertér hvert felt som skal regnes med, med int eller float — på stedet, med én gang, ikke «senere».

Her er hele forskjellen i to linjer:

pris_tekst = '21.90'
print(pris_tekst + pris_tekst)
print(float(pris_tekst) + float(pris_tekst))

Utskrift:

21.9021.90
43.8

Den øverste linja er ikke en feilmelding. Den er verre: den er et galt svar som ser riktig ut. Programmet fortsetter, og feilen dukker først opp lenger ned i besvarelsen.

✏️Eksempel 5: Fra fillinje til regnestykke (eksamensnivå)

En linje fra en prisliste ser slik ut, som ren tekst:

21.90

Butikken setter opp prisen med 12 prosent. Hva blir den nye prisen — og hva går galt hvis du hopper over konverteringen?

Først den gale veien, slik den faktisk ser ut i en besvarelse:

pris = '21.90'
print(pris * 2)

Utskrift:

21.9021.90

Ingen feilmelding, bare tull: teksten ble gjentatt to ganger. Hadde vi skrevet pris * 1.12, ville programmet stoppet med TypeError, fordi tekst ikke kan gjentas et desimalt antall ganger.

Så den riktige veien. Konvertér på stedet, regn, og gjør om til tekst igjen bare når du skal bygge en utskriftslinje:

pris = '21.90'
ny_pris = float(pris) * 1.12
print(ny_pris)
print(round(ny_pris, 2))
print('Ny pris: ' + str(round(ny_pris, 2)) + ' kr')

Utskrift:

24.528000000000002
24.53
Ny pris: 24.53 kr

Den første utskriften viser hele flyttallshalen — det er slik flyttall faktisk er, og noe du bør vente å se. round(..., 2) gir det tallet du vil vise. Den siste linja bygger en tekst, og der er str nødvendig.

Uttelling: sensor er ute etter at prisen representeres som flyttall. Å konvertere ved innlesing, én gang, er både det korteste og det som gir poeng.

📝Oppgave 6
Sjanger B

Hva skriver programmet ut? Én av linjene ser riktig ut, men er det ikke.

a = '8'
b = '10'
print(a + b)
print(int(a) + int(b))
print(a > b)
print(int(a) > int(b))

📝Oppgave 7
Sjanger B

Hva skriver programmet ut?

x = 7.8
print(int(x))
print(round(x))
print(int(-x))
print(-x // 1)

📝Oppgave 8
Eksamensnivå, sjanger B

En vaktliste oppgir hvor mange minutter en person har stått på post. Hva skriver programmet ut?

minutter = '415'
t = int(minutter) // 60
m = int(minutter) % 60
print(t, m)
print(str(t) + ':' + str(m))
print(minutter + str(t))

📝Oppgave 9
Eksamensnivå, sjanger B

Hva skriver programmet ut? Se nøye på både typer og fortegn.

n = -13
print(n // 4, n % 4)
print(int(n / 4))
print(abs(n) % 10)
print(type(n / 1))

API- og konstruksjonsliste
Repetisjon — de sju setningene som må sitte

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Norges teknisk-naturvitenskapelige universitet. Dette er ikke offisielt studiemateriell. Les mer.