chinesischer Restsatz

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
beginnertwo
User
Beiträge: 3
Registriert: Dienstag 25. August 2020, 08:21

Hallo liebe Mitglieder!

Vorweg möchte ich sagen, dass ich Anfänger bin, und daher womöglich nicht sehr elegant programmiere (dieser code ist nicht schön, mnM), bzw. evtl sehr dumme Fehler mache.

Ich habe hier einen Code, der eine Lösung des chinesischen Restsatzes in einem bestimmten Fall (für 3 kongruenzen) löst oder lösen sollte. (Nicht für den allgemeinen Fall!)

Mein Code:
def chinrest(a,b,c,d,e,f):
h1 = b*c
h2 = a*c
h3 = a*b
for i in range(1,a+1):
if (h1*i)%a == d:
sol1 = i
print(sol1)
for j in range(1,b+1):
if (h2*j)%b == e:
sol2 = j
print(sol2)
for k in range(1,c+1):
if (h3*k)%c == f:
sol3 = k
print(sol3)
return (sol1*h1 + sol2*h2 + sol3*h3) - a*b*c

a,b,c sind die Modulen und d,e,f die entsprechenden Reste.

Nun ist es so, dass diese Funktion durchaus das richtige Ergebnis in bestimmten Fällen liefert. So zum Beispiel für (3,5,7,1,2,4) oder auch (5,4,7,1,3,2). Rufe ich die Funktion jedoch mit (1,3,2,5,4,7) auf kommt eine Fehlermeldung. Und zwar:
"local variable 'sol1' referenced before assignment"

Nun verstehe ich nicht, warum diese Funktion für diese Eingabe nicht funktioniert und vor allem nicht die Fehlermeldung, denn die variable sol1 hat doch in der ersten for-schleife ihre Zuweisung bekommen.

Vielleicht kann mir jemand den Fehler erklären.
Danke
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@beginnertwo: Keine der Sonnenvariablen (`sol*`) hat einen Wert zugewiesen bekommen. Nicht nur `sol1` nicht. Das dem so ist, siehst Du an der Ausgabe, denn Du gibst da ja jede Sonne mit einem `print()` aus. Die Ausnahme tritt aber in der letzten Zeile der Funktion auf (``return …``) und davor steht *keine* Ausgabe, also wurde auch keiner der `print()`-Aufrufe ausgeführt, also auch keine der drei Sonnen definiert.

Das heisst entweder ist die jeweilige Schleife nicht durchlaufen worden weil das `range()` einen leeren Iterator geliefert hat, oder die Bedingung in dem ``if`` traf nicht zu. Warum gehst Du davon aus, das beides nicht passieren könnte?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
beginnertwo
User
Beiträge: 3
Registriert: Dienstag 25. August 2020, 08:21

Erstmal danke _blackjack_

Ich bin davon nicht ausgegangen, weil ich dachte, dass diese Bedingungen in diesem Fall immer erfüllt werden können, weil die Modulen a,b,c in eben diesem Beispiel(1,3,2) paarweise teilerfremd sind.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie soll denn eine Zahl modulo 1 jemals den Wert 5 annehmen können?

def calc_residual(h, a, d):
if a <= d:
raise ValueError("a must be larger than d")
for i in range(1, a+1):
if (h * i) % a == d:
return i
assert False, "not possible"

def chinrest(a,b,c,d,e,f):
h1 = b * c
solution1 = calc_residual(h1, a, d)
h2 = a * c
solution2 = calc_residual(h2, b, e)
h3 = a * b
solution3 = calc_residual(h3, c, f)
return (solution1*h1 + solution2*h2 + solution3*h3) - a*b*c
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Na, da hast etwas mit der Formatierung nicht geklappt.

Code: Alles auswählen

def calc_residual(h, a, d):
    if a <= d:
        raise ValueError("a must be larger than d")
    for i in range(1, a+1):
        if (h * i) % a == d:
            return i
    assert False, "not possible"

def chinesischer_restesatz(a, b, c, d, e, f):
    h1 = b * c
    solution1 = calc_residual(h1, a, d)
    h2 = a * c
    solution2 = calc_residual(h2, b, e)
    h3 = a * b
    solution3 = calc_residual(h3, c, f)
    return (solution1*h1 + solution2*h2 + solution3*h3) - a*b*c
Wenn etwas dreimal identisch gemacht wird, dann ist das ein Fall für eine Funktion. Hier noch mit zusätzlicher Fehlerprüfung.
beginnertwo
User
Beiträge: 3
Registriert: Dienstag 25. August 2020, 08:21

Sirius3 Vielen Dank. Ziemlich dummer Fehler von mir und danke für die Erläuterung!
Antworten