Ich finde den Fehler nicht (SageMath)

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.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sarah1111: das ist für mich gleich viel leichter zu lesen. Und wenn Du jetzt Deinen Code Zeile für Zeile liest, was fällt sofort auf (wo auch der Interpreter dann meckert)?
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@__deets__: Ich vermute mal das `Integer` vom `sympy`-Package kommt. Die Objekte haben jedenfalls eine `is_prime()`-Methode. Wobei ich mich dann jetzt frage ob hier tatsächlich etwas als Wert(e) ausgerechnet werden soll, oder ob eine symbolische Lösung gefragt ist. Bei ersterem würde ich glaube ich eher nicht den Weg über `sympy` gehen. Gerade als Anfänger holt man sich da eventuell verwirrende ”Indirektionen” ins Boot weil es plötzlich Objekte gibt die Python-Funktionen repräsentieren und welche die symbolische Funktionen repräsentieren, und Variablen die Variablen repräsentieren…

@Sarah1111: Was soll denn die erste Bedingung aussagen? Wann denkst Du das eine Variable die eine Variable, also keinen konkreten Zahlenwert repräsentiert, modulo 2 den Wert 0 ergeben kann? Hast Du das mal ausprobiert? Was hast Du als Ergebnis erwartet? Und was bekommst Du stattdessen?

Edit:

Code: Alles auswählen

In [18]: n = sympy.var('n')

In [19]: n % 2
Out[19]: Mod(n, 2)

In [20]: n % 2 == 0
Out[20]: False
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Also es dürfte noch ein return fehlen, aber ich weiß nicht an welcher stelle (vor dem else?).

Und, dass nur gerade Zahlen genommen werden, wird mir auch als Fehler angezeigt (also %2 geht wohl doch nicht?). Gibt es noch einen anderen Befehl, womit man nur gerade Zahlen auswählt?

Muss mein n nicht als Variable benannt werden? Denn vom Prinzip will ich doch später für mein n gerade natürliche Zahlen einsetzen.... Und k sollte ich auch noch benennen, das stimmt. Auch als Variable? Und dann fehlt doch eigentlich auch noch, dass irgendwo n = k + (n-k) definiert ist oder muss das nicht noch extra benannt werden, weil das in teil k in range(n) enthalten ist mit der anschließenden if-Bediengung?
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Wobei ich mich dann jetzt frage ob hier tatsächlich etwas als Wert(e) ausgerechnet werden soll, oder ob eine symbolische Lösung gefragt ist.
Ich benötige am Ende einen allgmeinen Lösungsweg, in dem ich am besten eine Zahlenrange ausrechenen kann. Also in dem ich die Zahlen von 1 bis 20 000 durchlaufen lassen kann und mir am ende gesagt wird, ob diese als Summe von Primzahlen geschrieben werden kann :)
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

__blackjack__ hat geschrieben: Montag 15. April 2019, 16:19 @Sarah1111: Was soll denn die erste Bedingung aussagen? Wann denkst Du das eine Variable die eine Variable, also keinen konkreten Zahlenwert repräsentiert, modulo 2 den Wert 0 ergeben kann? Hast Du das mal ausprobiert? Was hast Du als Ergebnis erwartet? Und was bekommst Du stattdessen?

Edit:

Code: Alles auswählen

In [18]: n = sympy.var('n')

In [19]: n % 2
Out[19]: Mod(n, 2)

In [20]: n % 2 == 0
Out[20]: False
Die erste Bedingung soll sagen, dass das gewählte n positiv sein muss (Aber muss das überhaupt da stehen, wenn ich n als Variable definiert habe? Dann kann ich ja direkt eine positive Zahl wählen...).
Und wenn ich das ausprobiere kommen bei mir auch schon Error. Aber meinst du damit, dass ich "n % 2" besser schreiben soll?
Zuletzt geändert von Sarah1111 am Montag 15. April 2019, 16:43, insgesamt 1-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sarah1111: Wenn Du meinst beim ``else``-Zweig würde ein ``return`` fehlen dann fehlt das im ``if``-Zweig nicht? Und natürlich geht das nur wenn es in einer Funktionsdefinition steht, denn was soll ``return`` ausserhalb einer Funktion denn bitte für eine Bedeutung haben? Wohin soll der Programmfluss an der Stelle denn zurückkehren wenn nicht an die Stelle von wo die Funktion aufgerufen wurde?

Doch mit ``% 2`` kann man testen ob eine Zahl gerade ist. Man muss das allerdings dann auch mit einer Zahl als erstem Argument machen und nicht mit einem Wert der eine symbolische Variable repräsentiert. Das testet übrigens nicht ob es eine positive Zahl ist.

`n` muss dann ein Zahlwert zugewiesen werden. Du weisst `n` aber einen Wert zu der eine Variable mit dem Namen 'n' repräsentiert. Der Wert ist ein Objekt das eine symbolische Variable darstellt. Und auf diesem Objekt ist die Modulo-Operation so definiert, das sie wieder ein Objekt ergibt, die dann diese Modulo-Operation symbolisch repräsentiert. Habe ich ja praktisch in einer IPython-Shell gezeigt. Wenn Du bei der Modulo-Operation eine konkrete Zahl als Ergebnis haben willst, dann müssen die Operatoren auch konkrete Zahlen sein.

Du solltest vielleicht einfach erst einmal ganz normal die Python-Grundlagen lernen. Ohne SageMath/`sympy`. Das brauchst Du soweit ich das sehe auch nicht wirklich. Ausser vielleicht eine Bibliothek für einen Primzahltest. `sympy.primetest.isprime()` böte sich da an, wenn man `sympy` sowieso schon installiert hat.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Ja, das mit dem return war nicht klug, das stimmt...

Also definiere ich mein n nicht als variable, sondern gebe ihm einen Startwert? Also erstmal einfach eine positive ganze Zahl:

Code: Alles auswählen

 n = int
und wie sage ich, dass sie positiv sein soll?"




Ich besuche gerade einen Anfängerkurs und versuche so gut es geht alles zu lösen :) Eure Hilfe macht auch einen Großteil :)
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Soweit sieht es jetzt bei mir aus:

Code: Alles auswählen

n = int 
n>=0
    
if n % 2:
    while k<n:
        for k in range(n):
            if ((n-k).is_prime() and (k).is_prime()):
                print(n-k)
                print(k)
          
else: print("ERROR")
dann kommt allerdings immer noch der folgende Fehlercode:

Code: Alles auswählen

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-6e4985409e47> in <module>()
      2 n>=Integer(0)
      3 
----> 4 if n % Integer(2):
      5     while k<n:
      6         for k in range(n):

/opt/sagemath-8.6/local/lib/python2.7/site-packages/sage/rings/integer.pyx in sage.rings.integer.Integer.__mod__ (build/cythonized/sage/rings/integer.c:21551)()
   3316 
   3317         # Use the coercion model
-> 3318         return coercion_model.bin_op(x, y, operator.mod)
   3319 
   3320     def quo_rem(Integer self, other):

/opt/sagemath-8.6/local/lib/python2.7/site-packages/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel_cache_maps.bin_op (build/cythonized/sage/structure/coerce.c:10649)()
   1209         # We should really include the underlying error.
   1210         # This causes so much headache.
-> 1211         raise bin_op_exception(op, x, y)
   1212 
   1213     cpdef canonical_coercion(self, x, y):

TypeError: unsupported operand parent(s) for %: '<type 'type'>' and 'Integer Ring'
Das sieht für mich so aus, als wäre dsa "% 2" nicht korrekt....
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sarah1111: wenn Du alle Zahlen in einem Bereich bis 20000 analysieren willst, würde ich ja mit einem Sieb alle Primzahlen bis 20000 berechnen und dann die möglichen Summen aller Kombinationen ausrechnen.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Sirius3 hat geschrieben: Montag 15. April 2019, 17:21 @Sarah1111: wenn Du alle Zahlen in einem Bereich bis 20000 analysieren willst, würde ich ja mit einem Sieb alle Primzahlen bis 20000 berechnen und dann die möglichen Summen aller Kombinationen ausrechnen.
Das klingt tatsächlich schlau :)

nichts destotrotz, ist die erste Aufgabe es allgemein zu programmieren. Also werde ich beides machen müssen :)

Aber deine Idee für meine zweite Aufgabe probiere ich gleich direkt mal aus :)
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sarah1111: Sorry, so funktioniert programmieren nicht. Du kannst nicht einfach wild herum raten bis es das macht was Du willst. Man kann natürlich nicht alles wissen und muss dann auch mal raten, aber dabei sollte man wissen was man da macht, was man erwartet. Und dann schauen wie das vom erwarteten abweicht. Um dann zu verstehen warum das falsch war was man da gemacht hat.

Zudem ist es wirklich wichtig, dass der Code den Du zeigst auch tatsächlich zum Traceback passt. Es macht wenig Sinn uns Tracebacks zu Code zu zeigen den wir nicht kennen, denn dann können auch wir nur raten was Du da tatsächlich gemacht hast.

Du musst Zeile für Zeile, Ausdruck für Ausdruck, Teilausdruck für Teilausdruck wissen was da jeweils passiert. Und wenn nicht das passiert was Du erwartest, dann musst Du dir das bis zu den Teilausdrücken genau anschauen um die Stelle zu finden, an der Deine Erwartungen vom tatsächlichen Wert oder Verhalten abweicht. Dazu kannst Du dann konktet die Frage stellen was Du nicht verstanden hast.

Bei dem gezeigten Quelltext wirst Du bereits in der zweiten Zeile einen `TypeError` bekommen – es sei denn Du verwendest noch Python 2, dann solltest Du das als erstes mal ändern, denn Python 2 wird ab Ende des Jahres nicht mehr gewartet und Python 3 ist schon recht lange da.

Du solltest wirklich mal einen Schritt von Deinem aktuellen Problem zurück treten und ein Grundlagentutorial durcharbeiten. In der Python-Dokumentation befindet sich eines.

Schon die erste Zeile vom gezeigten Quelltext macht wenig bis keinen Sinn. Du bindest den Wert `int` an den Namen `n`. Nun ist der `int`-Datentyp auch unter diesem Namen erreichbar. Du willst da aber keinen Wert binden der einen Datentyp repräsentiert, sondern eine Zahl. ``n = 42`` beispielsweise. Wenn die folgende Rechnung nicht mit einem festen Wert durchgeführt werden soll, dann musst Du eine Funktion definieren. Und die dann danach aufrufen. Das wird alles in einem Grundlagentutorial erklärt.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Schon die erste Zeile vom gezeigten Quelltext macht wenig bis keinen Sinn. Du bindest den Wert `int` an den Namen `n`. Nun ist der `int`-Datentyp auch unter diesem Namen erreichbar. Du willst da aber keinen Wert binden der einen Datentyp repräsentiert, sondern eine Zahl. ``n = 42`` beispielsweise. Wenn die folgende Rechnung nicht mit einem festen Wert durchgeführt werden soll, dann musst Du eine Funktion definieren. Und die dann danach aufrufen. Das wird alles in einem Grundlagentutorial erklärt.
Also nehme ich doch eine Funktion wie zuvor?

Ich schaue schon in den Unterlagen von mir nach. Aber ich blätter mal durch die grundlagentutorials hier. Danke für den Tipp.

Eure/deine Tipps helfen mir trotzdem sehr viel weiter. Daher wäre es lieb, wenn ihr parallel trotzdem helfen könntet.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Ok, ich habe leider wirklich nicht viel Ahnung vom Programmieren und da ich auch nicht viel programmieren werde, da ich nur diesen einen Kurs besuche, kann ich leider auch nur Python 2. Ich probiere so gut es geht, alles zu verstehen und zu machen. Und meistens ist es mehr probieren als wissen. Aber ich lerne aus den Sachen. Sowohl die, die hier erklärt werden, als auch in meinem Kurs parallel. Mich verwirrt das alles aber noch ein wenig und ich versuche Licht ins Dunkle zu bringen.


Zurück zur Aufgabe: Ich nutze also für den generellen Teil eine Funktion f(k) = k + (n-k) (wie zu Beginn?) und lasse diese dann laufen über die range der Primzahlen bis n, korrekt? Dann sind doch aber die Abbruchsbedingungen die selben, oder?
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Wenn ich jetzt also den allgemeinen Fall wieder betrachte, wäre für mich erstmal folgendes logisch:

Code: Alles auswählen

n=var('n') 
k=0
def f(k):
    k + (n-k)
    
if f(k) % 2:
    while k<n: 
        for k in range(n):
            if ((n-k).is_prime() and (k).is_prime()):
                print(n-k)
                print(k)
        else: k += 1   
else: print("ERROR")


würde das soweit erstmal Sinn ergeben? Oder sind da schon Fehler drin?
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Funktion hat keinen Rückgabewert, und hätte sie einen, könnte man sie zu `n` vereinfachen, eine Variable, die aber gar nicht der Funktion übergeben wird.

Ich verstehe auch nicht was Du mit „allgemeinem Fall“ meinst, Du brauchst immer einen konkreten Wert, mit dem Du rechnen kannst.
Die while-Schleife, der else-Block, die Klammerung, das sieht alles noch nicht ganz richtig aus.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Mit allgemeinen meine ich eher für einen bel. Wert der natürlichen Zahlen, den ich dann einsetzen könnte.
Das mit dem Rückgabewert verstehe ich ehrlich gesagt nicht... :(
Und was ist mit while, else und klammern gemeint? Falsche Bedingungen?
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sarah1111: Arbeite doch mal ein Grundlagentutorial durch. Und ich meine wirklich durcharbeiten, nicht nur blättern oder lesen, sondern auch ausprobieren was Du da lernst und auch ein wenig damit herumspielen, Sachen verändern, um zu überprüfen ob Du es verstanden hast.

Das was Du da geschrieben hast, macht immer noch keinen Sinn. `n` zum Beispiel mit einem Wert zu initialisieren der eine Variable repräsentiert macht keinen Sinn.

Schreib auch nicht so viel Code. Das sind lauter Fehler drin, zu denen der Programmablauf gar nicht kommt, weil der schon durch den ersten Fehler gestoppt wird. Programme entwickelt man. Stück für Stück. Schreib etwas kurzes was Dich auf dem Weg zu Deinem Problem weiter bringt, und probiere das dann erst einmal aus, ob das macht was Du willst, und mach erst weiter wenn das bis dahin funktioniert. Zum Beispiel die Funktion `f()`. Die macht schon nicht das was sie soll. Probier die erst einmal aus und schreibe die richtig, bevor Du anfängst die in weiterem Code aufzurufen, denn wenn die schon nicht funktioniert, wird auch Code der die verwendet nicht funktionieren.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten