Files
geograsim/App/sims/weltkueche/scripts/flatten-pantry.py
T
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

266 lines
16 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Überführt das pantry-Konzept (lokale Zutaten) auf die ings-Liste.
Pantry-Items werden auf ING-Slugs gemappt; nicht-erforschbare Standards
(Salz, Wasser, Pfeffer-Pulver, Backpulver, Hagelzucker etc.) werden SKIP."""
import json
from pathlib import Path
DATA = Path('C:/xampp/htdocs/geograsim/App/sims/weltkueche/assets/data')
# Mapping: Pantry-Label → ING-Slug (oder None für SKIP)
MAP = {
# SKIP — keine didaktisch sinnvolle Verortung
'Salz': None, 'Wasser': None, 'Pfeffer': None, 'Backpulver': None,
'Speisestärke': None, 'Staubzucker': None, 'Würfelzucker': None, 'Hagelzucker': None,
'Zucker': None, 'Salz (Limettensalz)': None, 'Natronlauge (oder Speisestärke)': None,
'Senf': None, 'Semmelbrösel': None, 'Brötchen (vom Vortag)': None,
'Brot (Vortagsbrot)': None, 'Fleischbrühe': None, 'Plunderteig': None,
'Spaghetti': None, 'Fladenbrot': None, 'Mürbteig (Butter, Mehl, Ei, Salz)': None,
'Kirschwasser (Schwarzwälder)': None, 'Kirschwasser (optional)': None,
'Korianderblätter': None, 'Koriandergrün': None, # → koriander schon in ings
# Mappings auf neue oder bestehende ING-Slugs
'Mehl': 'mehl', 'Mehl (Glatt)': 'mehl', 'Mehl (Strudelteig)': 'mehl',
'Mehl (Spätzlemehl)': 'mehl', 'Mehl (Weizen)': 'mehl',
'Eier': 'eier', 'Eigelb': 'eier',
'Butter': 'butter', 'Butterschmalz': 'butter', 'Schmalz': 'butter', 'Schweineschmalz': 'butter',
'Zwiebel': 'zwiebel', 'Schalotte': 'zwiebel', 'Frühlingszwiebel': 'zwiebel',
'Knoblauch': 'knoblauch',
'Schnittlauch': 'kraeuter', 'Petersilie': 'kraeuter', 'Lorbeer': 'kraeuter',
'Wacholderbeeren': 'kraeuter', 'Muskat': 'muskat', 'Rosmarin': 'kraeuter',
'Thymian': 'kraeuter', 'Basilikum': 'kraeuter', 'Minze (Bohnen­kraut)': 'kraeuter',
'Hefe': 'hefe',
'Speck': 'speck', 'Speck (geräuchert)': 'speck', 'Guanciale (Schweinebacke)': 'speck',
'Erdäpfel': 'kartoffel', 'Erdäpfel (mehlig)': 'kartoffel', 'Erdäpfel (festkochend)': 'kartoffel',
'Erdäpfel (festkochend, vom Vortag)': 'kartoffel', 'Bauernkartoffel': 'kartoffel',
'Karotten': 'wurzelgemuese', 'Karotte': 'wurzelgemuese',
'Sellerie': 'wurzelgemuese', 'Lauch': 'wurzelgemuese',
'Petersilwurzel': 'wurzelgemuese', 'Kren': 'wurzelgemuese',
'Topfen (Magertopfen)': 'topfen', 'Topfen (Quark)': 'topfen',
'Frischkäse': 'topfen', 'Camembert': 'mozzarella', # mild Käse → mozzarella-Familie
'Gruyère AOP': 'mozzarella', 'Vacherin Fribourgeois AOP': 'mozzarella',
'Vorarlberger Bergkäse': 'mozzarella', 'Räßkäse (Sauermilchkäse)': 'mozzarella',
'Sauerkirschen': 'kirschen',
'Apfel': 'apfel',
'Wachauer Marillen': 'marille', 'Marillenmarmelade': 'marille',
'Schokolade (dunkel)': 'kakao',
'Tomate': 'tomaten',
'Aubergine': 'gemuese', 'Zucchini': 'gemuese', 'Paprikaschoten': 'gemuese',
'Paprika (rot, gelb)': 'gemuese', 'Erbsen': 'gemuese', 'Blumenkohl': 'gemuese',
'Gurke': 'gemuese', 'Grüne Bohnen (Garrofó)': 'gemuese', 'Weiße Bohnen (Ferraúra)': 'gemuese',
'Spinat': 'gemuese', 'Sojasprossen': 'soja',
'Tofu': 'soja',
'Rindfleisch (Beinscheibe)': 'fleisch', 'Rindfleisch (Schulter)': 'fleisch',
'Rindfleisch (Wadschunken)': 'fleisch', 'Kalbsschnitzel': 'fleisch',
'Kalbfleisch (Filet oder Nuss)': 'fleisch', 'Hühnchen': 'fleisch',
'Kaninchen': 'fleisch', 'Lammhackfleisch': 'fleisch',
'Brät (Brühwurst-Mischung)': 'fleisch',
'Sahne': 'milch', 'Rahm (Sahne)': 'milch', 'Crème fraîche': 'milch',
'Schlagobers': 'milch', 'Milch': 'milch',
'Reisessig': 'essig', 'Essig': 'essig',
'Wein (rot)': 'wein', 'Rotwein': 'wein', 'Weißwein': 'wein',
'Weißwein (trocken, Fendant)': 'wein', 'Bier': 'wein',
'Grieß': 'hartweizen',
'Walnüsse': 'mandeln', 'Mandeln': 'mandeln',
'Tahini (Sesampaste)': 'sesam',
'Champignons': 'champignons',
'Kümmel': 'kuemmel',
'Olivenöl': 'olivenoel', 'Öl': 'olivenoel', 'Öl (zum Frittieren)': 'olivenoel',
'Sonnenblumenöl': 'olivenoel',
'Kürbiskernöl': 'olivenoel',
'Palmzucker': 'rohrzucker',
'Paprikapulver': 'paprika',
}
# Neue Standard-Zutaten-Einträge (werden zu ingredients-extras.json hinzugefügt
# falls noch nicht drin)
NEW_INGS = {
"mehl": {
"nm": "Mehl (Weizen)", "ic": "🌾",
"correct": ["kanada", "frankreich"],
"choices": ["kanada", "frankreich", "norwegen", "island"],
"econ": {"leader": "Kanada / Frankreich", "share": "Kanada exportiert weltweit am meisten Weizen",
"world": "~770 Mio t Weizen / Jahr", "price": "ca. 0,10 € / 100 g"},
"note": "Weizen wächst in gemäßigtem Klima — nicht zu kalt, nicht zu trocken. Kanada (Prairie) und Frankreich (Beauce) sind Hauptanbaugebiete.",
"more": "Aus 1 kg Weizen werden etwa 800 g Mehl — der Rest ist Kleie und Keimling."
},
"eier": {
"nm": "Eier", "ic": "🥚",
"correct": ["deutschland", "polen"],
"choices": ["deutschland", "polen", "norwegen", "island"],
"econ": {"leader": "Deutschland / Polen", "share": "EU produziert ~7 Mio t Eier / Jahr",
"world": "weltweit ~80 Mio t / Jahr", "price": "ca. 0,30 € / Ei"},
"note": "Eier in Mitteleuropa kommen meist aus lokaler Produktion — Bodenhaltung, Freiland, Bio.",
"more": "Eine Henne legt etwa 280 Eier pro Jahr. EU-Eier müssen einen Code tragen, der die Haltungsform verrät (0=Bio, 1=Freiland, 2=Boden, 3=Käfig)."
},
"butter": {
"nm": "Butter", "ic": "🧈",
"correct": ["frankreich", "deutschland"],
"choices": ["frankreich", "deutschland", "norwegen", "island"],
"econ": {"leader": "Frankreich, Deutschland, Irland", "share": "EU-Produktion ~2,4 Mio t / Jahr",
"world": "weltweit ~11 Mio t Butter / Jahr", "price": "ca. 1-2 € / 100 g"},
"note": "Butter braucht viele Liter Milch — 1 kg Butter = ca. 23 L Milch. Hoher Klima-Footprint, aber regional erzeugt.",
"more": "Die berühmte Beurre d'Isigny' aus der Normandie hat g.U.-Schutz. Französische Butter hat oft 82 % Fett, deutsche meist 80 %."
},
"zwiebel": {
"nm": "Zwiebel", "ic": "🧅",
"correct": ["niederlande", "polen"],
"choices": ["niederlande", "polen", "norwegen", "island"],
"econ": {"leader": "China (weltweit) / Niederlande (Export)", "share": "China produziert ~25 % der Weltzwiebeln",
"world": "~100 Mio t / Jahr", "price": "ca. 0,15 € / 100 g"},
"note": "Zwiebeln wachsen in gemäßigtem Klima fast überall — Niederlande sind weltgrößter Export-Drehkreuz.",
"more": "Beim Schneiden setzen Zwiebeln Schwefel-Verbindungen frei, die mit Tränenflüssigkeit zu Schwefelsäure reagieren — daher die Tränen."
},
"hefe": {
"nm": "Hefe", "ic": "🍞",
"correct": ["deutschland", "frankreich"],
"choices": ["deutschland", "frankreich", "norwegen", "island"],
"econ": {"leader": "Mitteleuropa", "share": "Lokale Produktion in jedem Industrieland",
"world": "weltweit ~3 Mio t / Jahr", "price": "ca. 0,30 € / Würfel"},
"note": "Backhefe sind Mikroorganismen, die Zucker zu CO₂ und Alkohol vergären. So geht der Teig auf.",
"more": "Hefe wurde 1857 von Louis Pasteur als lebender Pilz erkannt — vorher hielt man sie für tot."
},
"speck": {
"nm": "Speck / Bauchspeck", "ic": "🥓",
"correct": ["italien", "deutschland"],
"choices": ["italien", "deutschland", "norwegen", "island"],
"econ": {"leader": "Italien (Guanciale, Pancetta) / DE (Bauchspeck)", "share": "Regionale Spezialitäten",
"world": "Schweine-Welt-Produktion ~110 Mio t / Jahr", "price": "ca. 1-3 € / 100 g"},
"note": "Speck ist die geräucherte Schweinebacke oder -bauch. Guanciale (IT, Backe) und Pancetta (IT, Bauch) sind die Klassiker.",
"more": "Tiroler Speck ist g.g.A. Vom Schwein über Pökeln, Räuchern, Trocknen — bis zu 6 Monate Reife."
},
"kartoffel": {
"nm": "Erdäpfel / Kartoffeln", "ic": "🥔",
"correct": ["deutschland", "polen"],
"choices": ["deutschland", "polen", "saudi", "island"],
"econ": {"leader": "Deutschland / Polen (EU)", "share": "China weltweit Nr. 1",
"world": "~370 Mio t / Jahr", "price": "ca. 0,10 € / 100 g"},
"note": "Kartoffeln kamen erst nach 1492 aus Südamerika nach Europa. Heute Grundnahrungsmittel.",
"more": "Eine Kartoffel besteht zu 80 % aus Wasser. In ihrer schale stecken die meisten Vitamine."
},
"wurzelgemuese": {
"nm": "Wurzelgemüse", "ic": "🥕",
"correct": ["oesterreich", "deutschland"],
"choices": ["oesterreich", "deutschland", "saudi", "island"],
"econ": {"leader": "Mitteleuropa", "share": "Klassisches Wintergemüse",
"world": "lokal angebaut", "price": "ca. 0,10-0,20 € / 100 g"},
"note": "Karotten, Sellerie, Petersilwurzel, Lauch — die Klassiker des Wintergartens. Vor der Kühltechnik die Hauptquelle für Vitamine.",
"more": "Karotten waren ursprünglich VIOLETT (oder weiß/gelb). Die orange Karotte ist eine niederländische Züchtung aus dem 17. Jh. zu Ehren des Hauses Oranien."
},
"topfen": {
"nm": "Topfen / Quark", "ic": "🥛",
"correct": ["oesterreich", "deutschland"],
"choices": ["oesterreich", "deutschland", "norwegen", "island"],
"econ": {"leader": "DACH-Region", "share": "Traditionelles Mitteleuropa-Milchprodukt",
"world": "lokal produziert", "price": "ca. 0,60-1 € / 250 g"},
"note": "Topfen (AT) = Quark (DE) = Fromage blanc (FR). Frischkäse, keine Reife — schnell verbraucht.",
"more": "Aus 5 L Milch wird etwa 1 kg Topfen. Wichtige Eiweißquelle für Sportler:innen."
},
"fleisch": {
"nm": "Rotes Fleisch (Rind, Kalb, Lamm)", "ic": "🥩",
"correct": ["argentinien", "brasilien"],
"choices": ["argentinien", "brasilien", "norwegen", "saudi"],
"econ": {"leader": "Brasilien / USA / Argentinien", "share": "Brasilien ist weltgrößter Rindfleisch-Exporteur",
"world": "weltweit ~80 Mio t Rindfleisch / Jahr", "price": "ca. 2-5 € / 100 g"},
"note": "Rindfleisch hat den höchsten Klima-Footprint aller Lebensmittel — ~25 kg CO₂ pro kg Fleisch.",
"more": "Argentinische Rinder weiden auf der Pampa. Brasilianisches Rindfleisch ist oft mit Regenwald-Rodung verbunden."
},
"gemuese": {
"nm": "Sommer-Gemüse", "ic": "🥬",
"correct": ["spanien", "italien"],
"choices": ["spanien", "italien", "norwegen", "island"],
"econ": {"leader": "Spanien / Italien (EU)", "share": "Mittelmeer-Hauptlieferant für Europa",
"world": "lokal + Welthandel", "price": "ca. 0,20-0,40 € / 100 g"},
"note": "Aubergine, Zucchini, Paprika, Tomaten — die Mittelmeer-Klassiker. Spanien und Italien sind EU-Hauptlieferanten.",
"more": "Im Winter kommt das Gemüse aus beheizten Gewächshäusern in Almería (ES) — ein 350 km² großer Plastikgewächshaus-Komplex, sichtbar aus dem Weltall."
},
"milch": {
"nm": "Milch / Sahne", "ic": "🥛",
"correct": ["deutschland", "frankreich"],
"choices": ["deutschland", "frankreich", "norwegen", "saudi"],
"econ": {"leader": "Deutschland (EU Nr. 1)", "share": "EU produziert ~155 Mio t Milch / Jahr",
"world": "weltweit ~890 Mio t / Jahr", "price": "ca. 0,10 € / 100 ml"},
"note": "Milch in Europa kommt fast immer regional. DACH und Frankreich sind Kontinent-Hauptproduzenten.",
"more": "Eine Kuh gibt 25-40 Liter Milch pro Tag. Pro Kuh werden ~600 kg CO₂ pro Jahr ausgestoßen (Methan-Furze inklusive)."
},
"essig": {
"nm": "Essig", "ic": "🧪",
"correct": ["italien", "deutschland"],
"choices": ["italien", "deutschland", "norwegen", "island"],
"econ": {"leader": "Italien (Modena, Balsamico)", "share": "Mittelmeer-Tradition",
"world": "lokal produziert", "price": "ca. 0,30 € / 100 ml"},
"note": "Essig entsteht durch eine zweite Gärung: Alkohol → Essigsäure (Essigbakterien).",
"more": "Aceto Balsamico di Modena reift bis zu 25 Jahre in Holzfässern — kostet dann hunderte Euro pro 100 ml."
},
"wein": {
"nm": "Wein", "ic": "🍷",
"correct": ["frankreich", "italien"],
"choices": ["frankreich", "italien", "norwegen", "island"],
"econ": {"leader": "Italien / Frankreich / Spanien", "share": "Italien knapp vor Frankreich Nr. 1",
"world": "~260 Mio Hektoliter / Jahr", "price": "ca. 0,30-2 € / 100 ml"},
"note": "Wein braucht Sonne und mildes Klima — Mittelmeerraum perfekt. Sortenvielfalt, regionale Spezialitäten.",
"more": "Älteste Weingebiete der Welt liegen in Georgien (6000 v. Chr.). Heute ist Wein eines der EU-meistgehandelten Agrarprodukte."
},
"kirschen": {
"nm": "Kirschen / Sauerkirschen", "ic": "🍒",
"correct": ["deutschland", "polen"],
"choices": ["deutschland", "polen", "norwegen", "island"],
"econ": {"leader": "Türkei (Welt) / Polen (EU)", "share": "Türkei Nr. 1 Welt, Polen Nr. 1 EU",
"world": "~2,5 Mio t / Jahr", "price": "ca. 0,30-0,50 € / 100 g"},
"note": "Sauerkirschen sind in Mittel- und Osteuropa traditionell — Schwarzwald, Polen, Ungarn.",
"more": "Süßkirschen werden frisch gegessen, Sauerkirschen meist verarbeitet (Marmelade, Kuchen, Sirup)."
},
"marille": {
"nm": "Marillen / Aprikosen", "ic": "🍑",
"correct": ["oesterreich", "tuerkei"],
"choices": ["oesterreich", "tuerkei", "norwegen", "island"],
"econ": {"leader": "Türkei (Weltmarkt)", "share": "Türkei produziert ~25 % Welt-Aprikosen",
"world": "~4 Mio t / Jahr", "price": "ca. 0,40-0,80 € / 100 g"},
"note": "Marillen brauchen warme Sommer und milde Winter. Wachau (AT) hat g.U.-Status.",
"more": "Aprikosen kamen über die Seidenstraße nach Europa. In Österreich heißen sie Marillen, in Deutschland Aprikosen."
}
}
# 1. Erweitere ingredients-extras.json
ingredients_path = DATA / 'ingredients-extras.json'
ing_data = json.loads(ingredients_path.read_text(encoding='utf-8'))
added = 0
for slug, entry in NEW_INGS.items():
if slug not in ing_data:
ing_data[slug] = entry
added += 1
ingredients_path.write_text(json.dumps(ing_data, indent=2, ensure_ascii=False), encoding='utf-8')
print(f'ingredients-extras.json: {added} neue Standard-Zutaten ergänzt')
# 2. Mergen mit allen Tranchen + dishes.json updaten
dishes_path = DATA / 'dishes.json'
dishes = json.loads(dishes_path.read_text(encoding='utf-8'))
unknown_pantry = set()
total_added = 0
for key, dish in dishes.items():
if key.startswith('_'):
continue
pantry = dish.get('pantry', [])
existing_ings = list(dish.get('ings', []))
new_ings = list(existing_ings)
for p in pantry:
if p in MAP:
slug = MAP[p]
if slug is None:
continue # SKIP
if slug not in new_ings:
new_ings.append(slug)
total_added += 1
else:
unknown_pantry.add(p)
dish['ings'] = new_ings
# Pantry-Feld leeren — Konzept ist raus
dish['pantry'] = []
dishes_path.write_text(json.dumps(dishes, indent=2, ensure_ascii=False), encoding='utf-8')
print(f'dishes.json: +{total_added} Zutaten als ings ergänzt')
if unknown_pantry:
print(f'WARN: {len(unknown_pantry)} Pantry-Items hatten kein Mapping (übersprungen):')
for u in sorted(unknown_pantry):
print(f' - {u}')