Anfängerfragen...schon wieder...

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
green
User
Beiträge: 2
Registriert: Freitag 14. August 2009, 10:42

Hi,

Seit ein paar Wochen lerne ich Programmieren. Zuerst C++, doch nachdem ich gemerkt habe, dass ich die ganze Zeit hauptsächlich die Syntax gelernt habe, anstatt "richtig" zu programmieren, habe ich mit Python angefangen.
Natürlich habe ich einige Fragen zu der Sprache, doch zuerst möchte ich mein erstes Python-Programm posten und jemanden bitten, über den Quelltext zu schauen und mich auf Fehler (bzw. "Stilbrüche", da das Programm an sich funktioniert) aufmerksam zu machen.

Code: Alles auswählen

def create_numbers():
    numbers = []
    n = input("n: ")
    for i in range(2, (int(n)+1)):
        numbers.append(i)
    return numbers

def sort_out(numbers):
    primenumbers = []
    while len(numbers)>0:
        factor = numbers[0]
        primenumbers.append(numbers[0])
        del numbers[0]
        counter = 0 #vor allem die nächste Schleife gefällt mir nicht, aber ich wusste nicht, wie ich die Elemente anders durchforsten soll, ohne diesen "counter" zu erstellen
        for number in numbers:
            if number%factor == 0:
                    del(numbers[counter])
            counter = counter+1
    return primenumbers

def main():
    print("Primzahlen von 2 bis n berechnen")
    numbers = create_numbers()
    primenumbers = sort_out(numbers)
    print("Die Primzahlen lauten: ")
    print(primenumbers)
    beenden = input("Enter zum Beenden druecken")

if __name__=="__main__": main()
Grüße,
green
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ohne jetzt auf die anderen Sachen einzugehen, aber Nutzereingaben fragt man möglichst in der main()-Funktion ab. Man könnte die Eingabe dann an eine Funktion übergeben, die auf Korrektheit prüft bzw. Anpassungen vornimmt (Eingabe sollte in Ganzzahl umgewandelt werden können). Und die so vorbereiteten Daten übergibt man dann zur weiteren Verarbeitung nach create_numbers(). Zumindest würde ich das so machen. Im kleineren Rahmen fasst man Annahme der Eingabe und Aufbereitung vielleicht eher so zusammen:

Code: Alles auswählen

def main():
    try:
        n = int(input("n: "))
    except ValueError:
        sys.exit("FEHLER: Eingabe muss Ganzzahl sein")
    create_numbers(n)
Anmerkung: Bitte verändere deinen Code so, dass man hier nicht mehr zur Seite scrollen muss. Das nervt...

Ich gehe übrigens davon aus, dass du Python 3.x benutzt, andernfalls bitte unbedingt raw_input() statt input() verwenden!
Zuletzt geändert von snafu am Freitag 14. August 2009, 16:38, insgesamt 2-mal geändert.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Willkommen im Python-Forum.

Dein Programm ist schon mal nicht schlecht. Doch du berücksichtigst nicht, dass `for` mehr kann, als über Zahlen zu iterieren. Schau dir z.B. mal `range` an. Das liefert doch schon genau das, was du in `create_numbers` mühsam baust. Außerdem gilt in Python eine nicht-leere Liste als "wahr". Du musst nicht extra prüfen, ob ihre Länge größer 0 ist. Statt eine Liste zu verändern, würde ich empfehlen, dir keine Sorgen um irgendwelche Performance oder Speichergrößen zu machen, und lieber immer wieder neue Listen zu erzeugen und so die falschen Werte auszufiltern. Gerade mit List-Comprehensions ist das sehr bequem.

Code: Alles auswählen

def create_numbers():
    return range(2, input("N:") + 1)

def sort_out(numbers):
    primes = []
    while numbers:
        factor = numbers[0]
        primes.append(factor)
        numbers = [n for n in numbers if n % factor]
    return primes

print(sort_out(create_numbers()))
Stefan
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

sma hat geschrieben:... würde ich empfehlen, dir keine Sorgen um irgendwelche Performance oder Speichergrößen zu machen, und lieber immer wieder neue Listen zu erzeugen
Naja, das hängt davon ab, welche Werte für n der Anwender gedenkt einzugeben. Ab ca. 10^5 dauert es dann doch schon ein Weilchen, bis man das Ergebnis zu Gesicht bekommt.

@green: Im Prinzip machst du so etwas wie das Sieb des Eratothenes. Wenn man das per Hand auf dem Papier macht, fertigt man ja auch nicht nach jedem Streichdurchgang ein neues Sieb an, sondern streicht immer weiter. Erst am Ende sammelt man die Reste ein. Eine solche Implementation wäre erheblich performanter.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Ich würd noch statt:

Code: Alles auswählen

    print("Die Primzahlen lauten: ")
    print(primenumbers) 
das verwenden:

Code: Alles auswählen

print('Die Primzahlen lauten: {primzahlen}'.format(primzahlen=primenumbers))
macht das ganze übersichtlicher und du kannst mehr gleichzeitig einfügen
z.B.

Code: Alles auswählen

print('Die Primzahlen {l}: {primzahlen}'.format(l='lauten', primzahlen=primenumbers))
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Dav1d hat geschrieben:Ich würd noch statt:

Code: Alles auswählen

    print("Die Primzahlen lauten: ")
    print(primenumbers) 
das verwenden:

Code: Alles auswählen

print('Die Primzahlen lauten: {primzahlen}'.format(primzahlen=primenumbers))
Das ist schon etwas übertrieben. Hier reicht ein simples ``"... {0}".format(primenumbers)``.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Jo, durchaus, bloß ich wollte eigentlich gleich zeigen, wie es ausführlicher geht
green
User
Beiträge: 2
Registriert: Freitag 14. August 2009, 10:42

Danke für die Tipps. Was ich nicht verstanden habe: Wieso genau sollte die Tastatureingabe in der main-Funktion erfolgen? Ich habe zum Beispiel neulich gelesen, dass in der main wenig stehen soll und alle Aufgaben möglichst in den Klassen und Funktionen erledigt werden.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Du solltest deine Funktionen sowohl von Eingabe-, als auch Ausgabelogik trennen, um das modular aufbauen zu koennen. So bist du nicht an eine bestimmte Form der Eingabe gebunden.

Ja Funktionen sollten eines machen und das richtig, aber die Aufgabe von ``main`` ist das ganze zusammenzuschnueren, moeglichst wenig heisst hier, dass du deine Programmlogik mit den Daten fuetterst, dass sie arbeiten koennen. Ist das nicht-trivial kann man das wiederum in Funktionen auslagern.

"Moeglichst wenig" heisst aber nicht, dass sie nur die naechste Funktion aufruft, sondern eben so viel, dass du dein Programm sinnvoll modular aufbauen kannst.
Antworten