Die ersten 1000 Zahlen auf Primzahlen absuchen ....

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
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Hi zusammen :):wave:

Beschaeftige mit gerade mit dem folgenden Projekt .... seid Ihr so lieb und kuckt mal darueber pls?

Code: Alles auswählen

from math import sqrt

list_up_to_onethousand = []
list_of_primes = []

for i in range(1000):
    list_up_to_onethousand.append(i+1)

for i in list_up_to_onethousand:
    sqrt_list_for_i = []
    sqrt_list_for_i.append(int(sqrt(i+1)))
        
    for n in sqrt_list_for_i:
        if i % n == 0:
            continue
        else:
            list_of_primes.append(i)
     
#print(list_up_to_onethousand)
print(list_of_primes)

Das Ergebnis ist dabei Mangelhaft ..... "[3, 5, 7, 8, 10, 11, 13, 14, ...]"

Meine zwei Fragen:
- Wo ist die 1 und die 2 hin?
- zur 8, 10, 14, ...: ich vermute, dass die eingerueckte for-Zeile 'n in sqrt_list_for_i' falsch eingerueckt ist oder den falschen Bezug aufweist? Eigentlich will ich ja, dass fuer 'i' in 'list_up_to_onethousand' jeweils die Pruefung mit 'n' stattfindet und nicht andersherum ........ :? :?


GlG und schonmal Danke =D c.b.
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Konkrete Grunddatentypen haben in Namen nichts zu suchen. Wenn man den Typ mal ändern, und das kommt während der Programmentwicklung durchaus häufiger vor, dann muss man alle betroffenen Namen anpassen oder man hat falsche, irreführende Namen im Programm.

Die Liste mit den Zahlen bis 1000 wird umständlich generiert und eigentlich braucht man sie auch gar nicht genierieren, denn man kann ja auch einfach über ``range(1, 1001)`` iterieren.

Die Liste mit den Wurzeln ist keine Liste mit Wurzeln, sondern eine Liste in der immer nur *eine* Wurzel steckt. Das ist ziemlich sinnfrei. Da kann man auch einfach nur die Wurzel berechnen ohne Liste und ohne Schleife die immer nur über genau *ein* Element geht.

Wenn man das alles vereinfacht ist das hier das was Du effektiv in Deinem Programm machst:

Code: Alles auswählen

#!/usr/bin/env python3
from math import sqrt


def main():
    primes = []
    for i in range(1, 1001):
        if i % int(sqrt(i + 1)) != 0:
            primes.append(i)
         
    print(primes)


if __name__ == '__main__':
    main()
Beziehungsweise kann man das auch noch etwas kompakter als „list comprehension“ schreiben:

Code: Alles auswählen

#!/usr/bin/env python3
from math import sqrt


def main():
    primes = [i for i in range(1, 1001) if i % int(sqrt(i + 1)) != 0]
    print(primes)


if __name__ == '__main__':
    main()
Das das keine Primzahlen ausrechnet und wo die 1 und die 2 hin sind, wird aus dem Code hoffentlich klar.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

__blackjack__ hat geschrieben: Donnerstag 18. April 2019, 11:01 @c.burkes: Konkrete Grunddatentypen haben in Namen nichts zu suchen.
Du meinst damit Anhaengsel wie 'i' oder 'onethousand'? stimmt :thumbs_up: ist sinnig .... will ja dann gleich die 10k auschecken :D
Die Liste mit den Zahlen bis 1000 wird umständlich generiert
stimmt :sweat_smile:
Die Liste mit den Wurzeln ist keine Liste mit Wurzeln, sondern eine Liste in der immer nur *eine* Wurzel steckt. Das ist ziemlich sinnfrei. Da kann man auch einfach nur die Wurzel berechnen ohne Liste und ohne Schleife die immer nur über genau *ein* Element geht.
Ah okay ... das erklaert, warum meine Pruefung "nicht funktioniert" hat .... dachte die die Liste waere bspw. bei '10' => '1, 2, 3' .... kann ja aber nicht sein, weil ich ja gleichzeitig wert darauf gelegt habe, dass dass das Ding immer von 'for' bis 'else' durchlaeuft. Danke fuer diesen Hint :see_no_evil::thumbsup:

Code: Alles auswählen

  for i in range(1, 1001):
        if i % int(sqrt(i + 1)) != 0:
            primes.append(i)
Damit pruefst Du nur ob Eine Zahl durch seine abgerundete Wurzel teilbar ist, oder? Logischer Weise kann das bei einer Primzahl nicht der Fall sein, aber ich dachte mich zu entsinnen, dass die Probe immer verlangt die Wurzel aus der Zahl zu ziehen und die Zahl durch alle ganzen Zahlen der abgerundeten Wurzel zu ziehen und dann nur durch eins teilbar sein darf ....

also ..... 14 % (int(sqrt(14+1))) => (warum hier die '+1' ?)
=>=> 14 % 3 != 0 =>=> Primzahl, was ja dem nicht so ist ..... :thinking_face:

Den Rest lass ich mal gerade weg, bis ich das hier richtig einsortiert habe ..... :thinking_face:
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Weder `i` noch `onethousand` ist ein Datentyp in Python. Damit war `list` gemeint.

Die Probe verlangt kein wurzelziehen. Das kann an der richtigen Stelle aber nützlich sein um den Suchbereich für Teilbarkeitstests sinnvoll einzuschränken.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

hm, ..... ich verstehe es leider noch nicht ..... Dein erster code gibt mir ebenfalls "[3, 5, 7, 8, 10, 11, 13, 14, ....]" aus?

versuche es grade nochmal mit ner neuen Konsole ....

jupp ... bleibt dabei :thinking_face:
Zuletzt geändert von c.burkes am Donnerstag 18. April 2019, 12:36, insgesamt 1-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Mein Code macht genau das gleiche was Dein Code macht, also kommt da natürlich das gleiche falsche Ergebnis heraus. Ich habe nur Deinen Code deutlich vereinfacht, damit Du leichter siehst was Du da machst und warum das so nicht funktioniert.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

achso X'D .... ich setz mich nach dem Mittag nochmal ran :sweat_smile:
ich dachte schon, heute machst Du es mir aber sehr leicht xD
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Leicht wäre das hier:

Code: Alles auswählen

In [32]: import sympy

In [33]: print(list(sympy.primerange(0, 1001)))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
😎
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

c.burkes hat geschrieben: Donnerstag 18. April 2019, 12:39 .... ich setz mich nach dem Mittag nochmal ran :sweat_smile:
da kam mal grade das Leben dazwischen :$

__blackjack__ hat geschrieben: Donnerstag 18. April 2019, 14:20 Leicht wäre das hier:
ymmd x'D
__blackjack__ hat geschrieben: Donnerstag 18. April 2019, 11:01 [...] wo die 1 und die 2 hin sind, wird aus dem Code hoffentlich klar.
thx - :see_no_evil:

Jetzt ist noch die Frage nach dem richtigen Testverfahren offen ......
__blackjack__ hat geschrieben: Donnerstag 18. April 2019, 12:28 @c.burkes: Weder `i` noch `onethousand` ist ein Datentyp in Python. Damit war `list` gemeint.

Die Probe verlangt kein wurzelziehen. Das kann an der richtigen Stelle aber nützlich sein um den Suchbereich für Teilbarkeitstests sinnvoll einzuschränken.
also, da ich auf das Modul jetzt aus Prinzip verzichten und unbedingt das Rad ein zweites Mal erfinden will ......

Code: Alles auswählen

    for i in range(1, 1001):
        if i % [......]       
            primes.append(i)
hier muesste doch jetzt der Test folgen .... ich wuerde eben meinen durch alle Zahlen die unterhalb der agerundeten Wurzel zu finden sind? Ich mach mal in einem zweiten post weiter .....
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Habe Deinen Code jetzt wie folgt ergaenzt und meine, dass die Ueberpruefung der Primzahl jetzt stimmen muesste .....

Code: Alles auswählen

from math import sqrt

def main():
    primes = []
    for i in range(1, 17):
        #print(i)
        for n in range(2, (int(sqrt(i))+1)):
            #print(n)
            if i % n == 0:
                continue
            else:
                primes.append(i)
                break
        
    print(primes)
    #print(i)
    #print(range(2, (int(sqrt(i))+1)))


if __name__ == '__main__':
    main()
Das Ding ist jetzt, dass bei den Zahlen mit mehreren 'n'-Pruefungen ...

i --- n --- %

9 --- 2 --- R1
9 --- 3 --- R0

10 --- 2 --- R0
10 --- 3 --- R1

11 --- 2 --- R1
11 --- 3 --- R1

12 --- 2 --- R0
12 --- 3 --- R0

13 --- 2 --- R1
13 --- 3 --- R1

14 --- 2 --- R0
14 --- 3 --- R2

15 --- 2 --- R1
15 --- 3 --- R0

16 --- 2 --- R0
16 --- 3 --- R1
16 --- 4 --- R0

die Zahl als Prim erkannt wird, sobald diese einmal Rest 1 enthaelt. Kann man das unterbinden? Ich denke an 'and' Befehle, muesste diese dann aber ja jeweils n[1], [2], .... zuordnen. :?:?:?

Also mir geht es bei diesem Ding wirklich nicht um den code als solches .... da finde ich blackjacks modul schon sehr nice :sweat_smile: sondern lediglich darum die Arbeitsweise Pythons zu verstehen ......
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Der Code erkennt jede Zahl als Prim die irgend wann einmal *nicht* durch ein `n` glatt teilbar ist. Also nicht nur wenn der Rest 1 vorkommt, sondern immer wenn irgend ein anderer Rest als 0 vorkommt.

Vergiss am besten mal das es ``continue`` gibt, das ist sowieso eine recht verwirrende Anweisung. Und mach Dir klar, dass das ``continue`` in dem Code auch gar keinen sinnvollen Effekt hat. Das kannst Du durch ``pass`` ersetzen ohne das sich am Laufzeitverhalten des Programms etwas ändert. Oder eben die Bedingung vom ``if`` umkehren und den ``else``-Zweig in den ``if``-Zweig verschieben:

Code: Alles auswählen

from math import sqrt

def main():
    primes = []
    for i in range(1, 17):
        #print(i)
        for n in range(2, int(sqrt(i)) + 1):
            #print(n)
            if i % n != 0:
                primes.append(i)
                break
        
    print(primes)


if __name__ == '__main__':
    main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

:thumb_up: zu beidem .... aber das Problem bleibt dabei ja bestehen, dass sich die Pruefung leider nicht auf 'i', sondern die einzelnen 'n'-Pruefungen bezieht und daher falsch ausgibt. Ist das in "meinem" (xD) code nicht korrigierbar?
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Klar ist das korrigierbar. Zum Beispiel einfach mit `any()` oder `all()` und einem Generatorausdruck in einer Zeile mit einem ``if`` machbar. Du könntest aber auch erst einmal eine `is_prime()`-Funktion schreiben, die den Test für *eine* Zahl macht. Dann hast Du ein etwas kleineres Teilproblem. Und wenn das gelöst ist, kann man diese Funktion ja sehr einfach in der Hauptfunktion verwenden:

Code: Alles auswählen

def main():
    primes = []
    for i in range(1, 17):
        if is_prime(i):
            primes.append(i)
    print(primes)
Beziehungsweise kann man diese Schleife ja auch leicht als „list comprehension“ schreiben:

Code: Alles auswählen

def main():
    primes = [i for i in range(1, 17) if is_prime(i)]
    print(primes)
Oder auch:

Code: Alles auswählen

def main():
    primes = list(filter(is_prime, range(1, 17))
    print(primes)
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Hm, ..... alles noch ausserhalb meines Wissenshorizontes ... T-T .... da werde ich noch ein paar Tage fuer brauchen :/

Ich geb Dir Feedback, wenn ich durch bin.

Danke Dir aber fuer all das. War viel hilfreiches dabei :)
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Naja, die erste Variante ist ja noch keine Raketentechnik. Und letztlich laufen alle drei darauf hinaus eine Funktion `is_prime()` zu schreiben, die eine Zahl übergeben bekommt und `True` zurück geben muss wenn es sich um eine Primzahl handelt und `False` wenn nicht.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

sooo .... heute tut das alles sehr weh xD

die 'all()'-Funktion ist wahrscheinlich genau das, was ich mit "Ich denke an 'and' Befehle, muesste diese dann aber ja jeweils n[1], [2], .... zuordnen. :?:?:?
Vielen Dank dafuer.

Als list comprehension habe ich es jetzt gaube ich hinbekommen .... als funktion leider NOCH nicht .... :/

Code: Alles auswählen

from math import sqrt

def is_prime(n):
    if all(n % i != 0 for i in range(2, (int(sqrt(n))+1))):
        return True
    return False
    
primes = []

for i in range(1, 1001):
    if is_prime(i) == True:
        primes.append(i)

print(primes)

1, 2 und 3 sind dabei mit im Ergebnis, weil != 0 sondern 'None' mangels range ausgegeben wird, nech?
Benutzeravatar
__blackjack__
User
Beiträge: 13948
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Ähm, `all()` gibt `True` oder `False` zurück. Und wenn `all()` `True` ergibt, gibst Du `True` zurück. Ansonsten `False`. Da kannst Du Dir doch das ``if`` sparen und gleich das Ergebnis von `all()` zurückgeben.

Man vergleicht keine Wahrheitswerte mit ``==`` oder ``!=`` mit literalen Wahrheitswerten. Da kommt doch bloss wieder ein Wahrheitswert bei heraus. Also entweder den, den man sowieso schon hatte, oder dessen Gegenteil. Also kann man den auch gleich nehmen, oder ihn noch mit ``not`` negieren, je nach dem welchen Wert man in der Bedingung braucht.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Code: Alles auswählen

from math import sqrt

def is_prime(n):
    return all(n % i != 0 for i in range(2, (int(sqrt(n))+1)))
    
primes = []

for i in range(1, 1001):
    if is_prime(i):
        primes.append(i)

print(primes)
ah nice minimalistisch :thumb_up
Antworten