[Tutor] Storing dictionary value, indexed by key, into a variable
Peter Otten
__peter__ at web.de
Sat Apr 5 23:14:22 CEST 2014
John Aten wrote:
> I read the article on data driven programming that Danny linked too, and
> did some additional looking around. I couldn't find anything directly
> using Python, but I got an idea of the concept and went crazy with it.
> This may still be off the mark, but I created a complex combination of
> lists and dictionaries to represent each individual instance of each
> demonstrative (starting only with one):
>
> that_those = [ [ [ {'nom': 'ille', 'clue': 'That/Those, Singular,
> Masculine Nominative'}, {'gen': 'illīus', 'clue': 'That/Those, Singular,
> Masculine Genitive'}, {'dat': 'illī', 'clue': 'That/Those, Singular,
> Masculine Dative'}, {'acc': 'illum', 'clue': 'That/Those, Singular,
> Masculine Accusative'}, {'abl': 'illō', 'clue': 'That/Those, Singular,
> Masculine Ablative'} ], [{'nom': 'illī', 'clue': 'That/Those, Plural,
> Masculine Nominative'},
> {'gen': 'illōrum', 'clue': 'That/Those, Plural, Masculine
> {Genitive'},
> {'dat': 'illīs', 'clue': 'That/Those, Plural, Masculine Dative'},
> {'acc': 'illōs', 'clue': 'That/Those, Plural, Masculine Accusative'},
> {'abl': 'illīs', 'clue': 'That/Those, Plural, Masculine Ablative'} ] ], [
> [ {'nom': 'illa', 'clue': 'That/Those, Singular, Feminine Nominative'},
> {'gen': 'illīus', 'clue': 'That/Those, Singular, Feminine
> {Genitive'},
> {'dat': 'illī', 'clue': 'That/Those, Singular, Feminine Dative'},
> {'acc': 'illam', 'clue': 'That/Those, Singular, Feminine Accusative'},
> {'abl': 'illā', 'clue': 'That/Those, Singular, Feminine Ablative'} ], [
> {'nom': 'illae', 'clue': 'That/Those, Plural, Feminine Nominative'},
> {'gen': 'illārum', 'clue': 'That/Those, Plural, Feminine Genitive'},
> {'dat': 'illīs', 'clue': 'That/Those, Plural, Feminine Dative'}, {'acc':
> 'illās', 'clue': 'That/Those, Plural, Feminine Accusative'}, {'abl':
> 'illīs', 'clue': 'That/Those, Plural, Feminine Ablative'} ] ] , [ [
> {'nom': 'illud', 'clue': 'That/Those, Singular, Neuter Nominative'},
> {'gen': 'illīus', 'clue': 'That/Those, Singular, Neuter
> {Genitive'},
> {'dat': 'illī', 'clue': 'That/Those, Singular, Neuter Dative'},
> {'acc': 'illud', 'clue': 'That/Those, Singular, Neuter Accusative'},
> {'abl': 'illō', 'clue': 'That/Those, Singular, Neuter Ablative'} ], [
> {'nom': 'illa', 'clue': 'That/Those, Plural, Neuter Nominative'},
> {'gen': 'illōrum', 'clue': 'That/Those, Plural, Neuter
> {Genitive'},
> {'dat': 'illīs', 'clue': 'That/Those, Plural, Neuter Dative'},
> {'acc': 'illa', 'clue': 'That/Those, Plural, Neuter Accusative'},
> {'abl': 'illīs', 'clue': 'That/Those, Plural, Neuter Ablative'} ] ] ]
>
> Now, this is a big mess, for sure, but it seems possible that it is
> abstract enough that I could reuse the same logic and just switch out the
> data to make different types of similar programs. Also, I can write a
> script to populate this structure to construct a program to drill any type
> of word that is declined by gender, number and case. I can call each item
> pretty easily like this:
>
> question_to_be_dispalyed_to_user =
> that_those[gender][number][q_and_a]["clue"] answer_to_that_question =
> that_those[gender][number][q_and_a][case]
>
> Where gender, number, q_and_a, and case follow Peter's suggestion:
>
> cases = ['nom', 'gen', 'dat', 'acc', 'abl']
> case = random.choice(cases)
>
> The complete code will follow, but I have a spooky new problem. When I try
> to run the following code, I intermittently get the following error:
>
> Traceback (most recent call last):
> File "./latDemTest.py", line 59, in <module>
> answer = that_those[gender][number][q_and_a][case]
> KeyError: 'abl'
>
> I looked this error up online, and it seems the key error is generated
> when one attempts to retrieve a value from a dictionary with a key that
> does not exist. The problem is, it seems to me that the keys should in
> fact exist. The odd thing is, the code returns this error sometimes, and
> sometimes it doesn't. I did a bunch of trials, keeping track of which
> particular entries in the data structures worked and which failed, and I
> discovered that they overlap. The dictionary {'gen': 'illōrum', 'clue':
> 'That/Those, Plural, Neuter Genitive'} for example, happily spits out the
> proper question and answer sometimes, other times it shoots out the
> previously mentioned error. I cannot understand how this could happen!
There are dicts that have a "nom" key, other dicts that have a "gen" key,
and so on. I didn't read your code completely, but my guess is that you do
not get a KeyError in the rare case (roughly 1 out 5) that you pick a
dictionary that handles the same casus as the one you picked independently.
How would you go on fixing this? I think this little table is a good start:
> # place one: 0 = masculine, 1 = feminine, 2 = neuter
> # place two: 0 = singular, 1 = plural
> # place two:
> # place three: 0 = answer, 1 = clue
> # place four, 'nom' = answer, 'clue' = description
> # So, word[0][0][0]["nom"] should produce: ille
Unfortunately it gets a little fuzzy in the middle. So here's my fixed
table:
place one, genus: 0=m, 1=f, 2=n
place two, numerus: 0=sg, 1=pl
place three, casus: 0=nom, 1=gen, 2=dat, ...
place four: "answer"=answer, "clue"=description
Everything but place four is a list. That allows for a small simplification:
As random.choice() works on arbitrary lists you can apply it directly on
your data:
#untested
genus = random.choice(that_those)
numerus = random.choice(genus)
casus = random.choice(numerus)
clue = casus["clue"]
answer = casus["answer"]
Once you have more pronomina you just wrap the whole thing into
place zero, the word:
0=(everything from above for that/those),
1=(the same structure for this),
... # and so on
However, before you add more data you might give some thought to a format of
the data that is easier to write and proof-read. You can then write another
little script that morphs the structure into the one needed by your current
script.
More information about the Tutor
mailing list