Ist Django für mein Projekt geeignet?
In dem Fall würde ich sagen, dass sich die Klassenstufe nicht aus der Klassenbezeichnung zwangsläufig ableiten lässt. Und das würde bedeuten, dass beides voneinander getrennt ins Model gehört einmal der Name, einmal auswählbar die Klassenstufe.
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
gelöscht
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Hallo, da bin ich wieder mal. Es wäre schön, wenn ihr mir wieder weiterhelfen könntet:
Um den Code, den @whitie in 1 1/2 Stunden aufgesetzt hat, (größtenteils) nachzuvollziehen, habe ich jetzt 1 1/2 Monate gebraucht (manchmal zwei Tage für eine Zeile) und wollte jetzt mal drangehen, meine Aufgaben zu programmieren.
Die URL
ruft den view
(von Whitie) auf.
Für die Zeile "low, high, result = make_zahl(modul_id)" brauche ich jetzt eine Verzweigung für meine 35 Aufgabenarten. Es gibt doch sicher eine elegantere Verzweigungsmöglichkeit als "if modul_id==1: ...., elif ... elif ... ". Ich denke ja an 35 Funktionen (die könnte ich im Editor auch einklappen um den Code übersichtlicher zu halten). Wie rufe ich aber jetzt 35 verschiedene Funktionen möglichst elegant auf?
Um den Code, den @whitie in 1 1/2 Stunden aufgesetzt hat, (größtenteils) nachzuvollziehen, habe ich jetzt 1 1/2 Monate gebraucht (manchmal zwei Tage für eine Zeile) und wollte jetzt mal drangehen, meine Aufgaben zu programmieren.
Die URL
Code: Alles auswählen
path('modul/<int:modul_id>/', views.aufgabe, name='modul'),
Code: Alles auswählen
def aufgabe(req, modul_id):
modul = get_object_or_404(Kategorie, pk=modul_id)
if req.method == 'POST':
daten = Daten.objects.get(pk=req.session.get('eingabe_id'))
daten.tries += 1
form = AufgabeFormZahl(req.POST)
right=daten.value
if form.is_valid():
if check_str(form.cleaned_data['eingabe'], right):
daten.eingabe=form.cleaned_data['eingabe']
daten.bearbeitungszeit=(timezone.now() - daten.start).total_seconds()
daten.save()
min, sec = divmod(daten.bearbeitungszeit, 60)
msg = f'Zeit: {int(min)}min {int(sec)}s'
messages.info(req, f'Richtig! Versuche: {daten.tries}, {msg}')
return redirect('modul', modul_id)
messages.info(req, 'Leider falsch.')
daten.eingabe=form.cleaned_data['eingabe']
daten.save()
text = daten.text
else:
frage = Frage.objects.filter(
kategorie=modul
).order_by('?').first()
form = AufgabeFormZahl()
low, high, result = make_zahl(modul_id)
text = frage.text.format(low=low, high=high)
daten = Daten.objects.create(
user=get_fake_user(), kategorie=modul, text=text, value=result, loesung=str(result)
)
req.session['eingabe_id'] = daten.id
context = dict(category=modul, text=text, aufgabe=aufgabe, form=form)
return render(req, 'core/aufgabe.html', context)
Für die Zeile "low, high, result = make_zahl(modul_id)" brauche ich jetzt eine Verzweigung für meine 35 Aufgabenarten. Es gibt doch sicher eine elegantere Verzweigungsmöglichkeit als "if modul_id==1: ...., elif ... elif ... ". Ich denke ja an 35 Funktionen (die könnte ich im Editor auch einklappen um den Code übersichtlicher zu halten). Wie rufe ich aber jetzt 35 verschiedene Funktionen möglichst elegant auf?
Elegant wäre, statt einer modul_id einen sprechenden Namen zu haben und dann ein Wörterbuch zu benutzen.
Code: Alles auswählen
def addition():
return "was ist 3+4?", 7
def multiplikation():
return "was ist 5*5?", 25
AUFGABEN = {
"addition": addition,
"multiplikation": multiplikation,
}
def aufgabe(modul_id):
return AUFGABEN[modul_id]()
def main():
text, loesung = aufgabe("multiplikation")
if float(input(text)) == loesung:
print("richtig")
else:
print("falsch")
if __name__ == "__main__":
main()
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Hallo @Sirius3,
vielen Dank für die blitzschnelle Antwort. Kannst du da einem blutigen Anfänger bitte noch etwas weiterhelfen?
Also die ersten zwei Funktionen sind klar, das sind Funktionen, die entweder eine Additions- oder Multiplikationsaufgabe erstellen.
Dann kommt das Wörterbuch mit meinen 35 Aufgabentypen.
Die dritte Funktion wird von der URL aufgerufen und ordnet der modul_id einen Namen zu, das ist schon mal prima.
Aber dann verließen sie ihn.
Die vierte Funktion erzeugt eine Multiplikationsaufgabe und überprüft die Eingabe. ... und wo kommt die Verzweigung zum Tragen?
vielen Dank für die blitzschnelle Antwort. Kannst du da einem blutigen Anfänger bitte noch etwas weiterhelfen?
Also die ersten zwei Funktionen sind klar, das sind Funktionen, die entweder eine Additions- oder Multiplikationsaufgabe erstellen.
Dann kommt das Wörterbuch mit meinen 35 Aufgabentypen.
Die dritte Funktion wird von der URL aufgerufen und ordnet der modul_id einen Namen zu, das ist schon mal prima.
Aber dann verließen sie ihn.
Die vierte Funktion erzeugt eine Multiplikationsaufgabe und überprüft die Eingabe. ... und wo kommt die Verzweigung zum Tragen?
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Das mit dem Wörterbuch habe ich verstanden. Ich tue mich aber immer noch schwer mich in den Rest einzudenken und erkenne noch nicht wie bzw. wo genau die Funktionen "addition" bzw. "multiplikation" aufgerufen werden. Könnt ihr mir das bitte Schritt für Schritt aufzeigen?
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Danke, wahrscheinlich muss ich das jetzt mal ausprobieren.
Mich verwirrt, dass in def main() ... "multiplikation" steht. Wie komme ich an "addition"?
Bleibt mein Pfad "path('modul/<int:modul_id>/', views.aufgabe, name='modul')" so stehen oder muss ich den in "path('modul/<int:modul_id>/', views.main, name='modul')" ändern?
Ich hoffe ihr habt noch etwas Geduld mit mir - war bei euch der Anfang auch so schwer?
Mich verwirrt, dass in def main() ... "multiplikation" steht. Wie komme ich an "addition"?
Bleibt mein Pfad "path('modul/<int:modul_id>/', views.aufgabe, name='modul')" so stehen oder muss ich den in "path('modul/<int:modul_id>/', views.main, name='modul')" ändern?
Ich hoffe ihr habt noch etwas Geduld mit mir - war bei euch der Anfang auch so schwer?
Das ist im Beispiel ja nur illustriert. Wenn du da Addition schreibst, gibt’s eben Addition. Wenn du das per Kommandozeile angebracht machst, dann kommt’s eben daher. Und wenn es ein Teil eines URL-Pfades ist, dann eben daher. Ich bin mit Django nicht genug Perdu um da sagen auch können, ob du da was anders machen musst.
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Ah, ja, das ist wieder sehr erhellend. Ich muss also eine Möglichkeit finden, dieses "multiplikation" dynamisch mit der "modul_id" zu ersetzen. Das müsste ja, glaube ich, auch mit dem Key des Wörterbuchs gehen.
Und wofür dient das "if __name__ == "__main__":" in deinem Beispiel? Ich habe es in mehreren Tutorien und Erläuterungen gefunden, diese gelesen, in englisch und in deutsch - ich habe es aber immer noch nicht kapiert. (Zum Beispiel hier https://www.data-science-architect.de/__name____main__/ - da hat sich Andreas Wygrabek echt Mühe gegeben). Vielleicht hilft es mir, wenn du es hier konkret am Beispiel erklärst.
Und wofür dient das "if __name__ == "__main__":" in deinem Beispiel? Ich habe es in mehreren Tutorien und Erläuterungen gefunden, diese gelesen, in englisch und in deutsch - ich habe es aber immer noch nicht kapiert. (Zum Beispiel hier https://www.data-science-architect.de/__name____main__/ - da hat sich Andreas Wygrabek echt Mühe gegeben). Vielleicht hilft es mir, wenn du es hier konkret am Beispiel erklärst.
Wenn du bei deiner ID bleiben willst, z. B.:
Wenn du es etwas sprechender magst:
Dazu muss das Model natürlich ein Attribut name haben und das sollte unique=True haben.
Viele Grüße
Whitie
Code: Alles auswählen
def addition():
return "was ist 3+4?", 7
def multiplikation():
return "was ist 5*5?", 25
AUFGABEN = {
1: addition,
2: multiplikation,
}
Code: Alles auswählen
path('modul/<modul_name>/', views.aufgabe, name='modul')
def aufgabe(req, modul_name):
modul = get_object_or_404(Kategorie, name=modul_name)
...
Viele Grüße
Whitie
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Das mit dem unique=True muss ich erst noch verarbeiten.
Aber ohne dich würde ich drüber nachdenken, ob ich anstelle von meinem Ringen mit Python doch lieber endlich mal damit anfangen sollte meine Socken zu stopfen (das Projekt wartet auch noch auf mich,)
Aber ohne dich würde ich drüber nachdenken, ob ich anstelle von meinem Ringen mit Python doch lieber endlich mal damit anfangen sollte meine Socken zu stopfen (das Projekt wartet auch noch auf mich,)
Das unique bedeutet nur, dass die Datenbank schon darauf achtet, dass der Name einmalig ist. Da der Name gleichzeitig ein Schlüssel im Wörterbuch ist, sollte das auf jeden Fall so sein. Man könnte dann den Namen auch als Primärschlüssel nutzen, ich lasse aber immer die ID als numerischen Primärschlüssel.
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Hurra, das funktioniert!
Jetzt bin ich übermütig geworden und habe in meine Tabelle "Kategorie" ein Feld "function" eingefügt und dort z.B. den Wert "subtrahieren" eingetragen
und durch
ersetzt. Das funktioniert nicht ("'str' object is not callable"). Wo ist mein Denkfehler?
Code: Alles auswählen
AUFGABEN = {
1: ergaenzen,
2: addieren,
3: subtrahieren,
}
def aufgabenstellung(modul_id):
return AUFGABEN[modul_id]()
def aufgabe(req, modul_id):
modul = get_object_or_404(Kategorie, pk=modul_id)
...
low, high, result =aufgabenstellung(modul_id)
und
Code: Alles auswählen
low, high, result =aufgabenstellung(modul_id)
Code: Alles auswählen
low, high, result =modul.function()
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
OK, also ersetzt das Dictonary nicht nur meinen Wert in einen String sondern ist explizit dafür, da eine Funktion aufzurufen?
Nun gut, das hätte mir ansonsten 37 Zeilen Code erspart.
Nun gut, das hätte mir ansonsten 37 Zeilen Code erspart.
Es bildet die Werte (zahlen oder strings kannst du dir aussuchen) auf ein Funktionsobjekt ab.
eine_funktion
Ist keine String. Gib dir das mal mir print aus, zb
print(print) # man beachte die fehlenden inneren Klammern
Du kannst solche Objekte dann einfach aufrufen. Siehe zb
eine_funktion
Ist keine String. Gib dir das mal mir print aus, zb
print(print) # man beachte die fehlenden inneren Klammern
Du kannst solche Objekte dann einfach aufrufen. Siehe zb
Code: Alles auswählen
magie = print # schon wieder keine Klammern
magie('Ups, was passiert hier?')
-
- User
- Beiträge: 1053
- Registriert: Sonntag 19. September 2021, 09:40
Nun, ja, hätte ja klappen können, dass man durch Anhängen von () aus einem string einen Funktionsaufruf machen kann.