HighEnergy ... Projekt von Anfängern

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

Danke für die Einrückungstipps. Ich hab in der PEP8-Anleitung gelesen, dass man maximal 79 Zeichen pro Zeile schreiben soll, und dann Zeilenumbrüche mit \ . Soll man das wirklich einhalten? Dadurch wird der Code ja nur noch länger ;)

Und wieso schreibst du vor deinen Kommentar "Docstring:" ? ^^
lunar

Man sollte sich definitiv an eine Obergrenze von 80 Zeilen halten, im PEP sind ja auch gute Gründe angegeben. Wenn diese Obergrenze ernsthaft ein Problem darstellt, ist das oft ein Zeichen dafür, dass Dein Quelltext überarbeitet werden sollte. Denn was man in 80 Zeichen nicht ausdrücken kann, ist meist auch so komplex, dass man es im Sinne der Lesbarkeit besser auf mehrere Anweisungen und damit Zeilen verteilt.

Auf den Backslash würde ich persönlich eher verzichten.
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

Stimmt, ich hab jetzt schon bei vielen Objekten die ganzen Attribute (pos, color, material etc) in jeweils eine Zeile gepackt, sieht echt übersichtlicher aus. Ich lad den Text wieder hoch wenn ich die PEP-Anweisungen umgesetzt hab :D

Soll ich auch Objekte auf Englisch bezeichnen? Und besser alles groß/alles klein/Große Anfangsbuchstaben etc... was findet ihr am besten?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

MC_MO hat geschrieben: Soll ich auch Objekte auf Englisch bezeichnen? Und besser alles groß/alles klein/Große Anfangsbuchstaben etc... was findet ihr am besten?
Man sollte nicht unbedingt mischen; also wenn Englisch, dann alles. Allerdings kommt es dabei ja schon auch auf den Adressaten an. Wenn das ganze nur ein interner Projekt sein soll, geht imho auch komplett deutsch.

Die Benennung ist doch durch PEP8 definiert!
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

PEP8 lässt dir 9 Bennenungsmöglichkeiten :P

Ein Mix aus Deutsch und Englisch lässt sich ja garnicht verhindern, da die Attribute ja "width", "height" und so sind. Mir fallen nur oft keine guten englischen Namen für die Objekte ein ^^
lunar

@Hyperion: Wenn man „nicht mischen“ sollte, bleibt einem gar nichts anderes, als nur Englisch zu verwenden. Die Standardbibliothek gibts nicht in Deutsch ;)

Im Ernst: Ausschließlich Englisch zu verwenden, verträgt sich am besten mit der Lesbarkeit des Quelltexts.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

lunar hat geschrieben:@Hyperion: Wenn man „nicht mischen“ sollte, bleibt einem gar nichts anderes, als nur Englisch zu verwenden. Die Standardbibliothek gibts nicht in Deutsch ;)
Ich meinte auch eher die eigenen Objekte ;-) Aber sonst hast Du da Recht.
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

So mein Code ist jetzt schon auf über 1000 Zeilen angestiegen, sieht aber schon viel ordentlicher aus. Wisst ihr eine Abhilfe für den Bewegungsablauf? Der is halt echt extrem lang und wiederholt sich bis auf ein paar Zeichen dauernd, kann man da nichts mahcen?
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

MC_MO hat geschrieben:So mein Code ist jetzt schon auf über 1000 Zeilen angestiegen, sieht aber schon viel ordentlicher aus. Wisst ihr eine Abhilfe für den Bewegungsablauf? Der is halt echt extrem lang und wiederholt sich bis auf ein paar Zeichen dauernd, kann man da nichts mahcen?
Schleife oder Funktion fallen mir jetzt spontan bei dem Begriff "Wiederholung" auf ;-)
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

Naja Funktionen hab ich ja so weit wie möglich verwendet, das Problem ist halt dass sich die Geschwindigkeit des Rotors sehr oft ändert, um einen realistischen Bewegungsablauf zu zeigen...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

MC_MO hat geschrieben:Naja Funktionen hab ich ja so weit wie möglich verwendet, das Problem ist halt dass sich die Geschwindigkeit des Rotors sehr oft ändert, um einen realistischen Bewegungsablauf zu zeigen...
Dann lagere doch die sich ändernden, aber zusammengehörigen Werte in einer Datenstruktur, die Du dann eben in einer Funktion verarbeitest.

Versuch zu analysieren, was die sich immer wiederholenden Schritte alle gemeinsam haben. Welche Art von Daten benötigen sie? Wie kann man diese gut aggregieren? Dazu kann man vermutlich Listen und Dictionaries nutzen, ggf. auch in Kombination.

Ich hab den Code von Dir grad nicht zur Hand, daher kein konreter Ansatz :-)
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

Also eigentlich sieht die Bewegung so aus:

Code: Alles auswählen

    for i in range (50):
        rate(25)
        hauptarm.rotate(angle=radians(-0.6),
                        axis=(-1,0,0),
                        origin=(0,2.5,0))
        Fahrtbewegung()
Es verändert sich nur die Dauer "range" und die Drehgeschwindigkeit "angle=radians". Über die Veränderung dieser 2 Werte konnte ich eine relativ flüssige Bewegung im echten Fahrturnus machen (Mit Ausschwingen beim Start, bis zum Überschlag, nach ein paar Runden ein Stop ganz oben und dann noch drehen in die andere Richtung, dann wieder anhalten).

Die Methode "Fahrtbewegung" beinhaltet das Drehen der Spinne um die eigene Achse sowie das drehen der Sitze um deren Aufhängung.

mfg
MC MO

P.s:Wer sich darunter nichts vorstellen kann, hier nochmal der Link zu einem YouTube-Video des Fahrgeschäftes:http://www.youtube.com/watch?v=XI6kVbBw38E
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

MC_MO hat geschrieben:Es verändert sich nur die Dauer "range" und die Drehgeschwindigkeit "angle=radians".
Und was spricht gegen eine Funktion, die diese 2 Parameter entgegennimmt?! ;-)
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

Äääähm...

Danke für den Hinweis, das bau ich doch glatt gleich ein...LOL!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Und die Werte packst Du ann eben z.B. in ein Tupel von Tupeln:

Code: Alles auswählen

# inner tuple: (count, angle)
move_data = (
    (50, -0.6),
    (45, 0.3),
    ...
)

# irgend wann dann eben so was:
for move in move_data:
    do_move(*move)
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

Achso...ich hätte es so gemacht:

Code: Alles auswählen

def move(x,y)
    for i in range (x):
        rate(25)
        hauptarm.rotate(angle=radians(y),
                        axis=(-1,0,0),
                        origin=(0,2.5,0))
        Fahrtbewegung()

#beimFahren dann:
move(50,-0.6)
move(70,-0.8)
#und so weiter
Welcher Ansatz ist "ordentlicher" (bevor ich jetzt Anfang die gesamte Fahrt neu zu erstellen^^)?
Die 2 Werte sollten nicht miteinander gekoppelt sein (also z.B. 45/0.6 und 50/0.8 ), sondern individuell anpassbar sein (z.B. 45/0.8 damit ich am Ende einen sauberen Halt bei 0° machen kann).

Und wo müsste ich bei dir die "Formeln" (hauptarm.rotate etc) reinschreiben?
Zuletzt geändert von MC_MO am Freitag 2. April 2010, 07:56, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ok ;-)

Vor allem, weil Du die so auch leicht in eine Externe Datei schreiben kannst! Somit ist es recht einfach, die Routen dynamisch zu gestalten, indem man eben einfach andere Daten in das Programm läd.

Dazu könntest Du Dir mal JSON (json-Modul) angucken. Das ist echt extrem simpel!

Als "Krönung" verwendest Du dann noch das optparse-Modul und ermöglichst es so, die Daten-Datei frei wählbar zu machen :-)
MC_MO
User
Beiträge: 25
Registriert: Sonntag 28. März 2010, 10:07

So hier ein Update:

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

Was könnte man noch machen? Die Bank-Erstellung find ich noch zu lang, das beheb ich noch ;)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Öhm, der Code ist immer noch total grausam ;-) Dir sollte eigentlich aufgefallen sein, dass ein Großteil deines Codes nahezu identisch ist, dann sollte man das auch zusammenfassen. Ein sehr schlechtes Zeichen sind Copy&Paste und die Durchnummerierung von Namen.

Und dann überall diese ganzen Zahlen. Benutze doch mal Konstanten. Wenn du in deinem Code irgendwo eine Einstellung anpassen willst, dann musst du das an ca. 100 Stellen tun. Mit Konstanten hast du genau eine Stelle.

Deine Klassen sind übrigens total überflüssig. Dort passiert genau nichts. Außerdem muss der Ganze Code raus aus der Modulebene in Funktionen. So kann man dein Modul nicht verwenden. Außerdem solltest du den Hinweis von Hyperion umsetzen. Die Funktionsaufrufe am Ende sind unglaublich unflexibel. Funktionen sind übrigens auch Objekte.

Und dann schaue doch bitte PEP 8 an. Die ganzen

Code: Alles auswählen

class Stair:
    def __init__ (self):
        Stair=list()
treiben einen doch in den Wahnsinn ;-)

Sebastian
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich finde das alles ziemlich "lang"!

Wozu die ganzen Klassen? Eigentlich halten die nur Attribute - das könnte man dann auch über ein Dictionary lösen.

Außerdem sind viele Attribute der Klassen auch nur copy&paste! Wieso nicht weiter abstrahieren und dann Listen vbon Objekten gleichen Musters anlegen?

Ich würde generell diese vielen Daten auslagern (-> JSON, o.a.). Die gehören imho ja nicht direkt zum eigentlich Programm.

Code: Alles auswählen

bench_1.rotate(angle=0*pi/3,axis=(0,1,0))
bench_2.rotate(angle=1*pi/3,axis=(0,1,0))
bench_3.rotate(angle=2*pi/3,axis=(0,1,0))
bench_4.rotate(angle=3*pi/3,axis=(0,1,0))
bench_5.rotate(angle=4*pi/3,axis=(0,1,0))
bench_6.rotate(angle=5*pi/3,axis=(0,1,0))
Wieso packst Du das nicht in eine Liste? Wenn man Bezeichner durchnummeriert, hat man etwas falsch gemacht!

Wieso nutzt Du keine Funktionen? Zudem ist der ganze Code auf Modulebene! Das ist ziemlich unschön.

Code: Alles auswählen

"""Motion"""
while True:
    time.sleep(5)
    move_spider(1,0.1)
    move_spider(2,0.2)
    move_spider(3,0.3)
    move_spider(4,0.4)
    # usw.
Wieso nicht diese Werte auch in eine Datenstruktur auslagern (Hatte ich doch schon mal angeregt iifc!) und dann mit einer Schleife iterieren?

Das ganze ist irgend wie komplett unschön!

Viel zu viele Magic Numbers im Quellcode.

Ich würde versuchen fast alle diese Werte in eine externe Datendatei auszulagern und diese zu Beginn einzulesen und dann Schritt für Schritt Objekte zusammenzubauen, die sich sinnvoll aus den kleint möglichen Wertpaaren zusammensetzen.

Beispiel:

Code: Alles auswählen

        PILLAR_1=box(pos=(310,-660,-230),
                     length=30,
                     width=30,
                     height=1500,
                     color=(0.8,0.8,0.8),
                     material=materials.emissive)
Davon hast Du in der Klasse Scenery drei Stück.

Augenscheinlich brauchst Du für eine box also die Parameter: pos, length, width, height, color und material.

in JSON sähe das so aus:

Code: Alles auswählen

{
    "box_mitte": {
        "type": "box"
        "pos": [310,-660,-230],
        "length": 30,
        "width": 30,
        "height": 1500,
        "color": [0.8, 0.8, 0.8],
        "material": "emissive"
    },
...
}
Dies könntest Du nun parsen und eine neue box anlegen:

Code: Alles auswählen

import json

def load_data(filename):
    with open(filename, "r") as infile:
        scene = json.load(infile)
    return scene


def create_scene():
    create_funcs = {
        "box": create_box,
        "sphere": create_sphere,
        # usw.
    }
    # hier ein Dictionary für die fertigen Objekte
    objects = {}
    scene_data = load_data("scene.json")
    for name, values in scene_data.iteritems():
        objects[name] = create_funcs[values["type"]](**values)
    return objects
Die einzelnen "create"-Funktionen erzeugen dann eben je nach Art ein solches Objekt und geben es zurück. Dieses wird dann in das Dict objects gepackt und kann später weiter genutzt werden; etwa zum Bewegen einzelnen Objekte.
Dies könnte man auch in die JSON-Datei integrieren

Code: Alles auswählen

{
    "sphere_aussen": {
        "type": "sphere",
        "pos"= [0, -1615, 0],
        "radius": 15000,
        "color": [0, 0, 0.5]
        "rotations": [
            {
            "angle": ...
            },
            usw.
        ]
    }
}
Um diesen Klasse-Wust wegzubekommen, könnte man noch eine weitere Ebene in die JSON-Datei einbauen und in Python dann als "höchstes" Dictionary ablegen.

Code: Alles auswählen

{
    "scenery": {
        hier dann alle Daten für die Scene
    },
    "schriftzug": {
        hier alles für diesen High enegery Text
    },
    usw.!
}
So, ich hoffe das waren mal ein paar Anregungen!

Auf jeden Fall sagt dieses Script, dass Du von guter Modellierung noch weit entfernt bist - das ist kein Wunder als Anfänger, aber ein Zeichen, sich nicht zu hohe Ziele zu stecken (ich verweise da mal auf den Idee-Thread ;-) )

Wichtig ist immer, zu erkennen, welche Strukturen man geschickt und sinnvoll zusammenpacken kann. Für diese implementiert man dann Datenstrukturen und Operationen darauf. So wächst Stück für Stück etwas zusammen.
Antworten