Pound - Ein Python-Sampling-Programm

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Pythonaya
User
Beiträge: 90
Registriert: Sonntag 26. Januar 2003, 11:34
Wohnort: Großbeeren (nahe Berlin)

Hey Pythongurus und SourceCode-Schlächter,
ich trau mich ja kaum, das hier reinzustellen, weil es sowas von unreif ist, ohne wirkliche Kommentare und wie meine Informatiklehrerin immer zu sagen pflegte "absoluter Spaghetti-Code, also neeeeee!!!!".
Bitte helft mir den Code zu vereinfachen oder bringt positive Kritik ein. Ich habe versucht irgendwie Struktur reinzubringen, aber irgendwie wird das nix.

Genug der langen Vorrede. Was ihr dazu braucht ist pygame. Ich habs mit Python 2.4 und der letzten pygame-Version geschrieben. Später soll auch noch pymedia zur Aufnahme von Samples benutzt werden...

Pound findet ihr unter: http://www.1kor13.de/Pound.exe
oder als .zip http://www.1kor13.de/Pound.zip

Ich bin noch sehr unzufrieden mit dem Programm... also zerreist es nicht gleich in der Luft ;-) Falls jemand eine bessere Lösung zu den Scrollbars hat... bitte schreiben
Zuletzt geändert von Pythonaya am Freitag 23. Juni 2006, 20:36, insgesamt 1-mal geändert.
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Äh, wie jetzt??
'ne exe-Datei einfach so herunterladen??

Wie wäre es mit einem Archiv? Sowas wie zip, tar.gz, tgz und so.
Und selbst wenn die Exe ein selbstentpackendes Archiv ist: es gibt hier viele, die nicht mit Windows arbeiten.
mfg, querdenker
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Stell doch hier einfach den Source Code in Python Tags rein. Wie sollen wir dir sonst helfen(falls es kein selbstentpacktes setup ist)
mfg

Thomas :-)
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

@Python Master47:
Ich denke, den kompletten Quelltext hier zu posten wäre nicht so ganz Sinn des Forums, da das durchaus ein paar hundert LOC sein können. Siehe dazu auch den Thread von Rebecca unter Offtopic, wg Problemen bei großen Beiträgen.

mfg, querdenker
Pythonaya
User
Beiträge: 90
Registriert: Sonntag 26. Januar 2003, 11:34
Wohnort: Großbeeren (nahe Berlin)

Also, es ist ein selbstentpackendes Archiv. Ich weiß ja nicht ob du immer gleich an Nutzer anderer Betriebssysteme denkst, ich habs jedenfalls nicht.

Aber damit du es dir auf jeden Fall angucken kannst, habe ich extra für dich nochmal eine .zip hochgeschubbert.
Die findest du ebenfalls unter http://www.1kor13.de/Pound.zip

Es sind 3 Pythondateien mit insgesamt aus dem Kopf überschlagenen 1000 Zeilen... ich glaube nicht, dass sie irgendjemand in diesem Thread hin haben möchte.
BlackJack

Also erstmal funktioniert das Programm nicht unter Linux:

Code: Alles auswählen

$ python PoundMain.py
/home/bj/src/python-forum/pound/PoundObjects2.py:0: SyntaxWarning: name 'YSCROLL'
 is assigned to before global declaration
/home/bj/src/python-forum/pound/PoundObjects2.py:0: SyntaxWarning: name 'XSCROLL'
 is assigned to before global declaration
Traceback (most recent call last):
  File "PoundMain.py", line 191, in ?
    Main()
  File "PoundMain.py", line 38, in __init__
    self.abs_parent = image.load(self.texpath+"abs_parent.gif").convert()
pygame.error: Couldn't open
 /home/bj/src/python-forum/pound\textures\abs_parent.gif
Das verbinden von Pfaden sollte man immer mit `os.path.join()` machen, dann ist man unabhängig davon, welchen Pfadtrenner das Betriebssystem verwendet.

Dann ist ``from xyz import *`` nicht so toll. Du holst Dir damit alle nöglichen Namen in Dein Modul die Du nie benutzt und die unter Umständen zu Problemen führen können. Bei `pygame` sind das ganze 267 Namen die man sich da herein holt.

Einige Zeilen in allen drei Quelltexten sind länger als 80 Zeichen.

Explizite Vergleiche mit den Konstanten `True` und `False` sind überflüssig. Das was man damit vergleicht, kann schon selbst als Wahrheitswert dienen:

Code: Alles auswählen

if self.visible == True or visible == False: pass
# ->
if self.visible or not visible: pass

PoundMain
=========

Wenn man so etwas wie ``for a in range(len(self.dropnames))`` schreibt, dann programmiert man in 99% der Fälle nicht in Python sondern macht nach was man aus anderen Sprachen wie C oder Java kennt. Wenn man über das Objekt iterieren will, dann kann man das direkt machen, ohne Indices:

Code: Alles auswählen

        self.dropbuttons = list()
        letters = 0
        for name in dropnames:
            self.dropbuttons.append(ButtonObject(name,
                                                 fntsize=20,
                                                 fgcolor=(0, 0, 0)
                                                 bgcolor=(255, 255, 255),
                                                 pos=(30 + letters * 8, 2),
                                                 is_img=False))
            letters += len(name)
Falls man doch einmal zusätzlich einen Index benötigt, dann gibt's die Funktion `enumerate()`:

Code: Alles auswählen

        b_textures = ('button_play.gif',
                      'button_pause.gif',
                      'button_stop.gif')

        self.buttons = list()
        for i, texture in enumerate(b_textures):
            self.buttons.append(ButtonObject(os.path.join(self.texpath,
                                                          texture),
                                             pos=(30 + i * 50, 580),
                                             is_img=True))
`Main.EventHandler()` folgt nicht den Namenskonventionen. Funktionsnamen werden für gewöhlich klein geschrieben, nur Klassennamen beginnen mit Grossbuchstaben. Dann brauchst Du auch nicht an jeden Klassennamen den Suffix "Object" anhängen, der sowieso nicht ganz richtig ist.

Ist es notwendig das `temp` in `Main.EventHandler()` ein Attribut von `Main` Objekten ist? Auf den ersten Blick würde ich sagen, dass es reicht, wenn es nur lokal gültig ist. Das gleiche gilt für `motion` in `ScrollObject.scroll()` und `temp` und `calc_pos` in `MasterObject.slave_hit()`.


PoundObjects2
=============

``global`` hat auf Modulebene keinerlei Wirkung. Die Zeile 11 ist also überflüssig.

Der Name `PoundObjects` ist noch verwirrender als `PoundObject`. Ein Klassenname im Plural suggeriert ein Container-Objekt in dem mehrere andere Objekte gespeichert werden.

Ausserdem fehlt die `__init__()` Methode bzw. sollte die `_init_object()` so heissen. In erbenden Klassen wird die `__init__()` dann per ``BasisKlasse.__init__(self,...)`` aufgerufen.

Die `init()` Funktion von `pygame` wird beim erzeugen von jedem `PoundObjects` Objekt erneut aufgerufen. Das sieht nach einem Fehler aus.

In `SoundObject.update_res()` wird das Argument `res` nicht benutzt.

Der Code nach dem ``return`` in `MasterObject.pop_slaves()` wird nie ausgeführt. Ausserdem sieht es nicht so aus als wenn Name und Funktion der Methode zusammenpassen.
Pythonaya
User
Beiträge: 90
Registriert: Sonntag 26. Januar 2003, 11:34
Wohnort: Großbeeren (nahe Berlin)

Vielen Dank für die vielen Verbesserungsvorschläge.
Ich werde mich demnächst mal ran setzten und dann eine neue Version hier posten. Bis dahin: Hat jemand keine bessere Idee, wie ich eine Scrollbar programmieren kann???

Und wenn man von den grob fahrläsigen Formfehlern absieht:
Wie kann ich den Quellcode effizienter und die Module variabler gestalten?
Pythonaya
User
Beiträge: 90
Registriert: Sonntag 26. Januar 2003, 11:34
Wohnort: Großbeeren (nahe Berlin)

BlackJack hat geschrieben:Die `init()` Funktion von `pygame` wird beim erzeugen von jedem `PoundObjects` Objekt erneut aufgerufen. Das sieht nach einem Fehler aus.
aus der pygame-doc hat geschrieben:[...]It is safe to call this init() more than once: repeated calls will have no effect. This is true even if you have pygame.quit - uninitialize all pygame modules all the modules.
Darum habe ich sie mehrmals ausführen lassen
Antworten