Seite 1 von 4
gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 17:13
von Pitwheazle
Für meinen Rechentrainer erstelle ich alle Aufgaben mithilfe von Zufallszahlen, auch Grafiken und kurze Textaufgaben. Bei der neuen Kategorie "Sachaufgaben" bin ich da an Grenzen gestoßen und habe mich entschlossen, die Aufgaben in einer Datentabelle zu speichern. Die Aufgaben sehen z.B. so aus:
- Die Kinokarte kostet für Erwachsene 9€ und für Kinder 6,50€. Wie viel muss eine Familie mit 2 Erwachsenen und 2 Kindern insgesamt für die Eintrittskarten bezahlen?
In einem Schwimmbad gibt es ein 50 m langes Becken. Wie viele Bahnen müssen Sie schwimmen, um 1 km zurückzulegen?
Ein Kiosk verkauft Eis am Stiel für 0,80 € pro Stück. Wie viel Geld benötigt man, um 10 Eis am Stiel zu kaufen?
Ein Baum wächst durchschnittlich um 20 cm pro Jahr. Wie groß ist er nach 8 Jahren, wenn er zu Beginn 1,50 m groß war?
Das zugehörige Model:
Code: Alles auswählen
class Sachaufgabe(models.Model):
lfd_nr = models.SmallIntegerField(default=0, unique=True)
ab_jg = models.SmallIntegerField(default=0)
text = models.TextField()
loesung = models.JSONField()
pro_text = models.CharField(max_length=25)
links_text = models.CharField(max_length=25)
ergebnis = models.DecimalField(max_digits=7, decimal_places=2)
rechts_text = models.CharField(max_length=25)
Und so wird eine Aufgabe angezeigt:

Insgesamt müssen die Daten zum Rest meines Rechentrainers passen. Das Ergebnis muss ein numerischer Wert sein. Die Lösung wird angezeigt, wenn der User dreimal eine falsche Eingabe macht oder auf "Lösung" klickt und soll den Rechenweg aufzeigen. Für die baumaufgabe sieht das z.B. so aus: "1,50+8·0,20=3,10". "pro_text" ist ein kurzer Text für das Protokoll und da man wohl ein KI bräuchte um Antwortsätze auszuwerten, gebe ich den Antwortsatz mit "links_text" und "rechts_text" vor, sodass nur noch die Zahl für die Lösung eingesetzt werden muss.
Wie unschwer zu erkennen ist, sind bisher nur feste Zahlen vorgesehen. Ich wollte etwa 100 Aufgaben eingeben (diese hier hat übrigens chatGPT erstellt) um Abwechslung reinzubringen. Mir ist keine einfache Möglichkeit eingefallen, wie ich diese Zahlen jeweils variieren könnte. Der Rechnung ist jeweils eine andere und dieser Rechenweg müsste ja auch in den Datensatz. Habt ihr da eine geniale Idee?
Übrigens: Eine Betaversion meines Rechentrainers (an dem ihr ja kräftig mitgearbeitet habt) ist unter "rt.uber.space" zu finden.
Grüße aus Ibiza!
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 18:30
von __blackjack__
Die Aufgabe in der Grafik ist nicht wirklich lösbar. Man weiss weder ob sie bereits Taschengeld bekommen hat, noch wie oft, oder ob das Weihnachtsgeld von Oma noch vorhanden ist, oder wie das mit Schulden beim Drogendealer auf dem Spielplatz gegenüber der Schule aussieht.

Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 18:32
von Pitwheazle
Danke für den Hinweis - chatGPT fand die Aufgabe sinnvoll

Gefällt es dir so besser?
Eine Schülerin hat 20€ gespart. Sie möchte sich einen neuen Pullover kaufen, der 25€ kostet. Wie viel Geld fehlt ihr noch?
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 19:29
von nezzcarth
Pitwheazle hat geschrieben:
Mir ist keine einfache Möglichkeit eingefallen, wie ich diese Zahlen jeweils variieren könnte. Der Rechnung ist jeweils eine andere und dieser Rechenweg müsste ja auch in den Datensatz. Habt ihr da eine geniale Idee?
Eher nicht "genial", aber mal zur Inspiration. Um so flexibler man das halten möchte, um so komplizierter wird es natürlich:
Code: Alles auswählen
In [1]: from random import choice
In [2]: text = "{name} hat {a}€ gespart und möchte sich für {b}€ {item} kaufen. Wie viel Geld fehlt noch?"
In [3]: question = {'template':text, 'a':(5,10,15,20), 'b':(30,40,50), 'name':('Anna', 'Bernd', 'Claudia', 'David'), 'item':('eine neue Hose', 'eine neue Jacke', 'ein neues T-Shirt')}
In [4]: def get_exercise(question):
...: items = {key:choice(values) for key, values in question.items() if key != 'template'}
...: expected_result = items['b'] - items['a']
...: text = question['template'].format(**items)
...: return text, expected_result
...:
In [5]: get_exercise(question)
Out[5]:
('Bernd hat 15€ gespart und möchte sich für 50€ ein neues T-Shirt kaufen. Wie viel Geld fehlt noch?',
35)
In [6]: get_exercise(question)
Out[6]:
('Anna hat 5€ gespart und möchte sich für 50€ eine neue Jacke kaufen. Wie viel Geld fehlt noch?',
45)
In [7]: get_exercise(question)
Out[7]:
('David hat 5€ gespart und möchte sich für 30€ ein neues T-Shirt kaufen. Wie viel Geld fehlt noch?',
25)
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 19:36
von Pitwheazle
Vielen Dank für die Mühe. Sowas hatte ich schon. Aber das ist meines Erachtens zu einseitig. In einem view kann ich das auch. Ich möchte halt gerne innerhalb meiner in der Datenbank gespeicherten Texte, verschiedene Möglichkeiten (Zahlenwerte) speichern. Müsste dann aber auch die unterschiedlichen Rechenoperationen irgendwie mit abspeichern - wahrscheinlich gibt es da keine einfache, oder besser einfach realisierbare, Möglichkeit.
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 19:52
von Pitwheazle
Als Nachtrag:
Ich habe schon mal drei verschiedene Aufgaben konstruiert. Das ist mir aber zuviel Code für gerade mal drei Aufgaben:
Code: Alles auswählen
def schul_artikel(): # wird von Sachaufgaben aus aufgerufen
artikel_liste = ["ein Lineal", "ein neues Geodreieck", "ein neues Mäppchen", "Buntstifte", "Filzstifte", "einen Zeichenblock", "einen Taschenrechner", ]
preis_liste = [8,8, 10, 5, 5, 4, 10]
wahl = random.randint(0,6)
if preis_liste[wahl] == 8:
preis = random.randint(preis_liste[wahl],2*preis_liste[wahl])/10
else:
preis = random.randint(preis_liste[wahl],2*preis_liste[wahl])
artikel = artikel_liste[wahl] + " für " + format_zahl(preis) + "€"
return wahl, artikel, preis
def sachaufgaben(jg = 5, stufe = 3, aufgnr = 0, typ_anf = 0, typ_end = 0, typ = 0, typ2 = 0, optionen = "", eingabe = "", lsg = ""):
...
if typ == 1 : # Wechselgeld
titel = "Wechselgeld"
NOTES = [2, 5, 10, 20, 50, 100]
zahl1 = random.randint(5, 5950)/100
start = 0
while True:
if NOTES[start] > zahl1:
break
start += 1
zahl2 = (random.choice(NOTES[start:]))
if zahl2 != 2:
art = "Schein"
else:
art = "Stück"
text = "Du hast für {}€ eingekauft und bezahlst mit einem {}€ {}.<br> Wieviel Wechselgeld erhälst du?"
pro_text = "Wechselgeld: {}€- {}€"
variable = [format_zahl(zahl1,2),format_zahl(zahl2,0),art]
frage = "Wechselgeld="
einheit = "€"
erg = zahl2-zahl1
lsg = f"{format_zahl(erg)}€"
hilfe_id = 1
if typ == 2: # Seile oder Leisten aufteilen
titel = "Handwerkliches"
wahl = random.randint(0,1)
zahl1 = random.randint(1,5)*5
if wahl == 0:
zahl2 = random.randint(1, 10)
else:
zahl2 = random.randint(10, 35)/10
erg = zahl2*100//zahl1
lsg = str(int(erg))
if zahl2*100%zahl1 != 0:
anmerkung = "(Es bleibt noch etwas übrig)"
artikel = ["einem", "einer"]
teil = ["Seil", "Leiste"]
verb = ["abschneiden", "absägen"]
text = "Wie viele {}cm lange Stücke kann man von {} {}m langen {} {}?"
variable = [zahl1, artikel[wahl], str(zahl2).replace(".", ","), teil[wahl], verb[wahl]]
frage = "Es sind"
einheit = "Teile"
if typ == 3: # Einkaufen
titel = "Einkaufen"
person = ["Marius", "Lisa", "Luca", "Noah", "Marie"]
er_sie = ["er", "sie", "er", "er", "sie"]
wahl1 = random.randint(0,4)
wahl2, artikel_1, preis = schul_artikel()
summe = preis
wahl = wahl2
while wahl == wahl2:
wahl, artikel_2, preis = schul_artikel()
summe+= preis
anz_1 = random.randint(2,6)
preis_1 = random.randint(8,18)/10
summe += anz_1 * preis_1
preis_2 = preis_1
while preis_1 == preis_2:
anz_2 = random.randint(2,6)
preis_2 = random.randint(10,20)/10
summe += anz_2 * preis_2
erg=summe
lsg = f"{format_zahl(erg)}€"
anmerkung = "(Das darfst du gerne schriftlich rechnen)"
text = "{0} kauft für das neue Schuljahr {1}, {2}, {3} Hefte für je {4}€ und {5} Hefte für je {6}€.<br>Wieviel muss {0} dafür bezahlen?"
variable = [person[wahl1],artikel_1, artikel_2, anz_1, format_zahl(preis_1), anz_2, format_zahl(preis_2)]
frage = er_sie[wahl1].capitalize()+" muss"
einheit = "€ bezahlen"
return typ, typ2, titel, text, pro_text, frage, variable, einheit, anmerkung, [lsg], hilfe_id, erg, {'name':'normal'}
... nur den Typ 2 habe ich behalten.
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 19:55
von nezzcarth
Für das Generieren von natürlichem Text, der Sinn ergibt, braucht man nicht unbedingt eine KI, aber auch klassische Verfahren zur computergestützten Textgenerierung sind sehr kompliziert. Daher bietet sich meiner Meinung nach für den Hausgebrauch eigentlich nur so eine "Lückentext"-Variante an. Die gezeigte Herangehensweise, bei der Logik und Inhalt getrennt sind, lässt sich in der Form so in einem JSON-Feld in Django abbilden und ist auch noch stärker parametrisierbar. Mit etwas zusätzlicher Arbeit sind auch andere Operationen und komplexere Rechenwege machbar. Es ist auch denkbar, die Aufgaben nur vorzugenerieren und dann in die Datenbank einzuspeisen. Letztendlich hast du natürlich recht, dass eine gewisse Wiederholung bleibt. Ich denke aber schon, dass man mit etwas Arbeit da trotzdem einiges erreichen kann.
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Montag 20. März 2023, 21:20
von sparrow
Das würde ich ehrlich gesagt gar nicht so tun. Und zwar aus dem selben Grund, aus dem ich auch die Dezimaltrennzeichen nicht von Hand ändern würde: Internationalisiebarkeit.
Wenn man so einen großen Aufwand treibt Sätze in einer bestimmten Sprache zu randomisieren, macht man sich eine mögliche Internationalisierung unnötig schwer. Ja ich weiß, ist nicht geplant. Trotzdem muss man sich das ja nicht um jeden Preis verbauen. In anderen Sprachräumen lernen Menschen ja durchaus auch Mathematik und da von vornherein einzuschränken, empfinde ich als verlorene Chance.
"Wie viele Stücke kann man von der Leiste abschneiden" und "Wie viele Stücke kann man von dem Seil abschneiden" wären für mich zwei verschiedene Fragen. Wenn man unbedingt Varianten bilden möchte, dann muss man die in der Datenbank als verschiedene Varianten der selben Frage abbilden. Wo wir schon bei dem nächsten Punkt sind:
Ich finde nicht, dass diese Aufgaben in den Quelltext gehören. Das sind für mich Objekte, die in die Datenbank gehören und dort gepflegt werden sollten.
Der simpelste Fall: Man pflegt die verwendeten Variablen und deren Typ und ggf. die Range, die Frage, die Antwort und die Formel um die Antwort zu berechnen.
Variablen: a: INT 1 - 10, b INT (10, 20, 50, 100)
Frage: "Du hast für {a}€ eingekauft und bezahlst mit einem {b}€ Schein.<br> Wieviel Wechselgeld erhälst du?"
Antwort: "Ich erhalte ____ €"
Formel: b - a
Zum Evaluieren von Formeln gibt es Module, die das sicher können (
das hier scheint so eins zu sein).
Die Deklaration und das Auswürfelnd der Variablen ist sicher spanennd.
Und möglicherweise gibt es Fälle, die nicht so simpel abzubilden sind - aber wie gesagt: Ich sehe die Aufgaben nicht im Code,
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 12:37
von Pitwheazle
sparrow hat geschrieben: Montag 20. März 2023, 21:20
Ich finde nicht, dass diese Aufgaben in den Quelltext gehören. Das sind für mich Objekte, die in die Datenbank gehören und dort gepflegt werden sollten.
Genau das ist ja der Inhalt meines Posts
Geht euch das auch manchmal so, dass ihr nachts aufwacht und eine Idee habt und denkt: So müsste es gehen. Ich werde jetzt einfach ein weiteres jsonFeld einfügen und dort Varaiblen speichern und in einem weiteren Feld einen Lösungsweg und dieses im view auswerten und dort auch das erwartete Ergebnis berechnen. Mal sehen, ob das so klappt.
sparrow hat geschrieben: Montag 20. März 2023, 21:20
Das würde ich ehrlich gesagt gar nicht so tun. Und zwar aus dem selben Grund, aus dem ich auch die Dezimaltrennzeichen nicht von Hand ändern würde: Internationalisiebarkeit.
Nach deinem Hinweis habe ich, soweit ich das hinbekommen habe, die Lokalisierung angewendet.... aber wie gesagt, soweit ich das hinbekommen habe. Jetzt in den Textaufgaben macht es aber doch nicht wirklich Sinn, dass ich die Geldbeträge mit Punkt trenne - oder würdest du das auch noch machen?
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 14:52
von Kebap
> Geht euch das auch manchmal so, dass ihr nachts aufwacht und eine Idee habt
Dauernd. Schwieriger ist, sich morgens noch dran zu erinnern. Daher immer Stift + Zettel parat halten..

Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 14:59
von __blackjack__
Oder auf'm Smartphone als Audio aufnehmen. Ich hätte sonst nämlich das Probleme das verschlagene Geschreibsel aus der Nacht am nächsten Morgen zu entziffern.

Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 15:04
von Pitwheazle
Oh Mann! Natürlich bekomme ich es nicht alleine hin!
Also, ich habe ein JSONField ergänzt:
Code: Alles auswählen
class Sachaufgabe(models.Model):
..
variable = models.JSONField(default=[])
loe_weg = models.CharField(max_length=10)
..
... und gehe davon aus, dass man in diesem eine Liste speichern kann. Wenn ich das richtige sehe, muss ich diese aber als String speichern ( anders bekomme ich eine Fehlermeldung).
Der Aufgabentext:
"Wie viele {}cm lange Stücke kann man von einer {}m langen Leiste absägen?"
und im JSONField "variable":
"[[5,10,15,20,25];[1,1.2,1.5,2,2.5]]"
Wenn ich jetzt versuche, z.B. die "5" auszulesen, scheint der Inhalt eine String zu sein (nun ja, ist ja auch einer).
Code: Alles auswählen
aufgabe = Sachaufgabe.objects.get(lfd_nr = typ)
print(aufgabe.text)
variable=aufgabe.variable
print(variable)
a=variable[2]
print(a)
liefert
und
führt zu einem Fehler.
Ich habe mich in der Dokumentation und in Foren umgetan, finde aber immer nur Beispiele für dicts. Geht das mit Listen nicht oder mache ich was falsch?
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 15:12
von __blackjack__
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]]")
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 ',' delimiter: line 1 column 17 (char 16)
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 16:44
von Pitwheazle
__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]]")
Mann, Mann! Das war' schon? Ich habe den Eintrag direkt im Admin Bereich eingegeben.
... nur, mit Komma statt Semikolon will er auch nicht und meldet:
Code: Alles auswählen
WARNINGS:
core.Sachaufgabe.variable: (fields.E010) JSONField default should be a callable instead of an instance so that it's not shared between all field instances.
HINT: Use a callable instead, e.g., use `dict` instead of `{}`.
... heißt das, Liste geht nicht? Und warum "use `dict` instead of `{}"? Ich habe doch gar kein "{}" eingegeben sondern "[]".
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 17:00
von grubenfox
Liste geht...
Code: Alles auswählen
>>> json.dumps([[5,10,15,20,25],[1,1.2,1.5,2,2.5]])
'[[5, 10, 15, 20, 25], [1, 1.2, 1.5, 2, 2.5]]'
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 17:05
von Pitwheazle
grubenfox hat geschrieben: Dienstag 21. März 2023, 17:00
Liste geht...
Kannst du mir da bitte noch etwas auf die Sprünge helfen? Wahrscheinlich trage ich das falsch ein:

Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 17:35
von __blackjack__
@Pitwheazle: Du hast da als `default` eine Liste angegeben, die Fehlermeldung sagt Dir aber das dort etwas *aufrufbares* erwartet wird. Und `dict()` statt `{}` war dann ein *Beispiel*. „e.g.“ („exempli gratia“ („for example“)) ist auf Deutsch „z.B.“. Wenn Du also dort eine Liste haben möchtest, dann `list` statt `dict`.
Bei dem Beispiel sind die " zu viel, denn die machen aus der Liste eine Zeichenkette, die eine Liste enthält, beziehungsweise bei JSON eine Zeichenkette, die ein Array enthält.
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 18:01
von Pitwheazle
Ok Danke, Das mit dem "e.g" hatte ich sogar kapiert, nicht aber dass ich "list()" als Text eingeben soll anstelle von "[ ]". "Aufrufbar" heißt in diesem Zusammenhang also "kein String" sondern "dict" oder nun mal "list" und das geht anscheinend nicht mit "{ }" bzw. "[ ]". Diese defaults haben demnach keine wirkliche Funktion sondern erzeugen ein String mit "{ }" bzw. "[ ]"?
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 18:22
von Pitwheazle
Jetzt werde ich übermütig:
jetzt wird mir mit:
text:
Code: Alles auswählen
"Wie viele {}cm lange Stücke kann man von einer {}m langen Leiste absägen?"
variable:
und
Code: Alles auswählen
variable=aufgabe.variable
a=variable[0][0]
b=variable[1][0]
text = aufgabe.text.format(a,b)
tatsächlich:
"Wie viele 5cm lange Stücke kann man von einer 1m langen Leiste absägen?"
angezeigt!
Das "JS" in "JSON" steht ja für JavaScipt. Wenn ich jetzt in einem weiteren JSONField einen Pythoncode abspeichern und im View nutzen könnte wäre das genial. Also in dem Fall "ergebnis=100*a/b". Ich finde nichts dass das gehen könnte (ich finde ja aber auch anderes nicht

).
Re: gesucht wird eine kreative Methode um Sachaufgaben zu erstellen
Verfasst: Dienstag 21. März 2023, 18:45
von nezzcarth
Pitwheazle hat geschrieben: Dienstag 21. März 2023, 18:22
Also in dem Fall "ergebnis=100*a/b". Ich finde nichts dass das gehen könnte (ich finde ja aber auch anderes nicht

).
In dem Ansatz, den sparrow und ich vorgeschlagen hatten, wandert alles in die Datenbank und im eigentlichen Code bleibt nur eine generalisierte Verarbeitungslogik übrig.
Das, wonach du fragst würde jedoch ein massives Sicherheitsproblem darstellen. Du hast in einem der vorherigen Posts jedoch schon einen Vorschlag inkl. Module bekommen, wie man das eher lösen würde (mit einer Bibliothek, die Formeln auswerten kann).