Text aus Datenbankfeld mit Variablen aus anderem Feld ergänzen

Django, Flask, Bottle, WSGI, CGI…
Antworten
Pitwheazle
User
Beiträge: 896
Registriert: Sonntag 19. September 2021, 09:40

Ich habe in meinem "Rechentrainer" Projekt, das hier ja wohl zwischenzeitlich jeder kennt, die Grundstruktur, die mir @whitie dankenwerterweise gebastelt hat übernommen. Für jede einzelne Frage wird ein Eintrag in einer Datenbanktabelle erzeugt, bei mir heißt sie "Protokoll". Da steht unter anderem der Aufgabentext und u.U. auch ein Hilfetext drin. Ich habe mir überlegt, dass es sinnvoll sei, wenn ich diese Aufgabentexte und Hilfetexte in jeweils eigenen Datenbankeinträgen speichere. Ansonsten wird ja für hunderte von Nutzern und Tausenden von Aufgaben der immer gleiche Text in dieser Protokolldatei gespeichert. Für einfache Hilfetexte ist es mir auch schon gelungen, den Hilfetext aus dieser Datei in der entsprechenden Aufgabe anzuzeigen und auch mit dem Protokoll zu verknüpfen. Also zum Beispiel beim Zahlenstrahl mit Brüchen: "Um den Vorgänger auszurechnen musst du 1 subtrahieren.". Viele Hilfetexte und alle Aufgaben werden aber mit zufälligen Variablen erstellt, meistens aus zweien, manchmal aber auch mehreren. Als Beispiel für ein Hilfetext zum Multiplizieren mit Zehnerpotenzen: "Mal {0} heißt, dass die Zahl {1} um {2} Stelle(n) größer wird.".format(zahl2,zahl1, exp)". Meine Überlegung ist jetzt, dass ich den Textteil in der Hilfe- bzw. Aufgabetext-Datenbank speichere und die Variablen in der Protokolldatei (jsonfield?). Leider habe ich aber keine rechte Idee, wie ich die dann wieder zusammenführe - oder geht das gar nicht - oder ist es sogar eine blöde Idee?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Grundsaetzlich ist das schon eine gute Idee. Wobei ich mir nicht so sicher bin, ob fuer die Texte eine Datenbank der richtige Ansatz ist. Die sind ja im Grunde Code. Soll heissen: ohne entsprechenden Code fuer den Aufgabentyp etc. kannst du noch so viele Eintraege in der DB haben, eine neue Aufgabe ergibt sich nicht.

Darum haette ich die jetzt einfach in einer Python-Datenstruktur definiert.

Genutzt wird das dann mit format, zB so:

Code: Alles auswählen

parameter = [100, 13.56, 2]
dein_text_von_oben.format(*parameter) # der * ist wichtig, weil das dann Argumente an format werden!
Pitwheazle
User
Beiträge: 896
Registriert: Sonntag 19. September 2021, 09:40

Prima, das hilft mir doch schon weiter.
Ich habe jetzt in der Datei "Hilfe" den Text "{0} + {1} = {2}.format(*)" und im Protokoll die Liste [zahl1, zahl2, zahl1+zahl2] und bekomme im view mit

Code: Alles auswählen

print(hilfe.text) 
print(protokoll.parameter) 
wunderbar

({0} + {1} = {2}.format(*)
[66, 67, 133]"

angezeigt
wie bekomme ich jetzt die Parameter in die Klammer hinter*?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

hilfe.text(*protokoll.parameter)
Pitwheazle
User
Beiträge: 896
Registriert: Sonntag 19. September 2021, 09:40

Noch nicht ganz:

Code: Alles auswählen

    print(hilfe.text)
    print(protokoll.parameter)    
    return HttpResponse(hilfe.text(*protokoll.parameter))
ergibt:
{0} + {1} = {2}.format
['79', '16', '95']
Internal Server Error: /hilfe/1/67/
... für die letzte Zeile wird der Fehler: "'str' object is not callable" angezeigt

Ich habe die Variablen "zahl1", Zahl2" und "zahl1+zahl2" jetzt in Strings umgewandelt, das hilft aber auch nicht.

Nachtrag: Ich habe es mal mit:

Code: Alles auswählen

    neuertext=hilfe.text + "(*" + protokoll.parameter[0] + "," + protokoll.parameter[1] + "," + protokoll.parameter[2] + ")"  
    return HttpResponse(neuertext)
probiert, das ergibt:
{0} + {1} = {2}.format(*79,16,95)
... das kann es ja aber wohl nicht sein.

Das hängt ja wohl mit:
# der * ist wichtig, weil das dann Argumente an format werden!
zusammen

In der python Docu finde ich nur:
>>> '{2}, {1}, {0}'.format(*'abc') # unpacking argument sequence
'c, b, a'
... bringt mich das weiter?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eh, mein Fehler. Es haette natuerlich

Code: Alles auswählen

hilfe.text.format(*parameter)


sein sollen.
Pitwheazle
User
Beiträge: 896
Registriert: Sonntag 19. September 2021, 09:40

Das funktioniert, musst du mir aber trotzdem erkläeren. Woher kommt der Inhalt von "parameter" wenn ich nicht "protokoll.parameter" eingebe?
Ich habe jetzt das ganze geändert in:

Code: Alles auswählen

   
    parameter = (protokoll.parameter) 
    return HttpResponse(hilfe.text.format(*parameter))
... und bekomme tatsächlich:
40 + 38 = 78
aber ohne "parameter = (protokoll.parameter) " geht das nicht - oder?

Aber nochmal zurück zu deinem Hinweis:
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 13:24 Grundsaetzlich ist das schon eine gute Idee. Wobei ich mir nicht so sicher bin, ob fuer die Texte eine Datenbank der richtige Ansatz ist. Die sind ja im Grunde Code. Soll heissen: ohne entsprechenden Code fuer den Aufgabentyp etc. kannst du noch so viele Eintraege in der DB haben, eine neue Aufgabe ergibt sich nicht.
... dass ich "{} + {} =" in einer eigenen Tabelle speichere anstelle der Tabelle "Protokoll", macht sicher nicht so viel Sinn. Die Texte sind bei anderen Aufgaben aber oft länger, z.B. bei der Wahrscheinlichkeitsrechnung. Und auch die Hilfetexte sind, wenn vorhanden, oft sehr lang, wie z.B.

"Geteilt durch {0} heißt, dass die Zahl {1} um {2} Stelle(n) kleiner wird.".format(zahl2,zahl1, exp).replace(".", ",")"<br>Du musst also das Komma um {0} Stelle(n) nach links verschieben <br>(und unter Umständen noch Nullen ergänzen).".format(exp)<br>(Ja, stimmt, es ist kein Komma da - du musst es dir hinter der {zahl1} denken"

... der wurden bisher für jeden Nutzer und jede Aufgabe im Protokoll gespeichert und ich kann mir vorstellen, dass die Menge an Daten nach der Umstellung um einiges kleiner wird.
Und das mit den verschiedenen Aufgaben klappt doch. Ich muss halt jetzt nur die Texte einzeln in die Datenbank einpflegen, anstelle sie im Code zu speichern und erstelle nur die Parameter dazu im Code. Oder übersehe ich da was?
Ich muss allerdings noch sagen, dass ich bisher noch nie ein Projekt ins Internet gebracht habe und weder Vorstellung von der Mächtigkeit der Datenbanken noch von der Performance Ahnung habe.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sind nur Fluechtigkeitsfehler meinerseits. Ich kann das ja nicht testen, bzw das ist Aufwand. Worum es geht ist, dass du format auf einem String aufrufen musst, mit einer Liste. Ob die nun parameter heisst, oder ding.bums.dicke_liste, ist ja egal.

Deine Ueberlegung in Bezug auf die Laenge zweifele ich nicht an. Nur darauf, dass das *ueberhaupt* in der Datenbank sein muss. Denn es ist ja nicht wirklich einfacher, die Datenbank zu pflegen, insbesondere synchron zum Code. Wenn du jetzt einen neuen Aufgabentyp definierst, und der braucht diesen Text, aber hat natuerlich auch Code, dann ist die getrennte Verwaltung doch muehseliger als notwendig. Eine simple Python-Struktur, welche die Aufgabenart auf den Text abbildet wuerde in meinen Augen reichen.
Pitwheazle
User
Beiträge: 896
Registriert: Sonntag 19. September 2021, 09:40

__deets__ hat geschrieben: Freitag 21. Oktober 2022, 18:01 Das sind nur Fluechtigkeitsfehler meinerseits. Ich kann das ja nicht testen, bzw das ist Aufwand. Worum es geht ist, dass du format auf einem String aufrufen musst, mit einer Liste. Ob die nun parameter heisst, oder ding.bums.dicke_liste, ist ja egal.
Es ging ja nicht um Benennungen. Ich wollte wissen, warum
__deets__ hat geschrieben: Freitag 21. Oktober 2022, 16:11

Code: Alles auswählen

hilfe.text(*protokoll.parameter)
nicht funktioniert hat,

Code: Alles auswählen

parameter = (protokoll.parameter) 
return HttpResponse(hilfe.text.format(*parameter))
aber schon. Und wenn ich genau hingesehen hätte, wäre mir das "format" aufgefallen. :oops:
Danke!
Antworten