Programmering nivå 2

Kap 2.7 – Miniuppgift: datalagring och logik

Bygg en enkel bibliotekskatalog med listor, dictionaries, sökning och sortering.

Mål med lektionen

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

  • Kunna lagra och organisera data med hjälp av listor, tuples eller dictionaries.
  • Använda kontrollstrukturer för att skapa enkel programlogik.
  • Kombinera olika koddelar till ett fungerande program.
  • Planera, strukturera och reflektera över din egen lösning.

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

Börja med att tänka igenom vad programmet ska göra. Skapa en enkel plan i punktform eller pseudokod. Skriv koden steg för steg och testa ofta. Reflektera över hur du kan förenkla din lösning och återanvända kod.

Uppgift: Bibliotekskatalog

Skapa ett program där användaren kan:

  1. Lägga till böcker med titel, författare och år.
  2. Söka efter en bok utifrån titel eller författare.
  3. Skriva ut hela katalogen i alfabetisk ordning efter titel.

Det här bygger på tidigare kapitel

Uppgiften ska kunna lösas med sådant som redan har gåtts igenom:

  • Kap 1.3: funktioner och tydlig kodstruktur.
  • Kap 1.4: villkor med if, elif, else och logiska operatorer som or.
  • Kap 1.5: loopar och menyprogram med while.
  • Kap 1.6: enkel felhantering om du vill kontrollera årtal.
  • Kap 2.2: listor och append().
  • Kap 2.3: sökning och sortering med sorted().
  • Kap 2.4: dictionaries.
  • Kap 2.5: planering, pseudokod och testfall.
  • Kap 2.6: problemlösning med listor och dictionaries.

Du behöver inte spara böckerna till en fil i den här uppgiften. Datan får försvinna när programmet avslutas.

Förslag på struktur

Pseudokod:

Skapa tom lista för böcker som dictionaries

Meny: Lägg till / Sök / Visa alla / Avsluta

IF val == Lägg till:
    Läs in titel, författare, år
    Skapa dictionary och lägg till i listan

IF val == Sök:
    Läs in sökord
    Skriv ut alla böcker som matchar titel eller författare

IF val == Visa alla:
    Sortera listan och skriv ut

Innan hela programmet: förstå byggstenarna

Bibliotekskatalogen består av flera mindre delar. Läs dessa exempel först. Då blir den fullständiga koden längre ner mycket lättare att förstå.

Del 1: En bok som dictionary

En bok har flera egenskaper: titel, författare och år. Därför passar en dictionary bra. Varje egenskap får en tydlig nyckel.

book = {
    "title": "1984",
    "author": "George Orwell",
    "year": "1949"
}

print(book["title"])   # 1984
print(book["author"])  # George Orwell

Här betyder book["title"]: hämta värdet som hör till nyckeln "title".

Del 2: En katalog som lista med dictionaries

Katalogen ska kunna innehålla flera böcker. Därför använder vi en lista. Varje element i listan är en dictionary som beskriver en bok.

catalog = []

book = {"title": "1984", "author": "George Orwell", "year": "1949"}
catalog.append(book)

print(catalog)

Efter catalog.append(book) ligger boken sparad i listan. Det är alltså inte bara en vanlig lista med text, utan en lista med mer strukturerade objekt.

Del 3: Göra en funktion som lägger till en bok

När samma arbetsmoment har ett tydligt ansvar kan det bli en egen funktion. Funktionen add_book() tar emot listan catalog och lägger till en ny bok i den.

def add_book(catalog):
    title = input("Titel: ")
    author = input("Författare: ")
    year = input("År: ")

    book = {"title": title, "author": author, "year": year}
    catalog.append(book)
  1. title, author och year hämtas från användaren.
  2. Värdena samlas i en dictionary.
  3. Dictionaryn läggs till i listan med append().

Del 4: Söka med in och lower()

När användaren söker ska programmet hitta böcker även om användaren skriver med små bokstäver. Därför används lower(), som gör texten till små bokstäver.

title = "Bröderna Lejonhjärta"
query = "lejon"

if query in title.lower():
    print("Träff!")

query in title.lower() betyder: finns sökordet någonstans i titeln?

Del 5: Söka med en vanlig loop

Innan vi använder en kortare lösning är det bra att se den tydliga varianten med en vanlig for-loop.

found = []

for book in catalog:
    if query in book["title"].lower() or query in book["author"].lower():
        found.append(book)
  1. found = [] skapar en tom lista för böcker som matchar sökningen.
  2. for book in catalog går igenom en bok i taget.
  3. if-satsen kontrollerar både titel och författare.
  4. Om boken matchar läggs den till i found.

Del 6: Kortare sökning, om du vill

Du kan lösa uppgiften med den vanliga loopen i del 5. Om du vill kan du också använda list comprehension, som är ett kortare sätt att skapa en ny lista från en befintlig lista. Det är inte ett krav i övningen.

found = [
    book for book in catalog
    if query in book["title"].lower() or query in book["author"].lower()
]

Läs raden så här:

  1. Skapa en ny lista som heter found.
  2. Gå igenom varje book i catalog.
  3. Ta bara med boken om sökordet finns i titeln eller författaren.

Del 7: Skriva ut böcker med f-string

När en bok ska visas hämtas värdena från dictionaryn och sätts in i en text.

for book in found:
    print(f"{book['title']} av {book['author']} ({book['year']})")

Det här kan till exempel skriva ut:

1984 av George Orwell (1949)

Del 8: Sortera listan efter titel

Katalogen ska visas i alfabetisk ordning efter titel. Då används sorted() tillsammans med key.

sorted_books = sorted(catalog, key=lambda x: x["title"])

Här betyder x en bok i listan. Eftersom varje bok är en dictionary betyder x["title"] bokens titel. Sorteringen använder alltså titeln som sorteringsvärde.

Del 9: Menyn som styr programmet

Huvudprogrammet använder en meny med while True. Loopen fortsätter tills användaren väljer att avsluta.

while True:
    print("1. Lägg till bok")
    print("2. Sök bok")
    print("3. Visa alla")
    print("4. Avsluta")

    choice = input("Välj: ")

    if choice == "1":
        add_book(catalog)
    elif choice == "4":
        break

Menyn kopplar ihop de mindre funktionerna till ett helt program.

Kodexempel

def add_book(catalog):
    title = input("Titel: ")
    author = input("Författare: ")
    year = input("År: ")

    book = {"title": title, "author": author, "year": year}
    catalog.append(book)

def search_books(catalog):
    query = input("Sök titel eller författare: ").lower()

    found = []

    for book in catalog:
        if query in book["title"].lower() or query in book["author"].lower():
            found.append(book)

    for book in found:
        print(f"{book['title']} av {book['author']} ({book['year']})")

def print_catalog(catalog):
    sorted_books = sorted(catalog, key=lambda x: x["title"])

    for book in sorted_books:
        print(f"{book['title']} av {book['author']} ({book['year']})")

def main():
    catalog = []

    while True:
        print("\n1. Lägg till bok\n2. Sök bok\n3. Visa alla\n4. Avsluta")
        choice = input("Välj: ")

        if choice == "1":
            add_book(catalog)
        elif choice == "2":
            search_books(catalog)
        elif choice == "3":
            print_catalog(catalog)
        elif choice == "4":
            break
        else:
            print("Ogiltigt val.")

main()

Interaktiv övning: bibliotekskatalog

Testa uppgiften steg för steg. Lägg till böcker som dictionaries, sök efter titel eller författare och visa hela katalogen sorterad efter titel.

Prova till exempel att:

  • lägga till 1984, George Orwell, 1949
  • lägga till Bröderna Lejonhjärta, Astrid Lindgren, 1973
  • söka efter orwell eller astrid
  • visa alla och se att böckerna sorteras alfabetiskt efter titel
catalog = []

Programmering 2-koppling: katalogen kombinerar en lista med dictionaries, sökning med in, sortering med sorted() och en meny med villkor.

Utmaning

  1. Visa ett meddelande om sökningen inte hittar någon bok.
  2. Hindra dubbletter: kontrollera om en bok med samma titel redan finns innan den läggs till.
  3. Lägg till ett menyval som tar bort en bok utifrån titel.
  4. Svårare extrautmaning: lägg till ett menyval som ändrar årtal på en bok.

Öva själv

Skapa en Python-fil som heter kap2-7-bibliotek.py. Filen ska innehålla:

  • en kort plan som kommentarer högst upp: input, bearbetning, output, datastruktur och funktioner,
  • en lista som lagrar böcker,
  • böcker sparade som dictionaries med titel, författare och år,
  • en meny där användaren kan lägga till bok, söka bok, visa alla böcker och avsluta,
  • minst tre egna funktioner, till exempel add_book(), search_books() och print_catalog(),
  • sortering efter titel när hela katalogen visas,
  • minst tre testfall som kommentarer längst ner i filen.

Testfall att prova

Test Vad du ska kontrollera
Lägg till två böcker och visa alla Böckerna visas i alfabetisk ordning efter titel.
Sök på en del av en titel Rätt bok visas även om du bara skriver en del av titeln.
Sök på en författare Alla böcker av den författaren visas.
Sök på något som inte finns Programmet bör visa ett tydligt meddelande.

Extrautmaningarna är frivilliga. Bygg hellre ett tydligt fungerande grundprogram än ett större program där grundkraven inte fungerar.

När du har försökt själv kan du ladda ner ett lösningsförslag: kap2-7-bibliotek-losningsforslag.py

Reflektion

  • Hur valde du att strukturera datan? Varför?
  • Hur kan du utveckla programmet för att bli mer användarvänligt?
  • Vilka delar var svårast och varför?

Tillbaka till Kapitel 2