replace()

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

Ich habe zwar dran gedacht, aber auch das mal wieder vergessen. Zum Schuljahrwechsel muss der Jahrgang der Schülerinnen und Schüler um eins hochgesetzt werden - das kann ich. Ich wollte aber jetzt, wenn im Namen der Klasse der Jahrgang angegeben ist (das ist er normalerweise) auch hier die Bezeichnung ändern. In meinem jugendlichen Leichtsinn, wollte ich das einfach so ändern:

Code: Alles auswählen

def update(req):
    auswahl = Profil.objects.filter(user__date_joined__lt=date(2023,8,1))
    print("Teil: ",auswahl.count())    
    for a in auswahl:
        if a.jg <= 13:
            if str(a.jg) in a.klasse:
                print(a.klasse)
                a.klasse = a.klasse.replace(str(a.jg), str(a.jg+1))
            a.jg +=1
            print(a, "neuer_Jg: ", a.jg, ",  neue Klasse:", a.klasse)
Der Code findet die entsprechenden Klassenbezeichnungen, ändert sie aber nicht. Muss ich hier wirklich alle Möglichkeiten einzeln abfragen oder geht das auch so irgendwie?
nezzcarth
User
Beiträge: 1636
Registriert: Samstag 16. April 2011, 12:47

Ich persönlich müsste glaube ich bitte zusätzlich die Klasse sehen, von der "a" eine Instanz ist, um etwas dazu sagen zu können. Ich glaube übrigens auch, wenn ich nichts übersehen, dass der Code, so wie er jetzt geschrieben ist, auch eine 14. Jahrgangsstufe ermöglicht (?).
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Und auch hier wäre es wieder angebracht, das einfach mal interaktiv zu testen:

Code: Alles auswählen

In [1]: jg = 8

In [2]: klasse = "8b"

In [3]: if str(jg) in klasse:
   ...:     klasse = klasse.replace(str(jg), str(jg+1))
   ...: 

In [4]: klasse
Out[4]: '9b'
Wie Du siehst, funktioniert Dein Code einwandfrei, es muß also irgendwo anders das Problem liegen.

Also, woran erkennst Du, dass es ein Problem gibt? Wie sieht der Input aus, wie der Output?
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Danke! So geht es:

Code: Alles auswählen

    for a in auswahl:
        if a.jg < 13:
            if str(a.jg) in a.klasse:
                print(a.klasse)
                alt = str(a.jg)
                neu = str(a.jg+1)
                a.klasse = a.klasse.replace(alt, neu,1)
            a.jg +=1
            print(a, "neuer_Jg: ", a.jg, 
Jetzt muss ich, wenn ich die Grundschule berücksichtige, nur noch verhindern, dass aus Klasse '10.2" die Klasse "20.3" wird.
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Kann man, wenn man in JG 11 ist, in einer Klasse mit dem Namen „5c“ sein? Wenn nicht: Warum wird der Jahrgang im Klassennamen dupliziert? IMHO wäre es einfacher, den Klassennamen dynamisch aus JG und Buchstaben (bzw. was es da sonst noch gibt) zusammenzubauen. Und den JG dementsprechend in der DB als Ganzzahl abzuspeichern.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Man muß nicht jeden Zwischenwert an eine Variable binden, `alt` und `neu` sind überflüssig, so dass man es einfach so schreiben kann:

Code: Alles auswählen

    for a in auswahl:
        if a.jg < 13:
            if str(a.jg) in a.klasse:
                print(a.klasse)
                a.klasse = a.klasse.replace(str(a.jg), str(a.jg+1),1)
            a.jg +=1
Probleme bekommst Du ja nur bei "10.1" oder "12.2". Und wenn Du nur exakt die Zahl ersetzen willst und nicht Teile von Zahlen, dann benutze doch einfach einen einfachen regulären Ausdruck:

Code: Alles auswählen

a.klasse = re.sub(f'(?<!\d){a.jg}(?!\d)', str(a.jg + 1), a.klasse)
Wenn Du einfach so Daten eines Nutzers änderst, solltest Du zumindest beim nächsten Login fragen, ob die geänderten Daten auch korrekt sind, so dass es nicht ganz so wichtig ist, wenn in ein paar Fällen etwas schief geht.
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Sirius3 hat geschrieben: Samstag 16. September 2023, 16:30 Man muß nicht jeden Zwischenwert an eine Variable binden, `alt` und `neu` sind überflüssig, so dass man es einfach so schreiben kann:

Code: Alles auswählen

    for a in auswahl:
        if a.jg < 13:
            if str(a.jg) in a.klasse:
                print(a.klasse)
                a.klasse = a.klasse.replace(str(a.jg), str(a.jg+1),1)
            a.jg +=1
Das war ja eigentlich mein ursprünglicher Code - warum der jetzt geht wissen die Götter.
Sirius3 hat geschrieben: Samstag 16. September 2023, 16:30 Wenn Du einfach so Daten eines Nutzers änderst, solltest Du zumindest beim nächsten Login fragen, ob die geänderten Daten auch korrekt sind, so dass es nicht ganz so wichtig ist, wenn in ein paar Fällen etwas schief geht.
Ja klar, das ist so vorgesehen. Bis zum nächsten Schuljahreswechsel werde ich das auch fest einbauen.
nezzcarth
User
Beiträge: 1636
Registriert: Samstag 16. April 2011, 12:47

Pitwheazle hat geschrieben: Samstag 16. September 2023, 16:49 Das war ja eigentlich mein ursprünglicher Code - warum der jetzt geht wissen die Götter.
Ich glaube, da ist trotzdem noch Raum für Verbesserungen. Also mindestens mal bei den Namen ("a", "jg" sind keine guten Namen und entsprechen auch nicht der Konvention PEP8). Und vielleicht auch hinsichtlich dessen, was narpfel meinte. Warum wird "klasse" so relativ umständlich mit Stringprüfungen usw. zusammengebaut – Warum ist das nicht z.B. ein property der Klasse, das automatisch berechnet wird?
Antworten