Lab2

Oppgaver

Oppvarming

Obligatorisk

Frivillig

Hvordan fullføre laben

For å bestå laben, må alle de obligatoriske oppgavene være bestått. Laben leveres i CodeGrade; du finner som vanlig knappen dit på mitt.uib.


Oppvarming

Joker
Oppvarming
Nivå E

I denne oppgaven skal vi skrive en kunstig intelligens for å spille Joker fra Norsk Tipping. I dette spillet får man på forhånd vite fem hovedtall; for hvert av hovedtallene må man velge om man skal gå “opp” eller “ned” før et hemmelig vippetall avsløres. Dersom man valgte “opp” og det avslørte vippetallet er høyere eller lik hovedtallet, vinner man en større premie. Det samme skjer dersom man velger “ned” og vippetallet er lavere eller lik hovedtallet. Vi antar at de hemmelige vippetallene er tilfeldig valgt mellom 0 og 9.

Strategien vi skal implementere er å si “opp” dersom hovedtallet er 4 eller lavere, og si “ned” ellers.

I filen joker.py, skriv et program som ber brukeren om 5 tall. Disse representerer hovedtallene vi får oppgitt når vi begynner å spille Joker. Deretter skal programmet skrive ut enten “opp” eller “ned”, for hvert av de fem hovedtallene. En kjøring av programmet kan se slik ut:

tall1 = 3
tall2 = 4
tall3 = 5
tall4 = 6
tall5 = 1
opp
opp
ned
ned
opp
Volum av boks
Oppvarming
Nivå E

I denne oppgaven skal vi bli kjent med funksjoner med returverdi. I en fil volume_of_box.py, opprett en funksjon volume_of_box(w, h, d) som returnerer volumet av en eske med bredde w, høyde h og dybde d. (Se hintet under for formel.)

  • Volumet av en boks er definert som \(V = w \cdot h \cdot d\)

Du kan teste at funksjonen fungerer ved å legge til denne linjen på slutten av filen:

print(volume_of_box(2, 3, 5)) # Skal skrive ut 30

Når du kjører filen skal 30 skrives ut i terminalen om du har gjort alt riktig.

Multiplisere med 5 og trekke fra pi
Oppvarming
Nivå E

I en fil multiply_5_minus_pi.py, skriv en funksjon multiply_5_minus_pi(my_number) som:

  • Tar et argument my_number av typen int.
  • Multipliserer dette med 5 og trekker fra akkurat 3.14.
  • Returnerer resultatet (du skal ikke skrive ut resultatet til terminalen).

Test koden din ved å legge til disse linjene nederst i filen:

from math import isclose
print("Tester multiply_5_minus__pi... ", end="")
assert isclose(1.86, multiply_5_minus_pi(1))
assert isclose(56.86, multiply_5_minus_pi(12))
assert isclose(611.86, multiply_5_minus_pi(123))
print("OK")
Shout
Oppvarming
Nivå E

Nå skal vi lage en funksjon som behandler en str. I en fil shout.py, skriv en funksjon shout(text) som:

  • Tar et argument text.
  • Legger til et utropstegn («!») til slutten av ordet eller frasen.
  • Returnerer resultatet. (Ikke print noe!).

Test koden din ved å legge til disse linjene nederst i filen:

print("Tester shout... ", end="")
assert "I love programming!" == shout("I love programming") 
assert "Adventure awaits!" == shout("Adventure awaits") 
assert "Ikke print noe!" == shout("Ikke print noe") 
print("OK")
Kinetisk energi
Oppvarming
Nivå E

I en fil kinetic_energy.py, skriv en funksjon som heter kinetic_energy(m, v). Funksjonen skal ta to argumenter \(m\) og \(v\) begge av typen int, og skal returnere \(\frac{1}{2}mv^2\).

Test koden din ved å legge til disse linjene nederst i filen:

from math import isclose
print("Tester kinetic_energy... ", end="")
assert isclose(4.0, kinetic_energy(2,2))
assert isclose(128.0, kinetic_energy(4,8))
assert isclose(2.5, kinetic_energy(5,1))
print("OK")
Avstand med funksjon
Oppvarming
Nivå E

I en fil distance.py, skriv en funksjon distance(x1, y1, x2, y2) som regner ut og returnerer avstanden mellom to punkter \((x_1, y_1)\) og \((x_2, y_2)\).

Illustrasjon av avstandsformelen d=sqrt((x1-x2)^2 + (y1-y2)^2)

For å teste koden, kan du legge til denne linjen nederst i filen:

from math import isclose
print("Tester distance... ", end="")
assert isclose(1.414213562373, distance(0, 0, 1, 1))
print("OK")

  • For å finne absoluttverdien av et tall kan du benytte abs() -funksjonen som er innebygget i Python.

  • Operatoren for eksponentiering er **, f. eks. vil 3**2 evaluere til 9.

  • Å ta kvadratroten av et tall er det samme som å opphøye tallet i 0.5. For eksempel, 9**0.5 vil evaluere til 3.0.

Obligatorisk

Korteste ord
Obligatorisk
Nivå D

I filen shortest_words.py, skriv kode som leser inn 3 ord og skriver ut det korteste ordet. Om flere ord har den korteste lengden skal programmet skrive ut alle ordene.

Kjøring av programmet ditt skal se ut slik som følgende eksempelkjøringer:

Skriv et ord:
Game   
Skriv et annet ord:
Action
Skriv et siste ord:
Champion

Game
Skriv et ord:
pineapple   
Skriv et annet ord:
apple
Skriv et siste ord:
grape

apple
grape
Skriv et ord:
Four   
Skriv et annet ord:
Five
Skriv et siste ord:
Nine

Four
Five
Nine
Lengste ord
Obligatorisk
Nivå D

I filen longest_word.py skal du lage et program som leser inn 3 ord og skriver ut det lengste ordet. Men om flere ord har den lengste lengden skal programmet bare skrive ut det første ordet som har en lengst lengde.

Eksempelkjøringer:

Skriv et ord:
Game   
Skriv et annet ord:
Action
Skriv et siste ord:
Champion

Champion
Skriv et ord:
pear   
Skriv et annet ord:
apple
Skriv et siste ord:
grape

apple
Skriv et ord:
Four   
Skriv et annet ord:
Five
Skriv et siste ord:
Nine

Four
Paritet
Obligatorisk
Nivå E

I filen parity.py, skriv en funksjon parity(x) som tar inn et tall x og siden returnerer Partall hvis tallet er et partall og Oddetall hvis tallet er et oddetall. Du kan anta i funksjonen at x er et heltall og har typen int.

def parity(x):
    # Skriv koden din her

For å teste funksjonen din kan du legge til dette på slutten av filen:

print("Tester parity... ", end="")
assert "Partall" == parity(0)
assert "Oddetall" == parity(1) 
assert "Partall" == parity(42)
assert "Oddetall" == parity(99)
print("OK")

  • Benytt modulo (%) for å avgjøre om et tall er partall eller oddetall. Mer informasjon om modulo finner i kursnotatene om operatorer

Overlappende sirkler
Obligatorisk
Nivå D

I denne oppgaven skal du skrive et program som avgjør hvorvidt to sirkler overlapper. En sirkel kan beskrives ved hjelp av et koordinat for sirkelens sentrum \((x, y)\), samt en radius \(r\).

Illustrasjon av sirkel

Opprett en funksjon circles_overlap(x1, y1, r1, x2, y2, r2) i filen circles_overlap.py. La funksjonen returnere True dersom to sirkler beskrevet med henholdsvis x1, y1, r1 og x2, y2, r2 overlapper, og False hvis ikke.

To sirkler overlapper dersom avstanden mellom sirklenes sentrum er mindre enn eller lik summen av sirklenes radiuser.

For å teste funksjonen du har skrevet kan du legge til denne koden nederst i filen circles_overlap.py:

# Sirkel1 med sentrum (0, 0) og radius 1
# Sirkel2 med sentrum (1, 1) og radius 1
# Overlapper
print(circles_overlap(0, 0, 1, 1, 1, 1)) # Skal skrive ut True

# Sirkel1 med sentrum (0, 0) og radius 2
# Sirkel2 med sentrum (4, 1) og radius 2
# Overlapper ikke
print(circles_overlap(0, 0, 2, 4, 1, 2)) # Skal skrive ut False

# Sirkel1 med sentrum (0, 0) og radius 3
# Sirkel2 med sentrum (5, 0) og radius 2
# De overlapper hverandre i et enkelt punkt
print(circles_overlap(0, 0, 3, 5, 0, 2)) # Skal skrive ut True

Illustrasjon av testene:

Illustrasjon av sirkler/test-caser
Pop art
Obligatorisk
Nivå A-D

Denne øvelsen trenger du ikke å levere inn, men å gjøre den først kan være en god forberedelse for Pop Art -oppgaven.

Programmet under tegner én boks med suppe

from uib_inf100_graphics.simple import canvas, display

def draw_soup_can(canvas, x, y, bg_color, text_color):
    canvas.create_rectangle(x, y+10, x+100, y+130,
                            fill=bg_color, outline="black")
    canvas.create_oval(x, y, x+100, y+20, fill="gray", outline="black")
    canvas.create_oval(x, y+120, x+100, y+140, fill="gray", outline="black")
    canvas.create_text(x+50, y+50, text="SOUP",
                       fill=text_color, font=("Arial", 16, "bold"))

draw_soup_can(canvas, 50, 30, "red", "yellow")
# TODO: make three more calls to draw_soup_can with different arguments

display(canvas)

Skriv tre nye linjer med kode hvor du kaller funksjonen draw_soup_can med andre argumenter, slik at du får tegnet fire bokser med suppe som vist her:

Fire kanner med suppe

Denne øvelsen trenger du ikke å levere inn, men å gjøre den først kan være en god forberedelse for Pop Art -oppgaven.

Dette programmet tegner en vakker kvinne fire ganger:

from uib_inf100_graphics.simple import canvas, display

def draw_marilyn(canvas, x, y):
    # Background
    canvas.create_rectangle(x, y, x+100, y+100, fill='red', outline='')

    # Face
    canvas.create_oval(x+20, y+20, x+80, y+80, outline='yellow', width=2)

    # Eyes
    canvas.create_oval(x+35, y+40, x+45, y+50, fill='yellow', outline='')
    canvas.create_oval(x+55, y+40, x+65, y+50, fill='yellow', outline='')

    # Mouth
    canvas.create_arc(x+35, y+50, x+65, y+70, start=180, extent=180,
                      fill='yellow', outline='')

# Drawing four faces
draw_marilyn(canvas, 50, 50)
draw_marilyn(canvas, 250, 50)
draw_marilyn(canvas, 50, 250)
draw_marilyn(canvas, 250, 250)

display(canvas)

For å gjøre tegningen litt mer interessant, endre draw_marilyn -funksjonen slik at den i tillegg til x og y også tar inn to nye parametre background_color og detail_color. Oppdater funksjonskroppen (kodelinjene inne i funksjonen) slik at den benytter disse fargene i stedet for hardkodete farger når den tegner

I de fire funksjonskallene som utfører tegningen, velg ulike farger etter eget ønske. Det endelige resultatet kan for eksempel se slik ut:

Marily tegnet i fire ulike farger

Denne øvelsen trenger du ikke å levere inn, men å gjøre den først kan være en god forberedelse for Pop Art -oppgaven.

Dette programmet (som du kjenner igjen fra lab1) tegner en strekmann.

from uib_inf100_graphics.simple import canvas, display

canvas.create_oval(60, 80, 140, 160)   # Head
canvas.create_line(100, 160, 100, 280) # Body
canvas.create_line(50, 180, 150, 180)  # Arms
canvas.create_line(100, 280, 50, 330)  # Left leg
canvas.create_line(100, 280, 150, 330) # Right leg

display(canvas)

Oppgaven er å endre koden slik at tegningen av strekmannen skjer i en funksjon draw_stickman som tar inn tre parametre canvas, x og y. Tegn strekmannen i funksjonen slik at den som kaller på metoden enkelt kan flytte hele strekmannen rundt på skjermen ved å gi ulike argumenter for x og y.

Kall funksjonen to ganger med ulike argumenter for å tegne to strekmenn ved siden av hverandre, som vist her:

To strekmenn

Den resulterende koden din kan for eksempel se ca slik ut:

from uib_inf100_graphics.simple import canvas, display

def draw_stickman(canvas, x, y):
    # TODO: Kode som tegner strekmannen her
    # Koden kan være en kopi av den originale
    # sterk-mannen, men pluss på x på alle
    # x-koordinater, og pluss på y på alle
    # y-koordinater.

draw_stickman(canvas, 0, 0)
draw_stickman(canvas, 200, 0)

display(canvas)

I denne oppgaven skal du lage din egen pop art i filen pop_art.py.

Pop art er en kunststil som ble populær på 1950-tallet. Pop art-kunstnere brukte ofte fargerike bilder av kjente personer, produkter og reklame, og benyttet seg mye av repetisjon av samme bilde i ulike farger. Den fremste eksponenten av pop art var Andy Warhol fra nydelige Pittsburgh PA, som blant annet lagde bilder av Marilyn Monroe og Campbell’s suppebokser.

Programmet ditt skal benytte en funksjon for å tegne et motiv, og funksjonen må kalles minst to ganger for å tegne variasjoner av det samme motivet ulike steder på lerretet. Du må benytte uib_inf100_graphics.simple for å lage tegningen. Du kan velge motivet ditt helt selv. Når du leverer oppgaven på CodeGrade, vil bildet ditt automatisk lastes opp i galleriet, hvor du også kan se hva dine medstudenter har laget. Noen eksempler på hva du kan lage:

image
image
image
Belgisk flagg
Obligatorisk
Nivå D

Forberedelser: Repeter notatene om grafikk

I denne oppgaven skal vi lage en funksjon som tegner et belgisk flagg.

Opprett filen belgian_flag.py der du oppretter en funksjon draw_belgian_flag som tar inn fem parametere: canvas, x1, y1, x2, y2. Funksjonen skal tegne et belgisk flagg på canvas med øvre venstre hjørne i punktet \((x_1, y_1)\) og nedre høyre hjørne i punktet \((x_2, y_2)\). Funksjonen trenger ikke å ha noen returverdi.

Merk: I filen belgian_flag.py skal du ikke importere noe, og du skal heller ikke kalle på display-funksjonen. For å teste koden, opprett i stedet en separat fil belgian_flag_test.py i samme mappe som belgian_flag.py og kopier inn koden under. Når du kjører belgian_flag_test.py, skal det tegnes tre belgiske flagg på skjermen som vist under:

from uib_inf100_graphics.simple import canvas, display
from belgian_flag import draw_belgian_flag

draw_belgian_flag(canvas, 125, 135, 275, 265)
draw_belgian_flag(canvas, 10, 10, 40, 36)
draw_belgian_flag(canvas, 10, 340, 390, 360)

display(canvas)
Eksempelkjøring 1

Frivillig

Punkt i rektangel
Frivillig
Nivå D

Et hyperrektangel er et rektangel hvor sidene er vannrette og loddrette (ikke rotert). Vi kan representere et hyperrektangel med to koordinater \((x_1, y_1)\) og \((x_2, y_2)\) som representerer to diagonalt motsatte hjørner (du kan ikke anta noe om hvilken rekkefølge disse punktene kommer i, eller hvilke to motsatte hjørner i rektangelet de beskriver). I denne oppgaven skal du avgjøre hvorvidt et tredje punkt \((x_p, y_p)\) befinner seg innenfor et slikt rektangel eller ikke.

I en fil point_in_rectangle.py, skriv en funksjon point_in_rectangle som har seks parametre x1, y1, x2, y2, xp, yp, hvor de fire første parametrene representerer et hyperrektangel, og de to siste representerer et vilkårlig punkt. La metoden returnere True dersom punktet er innenfor rektangelet, og False hvis ikke. Dersom punktet befinner seg akkurat på linjen, regner vi det som at den er innenfor.

Illustrasjon av punkt i rektangel

Test koden din:

print("Tester point_in_rectangle... ", end="")
assert point_in_rectangle(0, 0, 5, 5, 3, 3)  # Midt i
assert point_in_rectangle(0, 5, 5, 0, 5, 3) # På kanten
assert not point_in_rectangle(0, 0, 5, 5, 6, 3)  # Utenfor
print("OK")

  • Omregn rektangelet slik at du vet hva som er høyre og venstre, top og bunn. For eksempel, opprett variabler x_left = min(x1, x2) og x_right = max(x1, x2). Tilsvarende for topp og bunn med y-aksen.

  • Sjekk at punktet \((x_p, y_p)\) både befinner seg mellom venstre- og høyresiden, og også mellom topp og bunn.

  • For eksempel: punktet \((x_p, y_p)\) er mellom høyre- og venstre siden dersom både x_left er mindre eller lik xp og xp er mindre eller lik x_right.

Kollisjonsdeteksjon
Frivillig
Nivå B

Denne oppgaven består av to deler. Skriv funksjoner til begge deloppgaver (A-B) i én felles fil, collision_detection.py.

Del A

I filen collision_detection.py, skriv en funksjon rectangles_overlap som har åtte parametre x1, y1, x2, y2, x3, y3, x4, y4, hvor de fire første parametrene representerer ett hyperrektangel, og de fire siste representerer et annet. La metoden returnere True dersom rektanglene overlapper hverandre, og False hvis ikke. Vi sier at rektanglene overlapper selv om de kun deler ett enkelt punkt.

Illustrasjon av overlappende rektangler

Test koden din:

print("Tester rectangles_overlap... ", end="")
assert(rectangles_overlap(0, 0, 5, 5, 2, 2, 6, 6)) # Delvis overlapp
assert(rectangles_overlap(0, 5, 5, 0, 1, 1, 4, 4)) # Fullstendig overlapp
assert(rectangles_overlap(0, 1, 7, 2, 1, 0, 2, 7)) # Kryssende rektangler
assert(rectangles_overlap(0, 5, 5, 0, 5, 5, 7, 7)) # Deler et hjørne
assert(not rectangles_overlap(0, 0, 5, 5, 3, 6, 5, 8)) # Utenfor
print("OK")

  • Omregn begge rektangler slik at du vet hva som er høyre og venstre, top og bunn (se hint for oppgaven Hyperrektangel).
  • Dersom høyresiden til ett rektangel er til venstre for venstresiden av det andre, blir svaret false (tilsvarende logikk med topp og bunn). Husk å sjekke begge retninger.

Illustrasjon av testcasene i assert’ene over:

Illustrasjon av testcasene over

Del B

I filen collision_detection.py, skriv en funksjon circle_overlaps_rectangle som har syv parametre x1, y1, x2, y2, xc, yc, rc, hvor de fire første parametrene representerer to motstående hjørner i et hyperrektangel, og de tre siste representerer en sirkel sentrert i \((x_c, y_c)\) med radius \(r_c\). La metoden returnere True dersom sirkelen overlapper rektangelet, og False hvis ikke. Dersom sirkelen og rektangelet deler kun ett enkelt punkt regnes det fremdeles som at de er overlappende.

Illustrasjon av sirkel og rektangel som ikke overlapper

Test koden din:

print("Tester circle_overlaps_rectangle... ", end="")
assert(circle_overlaps_rectangle(0, 0, 5, 5, 2.5, 2.5, 2)) # sirkel i midten
assert(not circle_overlaps_rectangle(0, 5, 5, 0, 8, 3, 2)) # langt utenfor
assert(circle_overlaps_rectangle(0, 0, 5, 5, 2.5, 7, 2.01)) # langs kanten
assert(circle_overlaps_rectangle(0, 5, 5, 0, 5.1, 5.1, 1)) # på hjørnet
assert(circle_overlaps_rectangle(0, 0, 5, 5, 8, 8.99, 5)) # på hjørnet
assert(not circle_overlaps_rectangle(0, 0, 5, 5, 8, 9.01, 5)) # akkurat ikke
print("OK")

  • Dersom sirkelens sentrum er inne i rektangelet, er svaret True. Bruk funksjonen du skrev i oppgaven over om hyperrektangel for å sjekke dette.
    • Du kan importere funksjonen ved å legge til from miscellaneous import point_in_rectangle øverst i collision_detection.py.
  • La det minste x-koordinatet av x1 og x2 kalles x_left, og la det største kalles x_right. På samme måte, slutt å tenke på punktene y1 og y2, og regn i stedet ut punktene y_top og y_bottom.
  • «Utvid» rektangelet med sirkelens radius i alle retninger. Hvis sirkelens sentrum er utenfor dette utvidede rektangelet (bruk funksjonen point_in_rectangle igjen), er det garantert ikke noe overlapp.
  • I de gjenstående tilfellene befinner sirkelen sitt sentrum seg i rammen rundt rektangelet som er tegnet med stiplet linje i illustrasjonen over.
    • Dersom sirkelens x-koordinat befinner seg mellom x-koordinatene til det opprinnelige rektangelet, er det overlapp.
    • Tilsvarende for y-aksen.
    • Hvis sirkelens sentrum ikke tilfredsstiller noen av de to punktene over, befinner det seg i et av hjørnene. Dersom sirkelens sentrum har større avstand enn \(r_c\) til samtlige hjørner i det opprinnelige rektangelet, er det ingen overlapp (f. eks. slik som på figuren over). For å finne avstanden, bruk funksjonen distance som du kan importere fra en tidligere oppgave (from miscellaneous import distance).

Illustrasjon av testcasene oppgitt over (en sirkel per testcase):

Illustrasjon av testcasene

Flytdiagram for circle_overlaps_rectangle

if point_in_rectangle(...):  # sirkelens sentrum inne i rektangel?
    return True
elif not point_in_rectange(...): # sentrum utenfor utvidet rektangel?
    return False
elif ... # punkt er mellom venstre og høyresiden til rektangel (x-aksen)
    return True
elif ... # punkt er mellom topp og bunn til rektangel (y-aksen)
    return True
elif distance(...) # sirkelen overlapper hjørnet oppe til venstre
    return True
elif ... # sirkelen overlapper hjørnet oppe til høyre
    return True
...

Hundeår
Frivillig
Nivå D

Vanligvis sier man at et menneskeår tilsvarer 7 hundeår. Dette tar ikke hensyn til at hunder blir voksne når de er ca 2 år. Derfor kan det være bedre å regne begge de første 2 menneskeårene som 10.5 hundeår hver, og etter det regne hvert menneskeår som 4 hundeår.

I filen dog_years.py skal du opprette funksjonen human_to_dog_years med én parameter som representerer antall menneskeår. La funksjonen returnere hvor mange hundeår dette tilsvarer.

Test koden din ved å legge til disse linjene nederst i filen:

def almost_equals(a, b):
    return abs(a - b) < 0.00000001

print("Tester human_to_dog_years... ", end="")
assert(almost_equals(15.75, human_to_dog_years(1.5)))
assert(almost_equals(21.00, human_to_dog_years(2)))
assert(almost_equals(57.00, human_to_dog_years(11)))
print("OK")

PS: Dersom en assert feiler, kan det være lurt å se hva resultatet faktisk ble. Legg til en print-setning som viser resultatet av human_to_dog_years før assertene for å hjelpe til å feilsøke.

Skuddår
Frivillig
Nivå C

Regelen for å beregne om et år er et skuddår eller ikke er som følger:

  • Vanligvis er et år som er delelig med 4 et skuddår (for eksempel 1996 var et skuddår);
  • bortsett fra år som også er delelige med 100 (for eksempel 1900 er ikke skuddår);
  • men hvis året som er delelige med 100 også er delelig med 400, da er det et skuddår likevel (for eksempel er 2000 et skuddår).

I filen leapyear.py opprett en funksjon is_leap_year(year) som tar inn et årstall og returnerer True dersom det er et skuddår, og False hvis ikke.

Test koden din ved å legge til disse linjene nederst i filen:

print("Tester is_leap_year... ", end="")
assert(not is_leap_year(2022))  # Forventer False (ikke delelig med 4)
assert(is_leap_year(1996))      # Forventer True
assert(not is_leap_year(1900))  # Forventer False
assert(is_leap_year(2000))      # Forventer True
print("OK")

  • Benytt modulo-operatøren (%) for å avgjøre om et heltall er delelig med et annet.

PS: Hvis alt er som det skal, vil programmet skrive ut

Tester is_leap_year... OK
Synlig lys
Frivillig
Nivå A

Våre øyne oppfatter elektromagnetisk stråling med en bølgelengde fra 380 til 740 nanometer, eller med en frekvens fra 405 til 790 terahertz. Dette område er kalt synlig lys eller bare lys. elektromagnetisk stråling i synlig lys omdannes til farger i hjernen hos mennesker og dyr. Tabellen nedenfor viser hvor de ulike fargene av synlig lys ligger i spekteret. Wikipedia.

Color Wavelength (nm) Frequency (THz)
Violet 380 - 450 670 - 790
Blue 450 - 485 620 - 670
Cyan 485 - 500 600 - 620
Green 500 - 565 530 - 600
Yellow 565 - 590 510 - 530
Orange 590 - 625 480 - 510
Red 625 - 750 400 - 480

Forholdet mellom bølgelengde og frekvens er gitt ved formelen: $$ \lambda = \frac{c}{f} $$ hvor \(\lambda\) er bølgelengde i meter, \(f\) er frekvens i Hz, og \(c = 3\cdot 10^8\text{ m/s}\) er lysets hastighet. Husk også på at vi har følgende forhold mellom enheter: $$ 1\text{ m} = 10^{9}\text{ nm} $$ $$ 1\text{ Hz} = 10^{-12}\text{ THz} $$ PS: Hz er det samme som 1/s.

I filen visible_light.py skal du skrive et program som spør brukeren om en enhet, enten nanometer (nm) eller terahertz (THz), og siden en verdi (et heltall). Programmet skal skrive ut hvilken farge i synlig lys den enheten og verdien tillhører. Om du får en enhet som ikke er nm eller THz skal programmet ditt informere brukeren at enheten må være enten nm eller THz, og programmet skal avslutte kjøringen (se eksempler under for nøyaktig ordlyd). Om brukeren skriver inn en bølgelengde eller frekvens som er utenfor spektrumet, skal det gis melding om dette også (se eksempler). Om du får en verdi som er akkurat på grensen mellom to farger skal du velge fargen med kortest bølgelengde (høyest frekvens) av de to.

Eksempelkjøringer:

Angi enhet (nm eller THz):
nm   
Angi verdi i nm:
520

Green
Angi enhet (nm eller THz):
THz
Angi verdi i THz:
680

Violet
Angi enhet (nm eller THz):
nm
Angi verdi i nm:
320

320 nm er utenfor det synlige spekteret.
Angi enhet (nm eller THz):
THz
angi verdi i THz:
800

800 THz er utenfor det synlige spekteret.
Angi enhet (nm eller THz):
foo

Enheten må være i nm eller THz, det kan ikke være foo.

Forslag til programflyt

Det er mange ulike måter å løse denne oppgaven på. Programflyten over er et forslag som kan hjelpe deg å bryte ned programkoden i mer overkommelige deler. I skjemaet over er det to større oppgaver vi ikke har løst for deg:

  • La \(f\) være frekvensen i antall Hz. Husk at verdien brukeren har gitt oss har enheten THz, så vi må først regne om. 1 THz er det samme som 10**12 Hz.
  • Lysets hastighet er \(c = 3\cdot 10^8\text{ m/s}\).
  • Plugg verdiene inn i formelen \(\lambda = c/f\) for å regne ut bølgelengden.
  • Regn svaret om fra meter til nanometer.

  • Det kan være lurt å benytte en if-elif -sekvens, hvor betingelsene sjekker verdien til bølgelengden opp mot grensene gitt i tabellen i oppgaveteksten.
  • Ikke overskriv den enhet og verdi brukeren opprinnlig gav som input, men ta vare på dem i variabler slik at du kan skrive ut en feilmelding basert på disse hvis det trengs.