Python er ...
Python 2.x vs 3.x
I heftet er det vist eksempler kopiert inn fra fra arbeidsflaten i Python, noen ganger med små kommentarer som forklaring,
>>> for n in range(3): # for hver n i området [0, 2]
... print(n)
0
1
2
Du får best utbytte av kurset ved å ha startet opp Python og prøve ut kommandoene som blir vist i stedet for bare å lese teksten. Bruk klipp/lim fra kodeeksemplene. Lag dine egne varianter og se hva som skjer. Når mine knappe forklaringer ikke er tilstrekkelige vil du finne utfyllende hjelp bak noen tastetrykk i Python. I avsnittene som er merket Gjør det selv finner du treningsoppgaver som du kan prøve deg på.
Siden dette er en nettside kan du bruke søkefunksjonen Ctrl+F, F3 i nettleseren til å finne nøkkelord.
Bakgrunnen til dette heftet er at
Tall er enten heltall, flyttall (desimaltall) eller komplekse tall. Regneuttrykk med heltall og flyttall blir flyttall. Komplekse tall bruker 1j
som imaginær enhet.
integer heltall, telletall float flyttall, desimaltall complex komplekse tall
>>> 6-5*4+3**2 # Et regnestykke med heltall, -5 # svaret blir heltall >>> 1+2*3-4/5 # Men, divisjon mellom heltall gir float 6.2
Kommandoer tastes inn etter promptet >>>
og svaret vises på neste linje. Kommentarer starter med et hashtegn # og gjelder resten av linja.
Evaluering skjer fra venstre mot høyre, men presedens overstyrer, operasjoner på høyere nivå utføres før operasjoner på lavere nivå. Uttrykk i parenteser beregnes først.
1. ( ) Parenteser 2. ** Eksponenter 3. +, - Fortegn, pos, neg 4. *, /, //, % Multiplikasjon, divisjon, heltallsdivisjon, rest 5. + - Addisjon og subtraksjon
Her er noen regnestykker som belyser evaluering og presedens,
>>> -2**3 # Eksponentoperator ** har høyere presedens enn fortegn -8 >>> 8+5-6/2/3**-2+1 # 13 - 3.0/(1/9) + 1 = -13.0 -13.0 >>> 8+(5-6/2)/3**-2+1 # 8 + 2.0/(1/9) + 1 = 27.0 27.0
Divisjon mellom heltall gir altså flyttall som resultat. Noen ganger ønsker vi å la svaret bli heltall ved at det rundes ned til nærmeste heltall. En heltallsdivisjon vil dermed gi hvor mange hele ganger divisor går opp i dividend. Her viser vi at $\frac {44}{3} = 14 + \frac 2 3$,
>>> 44 // 3 # Heltallsdivisjon 14 >>> 44 % 3 # Rest etter heltallsdivisjon 2 >>> 3*(44//3)+44%3 44
Komplekse tall på komponentform bruker 1j eller 1J som imaginær enhet. Her er noen operasjoner,
>>> 3+4j (3+4j) >>> (3+4j)/(1-2j) # Matematikk med komplekse tall (-1+2j) >>> abs(3+4j) # Absoluttverdi 5.0 >>> (3+4j).real # Reell komponent 3.0 >>> (3+4j).imag # Imaginær kommponent 4.0 >>> (3+4j).conjugate() # Kompleks konjugert (3-4j) >>> complex(3, 4) # Lager kompleks tall med konstruktørfunksjon (3+4j)
Her møter du plutselig de grunnleggende byggesteinene i Python som objektorientert programmeringsspråk - funksjoner, objekter med attributter, metoder og konstruktører. Alt dette blir forklart i detalj utover i kurset, men her en ultrakort oversikt i Pythons egen sjargong. Alle dataverdier vi opererer med er objekter som har visse egenskaper, attributter, metoder og konstruktører. Den siste linja, complex(3, 4)
konstruerer (oppretter) et objekt av klassen (datatypen) complex
, med de to parametrene 3 og 4 som verdier på reell- og imaginær attributt. Den første linja, 3+4j
konstruerer et komplekst tall med en kortform. Linja med (3+4j).imag
leser av attributten imag i objektet. Linja med (3+4j).conjugate()
bruker objektets metode conjugate()
til å gi den kompleks konjugerte verdien av objektet. Absoluttverdien (lengden) av et komplekst tall finner vi med funksjonen abs()
.
Python kan sjonglere med vanskeligere matteoppgaver enn de vi har sett her. Ved å hente inn definisjoner fra moduler som math
, cmath
, nympy
, scipy
og sympy
kan vi utføre avansert matematikk. Se kurset SymPyIntro.
En variabel er et navn som refererer til en verdi. Tall og andre dataverdier tilordnes variabler med operatoren likhetstegn, =. Det gir den fordelen at verdier kan brukes på nytt uten å taste inn hele regnestykket. Lag navn på variablene som forteller hva de står for. Skal vi regne ut arealet for et rektangel med gitt bredde og høyde kan vi for eksempel bruke bredde
for gbredde, hoyde
for høyde og areal
for area. Her beregnes arealet av et rektangel med bredde=4 og høyde=3,
>>> bredde = 4 >>> hoyde = 3 >>> areal = bredde * hoyde >>> areal 12.0
De to første programsetningene er tilordninger, de lar navnene bredde
og hoyde
referere til verdiene 4 og 3. Den tredje setningen lar navnet areal
referere til resultatet av beregningen bredde * hoyde
. I den siste linja ser vi at om vi gir selve variabelnavnet som kommando vil det vise verdien det refererer til.
Likhetstegnet brukes altså som tilordningsoperator i SymPy i setninger som
variabelnavn = verdi eller uttrykk
der verdien eller resultatet av beregningen på høyre side blir lagret og gitt variabelnavnet på venstre side, slik at for eksempel en setning som
alder = alder + 1
virker snodig hvis det feilaktig leses som en matematisk likning, men som tilordning betyr det at verdien som variabelen alder refererer til økes med 1. En tilordning som radius = 3
leses som 'radius tilordnes 3' eller 'radius får verdien 3'.
Variabelnavn må begynne med en bokstav og være uten mellomrom eller særnorske bokstaver. Med tegnet underscore kan vi lage oppdelte navn, for eksempel svar_5_b
. Python skiller mellom store og små bokstaver. Resultatet av siste utførte beregning blir automatisk lagt i variabelen _ (underscore).
Python tillater flere tilordninger i samme linje. Uttrykk på høyre side evalueres først fra venstre mot høyre, deretter tilordnes de til variablene på venstre side.
>>> a, b = 1, 2 # a=1, b=2 >>> a, b = b, a+b # a=b=2, b=a+b=1+2=3 >>> a 2 >>> b 3
Stringer, lister, tupler (tuples) og oppslagslister (dictionaries) er sekvensielle datatype som lagrer verdier i tabellform. Stringer og tupler defineres med dataverdier som ikke kan endres. Indekseringene starter med 0 som første element. ?? Legg merke til bruken av de forskjellige parentestypene. Hakeparenteser brukes ved indeksering. I matematikk vil funksjoner som finner flere løsninger gi disse i en liste. ??
>>> navn = 'Abraham' # string
>>> navn[0]
'A'
>>> navn[0]= 'B'
#...
TypeError: 'str' object does not support item assignment
Når vi skal lage utskrift av beregninger ønsker vi å sette sammen en tekst som består av ord og tallverdier. Hvis en variabel areal
inneholder verdien 12 ønsker vi at
Lister
>>> oddetall = [1, 3, 5, 7] # list >>> oddetall[2]= 9 >>> oddetall [1, 3, 9, 7]
Tupler
>>> nevoer = ('Ole', 'Dole', 'Doffen') # tuple nevoer[1] = 'Petter' #... TypeError: 'tuple' object does not support item assignment
Oppslagslister
>>> persondata = {'fornavn': 'Donald', 'etternavn': 'Duck', 'alder': 78} >>> persondata['alder'] = 89 >>> persondata {'alder': 89, 'fornavn': 'Donald', 'etternavn': 'Duck'}Innlesing og utskrift
Den enkleste måten å lage utskrift av en variabelverdi er å gi variabelnavnet som kommando. Vil vi styre litt mer av hva som skal vises bruker vi funksjonen print(), enten med en tallvariabel- eller med en string som argument.
>>> vekt = 75 >>> hoyde = 175 >>> bmi = vekt/(hoyde/100)**2 >>> bmi 24.489795918367346Moduler, navneområder
Moduler er samlinger av Python kode som utfører spesialiserte oppgaver. Modulene inneholder definisjoner av variabler, konstanter, funksjoner og klasser. Noen moduler, som math og cmath, følger med i standard installasjon av Python, andre må installeres separat, for eksempel SymPy. Når vi skal ta i bruk en modul må vi enten importere den som et eget navneområde (namespace), eller legge den inn i det gjeldende navneområdet.
>>> sqrt(8) # Funksjonen sqrt er ikke med i standard Python #... NameError: name 'sqrt' is not defined >>> import math # Leser inn modulen math >>> math.sqrt(8) # Bruker sqrt fra navneområdet math 2.8284271247461903 >>> from math import * # Lar math bli med i gjeldende navneområde >>> sqrt(8) 2.8284271247461903 >>> from sympy import * # Leser inn sympy til gjeldende navneområde >>> sqrt(8) # Bruker sqrt fra sympy 2*sqrt(2)Symbolsk matematikk hentes fra modulen
sympy
. Symbolske regneuttrykk må lages som stringer til funksjonenS
eller med symbolske variable.>>> from sympy import * >>> S('1/2 + 1/3') # S = sympify 5/6 >>> x = symbols ('x') # definerer symbolsk variabel >>> 6*x-5-4*x+3 2*x - 2Funksjoner, klasser og objekter
En funksjon er et stykke Python kode som utfører en avgrenset oppgave, for eksempel å finne kvadratrota av et tall. Når vi bruker funksjonen gjør vi et funksjonskall av formen
funksjonsnavn(inngangsverdi)
, der vi gjerne sender med en (eller flere) inngangsverdier. Funksjonen lager et resultat og sender det tilbake til programkjøringen i form av en returverdi.>>> def rot(x): # Dette er Python kode return x**(1/2) # som definerer en funksjon >>> rot(4) # Her er et funksjonskall 2.0 # som gir denne returverdienFunksjonen rot som ble laget ovenfor eksisterer bare så lenge Pythonskallet kjører, men om linjene legges i en fil som lagres med filnavn
navn.py
, vil vi kunne bruke funksjonen senere ved å importerenavn
som en modul.En klasse (class) er en samling funksjoner og variabler som beskriver en datatype. Vi har allerede møtt klassene heltall, komplekse tall, stringer, lister og andre. Et objekt er en enkelt instans (individ) av en klasse, på samme måte som at 'Tja' er et objekt av klassen string.
I modulene ligger det klassedefinisjoner som naturlig hører sammen. Vi henter et eksempel på modulen
cmath
som håndterer matematikk med komplekse objekter (tall). La oss sette opp to tall,w
ogz
, og gjøre noen sjongleringer.Noen datatyper og operasjoner med disse er altså innebygget i Python. Når vi bruker Python som kalkulator blir det ikke så mye snakk om klasser og objekter. La oss sette opp to komplekse tall,
w
ogz
, og gjøre noen sjongleringer.>>> w = complex(3, -4) # Vi 'konstruerer' objektet w av klassen complex >>> z = 2 + 1j # Objektet z konstrueres med kortform >>> w+z # Enkel matematikk fungerer (5-3j) >>> z.imag # Henter ut imaginærverdien av z 1 >>> w.conjugate() # Bruker klassemetoden conjugate() til å hente konjugert verdi av w (3+4j) >>> w # Men, w er ikke endret (3-4j) >>> abs(w) 5.0Her var det mye på en gang. Selve klassenavnet brukes som konstruktør, objektet
w
av klassencomplex
settes opp (konstrueres) i linjaw = complex(3, 4)
med komponentene 3 og 4 som innverdier. Vi ser at komplekse tall er innebygget som klasse i Python. Derfor er det også laget en mulighet til å taste inn et komplekst tall på kortform,z=2+1j
, som alternativ til formell konstrutør. Det samme gjelder også tall, der7
blir et objekt av heltallsklassen, mens7.0
blir et objekt av float-klassen.Et objekt har gjerne dataverdier som ligger lagret i attributter. Det har også funksjoner som gjør det i stand til å sjonglere med attributtene. Imaginærverdien av
z
kan vi finne ved å legge .imag bak objektnavnet,z.imag
. Den konjugerte verdien avw
kan vi finne ved å tilkalle metoden (funksjonen) conjugate,w.conjugate()
. Legg merke til forskjellene her,z.imag
henter ut en dataverdi fra objektet, mensw.conjugate()
gjør en operasjon på objektet. Til slutt bruker vi funksjonenabs
til å finne absoluttverdien (lengden) avw
. Denne funksjonen er altså laget slik at den kan operere med objekter.Vi går litt videre og onsker å finne kavdratrota av
z
, og prøver med funksjonensqrt
,>>> sqrt(w) Traceback (most recent call last): File "<pyshell#100>", line 1, in <module> sqrt(w) NameError: name 'sqrt' is not definedNeivel, kanskje ble det litt for avansert for standard Python, la oss importere modulen
cmath
,>>> import cmath >>> cmath.sqrt(w) # Bruker funksjonen sqrt i modulen cmath (2+1j) >>> _**2 # Tester siste svar om vi virkelig fant kvadratrot (3+4j)Her brukes funksjonen
sqrt
som er definert i modulencmath
til å beregne kvadratrota av det komplekse talletw
. Vi må altså henvise til funksjoner i en importert modul med 'modulnavn.
'. En annen måte å gjøre det samme på er altså å importere alle funksjoner icmath
inn i det gjeldende navneområdet. Da bruker vi funksjonsnavnene direkte,>>> from cmath import * >>> sqrt(w) (2+1j) >>> z.conjugate().imag * sqrt(w) (-2-1j)