Lab2

Nivå E:

Nivå A-D:

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


Nivå E
Korteste ord

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
Nivå E
Lengste ord

Her skal vi gjøre nesten samme sak som i forrige oppgave, men med noen små forskjeller. 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
Nivå E
Paritet

I filen parity.py, skriv kode som ber brukeren oppgi et tall og siden skriver ut «Partall» hvis tallet er et partall og «Oddetall» hvis tallet er et oddetall. Du kan anta at brukeren alltid oppgir et heltall.

Eksempelkøringer:

Angi et tall:
123456  
Partall
Angi et tall:
123
Oddetall

  • Benytt modulo (%) for å avgjøre om et tall er partall eller oddetall; les mer om modulo i kursnotatene om operatorer.

Nivå E
Hyperrektangel

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 filen hyperrectangle.py, skriv kode som ber brukeren skrive inn seks tall x1, y1, x2, y2, xp og yp hvor de fire første tallene representerer et hyperrektangel, og de to siste representerer et vilkårlig punkt. Se eksempler under for hvordan spørringen skal se ut. La metoden skrive ut «inne» dersom punktet er innenfor rektangelet, og «ute» hvis ikke. Dersom punktet befinner seg akkurat på linjen, regner vi det som at den er innenfor.

Illustrasjon av punkt i rektangel

Eksempelkjøringer:

x1 = 0   
y1 = 0
x2 = 5
y2 = 5
xp = 3
yp = 3

inne
x1 = 0
y1 = 5
x2 = 5
y2 = 0
xp = 5
yp = 3

inne
x1 = 0
y1 = 0
x2 = 5
y2 = 5
xp = 6
yp = 3

ute

Illustrasjon av eksempelkjøringer

  • 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.
  • Hvis punktet \((x_p, y_p)\) befinner seg lengre til venstre enn x_left (hvordan sjekker du det?) er punktet åpenbart utenfor rektangelet. Tilsvarende; hvis punktet er lengre til høyre enn x_right er det også utenfor. Det samme gjelder for topp og bunn.
  • Hvis punktet \((x_p, y_p)\) verken er for lang til høyre, for langt til venstre, for høyt oppe eller for lavt nede, kan du konkludere med at punktet er innenfor rektangelet.

...
if (xp < x_left):   # hvis P befinner seg lengre til venstre enn x_left
    print("ute")
elif (...):       # hvis P befinner seg lengre ...
    ...

Nivå E

Belgisk flagg

I filen belgian_flag.py, skriv en program som

  • først, leser fire tall x1, y1, x2, y2 fra brukeren (i terminalen) som representerer to motstående hjørner i et rektangel, og så
  • skriver ut (i terminalen) bredden og høyden på rektangelet, og så
  • skriver ut (i terminalen) ved hvilke x-koordinater den svarte stripen begynner og slutter, og så
  • skriver ut (i terminalen) ved hvilke x-koordinater den gule stripen begynner og slutter, og så
  • skriver ut (i terminalen) ved hvilke x-koordinater den røde stripen begynner og slutter, og så
  • åpner et vindu som tegner det belgiske flagget innenfor rektangelet som er angitt.

Du må benytte uib_inf100_graphics.simple for å tegne flagget. Når du skriver ut koordinatene til terminalen, rund av nedover til et heltall. Dette kan du gjøre ved å benytte int -funksjonen, f. eks vil int(2.9) rundes av til 2.

x1 = 125   
y1 = 135
x2 = 275
y2 = 265
Flag width is 150 Flag height is 130
Black stripe starts at x = 125 and ends at x = 175 Yellow stripe starts at x = 175 and ends at x = 225 Red stripe starts at x = 225 and ends at x = 275
Eksempelkjøring 1
x1 = 10   
y1 = 10
x2 = 310
y2 = 390
Flag width is 300 Flag height is 380
Black stripe starts at x = 10 and ends at x = 110 Yellow stripe starts at x = 110 and ends at x = 210 Red stripe starts at x = 210 and ends at x = 310
Eksempelkjøring 2
Nivå D
Katteår

Katter eldes raskere enn mennesker. Noen sier at ett menneske år tilsvarer 4 katteår bortsett fra kattens første og andre leveår som teller for 15 katteår og 9 katteår respektivt. En katt er altså 24 år gammel i katteår nå den er 2 år gammel i menneskeår. Deretter teller hvert menneskeår for 4 katteår.

I filen cat_years.py, skriv kode som gjør følgende:

  1. Ber bukeren skrive inn antall menneskeår (du kan anta at dette er et heltall).
  2. Regner antallet om til katteår.
  3. Skriver ut resultatet.

Eksempelkøringer:

Angi menneskeår:
2  
Dette tilsvarer 24 katteår.
Angi menneskeår:
1
Dette tilsvarer 15 katteår.
Angi menneskeår:
11
Dette tilsvarer 60 katteår.
Nivå D
Gyldig trekant

I filen legal_triangle.py, skriv kode som ber brukeren oppgi tre tall og siden melder om de tre tallene kan representere lengden på sidene i en trekant.

  • Dersom det er mulig å lage en vanlig trekant, skal programmet skrive ut «Mulig trekant.»
  • Dersom to av sidelengdene summerer til den tredje sidelengden, skal programmet i stedet skrive ut «Noen vil si det er en trekant, andre vil si det er en strek.»
  • Dersom det ikke er mulig å lage noen trekant med sidelengdene, skal programmet skrive ut «Umulig å lage en slik trekant.»

Programmet skal også fungere dersom brukeren skriver desimaltall. Du kan anta at ingen flyttall blir oppgitt med flere en fem desimaler.

PS! Trekantulikheten sier det slik: summen av to vilkårlige sidelengder i en trekant er aldri kortere enn den tredje sidelengden.

Eksempelkjøringer:

sideA = 3   
sideB = 4
sideC = 5

Mulig trekant.
sideA = 0.1   
sideB = 0.2
sideC = 0.3

Noen vil si det er en trekant, andre vil si det bare er en strek.
sideA = 2   
sideB = 2
sideC = 5

Umulig å lage en slik trekant.

  • Du kan benytte en sekvens med if-elif-elif-elif… der du har en utskrift i hver kodeblokk. I en slik sekvens er det kun én kodeblokk som utføres (den første hvor betingelsen slår til).
  • I de første par betingelsene, begynn med å se etter grensetilfellene der summen av to sider er lik den tredje siden.
  • Se deretter etter umulige trekanter (f. eks. sideA + sideB < sideC)
  • Hvis det verken er en umulig trekant eller et grensetilfelle, må det være en gyldig trekant.

Hvis du har problemer med casen 0.1, 0.2, 0.3, kan det være lurt å lese litt om flyttall og avrundingsfeil. TLDR; for å sammenligne om 0.1 + 0.2 er lik 0.3, kan du skrive abs(0.1 + 0.2 - 0.3) < 0.00000001.

Nivå C
Skuddår

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 leap_year.py, skriv kode som gjør følgende:

  1. Ber bukeren skrive inn et årstall.
  2. Avgjør om årstallet er et skuddår.
  3. Skriver ut resultatet.

Eksempelkjøringer:

Angi år:
1996  
Dette er et skuddår.
Angi år:
1900
Dette er ikke et skuddår.
Angi år:
2000
Dette er et skuddår.
Angi år:
2022
Dette er ikke et skuddår.

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

Nivå A-D

Pop art

I denne oppgaven bruker vi et konsept vi ikke har snakket om ennå: funksjoner. Mer om det kommer i uke 4, men du som har lyst kan allerede prøve det ut nå. Klikk på de følgende oppvarmingsøvelsene først før du prøver!

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. Noen eksempler på hva du kan lage:

Pop art E
Pop art D
Pop art A

Når du leverer denne oppgaven på CodeGrade, vil et skjermbilde av programmet ditt automatisk lastes opp i galleriet hvor du også kan se hva dine medstudenter har levert.

Nivå A
Synlig lys

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.