Øving 4 - Funksjoner

VIKTIG!

Minst 5 av 6 oppgaver må løses for å få godkjent øvingen. Husk å sjekk at alle deloppgaver er løst.

Dersom ikke annet er oppgitt skal koden for hver programmeringsoppgave bestå av èn celle med hele programkoder.

Celler med "In [ ]:" foran er kode-celler som kan kjøre kode. Ellers er cellene tekstbokser. En celle (både tekst og kode) kjøres hvis du markerer den og trykker SHIFT+ENTER. Se guide for utfyllende informasjon om hvordan man bruker jupyter notebooks.

Last ned øvingen fra jupyter til din pc som .pdf-fil (se guide) og last den opp i Blackboard for å levere den.

Oppgave 1

a)

Programmet under har tre feil som gjør at det ikke kjører, og ikke gir riktig resultat i print-setningen. Rett opp programmet.

In [5]:
""" Dette programmet tar inn en liste med tall og printer ut antallet 
unike tall, og hvilke tall som er unike. """

##

tall = [1,3,8,31,5,16,7,6,45,44,3,21,1,31,5,7,7,6,5,14,3,12,2,4,5,11,6,8,1,3,8,31,5,16,7,6,45,44,3,21,1,31,5,7,7,6,5,14,3,12,2,4,5,11,6,8]

# Funksjon som finner unike tall i en liste
def unik(liste1): 
    
    unike_liste = [] # Initier tom liste
      
    for x in liste1: # sjekk om tallet eksisterer i lista
        if x not in unike_liste: 
            unike_liste.append(x) # Legger nye unike tall til i lista over unike tall
            
    return unike_liste # Returnerer den unike listen

# Funksjon som sjekker hvilke tall i en liste som er unike, og hvor mange unike tall det er
def liste_sjekk(liste1):
    
    unikeTall = unik(liste1) # Kaller unik()-funksjonen med listen som er gitt som argument
    lengdeUnike = len(unikeTall) # Finner lengden på lista med unike tall som blir lagt i variablen unikeTall
    
    return unikeTall, lengdeUnike  # Returnerer antall unike tall, og de unike tallene.

unike, lengde = liste_sjekk(tall) # Kall liste_sjekk() på tall-listen og legg resultatene i variabler

print('Listen har', lengde, 'unike tall. De unike tallene er', unike)

b)

Koden under refererer, på ulike steder, til variabler som alle har det samme navnet "num". Hvorfor skaper ikke det problemer for kjøringen av programmet?

Svar: lokalt skop på "num"-variablene inni funksjonene, og det at funksjonene returnerer "num" gir ikke problemer fordi man gir verdiene som returneres nye variabelnavn når funksjonene kalles.

In [ ]:
num = int(input('Hva er tallet? '))

def tallMagi(tall1):
    num = tall1*2
    return num

def tallTull(tall1):
    num = 0
    if tall1 // 2 == 5:
        num = 1
    else: 
        num = 2
    return num

en = tallMagi(num)
to = tallTull(num)
 

print('Resultatet er: ', num, en, to)
    

Oppgave 2

Konvertering mellom fot/tommer og meter/centimeter.

Bruk følgende opplysninger til å løse oppgaven under:

  • en fot tilsvarer 12 tommer
  • en tomme tilsvarer 2.54 cm

a)

Lag en funksjon med navn imp2cm() som får inn som parametre antall fot og antall tommer og returnerer antall cm som dette tilsvarer. Print antall cm (avrundet til én decimal) til konsoll med en forklarende setning.

In [ ]:
## Oppgave 2a svar

def imp2met(brukerFot, brukerTom):
    
    cmPrTomme = 2.54 # Antall cm i en tomme
    
    cmTom = brukerTom*cmPrTomme # Regner antall cm i oppgitt antall tommer
    
    cmPrFot = cmPrTomme*12 # Antall cm i en fot
    
    cmFot = brukerFot*cmPrFot # Regner ut antall cm i oppgitt antall fot
    
    cm = cmTom+cmFot # Legger sammen antall cm i oppgitt fot go tommer
    
    return(cm)
    
brukerFot = int(input('Antall fot : '))
brukerTom = int(input('Antall tommer : '))
cm = imp2met(brukerFot,brukerTom)
print(brukerFot,'fot og', brukerTom, 'tommer er ', format(cm,'.1f'), 'cm.')

b)

Bruk programmet over, og lag en ny funksjon som du kaller "konverteringsprogram". Denne funksjonen skal hente input fra bruker og kalle "imp2met"-funksjonen. Spør brukeren om han/hun vil konvertere flere tall, og kall "konverteringsprogram"-funksjonen hvis svaret er "ja".

In [ ]:
## Oppgave 2b svar
def imp2met(brukerFot, brukerTom):
    
    cmPrTomme = 2.54 # Antall cm i en tomme
    
    cmTom = brukerTom*cmPrTomme # Regner antall cm i oppgitt antall tommer
    
    cmPrFot = cmPrTomme*12# Antall cm i en fot
    
    cmFot = brukerFot*cmPrFot # Regner ut antall cm i oppgitt antall fot
    
    cm = cmTom+cmFot # Legger sammen antall cm i oppgitt fot go tommer
    
    return(cm)

def konverteringsprogram():
    brukerFot = int(input('Antall fot : '))
    brukerTom = int(input('Antall tommer : '))
    cm = imp2met(brukerFot,brukerTom)
    print(brukerFot,'fot og', brukerTom, 'tommer er ', format(cm,'.1f'), 'cm.')

ny = 'j'
while ny.lower() == 'j':
    print('Skriv inn tallene du vil ha konvertert til centimeter. ')
    konverteringsprogram()
    
    ny = input('Vil du konvertere flere tall (J/N)? ')

Oppgave 3

a)

Lagring av konstanter

Gravitasjonsakselerasjonen g på jordoverflaten er omtrent 9.81 m/s². For våre formål i denne deloppgaven kan denne antas å være konstant. Tiden som trengs for at et objekt i fritt fall skal ramle et gitt antall meter (d) er gitt ved formelen

t = sqrt(2m/g)

hvor g er gravitasjonsakselerasjonen som gitt tidligere.

I denne deloppgaven skal du lagre gravitasjonskonstanten i en global variabel med navnet GRAVITY på toppen av programmet ditt. Deretter skal du lage en funksjon get_fall_time som tar inn et gitt antall meter, og bruker formelen gitt over til å returnere hvor lang tid det tar et objekt å ramle det gitte antallet meter. La så programmet ditt ta inn en fall-lengde i meter fra brukeren, og bruk funksjonen du har laget til å regne ut hvor lang tid det tar å ramle den gitte distansen. Print ut resultatet.

In [ ]:
## Oppgave 3a svar

import numpy as np

GRAVITY = 9.81

def get_fall_time(m):
    
    t = np.sqrt(2*m/GRAVITY)
    
    return t


m = int(input('Hvor mange meter? '))

tidTilBakken = get_fall_time(m)

print('Det tar', format(tidTilBakken,'.1f'), 'sekunder å falle', 
      m, 'meter ved en gravitasjon på ', GRAVITY)

b)

Oppdatere en global variabel

I denne oppgaven ønsker vi å legge til rette for flere verdier av gravitasjonsakselrasjonen, ettersom denne ikke er helt konstant over hele jordoverflaten, i tillegg til at den vil være forskjellig på f.eks. månen. En mulig måte å løse dette på kunne vært å introdusere en ny funksjon som lar brukeren overskrive verdien til den globale konstanten. Husk at denne nye konstanten fortsatt må være global for å kunne brukes i resten av programmet.

In [ ]:
## Oppgave 3b svar

import numpy as np

g = float(input('Hva er g? ')) # Angi tallet som skal pass'es til set_gravity
                                # funksjonen

def set_gravity(g):
    
    global GRAVITY # Gjør GRAVITY til en global variabel
    
    GRAVITY = g # Sett GRAVITY til parameter g
    
    return GRAVITY

GRAVITY = set_gravity(g)


def get_fall_time(m):
    
    t = np.sqrt(2*m/GRAVITY) # Sett m inn i formelen og bruk GRAVITY-konstanten
    
    return t


m = int(input('Hvor mange meter? ')) # be om antall meter objektet skal falle

tidTiBakken = get_fall_time(m) # Kall get_fall_time og pass input for meter 
                               # til funksjonen


print('Det tar', format(tidTiBakken,'.1f'), 'sekunder å falle', 
      m, 'meter ved en gravitasjon på ', GRAVITY)

Oppgave 4

Utvidelse av programmet "Finn multiplikatoren" fra test-deg-selv uke 37.

En mulig løsning på oppgaven fra uke 37 er gjengitt under, og denne oppgaven var:

Skriv et program som bruker random-biblioteket. Angi en variabel med et tilfeldig tall mellom 1-10 med funksjonen "random.randrange(1,10)", og spør brukeren om å angi et tall mellom 1-100. Multipliser tallet som brukeren angir med det tilfeldige tallet, og spør brukeren om å prøve å gjette hvilket tall mellom 1-10 han/hennes tall ble multiplisert med. Print ut hva brukeren gjettet, og hva som var riktig multiplikator.

I denne oppgaven skal du skrive om programmet slik at det bruker funksjoner:

  • Lag funksjoner for å 1) hente inn gjetting og 2) vurdere om gjettingen var riktig
  • Fortell brukeren om gjettingen var riktig eller feil og la han/hun prøve å gjette på nytt hvis svaret var feil
  • Når brukeren har funnet riktig svar, spør om han/hun vil spille på nytt, og start programmet på nytt hvis svaret er "ja"
In [6]:
# Oppgave 4 svar
import random

ny = 'j'

def gjett(hemTall,brukTall,res):
    
    gjettet = 0
    
    while hemTall != gjettet:
        
        gjettet = int(input('Gjett det hemmelige tallet: '))
        
        if hemTall == gjettet:
            print('Riktig!', gjettet , 'multiplisert med ',hemTall,'blir', res)
        else:
            print('Feil.. Prøv igjen: ')
    

def main():
    hemTall = random.randrange(1,10)
    
    brukTall = int(input('Skriv et tall mellom 1-100 som skal multipliseres med det hemmelige tallet: '))
    
    res = brukTall*hemTall
    
    print('Tallet du skrev inn var', brukTall,'. Multiplisert med det hemmelige tallet ble det', res)
    print('Kan du gjette hva det hemmelige tallet er? ')
    
    gjett(hemTall, brukTall, res)
    
while ny.lower() == 'j':
    
    main()
    
    ny = input('Vil du prøve igjen (J/N)? ')
    

Oppgave 5

Anagramsjekker

I denne oppgaven skal du skrive en funksjon som tar inn to ord fra bruker. Funksjonen skal sjekke om det ene er et anagram av den andre - altså om ordene inneholder de samme bokstavene. Funksjonen skal returnere enten True eller False basert på om ordene var anagrammer eller ikke, og det skal skrives en beskjed til bruker om ordene var eller ikke var anagrammer.

Hint: Bokstavene i et ord kan sorteres hvis de først legges inn i en liste.

In [8]:
## Oppgave 5 svar

def is_anagram(ord1, ord2):
    ord1 = list(ord1)
    ord1.sort()
    ord2 = list(ord2)
    ord2.sort()
    
    result = False
    
    if ord1 == ord2:
        result = True
        
    return result

inp1 = str(input('Skriv inn det første ordet: '))
inp2 = str(input('Skriv inn det andre ordet: '))

if is_anagram(inp1,inp2):
    print('Ordene', inp1, 'og ',inp2, 'er anagrammer!')
else:
    print('Ordene', inp1, 'og ',inp2, 'er ikke anagrammer.')

Oppgave 6

I denne oppgaven skal du ta utgangspunkt i programmet under. Dette programmet skal la brukeren velge om han/hun vil tegne en firkant, en sirkel, en linje eller en prikk, og i hvilken farge. Ut fra valget skal det kalles en funksjon som tegner riktig figur, med riktig farge, i vinduet som kommer opp.

Programmet er basert på biblioteket pygame. Det meste av koden er allerede skrevet, men det som mangler er å legge tegningen av figurer inn i hver sin funksjon, skrive input-setningene for figurtype og farge, og å skrive koden for å kalle riktig figur-funksjon ut fra input fra bruker. Fullfør programmet der det er angitt i koden.

Et eksempel på en figurfunksjon er gitt i koden.

In [9]:
## Oppgave 6 svar
""" Programmet lar brukeren velge en figur som skal tegnes, og angi hvilken farge den skal være i. Tilgjengelige farger er:
'red','black','blue','green', og 'yellow' """

import turtle
import time

window = turtle.Screen()

# Initierer en turle ved navn tim. Angir tim's strekbredde(pensize) og form(shape).
tim = turtle.Turtle()
tim.pensize(5)
tim.shape('arrow')

# Flytter tim til startposisjonen
tim.penup()
tim.goto(-400,0)
tim.pendown()


def main():
    figurValg = int('Hvilken figur? 1 = linje, 2 = kvadrat, 3 = sirkel, 4 = trekant.')
    farge = str(input('Hvilken farge? (red/black/blue/green/yellow)'))
    
    get_figur(figurValg,farge)

def get_figur(valg,farge):
    if valg == 1:
        tegn_linje(farge)
    elif valg == 2:
        tegn_kvadrat(farge)
    elif valg == 3:
        tegn_sirkel(farge)
    elif valg == 4:
        tegn_trekant(farge)
    

# Definerer funksjon for å flytte tim
def move(steps):
    time.sleep(1) # Vent 1 sekund med å flytte markøren
    tim.penup()
    tim.forward(steps) # Mottar antall pixler tim skal flyttes
    tim.pendown()

## Eksempel på figur-funksjon
def tegn_linje(farge):
    # Kode for å tegne en rett linje
    tim.color(farge) # Endre denne koden i alle funksjonene for å ta inn input fra bruker om farge
    tim.forward(200) # Angir størrelsen (i antall pixler) på elementet som tegnes
    move(50) # Flytter markøren unna den tegnede figuren

def tegn_kvadrat(farge):
    # Kode for å tegne et kvadrat og fylle det med farge
    tim.begin_fill() # Starte farge-fyllingen av figuren
    for i in range(4): # Loop for å tegne 4 streker
        tim.color(farge)
        tim.forward(200)
        tim.left(90) # Snur tim 90 grader for å tegne neste strek
    tim.end_fill() # Avslutte farge-fyllingen av figuren
    move(300)
    
def tegn_sirkel(farge):
    # Kode for å tegne en sirkel og fylle den med farge
    tim.begin_fill()
    tim.color(farge)
    tim.circle(50) # Definerer radius på sirkelen
    tim.end_fill()
    move(200)

def tegn_trekant(farge):
    # Kode for å tegne en likebeint trekant og fylle den med farge
    tim.begin_fill()
    for i in range(3):
        tim.color(farge)
        tim.left(120) # Her må tim snu 120 grader for å tegne en trekant med 60 graders vinkler
        tim.forward(100)
    tim.end_fill()

main()
    

# Flytter tim tilbake til startposisjonen
tim.penup()
tim.goto(-400,0)
tim.pendown()

# Forhindrer bildet fra å lukkes med en gang programmet er ferdig å tegne
#turtle.getscreen()._root.mainloop()
window.exitonclick()