Objekt-orientert programmering - livekoding og oppgaver

Vi skal skrive et lite program for ? administrere et lotteri der ulike personer kan kj?pe lodd, og det trekkes en vinner til slutt. Med alt vi har l?rt til n? (unntatt ? skrive klasser), kan vi representere et lotteri slik:

# Liste over lodd og hvem som har kj?pt loddene
lotterilodd = ["Espen", "Marius", "Mari", "Emilie"]
# Premien
lotteripremie = 1000000
# Navn p? lotteriet
lotterinavn = "Superjackpot"

# Funksjon som kalles n?r noen kj?per et nytt lodd. Merk at premien skal ?ke med 1000 kroner for hvert lodd
def legg_til_nytt_lodd(navn):
    lotteripremie += 1000
    lotterilodd.append(navn)

def trekk_vinner():
    print("Trekker vinner i", lotterinavn)
    vinner = random.choice(lotterilodd)
    print("Vinneren ble", vinner, ". Gratulerer, du vant ", lotteripremie, " kroner!")

def print_informasjon_om_lotteriet():
    print("Lotteriet", lotterinavn, " har en premie p? ", lotteripremie, " kroner og det er kj?pt", len(lotterilodd) , " lodd.")

Merk at vi her lar alle variablene v?re globale, noe vi ikke anbefaler. Denne l?sningen vil for eksempel fungere d?rlig hvis vi ?nsker ? ha to lotterier og ikke bare ett. Si for eksempel at vi har to lotterier som vi definerer med to sett med variable:

lotterilodd1 = ["Espen", "Marius", "Mari", "Emilie"]
lotteripremie1 = 1000000
lotterinavn1 = "Superjackpot"

lotterilodd2 = ["Mari", "Mari", "Mari", "Emilie"]
lotteripremie2 = 1000
lotterinavn2 = "Superjackpot nr. 2"

Funksjonene som tar globale variable m? ha "harkodet" variabelnavn, og vil ikke kunne trekke vinner i begge lotteriene.

Men dette kan l?ses ved ? la funksjonene ta parametere i stedet:

def legg_til_nytt_lodd(lotterilodd, lotteripremie, loddeier):
    lotterilodd.append(loddeier)
    lotteripremie += 1000

Alle funksjonene v?re (tre funksjoner i dette tilfellet) vil da m?tte ta parameterene som brukes. Dette blir fort litt tungvint, spesielt hvis man har mange funksjoner og mange parametere.

En m?te ? forenkle ting litt p? kan v?re ? gruppere variablene i en ordbok:

lotteri1 = {"navn": "Superjackpot", "lodd": ["Espen", "Marius", "Mari", "Emilie"], "premie": 1000000}
lotteri2 = {"navn": "Superjackpot nr. 2", "lodd": ["Mari", "Mari", Mari", "Emilie"], "premie": 1000}

Funksjonene trenger da bare ta ett parameter:

def print_informasjon_om_lotteriet(lotteri):
    print("Lotteriet", lotteri["navn"], " har en premie p? ", lotteri["premie"], " kroner og det er kj?pt", len(lotteri["lodd"]) , " lodd.")

# osv ...

En ordbok er én m?te ? gruppere ulik data sammen i én variabel p?. ? lage et objekt er en annen m?te. Vi har l?rt at vi kan lage v?re egne objekter slik:

class Lotteri:
    def __init__(self, lodd, premie, navn):
        self.lodd = lodd
        self.premie = premie
        self.navn = navn 

lotteri = Lotteri(["Mari", "Emilie"], 1000000, "Superjackpot")

lotteri er n? et objekt, og vi kan sende det objektet i stedet for ordboken v?r inn i funksjonene v?re:

def print_informasjon_om_lotteriet(lotteri):
    print("Lotteriet", lotteri.navn, " har en premie p? ", lotteri.premie, " kroner og det er kj?pt", len(lotteri.lodd) , " lodd.")

Vi kan alts? definere funksjoner som tar objekt som parameter. En slik l?sning blir veldig lik som ? sende en ordbok inn som parameter.

Men her har Python et triks som kan gj?re ting enda mer elegant og enklere for oss. Objekter kan nemlig ha egne funksjoner (s?kalte metoder) som automatisk har tilgang til alle variablene som er knyttet til objektet. Disse funksjonene kan alts? operere p? objektet selv:

class Lotteri:
    def __init__(self, lodd, premie, navn):
        self.lodd = lodd
        self.premie = premie
        self.navn = navn 

    # Her definerer vi en metode. F?rste parameter er alltid self, og via self f?r vi tilgang til alle variablene i objektet
    def print_informasjon_om_lotteriet(self):
        print("Lotteriet", self.navn, " har en premie p? ", self.premie, " kroner og det er kj?pt", len(self.lodd) , " lodd.")

Oppgave 1

Legg til de to andre metodene i klassen, trekk_vinner og legg_til_nytt_lodd.

Oppgave 2 (ekstraoppgave)

Lag en metode som endrer navn p? lotteriet og en metode som endrer premien til lotteriet.