append

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Bykl
User
Beiträge: 99
Registriert: Donnerstag 5. Oktober 2017, 17:57

Bis eben hat alles funktioniert. Plötzlich druckt er die kleinste PZ von Teiler nicht mehr aus... Was kann ich machen?

Code: Alles auswählen

j=1
i=1
zahl=0
nr=0
sozlr=0
Länge=0
Divisor=0
Teiler=[]
pznr=0
nr3t=0
n3nr=0

"""def AnzahlZZ(lst1):
    ZZAnzahl=0
    Divisor=0
    if len(lst1)>1:
        Länge=int(zahl/2)
        start=int(len(lst1))
        for i in range (start,0,-1):
            Divisor=lst1.pop(i-1)
            ZZAnzahl=ZZAnzahl+int(Länge/Divisor)
            return(ZZAnzahl)
"""

for zahl in range(13,5003,10):
    nr=nr+1
    j=1
    while j <= (zahl)/2:
            if zahl%j==0:
                Teilerb=zahl//j  
                if Teilerb%2>0 and isprime(Teilerb):
                    Teiler.append(Teilerb)
               # print(nr,"zahl",zahl,"if: i:",i,"j:",j,"Teilerb",Teilerb,"Teiler",Teiler) 
                j=j+1
            else:
                #Teiler.append(Teilerb)
                #print(nr,"zahl",zahl,"else: i:",i,"j:",j,"Teilerb",Teilerb,"Teiler",Teiler)
                j=j+1

            
    if isprime(zahl):
        #print("prime Nr:",nr,"zahl",zahl,len(Teiler),"PrimTeiler",Teiler,)
        pznr=pznr+1
        print(nr,"zahl",zahl,"PZNR:",pznr,)
    else:
        if zahl%3==0:
            nr3t=nr3t+1
            print(nr,"zahl",zahl,"NR3T:",nr3t,"3-",len(Teiler),"PrimTeiler",Teiler,AnzahlZZ(Teiler))
        else:
            n3nr=n3nr+1
            print(nr,"zahl",zahl,"N3NR:",n3nr,len(Teiler),"PrimTeiler",Teiler,AnzahlZZ(Teiler))
    Teiler.clear()
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Wußte gar nicht, dass die Teiler schon so gross sind dass sie ihre eigene Postleitzahl haben.
Benutze keine Abkürzungen, vor allem nicht bei Variablennamen. Variablennamen werden grundsätzlich komplett klein geschrieben.
Die meisten der Variablen, die am Anfang definiert werden, werden gar nicht gebraucht. Das macht das Programm zusätzlich schwer lesbar.
`nr` ist das selbe wie `zahl - 12`.
Was sollen die kryptischen nr3t und n3nr? Die lassen sich so leicht verwechseln. Daher keine Abkürzungen.
`isprime` wird nirgends definiert. `AnzahlZZ` wird verwendet, obwohl es in einem String steht (Kommentare macht man mit #)
Statt Listen zu leeren, erzeugt man eine neue Liste.
Wenn etwas sowohl im if- als auch im else-Block steht, kann man es auch einmal danach schreiben, wie bei j=j+1, oder besser, eine for- statt einer while-Schleife.

Die Funktion AnzahlZZ sollte alles, was sie braucht, über ihre Argumente bekommen, eine for-Schleife, die gleich bei ersten Durchgang per `return` beendet wird, ist keine for-Schleife. Ich gehe mal davon aus, dass das ein Einrückfehler ist. return ist keine Funktion, die Klammern also überflüssig.
Listen sollte man nicht verändern, vor allem nicht, wenn sie als Argument einer Funktion übergeben werden und das überhaupt nicht dokumentiert wird.
Dabei ist es doch in der for-Schleife völlig egal, ob die nun von Hinten durchgegangen wird, oder in normaler Reihenfolge. Bei `von hinten` würde man reversed benutzen.
Auch in dieser Funktion weißt Du Variablen Werte zu, die nie benutzt werden. In Python werden Variablen dann eingeführt, wenn sie gebraucht werden, und erst dann.

So sieht das etwas aufgeräumter aus:

Code: Alles auswählen

def ermittle_anzahl_von_was_auch_immer_zz_ist(zahl, alle_teiler):
    anzahl = 0
    länge = zahl // 2
    for divisor in reversed(alle_teiler):
        anzahl += länge // divisor
    return anzahl

anzahl_primzahlen = 0
anzahl_durch_drei_teilbar = 0
anzahl_nicht_durch_drei_teilbar = 0
for zahl in range(13,5003,10):
    alle_teiler = []
    for j in range(1, (zahl + 1) // 2 + 1):
        teiler, rest = divmod(zahl, j)
        if rest == 0 and teiler > 2 and isprime(teiler)
            alle_teiler.append(teiler)

    nr = zahl - 12
    if isprime(zahl):
        anzahl_primzahlen += 1
        print(nr, "zahl", zahl, "PZNR:", anzahl_primzahlen)
    else:
        if zahl % 3 == 0:
            anzahl_durch_drei_teilbar += 1
            print(nr, "zahl", zahl, "NR3T:", anzahl_durch_drei_teilbar, "3-", len(alle_teiler), "PrimTeiler", alle_teiler, ermittle_anzahl_von_was_auch_immer_zz_ist(zahl, alle_teiler))
        else:
            anzahl_nicht_durch_drei_teilbar += 1
            print(nr, "zahl", zahl, "N3NR:", anzahl_nicht_durch_drei_teilbar, len(alle_teiler), "PrimTeiler", alle_teiler, ermittle_anzahl_von_was_auch_immer_zz_ist(zahl, alle_teiler))
Da Du nicht beschreibst was Du eigentlich berechnen willst, ist der ganze Code für mich nur eine beliebige Berechnung. Daher kann ich auch nicht sagen, was daran falsch sein soll. Beschreibt doch mal, was da berechnet werden soll.
Bykl
User
Beiträge: 99
Registriert: Donnerstag 5. Oktober 2017, 17:57

Danke für Deine Hilfen. Grundsätzlich hast Du recht, aber wenn Du so komprimierten guten Code einstellst, kann ich nicht mehr genau folgen, was passiert. Bei diesem aber versteh ich - oder glaube zugestehen - fast alles, ausser:

for j in range(1, (zahl + 1) // 2 + 1):
teiler, rest = divmod(zahl, j)

Bei range fehlt mir die Schrittweite, und die Motivation der Obergrenze versteh ich auch nicht.
divmod kenn ich nicht. Hast Du 'nen Link, wo man das nachlesen kann?

Ich bin ja blutiger Anfänger und wollte grad die Übergabe von Werten aus Funktionen testen.

Habe jetzt noch eine Funktion geschrieben. Sie funktioniert als Schnipsel in meinem extra Programm. Bis Du so gut, die einzubauen. Ich möchte vom prozessualen Programmieren wegkommen und muß die Parameterübergabe studieren.... Ich hab sie schon etwas angepasst an Deinen Stil aber wohl noch nicht genug....


"""def combinator(x,alle_teiler):
abzüge=0
schnittsumme=0
erg=0
länge = zahl //10
for L in range(0, Start+1):
for x in itertools.combinations(alle_teiler, L):
if len(x)==2:
erg=x[0]*x[1]
abzüge=int(länge/erg)
schnittsumme=schnittsumme+abzüge
return(x,erg,abzüge,schnittsumme)
"""
Sirius3
User
Beiträge: 18220
Registriert: Sonntag 21. Oktober 2012, 17:20

Nachlesen kann man sowas in der Dokumention: https://docs.python.org/3/library/functions.html#divmod

Was soll denn die Funktion `combinator` machen? Alles was eine Funktion braucht, muß sie über ihre Argumente bekommen, `zahl` und `Start` kommen aus dem nichts. `x` wird dagegen gar nicht verwendet.
Die for-Schleife ist falsch eingerückt.
Einbuchstabige Variablennamen sind nichtssagend und damit schwer verständlich. Alle Variablen schreibt man komplett klein.
In welchem Fall ist denn die Länge von x 2? Und warum muß man da viele andere Kombinationen durchgehen?
Statt `int(länge/erg)` benutz man Ganzzahldivision: `länge // erg`
Bykl
User
Beiträge: 99
Registriert: Donnerstag 5. Oktober 2017, 17:57

Danke an alle Helfer...
Antworten