Seite 1 von 1

chinesischer Restsatz

Verfasst: Dienstag 25. August 2020, 08:46
von beginnertwo
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

Re: chinesischer Restsatz

Verfasst: Dienstag 25. August 2020, 09:08
von __blackjack__
@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?

Re: chinesischer Restsatz

Verfasst: Dienstag 25. August 2020, 09:23
von beginnertwo
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.

Re: chinesischer Restsatz

Verfasst: Dienstag 25. August 2020, 11:02
von Sirius3
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

Re: chinesischer Restsatz

Verfasst: Dienstag 25. August 2020, 16:18
von Sirius3
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.

Re: chinesischer Restsatz

Verfasst: Dienstag 25. August 2020, 17:54
von beginnertwo
Sirius3 Vielen Dank. Ziemlich dummer Fehler von mir und danke für die Erläuterung!