Typer og operasjoner


Typer

Det er mange typer som er innebygget i Python. Her er noen av de viktigste:

print("Noen elementære typer i Python:")
print(type(2))           # int   (heltall)
print(type(2.2))         # float (flyttall/desimaltall)
print(type(2 < 2.2))     # bool  (boolsk verdi, True eller False)
print(type("Foo"))       # str   (streng/tekst)
print(type(None))        # NoneType ("ingenting" har egen type)
print(type(type(42)))    # type 

print("##############################")

print("Flere viktige typer vi skal lære om senere")
print(type([1,2,3]))      # list
print(type((1,2,3)))      # tuple
print(type({1,2}))        # set
print(type({1:42}))       # dict

print("##############################")
print("Funksjonener er en egen type")
def my_function():
    return "Bar"

print(type(my_function))   # function
print(type(my_function())) # str
Konstanter

Noen konstanter er også innebygget i Python. For eksempel:

print("Elementære verdier:")
print(True)
print(False)
print(None)

print("Noen konstanter fra matematikken:")
import math
print(math.pi)
print(math.e)
Operasjoner

Noen operasjoner er så vanlige at vi har spesielle symboler vi bruker for å utføre dem. For eksempel symbolet +, som vi bruker for å utføre addisjon.

KategoriOperatorer
Aritmetikk+ - * / // ** %
Relasjoner== != < <= > >=
Medlemskapin not in
Logikkand or not
Betingelseif else

Det finnes også en mengde bitvise operasjoner, men vi hopper over dem i denne omgang (<< >> & | ^ ~).

Heltallsdivisjon

Heltallsdivisjon benyttes når man skal fordele likt en mendge av atomiske enheter som ikke kan deles opp i mindre biter

print("Operatøren / utfører 'vanlig' divisjon")
print(" 7/4  =", ( 7/4))  # 1.75
print()
print("Operatøren // utfører heltallsdivisjon:")
print(" 7//4 =", ( 7//4)) # 1 (runder nedover)
print(" 5//4 =", ( 5//4))
print("-1//4 =", (-1//4)) # -1 (runder også nedover)
print("-7//4 =", (-5//4))
print("Når nevneren er negativ")
print(" 7//-4 =", (7//-4)) # -2 (runder også nedover)
print("-7//-4 =", (-7//-4)) # 1 (runder alltid nedover)

PS: hvordan runde av på andre måter? Svar: Bruk vanlig divisjon og rund av i en egen operasjon.

# round-funksjonen runder av til nærmeste heltall
print("round(3/4) =", round(3/4)) # 1
# merk: oppfører seg merkelig når tallet slutter på .5
# (når tallet slutter på .5 runder den mot nærmeste partall)
print("round(1.5) =", round(1.5)) # 2
print("round(2.5) =", round(2.5)) # 2 wtf?

# int() -funksjonen runder av "mot null"
print("int(1.9) =", int(1.9)) # 1
print("int(-1.9) =", int(-1.9)) # -1

import math
# math.ceil() -funksjonen runder alltid oppover
print("math.ceil(1.1) =", math.ceil(1.1)) # 2
print("math.ceil(-1.9) =", math.ceil(-1.9)) # -1
# math.floor() -funksjonen runder alltid nedover
print("math.floor(1.9) =", math.floor(1.9)) # 2
print("math.floor(-1.1) =", math.floor(-1.1)) # -2

# Vanlig avrunding (rund av til nærmeste,
# og rund opp hvis halvveis) skriver vi selv:
def round_half_up(x):
    return math.floor(x + 0.5)

print("round_half_up(1.5) =", round_half_up(1.5))
print("round_half_up(2.5) =", round_half_up(2.5))
Modulus

For et heltall \(x\) og et positivt heltall \(y\) er operasjonen \(x \mod y\) definert i matematikken som forskjellen mellom \(x\) og det største tallet mindre enn eller lik \(x\) som er delbart med \(y\). For positive tall vil dette være det samme som resten etter heltallsdivisjon.

print(" 6%3 =", ( 6%3))
print(" 5%3 =", ( 5%3))
print(" 2%3 =", ( 2%3))
print(" 0%3 =", ( 0%3))
print("-4%3 =", (-4%3))
print(" 3%0 =", ( 3%0))

Eksempler på bruk

def is_odd(x):
    return x % 2 == 1

def last_digit(x):
    return abs(x) % 10  # abs()-funksjonen gir absolutt-verdi

def is_multiple_of(x, y):
    return x % y == 0

print(is_odd(3)) # True
print(is_odd(4)) # False
print(last_digit(123)) # 3
print(is_multiple_of(9, 3)) # True
print(is_multiple_of(8, 3)) # False

Det stemmer alltid at ((x // y) * y) + (x % y) == x.

def check(x, y):
    return ((x // y) * y) + (x % y) == x

print(check(17, 3))
print(check(3, 17))
print(check(-83, 9))
print(check(235142, -23))
Typen avgjør hva operasjonen betyr
print(3 * 2)
print(3 * "abc")
print(3 + 2)
print("abc" + "def")
print(3 + "def")
Flyttall og avrundingsfeil

Se også videoen Floating point numbers av Computerphile.

print(0.1 + 0.1 == 0.2)        # True, men...
print(0.1 + 0.1 + 0.1 == 0.3)  # False! 
print(0.1 + 0.1 + 0.1)         # gir 0.30000000000000004 (oj sann!)
print((0.1 + 0.1 + 0.1) - 0.3) # gir 5.55111512313e-17 (lite, men ikke 0!)

Derfor: Ikke bruk == for å sammenligne flyttall! Sjekk i stedet at de to tallene som sammenlignes er nesten like.

def almost_equals(a, b):
    epsilon = 0.0000000001
    return abs(a - b) < epsilon # abs()-funksjonen gir absolutt-verdien

print(0.1 + 0.1 + 0.1 == 0.3)  # Feil
print(almost_equals(0.1 + 0.1 + 0.1, 0.3))  # Riktig
Betinget verdi (if else)
print("Foo" if True else "Bar") # Foo
print("Foo" if False else "Bar") # Bar
print("Foo" if 1 < 2 else "Bar")
print()

x = -3
print(0 if x < 0 else x)
print(x if x < 0 else 0)
Truthy og falsy verdier

I en kontekst der vi ser etter en boolsk verdi (for eksempel betingelsen i en if else), vil ikke-boolske verdier automatisk tolkes som enten True eller False.

print("Alt kan tolkes som en boolsk verdi")
print("Sann" if True else "Usann") # Sann
print("Sann" if 1 else "Usann") # Sann
print("Sann" if "Hello" else "Usann") # Sann
print("Sann" if "0" else "Usann") # Sann
print("Sann" if 0 else "Usann") # Usann
print("Sann" if "" else "Usann") # Usann
print("Sann" if None else "Usann") # Usann
print()

print("Boolske tolkninger av noen verdier:")
print("bool(1) =", bool(1))
print("bool(-234) =", bool(-234))
print("bool(0.0001) =", bool(0.0001))
print("bool(0) =", bool(0))
print("bool(0.0) =", bool(0.0))
print("bool(-0.0) =", bool(-0.0))
print('bool("Hallo") = ', bool("Hallo"))
print('bool("") = ', bool(""))
print('bool([1, 2, 3]) = ', bool([1, 2, 3]))
print('bool([]) = ', bool([]))

Verdier som er falsy er:

De aller fleste andre verdier er truthy. Vi kan alltid dobbeltsjekke med bool -funksjonen.

Logiske operasjoner
print("'not' returnerer motsatt boolsk verdi av bool-funksjonen")
print(not True) # False
print(not False) # True
print(not "Hello") # False
print(not 0) # True
print()

print("'and' returnerer venstre ledd hvis det er falsy, og høyre ledd ellers")
# altså: and -operatøren returnerer truthy hvis begge sider er truthy
print(False and False) # False
print(False and True) # False
print(True and False) # False
print(True and True) # True
print(True and 5) # 5
print(0 and "Foo") # 0
print(2 and 3)
print(False and None)
print()

print("'or' returnerer venstre ledd hvis det er truthy, og høyre ledd ellers")
# altså: or -operatøren returnerer truthy hvis minst én side er truthy
print(False or False) # False
print(False or True) # True
print(True or False) # True
print(True or True) # True
print(True or 5) # True
print(0 or "Foo") # Foo
print(2 or 3)
print(False or None)