Schnittpunkte von zwei Punktewolken

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.
BlackJack

@zauro: Man kann als Sortierkriterium auch die Elemente einer anderen Liste mit dem `key`-Argument angeben. Das klingt aber nicht besonders gesund. Wenn die Elemente zusammengehören sollten sie nicht in *zwei* Listen stecken, sondern in *einer*.
zauro
User
Beiträge: 9
Registriert: Freitag 8. Januar 2010, 23:01

Der Source Code, den ich angehangen hatte, funktioniert übrigens doch. Allerdings muss darauf geachtet werden, dass die x Komponenten aufsteigend sortiert sein müssen. Das habe ich gerade herausgefunden.

wie sollte denn dann die Liste ausschauen, wenn ich da x- und y- Koordinaten drin haben möchte ? so [[x1,y1],[x2,y2]] ?

Ich danke euch schon mal für die Hilfe. Hoffentlich wird mein Programmierstil immer besser, da ich einen Großteil meiner Promotion in Python schreiben werde.
BlackJack

@zauro: Zum Beispiel so, oder als Tupel für die Punkte.
BlackJack

@zauro: Wenn Du in mehr in Python machen willst, dann lohnt sich vielleicht noch eine ausführlichere Kritik am gezeigten Quelltext.

Einrücken solltest Du mit 4 Leerzeichen pro Ebene statt Tabs. Dann läufst Du nicht Gefahr irgendwann Einrückungsfehler zu haben, die man nicht so ohne weiteres sieht, und man kann Quelltext besser mit anderen Leuten austauschen.

Dateien ab Python 2.5 wenn es geht mit ``with`` öffnen. Dann werden die auch in jedem Fall wieder ordnungsgemäss geschlossen. Bei Python 2.5 braucht man dafür noch ein ``from __future__ import with_statement`` als erste Anweisung im Programm, ab 2.6 gibt es die ``with``-Anweisung auch ohne diesen ``import``. Die `dat_write()` könnte dann so aussehen:

Code: Alles auswählen

def dat_write(vektor, filename):
    with open(filename, 'w') as datei:
        datei.writelines('%s\n' % i for i in vektor)
Typprüfungen sollte man vermeiden, und wenn dann nicht mit `type()` sondern `isinstance()` durchführen. Aber wie gesagt: am besten vermeiden. Die Funktionen von `numpy` sind da in gewisser Hinsicht schlechte Beispiele, dass die meisten auf Skalaren *und* "iterables" funktionieren. Auf die Weise geht immer irgendwo etwas "duck typing" verloren. Also die `signum()`-Funktion macht da IMHO zum Beispiel zuviel in der Richtung. Da hätte ich eher eine für Skalare geschrieben und eine für "iterables", und zwar für *alle* und egal was da *drin* ist. Wobei eine extra Funktion für "iterables" vielleicht sogar zuviel ist, denn es gibt ja `map()` und `itertools.imap()`. Dein `signum()` funktioniert zum Beispiel nicht für `float`, `decimal.Decimal` aus der Standardbibliothek, oder `gmpy.mpq`-Exemplaren, und das alles nur wegen dem expliziten Test auf den Typ `int`. Die Funktion hier kann das alles:

Code: Alles auswählen

def signum(x):
    if x == 0:
        return 0
    if x > 0:
        return 1
    if x < 0:
        return -1
    
    raise TypeError('Can not determine sign of %r' % x)
Und wenn man jetzt eine Liste mit solchen Zahlen hat, kann man einfach ``map(signum, liste)`` schreiben. Statt der Liste geht auch jedes andere iterierbare Objekt mit entsprechendem Inhalt. Das wird bei Deiner Funktion auch wieder durch die Typtests verhindert.

Bei `isempty()` hast Du auch wieder ein Typproblem. Das funktioniert nur mit Listen. Die Verwendung von `len()` würde dagegen mit viel mehr Typen funktionieren.

Was zum Henker ist `isequal()`? Das ist wohl zu ziemlich das Umständlichtste was ich für einen einfachen Vergleich bisher gesehen habe:

Code: Alles auswählen

def isequal(a, b):
    return a == b
Aber dafür würde ich keine Funktion schreiben. Und bei Python sollte man `True` und `False` anstelle von Zahlen nehmen, wenn man einen Wahrheitswert meint. Aus historischen Gründen kann man damit sogar Rechnen, denn ein `True` verhält sich wie eine 1 und ein `False` wie eine 0. Ist nicht schön, und sollte man nur in Code-Golf-Contests machen, aber es geht, wenn's sein muss. :-)

Dein `unique()` hat ein gruseliges Laufzeitverhalten. Das ist ziemlich deutlich eine Mengenoperation, dann sollte man auch `set()` verwenden:

Code: Alles auswählen

def unique(x, y):
    return sorted(set(x).update(y))
`any()` gibt's schon! Liesse sich aber auch einfacher implementieren, wenn man's selber machen müsste:

Code: Alles auswählen

def any(iterable):
    return True in itertools.imap(bool, iterable)
*Hust* `arange()` macht genau das was `range()` macht, mit Hilfe der `range()`-Funktion. ;-)

Code: Alles auswählen

In [77]: range(5, 10)
Out[77]: [5, 6, 7, 8, 9]
Der Rest ist mir zu kompliziert. :-)
BlackJack

Und noch einmal ich. Hier sind zwei Varianten, die das gleiche Ergebnis für Dein Beispiel berechnen. Alles Python 2.5-Standard, keine externe Bibliothek:

http://paste.pocoo.org/show/163787/
zauro
User
Beiträge: 9
Registriert: Freitag 8. Januar 2010, 23:01

Hallo Black Jack,
sorry dass ich nun erst antworte. Aber ich hatte viel um die Ohren.

Danke, dass du meinen Sourcecode so umfangreich kommentiert hast. Du hast mir viele Sachen gezeigt, die ich so noch nicht kannte. Ich werd mich bei meinen folgenden Arbeiten darum bemühen diese zu berücksichten.

Wie kann man sich denn autodidaktisch am besten einen guten Programmierstil aneignen?

Gruß
Zauro.
lunar

zauro hat geschrieben:Wie kann man sich denn autodidaktisch am besten einen guten Programmierstil aneignen?
Ich würde sagen, in dem man versucht, möglichst wenig zu programmieren. ;) Aus Python Is not Java:
[…] Take a step back, and above all, stop writing so much code.

To do this, become more demanding of Python. Pretend that Python is a magic wand that will miraculously do whatever you want without you needing to lifting a finger. Ask, "how does Python already solve my problem?" and "What Python language feature most resembles my problem?" You will be absolutely astonished at how often it happens that thing you need is already there in some form. […]
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

zauro hat geschrieben:Wie kann man sich denn autodidaktisch am besten einen guten Programmierstil aneignen?
Wenn du an eine neue Programmiersprache kommst, vergiss was du vorher gelernt hast, den im Kontext der neuen Sprache ist dein Wissen nichts Wert.

Fang von neu an und erkunde die neue Sprache, spiel mit ihr und wenn du dass getan hast, wirst du den Weg, die Verbindungen und die Ähnlichkeiten, zu dem was du schon vorher in anderen Kontexten wusstest, sehen.
Antworten