Alle fag › Videregående programmering
Videregående programmering: gratis øving, teori og oppgaver
Objektorientert programmering (OOP) lar deg samle data og funksjonene som hører til dataene, i én enhet: et objekt. En klasse er oppskriften, og et objekt er en konkret instans av den. Som ingeniør bruker du dette til å modellere ting i den virkelige verden – en sensor, en komponent, en simulering – slik at koden speiler problemet og blir lettere å bygge videre på.
Innhold
1. Objektorientering
Hva handler det om?
Objektorientert programmering (OOP) lar deg samle data og funksjonene som hører til dataene, i én enhet: et objekt. En klasse er oppskriften, og et objekt er en konkret instans av den. Som ingeniør bruker du dette til å modellere ting i den virkelige verden – en sensor, en komponent, en simulering – slik at koden speiler problemet og blir lettere å bygge videre på.
Begreper og formler
- Klasse vs objekt: klassen
class Bil:er oppskriften,b = Bil()lager et objekt (en instans). - Instansattributt: satt med
self.x = ...i__init__, unikt for hvert objekt. - Klassevariabel: satt rett i klassekroppen (utenfor metoder), delt av alle objekter av klassen, med mindre et objekt får sin egen versjon via
self.navn = .... - Magiske metoder (dunder):
__init__(konstruktør),__str__(teksten som brukes avprint(obj)),__eq__(==),__len__(len(obj)). @staticmethod: en metode utenself, hører logisk til klassen men trenger ikke noe objekt.@classmethod: tarclsi stedet forselfog virker på klassen selv (f.eks. en alternativ konstruktør).- Arv og overstyring: en underklasse kan definere en metode med samme navn som foreldreklassen; da brukes underklassens versjon når metoden kalles (polymorfi).
Slik løser du oppgavene
- Finn ut om et attributt er en klassevariabel (delt) eller en instansvariabel (satt med
self.i__init__). - Følg hvert objekt for seg: hvilke metoder kalles på hvilket objekt, og i hvilken rekkefølge?
- Ved arv: sjekk hvilken klasses versjon av metoden som faktisk kjører (den mest spesifikke som er definert for det objektet).
- Ved en klassevariabel: husk at en endring gjort via ett objekt kan påvirke alle andre, med mindre det lages en ny instansvariabel med samme navn.
Eksempel
class Konto:
rente = 0.02 # klassevariabel, delt av alle kontoer
def __init__(self, saldo):
self.saldo = saldo # instansvariabel
def legg_til_rente(self):
self.saldo += self.saldo * Konto.rente
a = Konto(1000)
b = Konto(500)
Konto.rente = 0.05
a.legg_til_rente()
print(round(a.saldo), round(b.saldo))
aogbfår hver sinsaldo(instansvariabler): 1000 og 500.Konto.rente = 0.05endrer klassevariabelen for alle objekter, siden ingen av dem har fått sin egenrente.- Bare
a.legg_til_rente()kalles: . b.saldoer uendret sidenlegg_til_rentealdri ble kalt påb.
Utskriften blir 1050 500.
Vanlige feil
- Å tro at en klassevariabel er privat for hvert objekt. Den er delt helt til noen setter en instansvariabel med samme navn.
- Å glemme
selfsom første parameter i en vanlig metode. - Å glemme parentes ved arv:
class ElBil(Bil):, ikkeclass ElBil: Bil. - Å blande sammen
__init__(kjøres automatisk når objektet lages) med en vanlig metode du selv må kalle. - Å tro at
@staticmethodhar tilgang tilselfeller objektets attributter – det har den ikke.
Begreper i denne delen
2. Algoritmer og datastrukturer
Hva handler det om?
Når data blir store, er det ikke nok at koden virker – den må også være rask nok. Kompleksitetsanalyse (Big-O) gir deg et språk for å beskrive hvor mye arbeid en algoritme bruker når mengden data vokser, uavhengig av datamaskinen. Som ingeniør trenger du dette for å velge riktig datastruktur og algoritme før koden blir treg med ekte, store datasett – for eksempel måleserier med millioner av punkter.
Begreper og formler
- Amortisert kompleksitet:
liste.append(x)er i gjennomsnitt, selv om lista av og til må kopieres til et større minneområde. liste.insert(0, x)ogliste.pop(0)er : alle elementene bak innsettingspunktet må flyttes.- En rekursiv funksjon trenger et basistilfelle for å stoppe, ellers gir den
RecursionError. Antall rekursive kall henger ofte sammen med hvor stor inndataen er. - Inversjon: et par elementer som står i feil rekkefølge i en liste. Innsettingssortering bytter naboelementer helt til alle inversjoner er borte.
- Vanlige kompleksitetsklasser fra raskest til tregest: .
- To nøstede løkker som begge går ganger, gir til sammen (kvadratisk).
Slik løser du oppgavene
- Finn hvilken del av koden som gjentas flest ganger når vokser – det er den som dominerer kompleksiteten.
- Tell løkker i dybden: én løkke over gir , en løkke inni en løkke gir .
- For rekursjon: skriv opp kallene helt til basistilfellet er nådd, og tell dem.
- For sortering: følg algoritmen steg for steg med en konkret liste, og noter hver sammenligning og hvert bytte.
Eksempel
Innsettingssortering bytter et element bakover til det står riktig, ett steg om gangen:
def sorter(a):
bytter = 0
for i in range(1, len(a)):
j = i
while j > 0 and a[j-1] > a[j]:
a[j-1], a[j] = a[j], a[j-1]
j -= 1
bytter += 1
return bytter
print(sorter([3, 1, 2]))
- : sammenlign og . , så de byttes: , bytter = 1.
- : sammenlign og . , bytt: , bytter = 2. Nå er , så den indre løkka stopper.
- Lista er sortert, og funksjonen returnerer 2.
Utskriften blir 2, som er antall inversjoner i den opprinnelige lista (parene 3–1 og 3–2).
Vanlige feil
- Å tro at
appendoginsert(0, x)er like raske. De er hhv. og . - Å glemme basistilfellet i en rekursiv funksjon.
- Å telle bare den ytre løkka og glemme at en indre løkke multipliserer arbeidet.
- Å blande sammen antall sammenligninger og antall bytter i en sorteringsalgoritme – de er ikke alltid like mange.
- Å tro at og er omtrent like raske for store . Forskjellen blir enorm.
Begreper i denne delen
3. Numerikk med NumPy
Hva handler det om?
NumPy gir Python rask, vektorisert regning med tallarrayer – uunnværlig for ingeniørberegninger med store datasett, som måleserier og simuleringer. I tillegg lærer du numeriske grunnmetoder: Newtons metode for å finne nullpunkter til en funksjon, og Eulers metode for å løse differensialligninger tilnærmet, steg for steg. try/except lar programmet håndtere feil i data uten å krasje.
Begreper og formler
np.array: regneoperatorene+ - * /virker elementvis, ikke som matrisemultiplikasjon. Bruk@ellernp.dotfor matriseprodukt.- Boolsk indeksering:
a[a > k]gir en ny array med bare de elementene som oppfyller betingelsen. - Broadcasting: arrayer med lik form, eller der én dimensjon er 1, kan regnes sammen elementvis. Ulike og ukompatible former gir
ValueError. np.mean,np.std,np.sum,a.min()/a.max(): statistikk over en array.- Newtons metode: , følger tangenten ned til nullpunktet.
- Eulers eksplisitte metode: for .
try: ... except NavnPåFeil: ...fanger en bestemt feiltype. En generellexcept:fanger alt, også feil du egentlig burde ha oppdaget.
Slik løser du oppgavene
- Se om koden regner elementvis eller er matriseregning – sjekk om det står
*eller@/np.dot. - Med boolsk indeksering: regn ut betingelsen for hvert element først, og hent ut bare de som er
True. - For Newton/Euler: sett inn tallene i formelen, ett steg om gangen, og hold styr på hvilken verdi som er / i neste steg.
- Sjekk formene til arrayene før du legger dem sammen – stemmer de, eller kan de broadcaste?
Eksempel
En sensor logger 5 målinger. Vi vil vite gjennomsnittet av målingene som er over 20:
import numpy as np
a = np.array([15, 24, 31, 18, 27])
over = a[a > 20]
print(over, round(over.mean(), 2))
a > 20gir en boolsk array[False, True, True, False, True].a[a > 20]bruker den til å hente ut verdiene der betingelsen er sann:[24, 31, 27].- Gjennomsnittet er .
Utskriften blir [24 31 27] 27.33.
Vanlige feil
- Å forveksle
*(elementvis) med@/np.dot(matrisemultiplikasjon). - Å tro at boolsk indeksering gir
True/False-verdier tilbake i stedet for de faktiske tallene. - Å legge sammen arrayer med ukompatible former og bli overrasket over
ValueError. - Å bruke en generell
except:som fanger og skjuler feil du egentlig burde ha oppdaget. - Å dele på
f'(x)uten å sjekke at den ikke er null eller veldig liten i Newtons metode.
.mean()/.sum() er den vanligste måten å filtrere og oppsummere måledata på.Begreper i denne delen
Eksempeloppgaver med løsning
Her er noen av oppgavene i videregående programmering. I appen får regneoppgavene nye tall hver gang, så du kan øve til det sitter – og ta en prøveeksamen med karakter før eksamen.
Objektorientering: Hva er __init__ i en Python-klasse?
Svar: Konstruktøren som kjører når et objekt opprettes
Den setter opp objektets attributter.
Algoritmer og datastrukturer: Hva er tidskompleksiteten til binærsøk i en sortert liste?
Svar:
Søkeområdet halveres for hvert steg.
Numerikk med NumPy: Hva gir np.linspace(0, 1, 5)?
Svar: [0, 0.25, 0.5, 0.75, 1]
Fem jevnt fordelte punkter der begge endepunktene er med.
Objektorientering: Hva refererer self til i en metode?
Svar: Objektet (instansen) metoden kalles på
obj.metode() blir til Klasse.metode(obj).
Passer for disse emnene
Innholdet dekker pensum som går igjen i ingeniørutdanningene, blant annet:
- MEK3100 (OsloMet)
- TDT4100 (NTNU)
- INF200 (NMBU)