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.
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Wenn ich das jetzt richtig verstanden habe, bekomme ich das folgende:

Code: Alles auswählen

n=var('n') 
k=0
def f(k):
    k + (n-k)
    
if n%2==0:
        for k in range(n):
            ((n-k).is_prime) and (k.is_prime()):
                print(n-k)
                print(k)
        else: k += 1    
else: print("ERROR")
Dann bekomme ich allerdings folgende Fehlermeldung:

Code: Alles auswählen

  File "<ipython-input-9-89255abdad00>", line 9
    ((n-k).is_prime) and (k.is_prime()):
                                       ^
SyntaxError: invalid syntax
Und an welcher stelle muss dann der return?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Du rätst hier wild herum, statt Deinen Code Zeile für Zeile aufzubauen und auch zu verstehen, was jede Zeile macht. Die Funktion `f` wird gar nicht benutzt, kann also weg.
k = 0 und k += 1 werden nicht mehr gebraucht, weil Du jetzt eine for-Schleife hast.
Die Klammersetzung ist falsch. Und in der Zeile, in der der Compiler meckert, hast Du etwas gelöscht, was vorher da war.

Einrückungen sind in Python wichtig, und man sollte sehr sorgfältig sein, richtig (mit jeweils 4 Leerzeichen pro Ebene) einzurücken. Dann fällt dem Leser auch viel schneller auf, wenn etwas nicht richtig ist (z.B. ein else-Block bei einer for-Schleife, der hier nicht sinnvoll ist).
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

Ich bin tatsächlich noch nicht sehr erfahren mit Programmieren. Ich hab jetzt es so geändert, wie du meinstest, bis auf die Klammersetzung, da verstehe ich nicht, welche falsch sind(?):

Code: Alles auswählen

n=var('n')
    
if n%2==0:
    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")
Sarah1111
User
Beiträge: 22
Registriert: Sonntag 14. April 2019, 14:21

__blackjack__ hat geschrieben: Montag 15. April 2019, 14:53 Edit: Moment mal: Das ist jetzt aber gar kein Syntaxfehler mehr, sondern ein `TypeError`. Und der sagt recht deutlich was das Problem ist: der Modulo-Operator (``%``) ist für Python-Funktionen und etwas vom Typ `Integer Ring` nicht definiert. Was hättest Du denn da erwartet als Ergebnis dieser Operation?
Ich möchte mit %2 gewährleisten, dass nur gerade zahlen genommen werden für n. Ich kenne den Befehl nur aus Java und der bedeutet in Sage doch das selbe, oder? Vertue ich mich?
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Prinzipiell bedeutet der in Python dasselbe, aber du hast ein anderes Objekt dort gehabt. Integer(i). Was auch immer das nun sein soll. Und hier ist dein n ja auch ein "var"-Objekt. Was auch immer *DAS* nun genau ist. Und in dem Code da oben gibt's auch kein k, und mal rufst du is_prime auf (mit Klammern dahinter), und mal nicht.... so geht das nicht. Der Code den du hier postest, das muss auch GENAU der Code sein, den du laufen laesst, UND die GENAU dazu passende Fehlermeldung. Nicht irgendwas das du dir gemerkt hast, und das auf irgendwelchen frueheren Zustaenden basiert. Sonst kann dir hier leider keiner helfen.
Sirius3
User
Beiträge: 17754
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: 13116
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
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
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: 13116
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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
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: 17754
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: 13116
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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
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: 17754
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.
Antworten