M05 Hjälp till uppgifter

På denna sidan kommer det finnas hjälp till lösning av uppgifter samt en fullt fungerande lösning i form av kod.

Att kopiera färdiga lösningar gör inte att du blir bättre på programmering, men det kan vara ett effektivt sätt att få lite hjälp för att bli en duktig programmerare. Det är ditt ansvar att använda hjälpen på rätt sätt.

Lösningsförslagen är inte alltid kommenterade i koden, tanken är att du skall kunna ta ner koden och själv förstå vad som händer genom att testa och formulera kommentarer för dig själv.

Flera av lösningarna har jag filmat och förklarar hur jag tänker när jag löser uppgiften. Ibland har jag kompletterat med andra bra filmer som förklarar olika delar på ett bra sätt. Det är inte alltid jag som har gjort filmen och då passar den bättre här än på momentets huvudsida.

Funktioner

Funktionsanrop

Videoklipp: python funktioner [klicka för att visa]

Här är en film som jag tidigare har spelat in som går igenom alla delar så här långt i momentet. Fördelen med denna film är att jag i en enda film går igenom de olika delarna som du som elev behöver kunna.

En liten varning för ljudet är på sin plats, det är lite ojämnt och det låter som att jag ibland använder en kofot för att skriva på tangentbordet.

Uppgift m05u01

Lösningsförslag [klicka för att visa]

Kodförslag

Inparametrar

Uppgift m05u02

Lösningsförslag [klicka för att visa]

Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Returvärde

Uppgift m05u03

Lösningsförslag [klicka för att visa]

Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Uppgift m05e01 (omdöpt från m05u04)

Denna uppgift har i nuläget inget lösningsförslag.

Funktioner i separat fil

Uppgift m05u05

Lösningsförslag [klicka för att visa]

Kodförslag Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Dokumentation av funktioner

Uppgift m05u06

Lösningsförslag [klicka för att visa]

Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Uppgift m05u07 - julvarianten

Lösningsförslag [klicka för att visa]

Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Filmen är ännu ej publicerad.

Tillägget har inget lösningsförslag.

Uppgift m05u07 - den andra varianten

Lösningsförslag [klicka för att visa]

Kodförslag

Lösningsförslag [klicka för att visa]

Kodförslag Kodförslag

Läsa från fil

Uppgift m05u08

Lösningsförslag [klicka för att visa]

Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Uppgift m05u09

Här gör jag en annorlunda grej mot mina vanliga lösningsförslag. Jag kommer lösa uppgiften på fyra olika sätt;

  • A. Lista med listor
  • B. Lista med enkla dictionarys
  • C. Lista med dictionarys som har index
  • D. Lista med tuples

Varje alternativ kommer lösa uppgiften men de kommer då lösas på olika sätt. Längst ner har jag också en jämförelse mellan de olika varianterna och lite text om saker man kan tänka på. Delar av analysen är gjord tillsammans med ChatGPT.

Denna gången kommer alla lösningar publiceras i kod som du kan kopiera och leka vidare med.

A. Lista med listor [klicka för att visa]

# m05u09a, lista med listor
# Ex. "[['Hedvig', 19],['Milo', 48]]"
# Snygga utskrifter är inte prioriterade, vissa uppgifter
# beräknas men skrivs inte ut.

# Listan
l_resultat = []

# Inläsning från filen
with open('poäng.txt', 'r', encoding='utf-8') as f:
    for rad in f:
        rad = rad.split("|")
        l_resultat.append([rad[0], int(rad[1])])

# Skriv ut hela listan
print(l_resultat)

# 1. Skriv ut provpoängen och tillhörande elev sorterat från det lägsta till högsta
# Viktigt att lagra den sorterade listan, sorted() påverkar inte orginallistan
l_resultat = sorted(l_resultat, key=lambda x: x[1])
# Skriv ut listan sorterad från lägst till högst.
print(l_resultat)

# 2. Beräkna och skriva ut medelvärdet av provpoängen
summa = 0
for l in l_resultat:
    summa += l[1]
medel = summa / len(l_resultat)

# Alternativt skrivsätt
# i "_" lagras namnen, men de är ointressanta i detta läget.
# Skrivsättet kallas list comprehension
summa1 = sum(poäng for _, poäng in l_resultat)
summa2 = sum(l[1] for l in l_resultat)
print(summa1, summa2)

# 3. Skriva ut eleven med sämst och bäst resultat
# de två indexen är plats i listan 0 är först, -1 är sist.
print(f"Sämsta resultat: {l_resultat[0][0]} med {l_resultat[0][1]} poäng")
print(f"Bästa resultat: {l_resultat[-1][0]} med {l_resultat[-1][1]} poäng")

B. Lista med enkla dictionarys [klicka för att visa]

# m05u09c, lista med större dictionarys
# Ex. "[{'name': 'Hedvig', 'result': 19}, {'name': 'Milo', 'result': 48}]"
# Snygga utskrifter är inte prioriterade, vissa uppgifter
# beräknas men skrivs inte ut.

# Listan
l_resultat = []

# Inläsning från filen
with open('poäng.txt', 'r', encoding='utf-8') as f:
    for rad in f:
        rad = rad.split("|")
        l_resultat.append({'name': rad[0], 'result': int(rad[1])})

# Skriv ut hela listan
print(l_resultat)

# Sortering kan göras i ett stag i detta fall
sorterade_resultat = sorted(l_resultat, key=lambda x: x['result'])
# Skriv ut listan
print(sorterade_resultat)
# Skriv ut den sorterade listan elev för elev
for elev in sorterade_resultat:
    print(f"{elev['name']}: {elev['result']}")

# 2. Beräkna och skriva ut medelvärdet av provpoängen, viktigt att använda listan med tuples
summa = 0
for elev in sorterade_resultat:
    summa += elev['result']
medel = summa / len(l_resultat)

# Alternativ skrivsätt
# Här använder jag mig av något som kallas generator expression som liknar list comprehension.
# Generator expressions använder en liknande syntax som list comprehensions men skapar inte en lista i minnet.
# Istället produceras värdena ett i taget och konsumeras av den omslutande funktionen, i det här fallet sum().
# Detta gör generator expressions till ett minneseffektivt sätt att utföra operationer på samlingar av data,
# speciellt för stora dataset.
total_summa = sum(elev['result'] for elev in l_resultat)
# Beräkna medelvärdet
medelvarde = total_summa / len(l_resultat)

# 3. Skriva ut eleven med sämst och bäst resultat
# -1 för att det är sista elementet i den sorterade listan.
print(f"Sämsta resultat: {sorterade_resultat[0]['name']} med {sorterade_resultat[0]['result']} poäng")
print(f"Bästa resultat: {sorterade_resultat[-1]['name']} med {sorterade_resultat[-1]['result']} poäng")

C. Lista med dictionarys som har index [klicka för att visa]

# m05u09c, lista med större dictionarys
# Ex. "[{'name': 'Hedvig', 'result': 19}, {'name': 'Milo', 'result': 48}]"
# Snygga utskrifter är inte prioriterade, vissa uppgifter
# beräknas men skrivs inte ut.

# Listan
l_resultat = []

# Inläsning från filen
with open('poäng.txt', 'r', encoding='utf-8') as f:
    for rad in f:
        rad = rad.split("|")
        l_resultat.append({'name': rad[0], 'result': int(rad[1])})

# Skriv ut hela listan
print(l_resultat)

# Sortering kan göras i ett stag i detta fall
sorterade_resultat = sorted(l_resultat, key=lambda x: x['result'])
# Skriv ut listan
print(sorterade_resultat)
# Skriv ut den sorterade listan elev för elev
for elev in sorterade_resultat:
    print(f"{elev['name']}: {elev['result']}")

# 2. Beräkna och skriva ut medelvärdet av provpoängen, viktigt att använda listan med tuples
summa = 0
for elev in sorterade_resultat:
    summa += elev['result']
medel = summa / len(l_resultat)

# Alternativ skrivsätt
# Här använder jag mig av något som kallas generator expression som liknar list comprehension.
# Generator expressions använder en liknande syntax som list comprehensions men skapar inte en lista i minnet.
# Istället produceras värdena ett i taget och konsumeras av den omslutande funktionen, i det här fallet sum().
# Detta gör generator expressions till ett minneseffektivt sätt att utföra operationer på samlingar av data,
# speciellt för stora dataset.
total_summa = sum(elev['result'] for elev in l_resultat)
# Beräkna medelvärdet
medelvarde = total_summa / len(l_resultat)

# 3. Skriva ut eleven med sämst och bäst resultat
# -1 för att det är sista elementet i den sorterade listan.
print(f"Sämsta resultat: {sorterade_resultat[0]['name']} med {sorterade_resultat[0]['result']} poäng")
print(f"Bästa resultat: {sorterade_resultat[-1]['name']} med {sorterade_resultat[-1]['result']} poäng")

D. Lista med tuples [klicka för att visa]

# m05u09d, Lista med tuples
# Ex. [('Hedvig', 19), ('Milo', 48), ('Elsa', 35)]
# Snygga utskrifter är inte prioriterade, vissa uppgifter
# beräknas men skrivs inte ut.

# Listan
l_resultat = []

# Inläsning från filen
with open('poäng.txt', 'r', encoding='utf-8') as f:
    for rad in f:
        rad = rad.split("|")
        l_resultat.append((rad[0], int(rad[1])))

# Skriv ut hela listan
print(l_resultat)

# 1. Skriv ut provpoängen och tillhörande elev sorterat från det lägsta till högsta
# Här visar jag att det går att direkt loopa igenom den sorterade listan utan att
# lagra denna listan separat, samma teknik går att använda även i de andra exemplen.
for namn, poang in sorted(l_resultat, key=lambda x: x[1]):
    print(f"{namn}: {poang}")

# 2. Beräkna och skriva ut medelvärdet av provpoängen
# Här skriver jag det så kort som möjligt, förklaring vad som händer finns i m05u09a
print(f"Medelvärdet av provpoängen är: {sum(poang for _, poang in l_resultat) / len(l_resultat)}")

# 3. Skriva ut eleven med sämst och bäst resultat
# Eftersom jag inte har någon sorterad lista så hämtar jag ut två tuple med dessa värden
sämsta = min(l_resultat, key=lambda x: x[1])
bästa = max(l_resultat, key=lambda x: x[1])
print(f"Sämsta resultat: {sämsta[0]} med {sämsta[1]} poäng")
print(f"Bästa resultat: {bästa[0]} med {bästa[1]} poäng")

Analys och jämförelser [klicka för att visa]

Min tanke med att visa fyra olika lösningar är att visa att det finns flera olika alternativ på lösning för denna uppgiften. Att jobba med listor, dictionarys och tuples på olika sätt och i olika kombinationer ger lite olika möjligheter, utmaningar och eventuellt fördelar. Det viktigaste är att lösa uppgiften, sedan kan vi alltid diskutera vilken lösning som är bäst lämpad vid varje unikt tillfälle. Oftast är det inte så stora skillnader på lösningarna och det utgår nog mer ifrån vilka tekniker programmeraren gillar bäst.

Om vi låter ChatGPT analyser likheter och skillnader på de fyra olika varianterna, vilken analys görs då?

När vi lägger till en fjärde teknik, en lista av tuples, till de tidigare nämnda teknikerna för att lagra och hantera provresultat, blir analysen mer nyanserad. Här är en uppdaterad jämförelse av de fyra teknikerna med deras för- och nackdelar:

A. Lista i lista

Exempel: [['Hedvig', 19], ['Milo', 48]]

Fördelar:

  • Enkel att använda och förstå.
  • Lätt att sortera och iterera över.

Nackdelar:

  • Mindre explicit vad gäller att koppla samman namn och poäng jämfört med dictionaries.

B. Lista med dictionaries

Exempel: [{'Hedvig': 19}, {'Milo': 48}]

Fördelar:

  • Tydlig koppling mellan elevnamn och poäng.
  • Flexibel med möjlighet att lägga till fler attribut per elev.

Nackdelar:

  • Kan vara mindre effektiv för sortering och beräkningar.

C. Lista med större dictionaries

Exempel: [{'name': 'Hedvig', 'result': 19}, {'name': 'Milo', 'result': 48}]

Fördelar:

  • Mycket tydlig struktur och lättläst.
  • Flexibel för framtida tillägg av fler attribut.

Nackdelar:

  • Kräver mer skrivande och uppmärksamhet vid sortering och jämförelser.

D. Lista av tuples

Exempel: [('Hedvig', 19), ('Milo', 48)]

Fördelar:

  • Minneseffektiv genom oföränderlighet.
  • Enkel och direkt för sortering och iterering.
  • Explicit koppling mellan namn och poäng.

Nackdelar:

  • Mindre flexibel om strukturen behöver utökas.
  • Oföränderlighet kan vara en begränsning vid uppdatering av data.

Analys och rekommendation

När vi överväger de olika teknikerna för att lösa de specifika uppgifterna (sortering, beräkning av medelvärde, hitta högsta och lägsta poäng) blir det tydligt att varje teknik har sina styrkor i olika sammanhang:

  1. Sortera och skriva ut från lägst till högst: Teknik A och D är båda enkla och effektiva för sortering, med teknik D som ger en tydligare koppling mellan namn och poäng. Teknik C är också bra men kräver lite mer kod.
  2. Beräkna och skriva ut medelvärde: Alla tekniker kan hantera detta effektivt, men teknik D erbjuder en balans mellan minneseffektivitet och enkelhet i kodningen.
  3. Hitta och skriva ut högsta och lägsta poängen: Teknik D är återigen mycket lämplig för sin enkelhet och direkt tillgång till data för jämförelse, likaså teknik A och C.

Slutsats: För de specifika uppgifterna i ditt scenario skulle jag rekommendera teknik D (lista av tuples) som det föredragna valet. Denna teknik erbjuder en bra balans mellan effektivitet, enkelhet, och direkt koppling mellan elevens namn och poäng, vilket gör den idealisk för sortering, medelvärdesberäkning, och identifiering av extrema värden. Om du dock förväntar dig att behöva utöka datamodellen med fler attribut per elev i framtiden, kan teknik C vara ett mer flexibelt alternativ.

Skriva till fil

Uppgift m05u10

Lösningsförslag [klicka för att visa]

Inget lösningsförslag finns för denna uppgift. Ta ner koden och testa för att se vad som händer.

Uppgift m05u11

Lösningsförslag [klicka för att visa]

Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Uppgift m05u12

Lösningsförslag [klicka för att visa]

Kodförslag Kodförslag

Inspelat lösningsförslag [klicka för att visa]

Uppgift m05u13

Lösningsförslag [klicka för att visa]

Kodförslag

Uppgift m05e02

Denna uppgift har i nuläget inget lösningsförslag.

Uppgift m05e03

Fullständig lösning finns länkad från uppgiften.