Optimierungsbedarf Code von BMaxzu Python

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.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 2. Februar 2008, 19:04

Yogi hat geschrieben:Also wurde immer dann eine Instanz erzeugt, als ich eigentlich nur auf eine Klassenmethode bzw. Klassenvariable zugreifen wollte??

Wenn dem so ist, wie greife ich dann darauf zu ohne eine Instanz zu erzeugen?
Naja, etwa so:

Code: Alles auswählen

u = Universium()
u.getBingos()
Du erstellst halt nicht irgendwelche neuen Instanzen sondern verwendest die, die es schon gibt.
Yogi hat geschrieben:@Blackjack: Ob ich das funktionale hinkriege bezweifele ich momentan. Das hat so was Perliges ;) Aber je mehr ich mich damit befasse, desto mehr imponiert mir die Sprache. Aber komplex ist sie trotzdem. Die Tücke liegt im Detail aber auch im wesentlichen. Ich habe leider noch keine ansprechende Literatur finden können. Immer nur Syntax oder die bekannte Rangehensweise.
Nein, perlesk ist der Code eher nicht. So einen Code würde man eher in Haskell, ML oder OCaml vermuten. Funktionale Programmierung ist eben nicht ganz so leicht wie der Name vermuten lässt.
Yogi hat geschrieben:Was hast du übrigens mit dem C++ Code gemacht, jetzt verstehe ich ja gar nichts mehr...?
Gepatcht, damit er in g++ kompiliert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Yogi
User
Beiträge: 80
Registriert: Montag 21. Januar 2008, 16:35
Wohnort: Bonner

Samstag 2. Februar 2008, 19:39

u = Universium()
u.getBingos()
ja aber so erzeuge ich doch auch erst eine Instanz, oder etwa nicht??
BlackJack

Samstag 2. Februar 2008, 20:12

@Yogi: Auf Klassenattribute greift man über die Klasse zu. Wer hätte das gedacht. ;-) Wobei Du keine Klassenmethode hast. Und wahrscheinlich eine statische Methode meinst. Siehe `classmethod()` und `staticmethod()`. Wobei zumindest `staticmethod()` häufig ein Zeichen dafür ist, dass man eine Funktion stattdessen verwenden könnte.

Hier ist noch einmal eine etwas weniger funktionale Variante, die zumindest in O-Notation schneller sein müsste als das Sortieren:

Code: Alles auswählen

    def direkt(self):
        def full_edges(n):
            return (n - 1) * n // 2
        
        print 'Start'
        start = datetime.datetime.now()
        
        histogram = defaultdict(int)
        for planet in self.countPlanets:
            histogram[tuple(planet.dingens)] += 1
        
        Universum.countBingo = sum(imap(full_edges, histogram.itervalues()))
        
        return datetime.datetime.now() - start
`defaultdict` kommt aus dem `collections`-Modul und `imap()` aus `itertools`.

Da ich mich in C++ nicht so gut auskenne, habe ich das mal in D implementiert: http://paste.pocoo.org/show/25284/

Vielleicht ist das ja verständlicher.

`check_doubles_old()` ist die C++-Variante von Deinem Bekannten in D. Da hier mit Referenzen auf Objekte und nicht mit einem zweidimensionalen `int`-Array gearbeitet wird, ist die Funktion schon ein kleines Stück langsamer. ca. 1.1 Sekunden für 10000 Planeten, statt der 0.71 Sekunden in C++.

Es gibt eine Bindung an OCaml, d.h. man müsste Python auch mit OCaml-Code erweitern können. Also ginge funktional schon. ;-)
Yogi
User
Beiträge: 80
Registriert: Montag 21. Januar 2008, 16:35
Wohnort: Bonner

Samstag 2. Februar 2008, 20:44

Oh Mann, warum muss jede Sprache die Dinge anders nennen :evil:
Static methods in Python are similar to those found in Java or C++.
Langsam weiss ich nicht mehr wo ich anfangen soll, ich fordere eine einheitliche Sprachregelung!!
In BlitzMax nennen sich z.B. Klassenvariablen Global KlassenVar und liegen innerhalb einer Klasse, aber ausserhalb der Methoden.
Field Instanzvariable gilt per Instanz, auch deklariert ausserhalb von Methoden.
Eine Funktion die Methode heisst ist bezogen auf eine Instanz, Funktionen mit dem Namen Function bezogen auf eine Klasse.

Weg damit! in Python ist alles anders :? Wo fange ich an? Ich habe den Fehler gemacht über Python Kompakt ran gehen zu wollen, also mehr Syntax-Mässig, der ganz falsche weg. Muss nach was vernünftigem suchen!
Gibt es denn ein empfehlenswertes Buch, das auch 2.5 abdeckt? Am liebsten in deutsch. Oder die Original-Docs in verständlicher, denn wie sonst komme ich jemals auf die itertools oder jetzt die defaultdict, die es auch erst ab 2.5 gibt?

( bevor ich mir D anschaue, lerne ich lieber noch was C, das kann ich wenigstens hier anwenden, obwohl auf den ersten Blick kommt mir D einleuchtender vor als dein Python-Code ;), halt eher bekanntes Terrain...)
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 8. Februar 2008, 12:34

Yogi hat geschrieben:Oder die Original-Docs in verständlicher, denn wie sonst komme ich jemals auf die itertools oder jetzt die defaultdict, die es auch erst ab 2.5 gibt?
Was findest du denn unverstaendlich. Statt so unspezifiziert rumzumeckern kannst du auch eine Mail mit deinen Einwaenden an die docs-Liste schreiben um die Original-Docs zu verbessern. Dann haben alle was davon.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
noise
User
Beiträge: 62
Registriert: Donnerstag 7. Februar 2008, 00:15

Freitag 8. Februar 2008, 17:49

Yogi hat geschrieben:Oder die Original-Docs in verständlicher, denn wie sonst komme ich jemals auf die itertools oder jetzt die defaultdict, die es auch erst ab 2.5 gibt?
Huch?

1. http://docs.python.org/
2. http://docs.python.org/whatsnew/whatsnew25.html
3. http://docs.python.org/lib/lib.html

Ich finde, mit Abstand, das Python eines der vollständigsten und umfangreichsten Dokumentionen hat. Natürlich kommt es schon mal vor das etwas nicht ganz korrekt ist, aber man kann sich doch direkt an die Zuständigen wenden.
Yogi hat geschrieben: ( bevor ich mir D anschaue, lerne ich lieber noch was C, das kann ich wenigstens hier anwenden, obwohl auf den ersten Blick kommt mir D einleuchtender vor als dein Python-Code ;), halt eher bekanntes Terrain...)
Ich finde D ist das C/C++ das ich mir immer gewünscht habe. Aber die frage ist auch mehr eine Ideologische:
1. Schwimme ich mit dem Mainstream (C++/Java/$INSERT_HERE_YOUR_LANGUAGE) oder entscheide ich mich für eine Sprache die nicht so populär ist aber meinem Denken mehr entspricht.
2. Muss/will ich damit Geld verdienen oder nicht.

Ich für mein Teil finde D sehr schön und mäße dem ein größeren Wert bei als z.B. C++ und Java. Obwohl ich reines C auch sehr schön finde und sehr Performant. Aber ich will ja auch nicht mit Programmieren mein Geld verdienen. Wenn dem so wäre würde ich C++ und/oder Java Programmierer sein, da die Chancen besser aussehen eine Anstellungen zu finden, statt mit Python. Die Chancen mit D eine Anstellungen zu finde sind gleich null, da die Sprache sehr Jung ist und die IT-Welt nocht nicht wirklich was von mitgekriegt hat.
Yogi
User
Beiträge: 80
Registriert: Montag 21. Januar 2008, 16:35
Wohnort: Bonner

Freitag 8. Februar 2008, 19:20

@Leonidas: Du hast mich da missverstanden. Das sollte nicht als gemeckere rüber kommen. Es ist halt nur so, dass Python eine andere Philosophie hat, wie die Sprachen die ich kenne. Und dafür sind die Docs MIR manches male zu unübersichtlich. Vielleicht bräuchte ich sowas wie: von Java nach Python oder so ähnlich. Mein gepackt Buch finde ich z.B sehr nett, leider isses die 2.Auflage mit Python 2.4. Das in der 2.5 die OOP-Funktionalität erweitert worden ist, war mir nicht bewusst, mein Fehler. Jetzt habe ich mir die 3. Auflage geholt und bin sehr zufrieden. Sogar die wichtigen Properties werden da erklärt. Von da aus, komme ich wahrscheinlich besser mit den Original-Docs klar. Muss halt erst einmal alles sickern...

@noise: siehe oben, definitiv kein Gemecker, ehrlich :)
Ich lerne jetzt noch C dazu und bin überrascht wie gut ich damit zurecht komme. Endlich mal dieses ganze Zeigergedöns verstehen. Aber bevor ich mir C++ nochmal tiefer gehend anschaue, werde ich mich lieber noch mehr in Java vertiefen. Aber momentan reicht mir und brauche ich auch nicht mehr als Python, C und BlitzMax und ein bisschen Java.

Ich bin ehrlich sehr begeistert von Python und den ganzen schönen netten Modulen.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 10. Februar 2008, 11:49

Yogi hat geschrieben:Und dafür sind die Docs MIR manches male zu unübersichtlich. Vielleicht bräuchte ich sowas wie: von Java nach Python oder so ähnlich. Mein gepackt Buch finde ich z.B sehr nett, leider isses die 2.Auflage mit Python 2.4. Das in der 2.5 die OOP-Funktionalität erweitert worden ist, war mir nicht bewusst, mein Fehler. Jetzt habe ich mir die 3. Auflage geholt und bin sehr zufrieden. Sogar die wichtigen Properties werden da erklärt. Von da aus, komme ich wahrscheinlich besser mit den Original-Docs klar. Muss halt erst einmal alles sickern...
Also es gibt schon Dokumente wie "What's new in Python X.Y", sind meiner Meinung nach durchaus lesenswert.
Und, ähm, wo in 2.5 OOP erweitert worden ist, ist mir nicht so ganz klar. Wenn du Deskriptoren meinst, die sind mindestens seit 2.2.3 dabei.
Und Python is not Java ist sicherlich für dich nützlich. Du darfst eben nicht erwarten, alles in der offiziellen Doku zu finden, denn dann würde sie absolut endlos sein ("CPython-Module in OCaml kompilieren", möglich, aber nicht in der offiziellen Dokumentation nötig).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Yogi
User
Beiträge: 80
Registriert: Montag 21. Januar 2008, 16:35
Wohnort: Bonner

Montag 11. Februar 2008, 01:24

Ich kann dir genau sagen was für mich neu ist, da nicht in Michael Weigends Python Ge-Packt Buch 2. Aufl.. Statische Methoden und die Properties z.B fehlten komplett.

Wobei mir jetzt was witziges aufgefallen ist. In meiner 3. Ausgabe werden statische Methoden anders definiert als in dem Online-Index bei Amazon und wie in der Python Doc. Und zwar definieren letztere statische Methoden mit @staticmethod vor der Methode und in seinem Buch werden die einfach nur mit staticmethod(Methodenname) aufgerufen :?

Kann ja sein, dass das alles schon vorher drinne war, aber wenn ich als Neueinsteiger einen Titel vorliegen habe, der sich 'praktische Referenz' nennt, dann gehe ich erst einmal davon aus, dass alles wesentliche enthalten ist. Wenn er jetzt plötzlich in der 3.Auflage neues einbringt, dann gehe ich erst einmal davon aus, dass sie neu sind und nicht nur vergessen worden sind.

Aber trotzdem danke für den hilfreichen Link wegen Java und Python.
noise
User
Beiträge: 62
Registriert: Donnerstag 7. Februar 2008, 00:15

Montag 11. Februar 2008, 02:15

Yogi hat geschrieben:Und zwar definieren letztere statische Methoden mit @staticmethod vor der Methode und in seinem Buch werden die einfach nur mit staticmethod(Methodenname) aufgerufen :?
http://www.python.org/dev/peps/pep-0318/
http://www.python.org/doc/2.4/whatsnew/whatsnew24.html
http://wiki.python.org/moin/FrontPage?a ... arch=Titel

Da ich kein Java-Programmierer bin und daher nicht weiß ob es in Java First-Class-Functions und closures gibt (darauf basiert halt das ganze), schreibe ich das folgende.

mit ``@`` Dekoriert man Funktionen und Methoden. Dieses Future wurde in Python 2.4 eingeführt, weil, IMHO, die Python Programmierer angefangen haben immer mehr Funktionen zu schreiben die als Decorator eingesetzt wurden.

Dekoratoren werden definiert, in dem der äußeren Funktion eine inner definiert wird, die beim aufruft der äußeren zurückgegeben wird. Stichwort closures

Code: Alles auswählen

def mydeco(f):
    def inner(*args, **kwargs):
        print "args: %r; kwargs: %r" % (args, kwargs)
        return f(*args, **kwargs)
    return inner

@mydeco
def my_func1(a, b=2):
    return a * b

print my_func1(2)
Dabei ist

Code: Alles auswählen

@mydeco
def my_func1(a, b=2):
    return a * b
äquivalent mit

Code: Alles auswählen

def my_func1(a, b=2):
    return a * b
my_func1 = mydeco(my_func1)
``@`` ist also nur syntaktischer Zucker, um das Dekorieren näher an die Funktionsdefinition zu "Binden".


So, dann gibt es noch folgenden Form, die es zulässt dem Decorator Argumente zu übergeben:

Code: Alles auswählen

def mydeco(counts):
    assert not hasattr(counts, "__call__")

    def inner(f):
        def inner_inner(*args, **kwargs):
            print "args: %r; kwargs: %r, counts: %r" % (args, kwargs, counts)
            return f(*args, **kwargs)
        return inner_inner
    return inner

@mydeco(100)
def my_func1(a, b=2):
    return a * b

print my_func1(2, b=3)
Dies ist äquivalent mit der hässlichen Variante

Code: Alles auswählen

def my_func1(a, b=2):
    return a * b
my_func1 = mydeco(100)(my_func1)

Dann gibt es noch Deskriptoren (``property`` und ``classmethod`` sind sogenannte Deskriptoren), die man dann auch als Decorator benutzen kann.

Zum Thema descriptors:
http://docs.python.org/ref/descriptors.html
http://www.python.org/doc/2.2.3/whatsne ... 0000000000
http://users.rcn.com/python/download/Descriptor.htm
http://gulopine.gamemusic.org/2007/nov/ ... rt-1-of-2/

Yogi hat geschrieben:Kann ja sein, dass das alles schon vorher drinne war, aber wenn ich als Neueinsteiger einen Titel vorliegen habe, der sich 'praktische Referenz' nennt, dann gehe ich erst einmal davon aus, dass alles wesentliche enthalten ist.
Darauf kannst du dich aber nicht verlassen. Bücher veralten schneller als man denkt und die Online-Dokumentation ist immer up2date.

EDIT:
Klassen kann man momentan nicht mit ``@`` dekorieren (Da muss man ahlt mit der gewöhnlichen Syntax leben). Class-Decorators mit ``@`` wird es aber in Py3K geben, worauf ich mich schon richtig freue :D
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 11. Februar 2008, 10:24

noise hat geschrieben:Da ich kein Java-Programmierer bin und daher nicht weiß ob es in Java First-Class-Functions und closures gibt
Wenn ich mich richtig erinnere: Nein (Higher order functions) und Nein (Closures), da es keine Nested Functions gibt. Vielleicht kann man mit Nested Classes so etwas ähnliches bauen...

Interessanterweise kann GCCs Gnu89-C-Dialekt Nested Functions :D
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Montag 11. Februar 2008, 10:59

Wobei der `gcc` da soweit ich weiss auch nur verschachtelte Funktionen kann und keine Closures. Wenn der äussere Funktionsaufruf beendet ist, sind auch alle lokalen Variablen weg, weil die auf dem Stack liegen.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 11. Februar 2008, 11:05

Ja, stimmt:
gcc info page hat geschrieben:If you try to call the nested function through its address after the containing function has exited, all hell will break loose.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Yogi
User
Beiträge: 80
Registriert: Montag 21. Januar 2008, 16:35
Wohnort: Bonner

Montag 11. Februar 2008, 11:50

Hilfe!! Ich habe das Gefühl, dass immer wenn ich glaube was verstanden zu haben, sich ein neuer Abgrund auf tut...
Python ist ja so dermaßen in der stetigen, weiteren Entwicklung, dass ich als Python-Newbie gar nicht weiß wo ich da einsteigen soll. Zu jedem Thema gibt es ellenlange tiefer greifende Dokumentationen. Da komme ich langsam vor lauter lesen nicht mehr zum programmieren :shock:

Am besten ich fange einfach an und halte alles refaktorierfähig :wink:

PS: Mit den closures habe ich noch so meine Schwierigkeiten. Auch hatte ich mich daran gewöhnt alles in Klassen und Objekten zu sehen, aber in Python ist das scheinbar gar nicht immer so erwünscht, oder??
BlackJack

Montag 11. Februar 2008, 12:07

Als Objekte solltest Du schon alles sehen (können). Alles in Python ist Objekt, inklusive Funktionen. Man muss halt nur nicht unbedingt zu jedem Objekt eine Klasse sehen, es gibt ja auch Funktionsdefinitionen um Funktionsobjekte zu erstellen. Und die können dann auch Closures sein.
Antworten