primitive Pythagoreische Tripel

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

Hallo,
ich bin dabei mir Python beizubringen. Bisher habe ich unter Linux Bash-Skripte programmiert. Hier also mein erstes Programm. Zur Info:http://de.wikipedia.org/wiki/Pythagoreisches_Tripel
Zunächst läuft es schon mal fehlerfrei, aber noch nicht optimal.
An eine grafische Oberfläche habe ich mich noch nicht getraut, das kommt aber später noch. Der Input-Teil soll einfache Anwendungsmöglichkeiten veranschaulichen und ist daher über jede Kritik erhaben (Zeilenlänge etc.). :wink:
Daher ein paar Fragen:
Habe ich Funktionen geschrieben, die es schon in irgendwelchen Modulen gibt?
Ist die Funktion pPT so in Ordnung oder wäre ein Listenvergleich der Primfaktoren von a, b und c optimaler?
Wie kann ich das Ganze objektorientiert lösen?
Allgemein: Lob und Kritik?

Schon mal vielen Dank
JaKlaRo

Und hier das Programm:

Code: Alles auswählen

#! /usr/bin/env python
# -*- coding: utf-8 -*-

#  Ein Pythagoreisches Tripel (PT) ist eine ganzzahlige
#  Lösung der Gleichung a^2 + b^2 = c^2.
#  Aus einem primitiven PT lassen sich durch Multiplikation
#  weitere PTs erzeugen. Bsp.: a = 3, b = 4, c = 5.
#  Dann ist auch a = 6, b = 8, c =10 ein PT, aber nicht primitiv.
#  Interessant sind daher vor allem die primitiven PTs.

import sys

# Prüfe, ob ein Pythagoreisches Tripel vorliegt.
def IfPythTrip (a, b, c):
  if (a**2 + b**2) == (c**2):
    return True
  else:
    return False

# Primfaktorzerlegung von num.
# Bsp.: 8 -> (2, 2, 2), 110 -> (2, 5, 11); 13 -> (13)
def Factor (num):
  factorlist = []
  i = 2
  while i <= num / 2:
    if num % i == 0:
      factorlist.append(i)
      num = num / i
    else:
      i = i +1
  factorlist.append (num)
  return factorlist

# Eleminiere doppelte Primfaktoren aus factorlist.
# factorlist ist sortiert!
def DelDupList (factorlist):
  if len(factorlist) == 1:
    return factorlist
  else:
    for i in range (0, len(factorlist)-1):
      if factorlist[i] == factorlist[i +1]:
        del factorlist[i +1]
        DelDupList(factorlist)
        break
  return factorlist

# Prüfe, ob Pythagoreisches Tripel auch primitv ist.
def IfpPT (a, b, c):
  factorlist = DelDupList (Factor(a))
  for i in factorlist:
    if (b % i) == 0 and (c % i) == 0:
      return False
  return True
 
def Input_1 ():
  try:
    print 'Benötigt werden 3 positive Ganzzahlen.'
    a = int(raw_input('Gib a ein: '))
    b = int(raw_input('Gib b ein: '))
    c = int(raw_input('Gib c ein: '))
    if a < 1 or b < 1 or c < 1:
      print 'Falsche Eingabe'
      sys.exit()
    if IfPythTrip (a, b, c):
      if IfpPT (a, b, c):
        print '%d, %d und %d sind ein primitives Pythagoreisches Tripel' % (a, b, c)
        print '%d²+%d²=%d²' % (a, b, c)
        print '%d+%d=%d' %(a**2, b**2, c**2)
      else:
        print '%d, %d und %d sind ein Pythagoreisches Tripel, aber kein primitives.' % (a, b, c)
        print '%d²+%d²=%d²' % (a, b, c)
        print '%d+%d=%d' %(a**2, b**2, c**2)
    else:
      print '%d, %d und %d sind kein Pythagoreisches Tripel.' % (a, b, c)
  except ValueError:
    print 'Falsche Eingabe'
    sys.exit()

def Input_2 ():
  try:
    print 'Benötigt wird eine positive Ganzzahl.'
    max = int(raw_input('Gib a ein: '))
    count=0
    for i in range (1, max +1):
      for j in range (i +1, i * i):
        k = j +1
        while (k * k) <= (i * i + j * j):
          if IfPythTrip(i, j, k) and IfpPT(i, j, k):
            print '%d %d %d %d ' % (i, j, k, k**2)
            count = count +1
          k = k +1
    print 'Insgesamt %d primitive pythagoreische Tripel.' % (count)
  except ValueError:
    print 'Falsche Eingabe.'
    sys.exit()

def Input ():
  try:
    print 'Möchtest Du'
    print '1: Drei Zahlen prüfen.'
    print '2: Die Liste aller Tripel bis zu einer Obergrenze von a.'
    i = int(raw_input('Auswahl: '))
    if i == 1:
      Input_1()
    elif i == 2:
      Input_2()
    else:
      print 'Unbekannte Option.'
      sys.exit ()
  except ValueError:
    print 'Falsche Eingabe.'
    sys.exit()

if __name__ == '__main__':
  Input()
Zuletzt geändert von JaKlaRo am Dienstag 14. Juli 2009, 15:49, insgesamt 1-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Hallo JaKlaRo und Willkommen im Forum.

Weil dein Programm relativ schlecht lesbar ist, nur ein paar oberflaechliche Anmerkungen:

1. Ungebundene Strings sind keine Kommentare! Kommentare werden mit einem '#' eingeleitet und sogenannte Docstrings sind Strings nur, wenn sie direkt auf die Definition folgen.

2. Die ``for``-Schleife iteriert wie die der Bash ueber Sequenzen, du musst keine C-artigen nachbilden. Brauchst du doch den Index, nutze ``enumerate``

3. Benutze sprechende Namen und lass built-ins (wie ``list``) in Ruhe! Input{1,2,3} ist nun wirklich nicht hilfreich, sag was sie im abstrakten Sinn machen, beschreibe nicht die low-level Schritte.

4. Nutze kein nacktes ``except``! Gib immer die Exception an, die du auch Abfangen willst. In deinen konkreten Faellen ist das Konstrukt auch schaedlich, da du den wertvollen Traceback durch eine nichtssagende Fehlermeldung austauschst.

5. ``switch`` Anweisungen kannst du mit Dictionaries nachbilden, du brauchst keine ellenlangen ``if ... elif ... else`` Kaskaden

Zu guter Letzt: Du solltest dir mal [wiki]PEP 8 (Übersetzung)[/wiki] oder das Original anschauen.
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

So, ich habe einige Dinge geändert wie von cofi angeregt. Wie ich "enumerate" in der Funktion "DelDupList" anwenden soll, ist mir noch nicht ganz klar, da muss ich mich noch schlau machen.
Was cofi's 3. Punkt angeht, da brauche ich konkrete Vorschläge. Ich verstehe, was ich schreibe und wie ich es bezeichne, wie Ihr ja auch Eure Programme und Bezeichnungen versteht.

Gruß
JaKlaRo
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Zu dem, was aus Python-Sicht verbesserungsbedürfig ist, hat cofi ja schon wichtige Punkte benannt.

Wenn es dir bei deinem Programm auch auf Performance ankommt, dann solltest du einen anderen Algorithmus für die Erzeugung der pythagoreischen Zahlentripel implementieren. Mit einem guten Algorithmus kannst du die ersten 100.000 primitiven pythagoreischen Zahlentripel in der Größenordnung von 1 sec. erzeugen, mit deinem Algorithmus kommt man in dieser Zeit über ein paar Dutzend nicht hinaus (naja, vielleicht auch ein paar Hundert). :cry:

Und falls dein Interesse an pythagoreischen Zahlentripeln noch weiter anhält, dann wäre diese Aufgabe auch was für dich.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

JaKlaRo hat geschrieben:So, ich habe einige Dinge geändert wie von cofi angeregt.
Besser als die Änderungen nachträglich in den gezeigten Code einzubauen ist es, den geänderten Code neu zu posten, dann sieht man die Veränderungen besser.

Und: Wenn du den Code als Python-Code angibst, gibt es hier im Forum Syntax-Highlighting und der Code liest sich deutlich besser.

Was Punkt 3 angeht: Input_1 etc. sagt doch nichts aus, außer dass es um irgendeine Eingabe geht. Gemäß Python-Konvention würde man darüber hinaus erwarten, dass hier ein Exemplar der Klasse Input_1 erzeugt wird und nicht eine Funktion aufgerufen.

Ich persönlich finde die gewählte Form der Eingabe auch zu umständlich für den Anwender. Eine Alternative wäre, dem Anwender zu sagen, dass er entweder nur 1 Zahl eingeben soll (und was es damit auf sich hat) oder aber 3 Zahlen hintereinander (durch Komma oder Leerzeichen getrennt). Das Programm kann dann anhand der Eingabe - 1 Zahl oder 3 Zahlen - ermitteln, was der Anwender wünscht und erledigt seine Aufgabe dann direkt nach einer einzigen Anwendereingabe.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Punkt 3 enthaelt auch, dass man keine Abkuerzungen verwendet oder zumindest nur solche, die offensichtlich - fuer jeden Python-Programmierer, am Besten sogar fuer jeden Benutzer! - sind.
Konkret koenntest du deine Input-Funktionen so umbenennen: ``show_menu``, ``show_proof``, ``show_generation`` (unter der Annahme, dass du das in ein Modul wie ``user_interface`` steckst, damit du das nicht ergaenzen musst ;) )
Gleichzeitig solltest du ueberdenken die Ausgabe aus den Eingabe Funktionen zu entfernen.
Dazu kommen solche Namen wie ``a``, ``k``, ``j``, usw. das ist zwar in der Mathematik so gebraeuchlich, aber schwer zu lesen, benenn sie nach dem was sie repraesentieren!

Zu 1. da ich deine Aenderungen sehe: Wenn du die Kommentare als Strings unter deine Funktionsedefinitionen schreibst, sind es Docstrings ;)

Weil ichs gerade noch sehe: Was sollen denn die ganzen ``sys.exit`` ? gerade bei der Eingabe solltest du dem Anwender eher nochmal die Auswahl praesentieren, als das Programm zu beenden.

P.S. Nimms nicht persoenlich, wenn wir viel kritisieren, aber durch Lob lernst du nicht viel. Aber die (ansatzweise vorhandene) Trennung von Ausgabe und Logik ist ein guter Anfang ;)
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

Nächste Version:
"enumerate" ist drin
Docstrings sind drin
"sys.exit()" reduziert
Variablen umbenannt
numerix hat geschrieben:Ich persönlich finde die gewählte Form der Eingabe auch zu umständlich für den Anwender. Eine Alternative wäre, dem Anwender zu sagen, dass er entweder nur 1 Zahl eingeben soll (und was es damit auf sich hat) oder aber 3 Zahlen hintereinander (durch Komma oder Leerzeichen getrennt). Das Programm kann dann anhand der Eingabe - 1 Zahl oder 3 Zahlen - ermitteln, was der Anwender wünscht und erledigt seine Aufgabe dann direkt nach einer einzigen Anwendereingabe.
Wie lese ich 3 Zahlen ein. Da brauche ich etwas Code. :?

Und Dank an numerix für den Link, kann auch noch eingebaut werden. Die Optimierung bzw. Umschreibung des Algorithmus folgt später, wenn die vorliegende Version o.k. ist.

... und allgemeines Lob für den angenehmen Ton in diesem Forum.

JAKlaRo

http://paste.pocoo.org/show/128670/
Zuletzt geändert von JaKlaRo am Mittwoch 15. Juli 2009, 06:51, insgesamt 1-mal geändert.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Bitte mal den ganzen Code loeschen und auf http://paste.pocoo.org/ auslagen. Antworten wird sonst unmoeglich.

Aber was ich schon gesehen habe:
Ein unnoetiges ``eval``:
Du kannst dein Dictionary auch mit Strings - als Keys - und mit den Funktionsobjekten ``Exit`` usw. bestuecken (Aufruf: ``selection[answer]()``), dann musst du den Key nichtmal konvertieren, gleichzeitig kannst du auch "menschlichere" nehmen.

Befreie dich von den Abkuerzungen! Wenn du das Tippen sparen willst, dann nimm einen anstaendigen Editor (die haben Completion ;))

Und lies doch bitte mal PEP 8 - oder die Kurzuebersicht im Tutorial: http://docs.python.org/tutorial/control ... ding-style
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

JaKlaRo hat geschrieben:Wie lese ich 3 Zahlen ein. Da brauche ich etwas Code. :?

Code: Alles auswählen

eingabe = raw_input("Eine Zahl oder drei Zahlen durch Komma getrennt")
werte = map(int,eingabe.split(","))
if len(werte) == 1:
    print "Es wurde 1 Wert eingegeben"
    n, = werte
elif len(werte) == 3:
    print "Es wurden 3 Werte eingegen"
    a, b, c = werte
else:
    print "Falsche Eingabe."
Nur so als Gerüst und zum Verbessern. Die Eingabe ist nicht ausreichend gegen Fehleingaben geschützt, die Anwenderinformation ist zu dürftig etc.
map() ist hier nicht unbedingt nötig, aber es schadet ja nichts, wenn du es auch mal kennenlernst.
BlackJack

@JaKlaRo: Es wurde ja schon ein paar mal gesagt, aber wegen `IfpPT()` (Gesundheit!) möchte ich auch noch einmal unterstreichen, dass Abkürzungen zu sehr unverständlichem Quelltext führen können. :-)

Vergleiche ergeben in der Regel `True` oder `False`, dass heisst man kann das Ergebnis eines solchen Vergleichs auch direkt zurückgeben, wenn man eben dieses Ergebnis haben möchte. Also:

Code: Alles auswählen

def f(a, b):
    if a == b:
        return True
    else:
        return False

# <=>

def f(a, b):
    return a == b
Man sollte versuchen den Datentyp aus Namen heraus zu halten. Wenn man den Typ später mal ändern sollte muss man dann nicht den Namen überall ändern. Beispiel `factorlist` -> `factors`.

`DelDupList()` ist viel zu kompliziert. Falls es nicht auf die Reihenfolge ankommt, ist das mit ``list(set(factors))`` erledigt. Mit Beibehaltung der Reihenfolge ist es auch nicht besonders viel länger. Im Grunde würde ich die Funktion komplett einsparen, denn `IfpPT()` liesse sich so ausdrücken:

Code: Alles auswählen

def is_primitive(leg_a, leg_b, hypothenuse):
    return all(leg_b % i == 0 and hypothenuse % i == 0
               for i in set(factor(leg_a)))
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

Hallo,
ich habe einiges geändert und hoffe, dass das Programm besser lesbar ist. Ich habe einen neuen Algorithmus zum Erzeugen primitiver Pythagoreischer Tripel eingefügt und den alten entfernt. Die Ein- und Ausgabe wurde überarbeitet und ein längerer einführender Kommentar (bitte gründlich lesen).
Unzufrieden bin ich noch mit dem clear Befehl. Ich habe in meinen Modulen nichts derartiges gefunden, vielleicht ist das entsprechende Modul bei mir auch nicht installiert.
Eine allgemeine Frage noch: Ist die Reihenfolge der Funktionen hinsichtlich der Lesbarkeit so in Ordnung, ich habe sie schon umgeordnet?

Gruß
JaKlaRo

http://paste.pocoo.org/show/129050/
Benutzeravatar
snafu
User
Beiträge: 6833
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

JaKlaRo hat geschrieben:Unzufrieden bin ich noch mit dem clear Befehl.
Du könntest dir als Alternative höchstens das Modul [mod]curses[/mod] angucken. Das ist jedoch auch nicht plattformunabhängig (gibt's nicht unter Windows). Und von daher solltest du vielleicht einfach bei dem `clear` bleiben. Ansonsten könntest du bei Programmstart das System des Benutzers überprüfen und das entsprechende Verfahren bei Bedarf einleiten (`if 'windows':`...).
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

JaKlaRo hat geschrieben:Hallo,
ich habe einiges geändert und hoffe, dass das Programm besser lesbar ist.
Gegenüber dem, was du hier zuerst gezeigt hast, ist das wirklich ein ganz erheblicher Fortschritt. Noch ein paar Anmerkungen zum algorithmischen Teil:

1. Eine Primfaktorzerlegung ist hier nicht erforderlich. Ein pyth. Tripel (a,b,c) ist genau dann nicht-primitiv, wenn a und b nicht teilerfremd sind, d.h. wenn ggT(a,b) != 1 ist. Das lässt sich mit dem euklidischen Algorithmus einfacher, eleganter und auch performanter prüfen.

2. Falls du wirklich mal eine Primfaktorzerlegung (für "kleine Zahlen") brauchst, dann lässt sich dein Verfahren leicht erheblich beschleunigen: Bu brauchst nicht bis n/2 zu prüfen, sondern nur bis sqrt(n) und da alle Primzahlen außer 2 ungerade sind, brauchst du die geraden Zahlen > 2 überhaupt nicht als Teiler in Betracht ziehen.

3. Die Funktionen "is_lower" und "is_xor_modulo_2" halte ich für überflüssig. Das, was sie leisten, kannst du auch direkt codieren ohne den Umweg einer Funktion. In der Regel würde ich keine extra Funktion kodieren, wenn der Funktionsaufruf nur unwesentlich kürzer (in deinem Fall sogar länger ...) ist als das, was die Funktion leistet. Zu viele kleine Funktionen machen einen Code auch nicht übersichtlicher.

4. Die Produktion der primitiven Tripel lässt sich verschlanken. Statt zunächst s und t beliebig zu erzeugen und danach zu prüfen, ob genau einer der Werte ungerade ist, ist es sinnvoller, von vornherein nur solche s und t zu verwenden, die die Bedingung erfüllen, d.h. ist s ungerade, dann iterierst du mit t nur über die geraden Zahlen, ist s gerade, dann nur über die ungeraden.
Wenn du dann ein Tripel (a,b,c) gebildet hast, prüfst du, ob ggT(a,b) = 1 ist und wenn ja, hast du ein primitives Tripel gefunden.
BlackJack

@JaKlaRo: In `output_check_3_numbers()` enthalten die beiden innersten ``if``/``else``-Zweige grösstenteils identischen Code. Auch im letzten ``else`` steht Quelltext der sehr änhlich zum Anfang aller anderen Zweige ist.

Bei `formula_primitive()` und speziell `is_lower()` stellt sich die Frage ob man das wirklich in eine Funktion auslagern muss!? An sonsten gibt es `is_lower()` schon als `operator.lt()` in der Standardbibliothek.

`isnot_equal_factor()` sollte besser `is_coprime()` heissen.

Ebenfalls kein toller Name ist `is_xor_modulo_2()`. Da ist der Funktionsname länger als die Berechnung wobei der Informationsgehalt ziemlich gleich Null ist, weil der Name die Berechnung in Worten ist. Ob da statt des Aufrufs nun die Berechnung oder der Name steht, macht fast keinen Unterschied.

Insgesamt gibt es eine IMHO unglückliche Vermischung von Ausgaben, Berechnungen, und Tests in dem Programm. `create_primitive()` zum Beispiel sollte nie (0, 0, 0) zurückgeben, weil das einfach kein primitives pythagoräisches Tripel ist. Der erste und der letzte Test in dem ``if`` dort sollte auch nicht nötig sein, weil man dafür schon `s` und `t` vorher passend wählen beziehungsweise generieren kann.

Bei dem Programm bieten sich Generatorfunktionen an, und zwar eine, die einfach "unendlich" viele solcher Tripel generiert. Die ersten `n` kann man sich dann ganz einfach per `itertools.islice()` holen.

Den Bildschirm würde ich nicht löschen, zumindest nicht, solange die Anwendung nicht auch sonst die volle Kontrolle über die Textanzeige übernimmt, zum Beispiel mit `curses` oder `urwid`.

`dict.has_key()` ist veraltet, da sollte man besser den ``in``-Operator verwenden.
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

snafu hat geschrieben:[Ansonsten könntest du bei Programmstart das System des Benutzers überprüfen und das entsprechende Verfahren bei Bedarf einleiten (`if 'windows':`...).
Danke für den Tip, ich habe das Problem mit [wiki]Terminal Gr?abfragen[/wiki] gelöst. Der Link funktioniert nicht richtig. :( :?: Auf Terminal Größe abfragen klicken!

Vorläufig neue Version von `clearscreen()`, siehe Anmerkungen von BlackJack.

Code: Alles auswählen

def clearscreen():
    if os.name == 'posix':
        os.system('clear')
    else:
        print '\n' * get_terminal_dimension()[0]

def get_terminal_dimension():
    ''' Ermittelt Höhe und Breite des Terminals. '''
    s = pack('HHHH', 0, 0, 0, 0)
    return unpack('HHHH', ioctl(sys.stdout.fileno(), TIOCGWINSZ, s))[:2]
numerix hat geschrieben:Gegenüber dem, was du hier zuerst gezeigt hast, ist das wirklich ein ganz erheblicher Fortschritt.
Danke. Ich werde deine Anregungen noch einbauen. Vor Montag gibt es kein neues Listing, da ich arbeiten muss.
BlackJack hat geschrieben:`dict.has_key()` ist veraltet, da sollte man besser den ``in``-Operator verwenden.
Wie kann ich als Anfänger feststellen, wann Funktionen veraltet sind? Ich habe das ``dic.has_key()`` aus "A Byte of Python".
Zu den Funktionsnamen: Mein Englisch ist wirklich nicht gut, daher Danke für die Anregungen.
Zu `clearscreen()`: Wie schon snafu schrieb, ist `curses` nicht plattformunabhängig, `urwid` muss ich noch installieren, anschauen und verstehen.
Zur übrigen Kritik: Ich werde deine Anmerkungen durcharbeiten und das Programm entsprechend überarbeiten.

Gruß
JaKlaRo
BlackJack

Das man `dict.has_key()` nicht mehr verwenden sollte steht ziemlich unscheinbar in der Dokumentation: http://docs.python.org/library/stdtypes ... ct.has_key

Spätestens in Python 3 merkt man es dann, weil die Methode dort nicht mehr existiert.
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

Hallo,
ich habe die Anregungen von numerix und BlackJack übernommen. Die Ausgabe würde ich gerne über `curses` realisieren (`urwid` habe ich mir angeschaut, bin jedoch von der Vielzahl der Methoden etwas überfordert). Ich suche derzeit ein Beispiel für `curses`, um meine unendliche Tripelliste auszugeben, Hinweise nehme ich dankbar an.

Der aktuelle Code:

http://paste.pocoo.org/show/129744/

Gruß
JaKlaRo
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sieht doch eigentlich ganz gut aus. Nur noch ein paar Kleinigkeiten, die mir auf den ersten Blick aufgefallen sind:

"check_3_numbers" hätte ich anders benannt, da dort auch die Werte eingelesen werden. Die eigentliche Prüfung geschieht ja auch in einer anderen Funktion. Ähnliches bei "check_number".

"first_n_triples" geht noch einfacher. Meine "a" und "b" sollte man vielleicht noch durch vernünftige Namen ersetzen :roll:

Code: Alles auswählen

def first_n_triples (n):
    for counter, i in enumerate(itertools.islice(create_primitive(), n)):
        if i[0] > i[1]:
            a, b = i[1], i[0] #oder aber in gruselig: i[:2][::-1], oder i[1::-1]
        else:
            a, b = i[:2]
        
        print "%d\t%d\t%d\t%d" % (counter+1, a, b, i[2])
Deine "quit"-Funktion ist ein wenig überflüssig. Im Dictionary von "show_menu" kannst du auch gleich "sys.exit" angeben. Ich finde den Einsatz von "sys.exit" aber eher unelegant und würde die Schleife explizit beenden.

Die wait-Funktion finde ich etwas unglücklich. Wenn du unbedingt den Bildschirm löschen möchtest, dann würde ich das vor der Fehlermeldung machen (mit etwas mehr Information über den Fehler, welche Option den ungültig war) und dann direkt die neue Eingabeaufforderung anzeigen.

Einige PEP-8-Ausrutscher sind noch drin, aber die sehen mir eher nach Versehen aus und nicht systematisch.
Das Leben ist wie ein Tennisball.
Benutzeravatar
JaKlaRo
User
Beiträge: 10
Registriert: Dienstag 14. Juli 2009, 11:52
Wohnort: Bochum

Hallo,
die erste Umsetzung mit `curses` ist fertig. In der Methode `show_triples' ist eine Zeile auskommentiert, die nicht funktioniert, wo ist der Haken? :?:
In der Methode `read_n_numbers` gibt es etwas doppelten Code, soll ich diesen in eine neue Methode auslagern?
Bei einer großen Tripelliste (10000000) funktioniert das Programm nicht. :cry:
Aber:
curses.newpad(nlines, ncols)

Creates and returns a pointer to a new pad data structure with the given number of lines and columns. A pad is returned as a window object.

A pad is like a window, except that it is not restricted by the screen size, and is not necessarily associated with a particular part of the screen. Pads can be used when a large window is needed, and only a part of the window will be on the screen at one time. Automatic refreshes of pads (such as from scrolling or echoing of input) do not occur. The refresh() and noutrefresh() methods of a pad require 6 arguments to specify the part of the pad to be displayed and the location on the screen to be used for the display. The arguments are pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol; the p arguments refer to the upper left corner of the pad region to be displayed and the s arguments define a clipping box on the screen within which the pad region is to be displayed.

Die Anregungen von EyDu sind aufgenommen worden.

Gruß
JaKlaRo

http://paste.pocoo.org/show/130017/
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Warum muss man im Menü mit Space bestätigen, statt Enter?
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten