Programmering nivå 2

Kap 2.6 – Problemlösning med listor

Använd listor tillsammans med funktioner, loopar och villkor för att bygga ett större program.

Mål med lektionen

När du har arbetat klart med denna lektion ska du:

  • Kunna använda listor för att lösa sammansatta programmeringsuppgifter.
  • Kombinera listor med funktioner, loopar och villkor.
  • Analysera och bryta ner problem i steg.
  • Strukturera kod som hanterar inmatning, lagring och bearbetning av data.

Så här lär du dig bäst

Börja med att analysera uppgiften noggrant. Skapa en algoritm i form av pseudokod eller punktlista innan du börjar koda. Skriv din kod steg för steg och testa varje del. Använd print() för att följa vad som händer i listan under körning.

Scenario: Poänghantering i ett spel

Du ska skapa ett program som:

  • tar emot namn och poäng från flera användare,
  • sparar resultaten i en lista,
  • skriver ut en topplista baserat på poäng,
  • håller igång tills användaren väljer att avsluta.

Det här är ett bra exempel på problemlösning med listor eftersom programmet måste samla flera värden, bearbeta dem och sedan presentera dem i en annan ordning än de matades in.

Programstruktur

Pseudokod:

Skapa en tom lista

WHILE användaren vill fortsätta:
    Läs in namn och poäng
    Lägg till som tuple i listan
    Fråga om användaren vill fortsätta

Sortera listan efter poäng
Skriv ut topplistan

Planera datan först

Innan du skriver funktionerna behöver du bestämma hur varje resultat ska lagras. I exemplet används en lista med tuples:

scores = [
    ("Anna", 120),
    ("Erik", 95),
    ("Sara", 150)
]

Listan behövs eftersom det finns flera resultat. Varje tuple behövs eftersom namn och poäng hör ihop. När du planerar ett program med listor bör du alltid fråga: vad är ett element i listan?

Tuple eller dictionary? En tuple fungerar här eftersom varje resultat bara består av två värden som inte behöver ändras: namn och poäng. Om programmet senare ska kunna ändra poäng, lägga till datum eller spara flera uppgifter om spelaren är en dictionary ofta tydligare.

result = {
    "name": "Anna",
    "points": 120
}

Kodexempel

# Funktion som lägger till ett nytt resultat i listan
def add_score(scores):
    # Läs in spelarens namn
    name = input("Ange namn: ")

    # Försök göra om poängen till ett heltal
    try:
        points = int(input("Ange poäng: "))

        # Spara namn och poäng tillsammans som en tuple
        scores.append((name, points))
    except ValueError:
        # Om poängen inte är ett heltal visas ett felmeddelande
        print("Du måste ange ett heltal.")

# Funktion som sorterar och skriver ut topplistan
def print_high_scores(scores):
    # Sortera listan efter poängen, alltså värdet på index 1 i varje tuple
    scores.sort(key=lambda x: x[1], reverse=True)

    print("\nTopplista:")

    # Gå igenom varje tuple och packa upp namn och poäng
    for name, points in scores:
        print(f"{name}: {points}")

# Programmets huvudfunktion
def main():
    # Här sparas alla resultat
    scores = []

    # Loopen håller programmet igång tills användaren vill sluta
    while True:
        add_score(scores)
        cont = input("Vill du lägga till fler resultat? (j/n): ")

        # Om användaren inte skriver j avslutas loopen
        if cont.lower() != "j":
            break

    # När inmatningen är klar skrivs topplistan ut
    print_high_scores(scores)

# Startar programmet
main()

Steg för steg: så fungerar hela programmet

  1. main() startar programmet och skapar en tom lista: scores = [].
  2. while True gör att programmet kan fortsätta fråga efter fler resultat.
  3. add_score(scores) anropas och får listan scores som argument.
  4. I add_score() frågar programmet efter namn och poäng.
  5. int(input(...)) försöker göra om poängen till ett heltal.
  6. Om det lyckas sparas resultatet som en tuple, till exempel ("Anna", 120).
  7. Om användaren skriver något som inte är ett heltal fångas felet av except ValueError.
  8. Efter varje inmatning frågar programmet om användaren vill fortsätta.
  9. Om svaret inte är j körs break, och loopen avslutas.
  10. print_high_scores(scores) sorterar listan och skriver ut topplistan.

Vad är lambda?

lambda är ett kort sätt att skriva en liten funktion direkt där den behövs. I det här kapitlet används den för att tala om vilken del av varje tuple sorteringen ska titta på.

Den här raden:

scores.sort(key=lambda x: x[1], reverse=True)

betyder ungefär samma sak som:

def get_points(x):
    return x[1]

scores.sort(key=get_points, reverse=True)

Om varje resultat är en tuple som ("Anna", 120), betyder x[0] namnet och x[1] poängen. Därför sorterar lambda x: x[1] efter poäng.

Obs: scores.sort(...) ändrar listan direkt. Om du vill behålla originalordningen kan du använda sorted(scores, ...), som skapar en ny sorterad lista.

Interaktiv övning: lambda vid sortering

Testa hur samma lista kan sorteras på olika sätt beroende på vad lambda-funktionen returnerar.

Prova till exempel att:

  • sortera efter namn med lambda x: x[0]
  • sortera efter poäng med lambda x: x[1]
  • ändra poängen och se hur sorteringen påverkas
Tryck på Kör sortering för att testa lambda.

Interaktiv övning: problemlösning med listor

Testa poängprogrammet steg för steg. Lägg till namn och poäng i listan, skriv ut topplistan och se hur sorteringen använder poängen i varje tuple.

Prova till exempel att:

  • lägga till Anna med 120 poäng
  • lägga till Erik med 95 poäng
  • skriva ut topplistan och se högsta poängen först
  • skriva text i poängfältet och se hur felhanteringen fungerar
scores = []

Programmering 2-koppling: övningen kombinerar lista, tuple, funktioner, felhantering och sortering med key=lambda x: x[1].

Vad händer i programmet?

  • Listan scores innehåller tuples med namn och poäng.
  • sort() med lambda gör att listan sorteras efter poäng.
  • Funktioner används för att strukturera koden.

Testfall och kantfall

Testa inte bara när användaren gör rätt. Ett program med listor behöver också klara tomma listor, felaktig inmatning och flera värden med samma poäng.

Test Exempel Vad du kontrollerar
Vanlig inmatning Anna 120, Erik 95, Sara 150 Högsta poängen skrivs ut först.
Fel poäng Anna abc Programmet visar felmeddelande i stället för att krascha.
Tom topplista Användaren avslutar utan resultat. Programmet hanterar en tom lista tydligt.
Samma poäng Oskar 100, Maja 100 Programmet skriver fortfarande ut båda resultaten.

Utvidgning

  • Lägg till kontroll för dubbletter.
  • Lägg till möjlighet att spara listan till en fil.
  • Skapa ett alternativ för att ta bort en spelare.

Öva själv

Övning 1: Skriv ut en resultatlista

Skapa en lista med minst fyra tuples. Varje tuple ska innehålla ett namn och en poäng. Använd en for-loop och packa upp varje tuple för att skriva ut namn och poäng.

Kontrollera programmet

  • Listan ska innehålla minst fyra resultat.
  • Varje namn och poäng ska skrivas ut på en egen rad.
  • Lägg till ett nytt resultat och kontrollera att det också skrivs ut.

Fundera: Vad är ett element i listan och vilka värden finns i elementet?

När du har försökt själv: visa lösningsförslaget till övning 1 på GitHub.

Övning 2: Sortera efter poäng

Utgå från en lista med tuples som innehåller namn och poäng. Sortera listan så att den högsta poängen kommer först. Använd sort(), key=lambda x: x[1] och reverse=True. Skriv sedan ut den sorterade listan.

Testa programmet med

  • resultat som ligger i blandad ordning.
  • två personer som har samma poäng.
  • ett nytt resultat som har högst poäng.

Fundera: Varför används index 1 i lambda-funktionen?

När du har försökt själv: visa lösningsförslaget till övning 2 på GitHub.

Övning 3: Behåll originalordningen

Skapa funktionen sort_by_name(results). Funktionen ska använda sorted() och returnera en ny lista där resultaten är sorterade efter namn. Den ursprungliga listan ska inte ändras. Skriv ut båda listorna efter funktionsanropet.

Kontrollera programmet

  • Den nya listan ska vara sorterad efter värdet på index 0.
  • Den ursprungliga listan ska ha kvar sin ordning.
  • Testa även funktionen med en tom lista.

Fundera: Vad är skillnaden mellan sort() och sorted()?

När du har försökt själv: visa lösningsförslaget till övning 3 på GitHub.

Övning 4: Hitta godkända resultat

Skriv funktionen get_approved(results, limit). Funktionen ska gå igenom en lista med resultat-tuples och returnera en ny lista med de resultat som har minst lika många poäng som gränsen. Skriv ut de godkända resultaten.

Testa funktionen med

  • en gräns som ger flera godkända resultat.
  • en poäng som är exakt lika med gränsen.
  • en gräns som gör att den nya listan blir tom.

Fundera: Varför är det bra att funktionen skapar och returnerar en ny lista?

När du har försökt själv: visa lösningsförslaget till övning 4 på GitHub.

Övning 5: Klassens resultat

Svårare övning: Här kombinerar du en lista med dictionaries, funktioner, loopar, villkor och beräkningar.

Skapa en lista med minst fyra elev-dictionaries. Varje elev ska ha nycklarna name och points. Skriv en funktion som räknar ut medelvärdet och en funktion som hittar eleven med högst poäng. Skriv ut alla elever, medelvärdet och den elev som fick högst poäng.

Kontrollera programmet

  • Båda funktionerna ska ta emot resultatlistan som parameter.
  • Programmet ska hantera en tom lista utan att krascha.
  • Ändra en poäng och kontrollera att både medelvärde och högsta resultat uppdateras.

Fundera: Varför blir en dictionary tydligare än en tuple om varje elev senare ska få fler uppgifter?

När du har försökt själv: visa lösningsförslaget till övning 5 på GitHub.

Övning 6: Meny för en topplista

Svårare övning: Här kombinerar du problemlösning, lista, dictionaries, funktioner, meny, säker inmatning och sortering med lambda.

Bygg ett menyprogram med alternativen 1. Lägg till resultat, 2. Visa hela topplistan, 3. Visa de tre bästa, 4. Sök efter spelare och 5. Avsluta. Varje resultat ska sparas som en dictionary med nycklarna name och points i en lista. Poängen ska läsas in som ett heltal och felaktig inmatning ska hanteras med try och except ValueError. Topplistan ska sorteras efter poäng med lambda.

Testa programmet genom att

  • visa topplistan när den är tom.
  • lägga till minst fyra spelare i blandad poängordning.
  • visa hela topplistan och därefter de tre bästa.
  • söka efter en spelare som finns och en som saknas.
  • skriva text i stället för poäng och sedan avsluta programmet.

Fundera: Vilka mindre funktioner behöver programmet delas upp i för att bli lätt att testa?

När du har försökt själv: visa lösningsförslaget till övning 6 på GitHub.

Reflektion

  • Vad gjorde listor till rätt val i detta program?
  • Hur hjälpte det att använda tuples i listan?
  • Vilka delar av programmet blev enklare tack vare funktioner?

Tillbaka till Kapitel 2