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.
- Python Lijst-methoden
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"])
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()
- Regel 4:
Ophalen.
sarais nu een gewone dictionary in je programma. - Regel 5-6:
Aanpassen, zoals je met elke dictionary en lijst doet.
- Regel 7:
Terugzetten. Pas deze regel stuurt de aangepaste dictionary naar de database.
- 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()
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"])
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.