Ga naar hoofdinhoud

Een dictionary aanpassen: ophalen, aanpassen, terugzetten

Hier bouw je op verder: Lijst-methoden

Weet je dit niet meer zeker? Lees het terug voordat je verdergaat.

Sara gaat naar 5B. In een gewone dictionary pas je dat aan op de plek zelf, met sara["klas"] = "5B". Je werkt verder met de Sara uit Een dictionary als waarde, in mijn_data.db, waar ze nog in 4B zit.

Op de plek zelf aanpassen?​

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
db["sara"]["klas"] = "5B"
db.commit()

with SqliteDict("mijn_data.db") as db:
print(db["sara"]["klas"])
Voorspel
Wat print dit script?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Draai het script zelf, en kijk of je voorspelling klopte. Een gewone dictionary in Python onthoudt zo'n wijziging wel. SqliteDict niet: ophalen geeft een kopie.

Ophalen, aanpassen, terugzetten​

Je haalt de dictionary op, past hem aan en zet hem terug. Pas als je de aangepaste dictionary terugzet met db["sara"] = …, schrijft SqliteDict hem weg. Sara krijgt er meteen een vak bij. Maak aanpassen.py:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
sara = db["sara"]
sara["klas"] = "5B"
sara["vakken"].append("biologie")
db["sara"] = sara
db.commit()
  1. Regel 4:

    Ophalen. sara is nu een gewone dictionary in je programma.

  2. Regel 5-6:

    Aanpassen, zoals je met elke dictionary en lijst doet.

  3. Regel 7:

    Terugzetten. Pas deze regel stuurt de aangepaste dictionary naar de database.

  4. Regel 8:

    En zoals altijd: commit() schrijft het naar het bestand.

Draai aanpassen.py en daarna bekijk_db.py:

sara = {'klas': '5B', 'vakken': ['informatica', 'wiskunde', 'biologie']}

Onthoud die drie stappen: ophalen, aanpassen, terugzetten.

Test jezelf. Na aanpassen.py zit Sara in 5B. Je draait dit script:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
sara = db["sara"]
sara["klas"] = "6B"
db.commit()
Controlevraag
Welke klas laat bekijk_db.py daarna bij Sara zien?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Er gaat iets mis​

Je aanpassing is weg, zonder foutmelding​

Je script past een veld aan of zet iets in een lijst, er komt geen fout, en toch toont bekijk_db.py de oude waarde.

Oorzaak: je past de kopie aan die db["sara"] je geeft, en zet hem niet terug. Met db.commit() erbij verandert dat niets: er is voor de database niets gewijzigd.

Oplossing: haal de waarde op in een variabele, pas die aan, en zet hem terug onder dezelfde sleutel.

from sqlitedict import SqliteDict

# FOUT: de kopie krijgt het vak, het bestand niet
with SqliteDict("mijn_data.db") as db:
db["sara"]["vakken"].append("Duits")
db.commit()

# GOED
with SqliteDict("mijn_data.db") as db:
sara = db["sara"]
sara["vakken"].append("Duits")
db["sara"] = sara
db.commit()

Opdrachten​

Opdracht 1: Predict - Twee keer append​

from sqlitedict import SqliteDict

with SqliteDict("scores.db") as db:
db["piet"] = {"scores": [10]}
db.commit()

with SqliteDict("scores.db") as db:
db["piet"]["scores"].append(20)
piet = db["piet"]
piet["scores"].append(30)
db["piet"] = piet
db.commit()

with SqliteDict("scores.db") as db:
print(db["piet"]["scores"])
Voorspel
Wat print dit?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Opdracht 2: Run​

Draai aanpassen.py uit deze les, en controleer met bekijk_db.py dat Sara in 5B zit met drie vakken.

Antwoord

bekijk_db.py toont sara = {'klas': '5B', 'vakken': ['informatica', 'wiskunde', 'biologie']}. Heb je aanpassen.py twee keer gedraaid, dan staat biologie er twee keer in: elke keer komt er één bij.

Opdracht 3: Investigate - Twee keer ophalen​

Draai dit, en verklaar wat je ziet:

from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
eerste = db["sara"]
tweede = db["sara"]
eerste["klas"] = "3A"
print(eerste["klas"], tweede["klas"])
Antwoord

Het print 3A 5B. eerste en tweede zijn twee losse kopieën uit het bestand. Pas je de ene aan, dan verandert de andere niet, en de database ook niet, want het script zet niets terug.

Opdracht 4: Modify - Een vak eraf​

Pas aanpassen.py aan, zodat het wiskunde weghaalt uit de vakken van Sara. Controleer met bekijk_db.py dat het echt weg is.

Tip

Een lijst heeft remove(). Daarna dezelfde stappen: terugzetten en commit().

Antwoord
from sqlitedict import SqliteDict

with SqliteDict("mijn_data.db") as db:
sara = db["sara"]
if "wiskunde" in sara["vakken"]:
sara["vakken"].remove("wiskunde")
db["sara"] = sara
db.commit()

De if voorkomt een ValueError als je het script een tweede keer draait: dan staat wiskunde er niet meer in.

Opdracht 5: Make - Scorebord​

Maak scorebord.py. Het vraagt een naam en een score. Bestaat de speler nog niet in scorebord.db, dan komt hij erin met een lege lijst scores. Daarna komt de score in zijn lijst, en print het alle scores van die speler.

Tip

db.get(naam, {"scores": []}) geeft de speler, of een nieuwe dictionary als hij er nog niet is. Daarna ophalen, aanpassen, terugzetten.

Antwoord
from sqlitedict import SqliteDict

naam = input("Naam: ")
score = int(input("Score: "))

with SqliteDict("scorebord.db") as db:
speler = db.get(naam, {"scores": []})
speler["scores"].append(score)
db[naam] = speler
db.commit()
print(f"Scores van {naam}: {speler['scores']}")

Zonder db[naam] = speler print het de nieuwe score wel, want speler is de aangepaste kopie. Maar de volgende keer is hij weg.

Nu ken je SqliteDict genoeg om hem in je server te gebruiken. Dat doe je in Een formulier opslaan.