gesucht wird eine kreative Methode um Sachaufgaben zu erstellen

Django, Flask, Bottle, WSGI, CGI…
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du sollst ja auch nicht die Keys in einem Wörterbuch in Variablen im Python-Code umwandeln, sondern einfach immer nur mit Wörterbüchern arbeiten.

Wie ich gerade sehe, gibt es einen Bug in parser-Funktion, da / eine höhere Priorität hat als *. Dass das Paket unnötige Klammern einführt, macht es nicht wirklich geeignet.

Dann hast Du noch besondere Anforderungen, dass Du Kommazahlen möchtest und mit Rest rechnen möchtest.

Als erstes muß also die `parser`-Methode gepatcht werden:

Code: Alles auswählen

def isOperator(self):
    ops = (
        ('**', 8, '**'),
        ('^', 8, '^'),
        ('%', 5, '%'),
        ('/', 5, '/'),
        ('*', 5, '*'),
        ('+', 4, '+'),
        ('-', 4, '-'),
    )
    for token, priority, index in ops:
        if self.expression.startswith(token, self.pos):
            self.tokenprio = priority
            self.tokenindex = index
            self.pos += len(token)
            return True
    return False

Parser.isOperator = isOperator
parser = Parser()
parser.ops2['/'] = divmod
Dann haben wir die Werte aus der Datenbank. Hier sind alle Platzhalter mit Namen bezeichnet:

Code: Alles auswählen

text = "Wie viele {a}cm lange Stücke kann man von einer {b}m langen Leiste absägen?"
ergebnis = "100*{b} / {a}"
variablen_auswahl = {"a": [5,10,15,20,25], "b": [1,1.2,1.5,2,2.5]}
Wir würfeln also die Variablen aus der Liste und wandeln Zahlen in Kommazahlen um:

Code: Alles auswählen

variablen = {
    name: random.choice(werte)
    for name, werte in variablen_auswahl.items()
}
variablen_text = {
    name: str(wert).replace('.', ',')
    for name, wert in variablen.items()
}
Wichtig also, dass wir eine Variante zum Rechnen und eine für die Ausgabe haben.

Code: Alles auswählen

print(text.format(**variablen_text))
Jetzt willst Du noch den Lösungsweg und den Wert (inklusive Rest) ausgeben:

Code: Alles auswählen

loesungs_weg = ergebnis.format(**variablen_text)
wert = parser.evaluate(ergebnis.format(**{k: k for k in variablen}), variablen)
if isinstance(wert, tuple):
    wert, rest = wert
    if rest:
        print(f"Lösung: {loesungs_weg} = {wert:.0f} Rest {rest:.0f}")
    else:
        print(f"Lösung: {loesungs_weg} = {wert:.0f}")
else:
    print(f"Lösung: {loesungs_weg} = {wert}")
Bei Rechnungen mit Rest ist es wichtig, dass die Division immer die letzte Operation ist.
Hier wird als erstes in der `ergebnis`-Variable die Platzhalter durch ihren Namen ersetzt, um den Ausdruck parsen zu können.

Beispiel:

Code: Alles auswählen

Wie viele 20cm lange Stücke kann man von einer 2,5m langen Leiste absägen?
Lösung: 100*2,5 / 20 = 12 Rest 10
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Da muss ich mich jetzt eratmal durcharbeiten:
Sirius3 hat geschrieben: Sonntag 26. März 2023, 14:19 Du sollst ja auch nicht die Keys in einem Wörterbuch in Variablen im Python-Code umwandeln, sondern einfach immer nur mit Wörterbüchern arbeiten.
Ich hatte halt gedacht, dass ich nur über die Keys auf die einzelnen Variablen zugreifen kann.
Sirius3 hat geschrieben: Sonntag 26. März 2023, 14:19 Wie ich gerade sehe, gibt es einen Bug in parser-Funktion, da / eine höhere Priorität hat als *. Dass das Paket unnötige Klammern einführt, macht es nicht wirklich geeignet.
Als erstes muß also die `parser`-Methode gepatcht werden:

Code: Alles auswählen

def isOperator(self):
    ops = (
        ('**', 8, '**'),
        ('^', 8, '^'),
        ('%', 5, '%'),
        ('/', 5, '/'),
        ('*', 5, '*'),
        ('+', 4, '+'),
        ('-', 4, '-'),
    )
    for token, priority, index in ops:
        if self.expression.startswith(token, self.pos):
            self.tokenprio = priority
            self.tokenindex = index
            self.pos += len(token)
            return True
    return False

Parser.isOperator = isOperator
parser = Parser()
parser.ops2['/'] = divmod
was macht der Code? Sehe ich das richtig, dass du hier die Reihenfolge der Rechenoperationen änderst oder genauer, der Multiplikation und Divison gleiche Priorität zuordnest? Für meinen derzeitige Nutzung ist das, glaube ich, egal, das werde ich aber später sicher brauchen. Und "parser.ops2['/'] = divmod" erzeugt ein Paar mit Ergebnis und Rest anstelle einer Kommazahl? Außer bei der Leistenaufgabe brauche ich Kommazahlen und das wird mit "if isinstance(wert, tuple)" erreicht?
Sirius3 hat geschrieben: Sonntag 26. März 2023, 14:19 Dann hast Du noch besondere Anforderungen, dass Du Kommazahlen möchtest und mit Rest rechnen möchtest.
Nicht ganz. Diese Besonderheit ergibt sich aus dieser speziellen Aufgabe
"Wie viele 15cm lange Stücke kann man von einer 1m langen Leiste absägen?"
Ich brauche nicht den Rest, ich möchte nur anzeigen, dass ein Rest bleibt - wenn dem so ist.
Daher übergebe ich mit den Variablen die Anzahl der gewünschten Nachkommastellen. Bei Null, bleibt unter Umständen was übrig (wie bei der Leistenaufgabe, daher macht es keinen Sinn aufzurunden) und bei Aufgaben mit Geldbeträgen möchte ich zwei Stellen, da ansonsten auch z.B. "1,2€" als Lösung angezeigt wird.
Sirius3 hat geschrieben: Sonntag 26. März 2023, 14:19 Beispiel:

Code: Alles auswählen

Wie viele 20cm lange Stücke kann man von einer 2,5m langen Leiste absägen?
Lösung: 100*2,5 / 20 = 12 Rest 10
... wo genau im Code wirst du die Klammern los?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt irgendeine Darstellung der Formel zu nehmen, um die danach mit Stringoperationen zurechzubiegen, definiere ich die Darstellung explizit.

Je nach Anforderungen mußt Du halt entsprechende Funktionen schreiben, die die verschiedenen Fälle unterstützen. Zum Beispiel:

Code: Alles auswählen

class CommaFormatter(string.Formatter):
    def format_field(self, value, format_spec):
        result = format(value, format_spec)
        if format_spec.endswith('f') or isinstance(value, float):
            result = result.replace('.', ',')
        return result

    def evaluate(self, format_string, **kwargs):
        text = format_string.split('=')[0].format(**kwargs)
        return Parser().evaluate(text, {})

text = "Wie viele {a}cm lange Stücke kann man von einer {b}m langen Leiste absägen?"
ergebnis = "100*{b} / {a} = {:.0f}"
variablen_auswahl = {"a": [5,10,15,20,25], "b": [1,1.2,1.5,2,2.5]}

variablen = {
    name: random.choice(werte)
    for name, werte in variablen_auswahl.items()
}
formatter = CommaFormatter()
loesung = formatter.evaluate(ergebnis, **variablen)
print(formatter.format(text, **variablen))
print(formatter.format(ergebnis, loesung, **variablen))


text = "Du kaufst {a} Brötchen für {b:.2f}€ und ein Brot für {c:.2f}€. Was kostet das insgesamt?"
ergebnis = "{a} * {b:.2f} + {c:.2f} = {:.2f}€"
variablen_auswahl = {"a": [3, 4, 5, 6, 7], "b": [0.35, 0.40, 0.45, 0.50, 0.55], "c": [2.50, 2.80, 3.20]}

variablen = {
    name: random.choice(werte)
    for name, werte in variablen_auswahl.items()
}
formatter = CommaFormatter()
loesung = formatter.evaluate(ergebnis, **variablen)
print(formatter.format(text, **variablen))
print(formatter.format(ergebnis, loesung, **variablen))
Das gibt dann je nach Aufgabe:

Code: Alles auswählen

Wie viele 25cm lange Stücke kann man von einer 1,2m langen Leiste absägen?
100*1,2 / 25 = 5

Du kaufst 5 Brötchen für 0,55€ und ein Brot für 3,20€. Was kostet das insgesamt?
5 * 0,55 + 3,20 = 5,95€
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Das ist hohe Kunst. Ich bewundere dich sehr - aber ich lerne das nie!!
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

@sparrow
Pitwheazle hat geschrieben: Sonntag 26. März 2023, 20:21 Das ist hohe Kunst. Ich bewundere dich sehr - aber ich lerne das nie!!
.... aber ich will es wenigstens versuchen und mich durch deinen Code arbeiten. Da ich ihn aber nahezu nicht verstehe und versuche, ihn Zeile für Zeile nachzuvollziehen, hänge ich schon an der ersten Zeile - ich erhalte den Fehler
"NameError: name 'string' is not defined"
Wie kann ich den Code irgendwo unabhängig zum Laufen bringen?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein "import string" koennte Wunder bewirken.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Das muss einem ja auch gesagt werden :oops: (... Habe ich schon erwähnt, dass ich keine Ahnung habe?)

Und noch was:
Wenn ich meine Bandwürmer von Variablen wie

Code: Alles auswählen

["", 0, {"a": ["Julia", "Sophie", "Maria","Paul"], "b": ["Sie", "Sie", "Sie","Er"],  "c": ["ihr", "ihr", "ihr","ihm"],  "d": ["einen neuen Pullover", "eine neue Tasche"], "e": [10, 15, 20], "f": [25, 28, 30], }]
in ein JSONFeld eingebe, bekomme ich gerne den Hinweis, dass irgendwas falsch ist, aber nicht was. Wenn ich das richtig sehe, hat @--blackjack__ das hier mit "json.loads" gemacht - wie geht das ... und wo macht man das?
__blackjack__ hat geschrieben: Dienstag 21. März 2023, 15:12 Wie ist denn das in die Datenbank gekommen? Denn das ";" da drin ist falsch, das ist damit kein gültiges JSON:

Code: Alles auswählen

In [3]: json.loads("[[5,10,15,20,25];[1,1.2,1.5,2,2.5]]")
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
Cell In [3], line 1
----> 1 json.loads("[[5,10,15,20,25];[1,1.2,1.5,2,2.5]]")
....
JSONDecodeError: Expecting ',' delimiter: line 1 column 17 (char 16)
Nachtrag: Ich habe es gefunden, am Ende ist ein Komma zuviel - aber trotzdem: Wie macht man das?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich starte eine interaktive Python-Shell, in meinem Fall IPython, aber einfach ``python`` in einer Konsole starten, geht natürlich auch. Dort importiere ich dann das `json`-Modul, und rufe dann `json.loads()` mit den Daten auf, die ich aus dem Beitrag hier im Forum kopiere und in der Konsole an der entsprechenden Stelle einfüge:

Code: Alles auswählen

$ ipython
Python 3.8.13 (default, Sep  7 2022, 15:32:40) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import json

In [2]: json.loads("""["", 0, {"a": ["Julia", "Sophie", "Maria","Paul"], "b": ["
   ...: Sie", "Sie", "Sie","Er"],  "c": ["ihr", "ihr", "ihr","ihm"],  "d": ["ein
   ...: en neuen Pullover", "eine neue Tasche"], "e": [10, 15, 20], "f": [25, 28
   ...: , 30], }]""")
---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
Cell In [2], line 1
----> 1 json.loads("""["", 0, {"a": ["Julia", "Sophie", "Maria","Paul"], "b": ["Sie", "Sie", "Sie","Er"],  "c": ["ihr", "ihr", "ihr","ihm"],  "d": ["einen neuen Pullover", "eine neue Tasche"], "e": [10, 15, 20], "f": [25, 28, 30], }]""")

File /usr/local/lib/python3.8/json/__init__.py:357, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    352     del kw['encoding']
    354 if (cls is None and object_hook is None and
    355         parse_int is None and parse_float is None and
    356         parse_constant is None and object_pairs_hook is None and not kw):
--> 357     return _default_decoder.decode(s)
    358 if cls is None:
    359     cls = JSONDecoder

File /usr/local/lib/python3.8/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)                                                                           
    332 def decode(self, s, _w=WHITESPACE.match):
    333     """Return the Python representation of ``s`` (a ``str`` instance
    334     containing a JSON document).
    335 
    336     """
--> 337     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338     end = _w(s, end).end()
    339     if end != len(s):

File /usr/local/lib/python3.8/json/decoder.py:353, in JSONDecoder.raw_decode(self, s, idx)
    344 """Decode a JSON document from ``s`` (a ``str`` beginning with
    345 a JSON document) and return a 2-tuple of the Python
    346 representation and the index in ``s`` where the document ended.
   (...)
    350 
    351 """
    352 try:
--> 353     obj, end = self.scan_once(s, idx)
    354 except StopIteration as err:
    355     raise JSONDecodeError("Expecting value", s, err.value) from None

JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 210 (char 209)

In [3]:
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit dem Tool hier https://jsonlint.com/ kann man sowas auch schnell pruefen.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

__deets__ hat geschrieben: Montag 27. März 2023, 14:55 Mit dem Tool hier https://jsonlint.com/ kann man sowas auch schnell pruefen.
Gibt es auch was, was es nicht gibt? Erstaunlich!
Benutzeravatar
grubenfox
User
Beiträge: 412
Registriert: Freitag 2. Dezember 2022, 15:49

Sirius3 hat geschrieben: Sonntag 26. März 2023, 14:19 Wie ich gerade sehe, gibt es einen Bug in parser-Funktion, da / eine höhere Priorität hat als *. Dass das Paket unnötige Klammern einführt, macht es nicht wirklich geeignet.
Ach, was den Parser betrifft... da wollte ich doch noch SymPy in den Raum werfen...
Ich kenne beide nicht, daher muss die Tauglichkeit für dieses Projekt von anderer Seite beurteilt werden. ;)
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Ich bin schon ein Stück weiter (das ist sehr mühselig für mich) und habe eine neue Frage:
Ich habe ja zwischenzeitlich meinen alten Code auch schon weiter entwickelt und in diesem Zusammenhang sichergestellt, dass eine bestimmte Anzahl von Variablen nicht zufällig erstellt werden. Ich zeige es hier mal an obigem Beispiel:

Code: Alles auswählen

{0} hat {4}€ gespart. {1} möchte sich {3} kaufen, der {5}€ kostet. Wie viel Geld fehlt {2} noch?
und

Code: Alles auswählen

["G23", 0, {"a": ["Julia", "Sophie", "Maria", "Paul"], "b": ["Sie", "Sie", "Sie", "Er"], "c": ["ihr", "ihr", "ihr", "ihm"], "d": ["einen neuen Pullover", "eine neue Tasche"], "e": [10, 15, 20], "f": [25, 28, 30]}]
Mit "G23" sorge ich in meinem Code dafür, dass die ersten drei Variablen mit der gleichen Zufallszahl (gendermäßig) erzeugt werden und die restlichen nicht.
(Den code, zeige ich lieber nicht (ich glaube nicht, dass er euch gefällt) - er funktioniert aber).
Wenn ich @sparrow s Code übernehmen will, müsste ich in der Schleife:

Code: Alles auswählen

        variablen = {
            name: random.choice(werte)
            for name, werte in variablen_auswahl.items()
         }
noch eine if Abfrage einbauen also

Code: Alles auswählen

"if name = "a"
oder ähnlich - das gelingt mir nicht.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum hast Du im Aufgabentext jetzt Zahlen statt Buchstaben verwendet?

Code: Alles auswählen

"{a} hat {e}€ gespart. {b} möchte sich {d} kaufen, der {f}€ kostet. Wie viel Geld fehlt {c} noch?"
Jetzt können Formatangaben nicht nur einfache Namen sein, sondern können auch Indizes enthalten:

Code: Alles auswählen

variablen_auswahl = {
    "a": [
        ('Julia', 'Sie', 'ihr'),
        ('Sophie', 'Sie', 'ihr'),
        ('Maria', 'Sie', 'ihr'),
        ('Paul', 'Er', 'ihm')],
    "d": [
        ("einen neuen Pullover", "der"),
        ("eine neue Tasche", "die")],
    "e": [10, 15, 20],
    "f": [25, 28, 30]
}

text = "{a[0]} hat {e}€ gespart. {a[1]} möchte sich {d[0]} kaufen, {d[1]} {f}€ kostet. Wie viel Geld fehlt {a[2]} noch?"
ergibt

Code: Alles auswählen

Sophie hat 10€ gespart. Sie möchte sich eine neue Tasche kaufen, die 25€ kostet. Wie viel Geld fehlt ihr noch?
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

@Sirius3 wo kommt in deinem Code denn 'Parser()' her?
PyCharm gibt mir zwar eine ganze Liste an Möglichkeiten , wo ich das importieren könnte, aber da war nichts passendes dabei. Auch in der Suchmaschine habe ich nichts gefunden.

@Pitwheazle Ich persönlich finde es sehr schwer, aus den Code-Stückeln herauszufinden, wo genau dein Problem liegt. Lieber ein Minimalbeispiel an dem man den Fehler erkennt. Aber vielleicht fehlt mir auch nur die Programmiererfahrung dazu.

Wieso musst du eine 'If'-Abfrage einbauen, wenn du das Wörterbuch erstellst?

Code: Alles auswählen

variablen = {
    name: random.choice(werte)
    for name, werte in variablen_auswahl.items() if name =='a'
}
Grüße
Dennis

Ich sehe gerade, das Sirius3 schon geantwortet hat, ich lass das mit der 'if'-Abfrage hier trotzdem mal drin.
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dennis89: ich mußte auch eine Weile suchen, bis ich die Referenz gefunden hatte:
Pitwheazle hat geschrieben: Mittwoch 22. März 2023, 13:21
sparrow hat geschrieben: Montag 20. März 2023, 21:20 Zum Evaluieren von Formeln gibt es Module, die das sicher können (das hier scheint so eins zu sein).
@grubenfox: Sympy hatte ich auch verwendet. Das ist ein gut gepflegtes Projekt, vom Umfang aber ziemlich groß.
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Dankeschön, dein Codebeispiel ist ja wirklich cool 😎

Dass man das alles so formatieren kann, hatte ich bis jetzt noch nie gesehen. Das muss ich mir abspeichern.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Sirius3 hat geschrieben: Montag 27. März 2023, 19:10 Warum hast Du im Aufgabentext jetzt Zahlen statt Buchstaben verwendet?
Das ist noch aus der Zeit als ich die Variablen in Listen gespeichert habe. Zwischenzeitlich habe ich die Vorteile von Wörterbüchern erkannt und bin ja dabei das umzustellen. Noch sind die Texte aber so in der Datenbank.
Dennis89 hat geschrieben: Montag 27. März 2023, 19:28 @Pitwheazle Ich persönlich finde es sehr schwer, aus den Code-Stückeln herauszufinden, wo genau dein Problem liegt. Lieber ein Minimalbeispiel an dem man den Fehler erkennt. Aber vielleicht fehlt mir auch nur die Programmiererfahrung dazu.
Wieso musst du eine 'If'-Abfrage einbauen, wenn du das Wörterbuch erstellst?

Code: Alles auswählen

variablen = {
    name: random.choice(werte)
    for name, werte in variablen_auswahl.items() if name =='a'
}
Ich habe ja zwischenzeitlich an meinem alten Code weitergearbeitet und da erschien es mir nötig, u.U. Variablen zu gruppieren. In dem Beispiel oben, muss ich die Variablen geschlechtmäßig ordnen:

Code: Alles auswählen

{0} hat {4}€ gespart. {1} möchte sich {3} kaufen, der {5}€ kostet. Wie viel Geld fehlt {2} noch?
und:

Code: Alles auswählen

["G23", 0, {"a": ["Julia", "Sophie", "Maria", "Paul"], "b": ["Sie", "Sie", "Sie", "Er"], "c": ["ihr", "ihr", "ihr", "ihm"], "d": ["einen neuen Pullover", "eine neue Tasche"], "e": [10, 15, 20], "f": [25, 28, 30]}]
hier habe ich die ersten drei Variablen gruppiert. Mithilfe von "G23". Ich überprüfe bei der ersten Variablen, wieviele Möglichkeiten es gibt und lege danach eine Zufallszahl "gruppe" fest, mit der ich auch die Variablen 2 und 3 erzeuge.
Du hast es so gewollt, ich stelle dir hier meinen Code dazu ein, er ist häßlich - aber er funktioniert - ist aber nichts für schwache Nerven:

Code: Alles auswählen

        parameter=aufgabe.variable
        art=parameter[0]
        stellen=parameter[1]            # Anz der Dezimalstellen
        variable=parameter[2]
        term=aufgabe.loe_weg
        parser = Parser() 
        items = len(variable)           # variable insgesamt 
        a=b=c=d=e=f=""
        gruppe=0
        if items>0:
            if "G" in art:
                anz=len(variable['a'])
                gruppe=random.randint(1,anz-1)
                a=variable["a"][gruppe]
            else:
                a=random.choice(variable["a"])
            if 'a' in term:
                term=parser.parse(term).substitute('a',a).toString()
        if items>1:
            if '2' in art and gruppe>0:
                b=variable["b"][gruppe]
            else:
                b=random.choice(variable["b"])
            if 'b' in term:
                term=parser.parse(term).substitute('b',b).toString()          
        if items>2:
            if '3' in art and gruppe>0:
                c=variable["c"][gruppe]
            else:
                c=random.choice(variable["c"])
            if 'c' in term:
                term=parser.parse(term).substitute('c',c).toString()  
        if items>3:
            if '4' in art and gruppe>0:
                d=variable["d"][gruppe]
            else:
                d=random.choice(variable["d"])
            if 'd' in term:
                term=parser.parse(term).substitute('d',d).toString() 
        if items>4:
            if '5' in art and gruppe>0:
                e=variable["e"][gruppe]
            else:
                e=random.choice(variable["e"])
            if 'e' in term:
                term=parser.parse(term).substitute('e',e).toString() 
        if items>5:
            if '6' in art and gruppe>0:
                f=variable["f"][gruppe]
            else:
                f=random.choice(variable["f"])
            if 'f' in term:
                term=parser.parse(term).substitute('f',f).toString() 
        ergebnis=parser.parse(term).evaluate({}) 
        text = aufgabe.text.format(a,b,c,d,e,f)
        pro_text = aufgabe.pro_text+term

        frage = aufgabe.links_text
        einheit = aufgabe.rechts_text
        rest=""
        if stellen==0:
            if ergebnis%1:
                anmerkung=aufgabe.anmerkung
                rest = "+Rest"
            ergebnis=ergebnis//1
        term=term.replace("(","").replace(")","")
        term=term.replace(".",",")
        lsg = term + "=" + format_zahl(ergebnis,stellen) + rest
... ich möchte das ändern und dazu mittels "if name == 'a': " oder so Variablen u.U. gruppieren.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Und ich habe die Gruppierung einfach in die Datenstruktur gepackt. Änderungen am Code: keine.

Code: Alles auswählen

variablen_auswahl = {
    "a": [
        ('Julia', 'Sie', 'ihr'),
        ('Sophie', 'Sie', 'ihr'),
        ('Maria', 'Sie', 'ihr'),
        ('Paul', 'Er', 'ihm')],
    "d": [
        ("einen neuen Pullover", "der"),
        ("eine neue Tasche", "die")],
    "e": [10, 15, 20],
    "f": [25, 28, 30]
}
text = "{a[0]} hat {e}€ gespart. {a[1]} möchte sich {d[0]} kaufen, {d[1]} {f}€ kostet. Wie viel Geld fehlt {a[2]} noch?"

variablen = {
    name: random.choice(werte)
    for name, werte in variablen_auswahl.items()
}
print(formatter.format(text, **variablen))
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Sirius3 hat geschrieben: Dienstag 28. März 2023, 05:21 Und ich habe die Gruppierung einfach in die Datenstruktur gepackt. Änderungen am Code: keine.

Code: Alles auswählen

variablen_auswahl = {
    "a": [
        ('Julia', 'Sie', 'ihr'),
        ('Sophie', 'Sie', 'ihr'),
        ('Maria', 'Sie', 'ihr'),
        ('Paul', 'Er', 'ihm')],
    "d": [
        ("einen neuen Pullover", "der"),
        ("eine neue Tasche", "die")],
    "e": [10, 15, 20],
    "f": [25, 28, 30]
}
einfach, genial!! Und du hast sogar den Pullover und die Tasche gegendert! Sorry, es hat etwas gedauert, aber einerseits habe ich versucht, das alles einzubauen und andererseits bin ich auf Reisen (z.Z. auf Ibiza) und muss ja auch noch das Urlauberding erledigen.

Ich habe das, deine Zustimmung voraussetzend, größtenteils eingebaut und es funktioniert (größtenteils) prima. Das mit dem Verstehen klappt meinerseits noch nicht so wirklich. Es ergeben sich einige Fragen:
1. Das obige Wörterbuch wollte ich in mein JSON Feld eingeben, das wird aber abgelehnt. Da ich keinen Fehler finde, habe ich habe es auch, auf @__deets__ Rat:
__deets__ hat geschrieben: Montag 27. März 2023, 14:55 Mit dem Tool hier https://jsonlint.com/ kann man sowas auch schnell pruefen.
dort mal probiert und erhalte die Meldung:
Error: Parse error on line 2:
{ "a": [('Julia', 'Sie', 'ih
--------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', ']', got 'undefined'
(der kleine Pfeil zeigt auf die ersten Anführungszeichen) - das verstehe ich schon wieder mal nicht.
2. Ich habe auch dies:

Code: Alles auswählen

def isOperator(self):
    ops = (
        ('**', 8, '**'),
        ('^', 8, '^'),
        ('%', 5, '%'),
        ('/', 5, '/'),
        ('*', 5, '*'),
        ('+', 4, '+'),
        ('-', 4, '-'),
    )
    for token, priority, index in ops:
        if self.expression.startswith(token, self.pos):
            self.tokenprio = priority
            self.tokenindex = index
            self.pos += len(token)
            return True
    return False

Parser.isOperator = isOperator
parser = Parser()
parser.ops2['/'] = divmod
[/quote]
in meinen Code integriert, versteh aber nicht, wo auf diese Funktion zugegriffen wird. Vor allem die letzten drei Zeilen, was machen die? Und wie greife ich auf dieses "divmod" zu?
3. Du @sirius3, hast ja weiter oben, das mit dem Rest gelöst, mir ist es nicht gelungen das einzubauen. Ich habe es jetzt folgendermaßen zusammengepfuscht (ich habe die Benennungen von Ergebnis und Lösung getauscht, damit sie zum rest meines Programms passen):

Code: Alles auswählen

        variablen = {
            name: random.choice(werte)
            for name, werte in variablen_auswahl.items()
        }
        formatter = CommaFormatter()
        ergebnis = formatter.evaluate(loesung, **variablen)
        lsg_weg = loesung.split("=") 
        if ":.0" in lsg_weg[1]:
            if ergebnis%1 >0:
                anmerkung=aufgabe.anmerkung
            ergebnis=ergebnis//1 
            rest=" + Rest" 
        else:
            rest=""            
        text = (formatter.format(text, **variablen))
        lsg = (formatter.format(loesung, ergebnis, **variablen))+rest
Und noch zuletzt:
4. Das mit der Gruppierung ist ja genial, möglicherweise muss ich aber auch zwei unterschiedliche Variablen gruppieren und komme auf meinen ursprünglichen Ansatz zurück. Das hier:

Code: Alles auswählen

gruppenzahl=2
        variablen = {
            name: random.choice(werte)
            for name, werte in variablen_auswahl.items()
            if name not in gruppe else name: werte[gruppenzahl]
        }
geht doch sicher auch irgendwie, wenn man weiß wie?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist ja auch kein JSON, sondern eine Python-Datenstruktur. Die sehen sich aehnlich, sind aber nicht das gleiche.
Antworten