Repository: fniessink/toisto (language: python)

Issue:
Crashes when practicing target language Dutch and source language Finnish
```console
Traceback (most recent call last):
  File "/Users/fniessink/Developer/toisto/venv/bin/toisto", line 8, in <module>
    sys.exit(main())
  File "/Users/fniessink/Developer/toisto/src/toisto/app.py", line 48, in main
    practice(console.print, progress, config)
  File "/Users/fniessink/Developer/toisto/src/toisto/command/practice.py", line 63, in practice
    while quiz := progress.next_quiz():
  File "/Users/fniessink/Developer/toisto/src/toisto/model/quiz/progress.py", line 52, in next_quiz
    if unblocked_quizzes := self.__unblocked_quizzes(potential_quizzes, eligible_quizzes):
  File "/Users/fniessink/Developer/toisto/src/toisto/model/quiz/progress.py", line 80, in __unblocked_quizzes
    return Quizzes(
  File "/Users/fniessink/Developer/toisto/src/toisto/model/quiz/progress.py", line 83, in <genexpr>
    if not self.__root_concepts_have_quizzes(quiz, eligible_quizzes)
  File "/Users/fniessink/Developer/toisto/src/toisto/model/quiz/progress.py", line 92, in __root_concepts_have_quizzes
    for root in quiz.concept.roots(target_language)
  File "/Users/fniessink/Developer/toisto/src/toisto/model/language/concept.py", line 165, in roots
    return self.instances.get_values(*concept_ids_of_roots)
  File "/Users/fniessink/Developer/toisto/src/toisto/tools.py", line 30, in get_values
    return tuple(self.__items[key] for key in keys)
  File "/Users/fniessink/Developer/toisto/src/toisto/tools.py", line 30, in <genexpr>
    return tuple(self.__items[key] for key in keys)
KeyError: 'to stand'
```

Same crash also happens with key `light`, `werk`.




Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f14025e4..3dc8c72b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 
 ### Fixed
 
-- Don't show builtin spelling alternatives as other correct answers. For example, Toisto would show "de pijn" as another correct answer when a user with Dutch as source language had entered "pijn" as answer. Closes [#623](https://github.com/fniessink/toisto/issues/623).
+- Don't show builtin spelling alternatives as other correct answers. For example, Toisto would show "de pijn" as another correct answer when a user with Dutch as source language had entered "pijn" as answer. Fixes [#623](https://github.com/fniessink/toisto/issues/623).
+- When practicing Dutch, Toisto would crash on certain concepts because they would refer to non-existing root concepts. Fixes [#626](https://github.com/fniessink/toisto/issues/626).
 
 ### Added
 
diff --git a/src/concepts/adpositions.json b/src/concepts/adpositions.json
index f485e446..75cb83c6 100644
--- a/src/concepts/adpositions.json
+++ b/src/concepts/adpositions.json
@@ -120,7 +120,6 @@
             ],
             "nl": [
                 "table",
-                "to stand",
                 "in the middle",
                 "room"
             ],
@@ -175,7 +174,6 @@
             ],
             "nl": [
                 "lamp",
-                "to stand",
                 "on top of"
             ],
             "fi": [
@@ -211,7 +209,6 @@
             ],
             "nl": [
                 "glass",
-                "to stand",
                 "below",
                 "table"
             ],
@@ -240,4 +237,4 @@
             "na"
         ]
     }
-}
\ No newline at end of file
+}
diff --git a/src/concepts/mixed/food.json b/src/concepts/mixed/food.json
index 1b405058..58f33e07 100644
--- a/src/concepts/mixed/food.json
+++ b/src/concepts/mixed/food.json
@@ -450,7 +450,7 @@
         "roots": {
             "en": [
                 "hot",
-                "chocoloate"
+                "chocolate"
             ],
             "nl": [
                 "chocolate",
diff --git a/src/concepts/nature.json b/src/concepts/nature.json
index 6841f7a4..ab4639d6 100644
--- a/src/concepts/nature.json
+++ b/src/concepts/nature.json
@@ -363,15 +363,9 @@
     },
     "northern lights": {
         "roots": {
-            "en": [
-                "north",
-                "light"
-            ],
+            "en": "north",
             "fi": "fire",
-            "nl": [
-                "north",
-                "light"
-            ]
+            "nl": "north"
         },
         "en": "northern lights",
         "fi": "revontulet",
@@ -443,4 +437,4 @@
         "fi": "Me kävelemme metsässä.",
         "nl": "Wij wandelen in het bos."
     }
-}
\ No newline at end of file
+}
diff --git a/src/concepts/work.json b/src/concepts/work.json
index 54401ec4..30e61676 100644
--- a/src/concepts/work.json
+++ b/src/concepts/work.json
@@ -165,15 +165,9 @@
     "part-time job": {
         "hypernym": "job",
         "roots": {
-            "en": [
-                "job"
-            ],
-            "fi": [
-                "work"
-            ],
-            "nl": [
-                "werk"
-            ]
+            "en": "job",
+            "fi": "work",
+            "nl": "work"
         },
         "en": "part-time job",
         "fi": "osa-aikatyö",


Test patch:
diff --git a/tests/concepts/test_concepts.py b/tests/concepts/test_concepts.py
index 45fa4c20..b32f2c9f 100644
--- a/tests/concepts/test_concepts.py
+++ b/tests/concepts/test_concepts.py
@@ -28,8 +28,9 @@ def test_load_concepts(self):
     def test_roots_exist(self):
         """Test that all roots use existing concept ids."""
         for concept in self.concepts:
-            for root in concept.roots(self.fi):
-                self.assertIn(root, Concept.instances.get_values(root.concept_id))
+            for language in BUILT_IN_LANGUAGES:
+                for root in concept.roots(language):
+                    self.assertIn(root, Concept.instances.get_values(root.concept_id))
 
     def test_examples_exist(self):
         """Test that all examples use existing concept ids."""