Seite 1 von 2
Punkt in Polygon bestimmen
Verfasst: Donnerstag 9. Juli 2009, 17:24
von feldmaus
Hallo Alle,
ich war mir jetzt nicht ganz sicher, ob ich einen neuen Thread zu diesem Thema aufmachen soll, da es ja schon ein paar gibt. Allerdings habe ich nicht alles verstanden und hätte gerne auch noch Eure Meinung zu meiner Kreation.
Wie die Überschrift sagt will ich bestimmen ob ein Punkt innerhalb eines Polygons liegt, dazu nutze ich 2 Verfahren, die auf der Strahl-Methode aufsetzen. Eine Methode ist schnell und siebt die meisten Fälle raus und die zweite Methode siebt das über gebliebene nochmal raus.
Hier mein Code.
http://pastebin.com/m467e3e67
Ich habe in meinen Code eine Methode zum Testen implementiert, haltet Ihr meinen Stil für ok oder habt ihr daran eine Kritik zu äußern ?
Was haltet Ihr von meinem Dokumentationsstil ?
Hier ein Link wo die Methoden beschrieben sind, aber ich habe sie bis jetzt nicht ganz verstanden habe.
http://rw7.de/ralf/inffaq/polygon.html
Die Langsame Methode leuchtet mir noch nicht ganz ein. Vielleicht kann mir das Jemand auf eine andere Weise vielleicht nochmal erklären, speziell die Ignore-Variante. Der Author erzählt was von einem Fehler. Ist der dort angegebene Code nur korrekt ?
Grüße Markus
Verfasst: Donnerstag 9. Juli 2009, 17:49
von Defnull
Was den Stil angeht:
Statt der unschönen if/else Kaskaden kannst du folgende etwas übersichtlichere Schreibweisen verwenden.
Code: Alles auswählen
def __testquick(self, point=point, polygon=polygon):
if np.amin(polygon[0]) <= point[0] <= np.amax(polygon[0]) \
and np.amin(polygon[1]) <= point[1] <= np.amax(polygon[1]):
return True
return False
# Oder gleich, wenn es in eine Zeile passt:
def __runTest(self, point, polygon):
return self.__testquick(point, polygon) and self.__testslow(point, polygon)
Außerdem können die beiden Test-Methoden ruhig public sein, sie sind ja auch einzeln recht nützlich.
Und ich will hoffen, das du diesen Testmodus-Quatsch raus wirfst und anständige Unit-Tests schreibst

Verfasst: Donnerstag 9. Juli 2009, 17:54
von Dauerbaustelle
`__irgendwas` ist nicht gut, weil schau mal was da rauskommt als Name:
Code: Alles auswählen
In [1]: class Foo(object):
...: __a = 1
In [2]: dir(Foo())
Out[2]:
['_Foo__a',
...
]
`__runTest` könntest du übrigens auch so schreiben:
Code: Alles auswählen
__runTest(self, point, polygon):
return self.__testquick(point, polygon) and self.__testslow(point, polygon)
Gruß
Verfasst: Donnerstag 9. Juli 2009, 19:05
von feldmaus
Dauerbaustelle hat geschrieben:`__irgendwas` ist nicht gut, weil schau mal was da rauskommt als Name:
Code: Alles auswählen
In [1]: class Foo(object):
...: __a = 1
In [2]: dir(Foo())
Out[2]:
['_Foo__a',
...
]
Ich wollte die Methoden nach aussen verstecken. Das das nicht 100% möglich ist wie bei C++ weiss ich bereits. Aber zumindest ist es ein kleiner Schutz, oder meinst Du was anderes ?
Verfasst: Donnerstag 9. Juli 2009, 19:08
von CM
Code: Alles auswählen
In [1]: class Foo(object):
...: __a = 1
...: b = 2
...:
...:
In [2]: dir(Foo())
Out[2]: ['_Foo__a',
...,
'b']
Na?
Verfasst: Donnerstag 9. Juli 2009, 19:11
von hendrikS
Ich hatte mich gefragt wozu überhaupt eine Klasse Pointtest. Trägt irgendwie nichts bei zur Lösung. Was soll den eine Instanz der Klasse darstellen?
Verfasst: Donnerstag 9. Juli 2009, 19:27
von feldmaus
hendrikS hat geschrieben:Ich hatte mich gefragt wozu überhaupt eine Klasse Pointtest. Trägt irgendwie nichts bei zur Lösung. Was soll den eine Instanz der Klasse darstellen?
Du meinst, warum ich nicht alles in die __init__ Methode schreibe ? Weil sonst die __init__ Methode, die ja einen wesentlich Teil der Steuerung darstellt, das ganze zu unübersichtlich macht. Ich nutze gerne Methoden wo ich unübersichtlichen Balast auslagern kann.
Der Grundgedanke ist ja zwischen einem Testmodus und Praxismodus zu unterteilen. Allerdings kann der Praxismodus wieder unterteilt werden in eine schnelle und eine langsame Methode.
Grüße Markus
Verfasst: Donnerstag 9. Juli 2009, 19:38
von hendrikS
Ansich sollte man dafür eine Funktion schreiben. So komplex ist der Algo doch nicht.
Vorstellbar wäre aber eine Klasse Polygon, die beispielsweise die Koordinaten der Eckpunkte enthält und vielleicht ein Attribut für konvex oder konkav. Dazu eine Methode isPointInPolygon(point).
Aus OOP Sicht der logischere Ansatz.
Verfasst: Donnerstag 9. Juli 2009, 20:20
von Leonidas
hendrikS hat geschrieben:Vorstellbar wäre aber eine Klasse Polygon, die beispielsweise die Koordinaten der Eckpunkte enthält und vielleicht ein Attribut für konvex oder konkav. Dazu eine Methode isPointInPolygon(point).
Da würde man doch eher ``__contains__`` implementieren, so dass man ``point in Polygon()`` nutzen kann.
Verfasst: Donnerstag 9. Juli 2009, 20:24
von hendrikS
@Leonidas: Das ist natürlich noch eleganter. Keine Frage.
Verfasst: Donnerstag 9. Juli 2009, 20:41
von Dauerbaustelle
feldmann_markus hat geschrieben:Ich wollte die Methoden nach aussen verstecken.
Warum?
Verfasst: Donnerstag 9. Juli 2009, 20:47
von feldmaus
Dauerbaustelle hat geschrieben:feldmann_markus hat geschrieben:Ich wollte die Methoden nach aussen verstecken.
Warum?
Damit anderer Programmierer die an meinem Projekt eventuell mitmachen nicht auf krumme Gedanken kommen. Das ist der Grundgedanke von privaten Attributen. Ansonsten wären wir wieder bei der Sicherheitsstufe Win95.

Verfasst: Donnerstag 9. Juli 2009, 20:54
von Leonidas
Dafür würde man wenn dann `_` nehmen. Außerdem ist sicherheit nicht gleich Sicherheit. Bei privaten Attributen geht es um API-Sicherheit, bei Sicherheit wie du das mit Win95 meinst geht es um Speicherschutz, wo Programme sich gegenseitig überschrieben konnten - also um Datensicherheit.
Verfasst: Donnerstag 9. Juli 2009, 21:23
von ms4py
Leonidas hat geschrieben:Dafür würde man wenn dann `_` nehmen.
Aber dann ist das Attribut ja nicht mehr nach außen geschützt. Es wird ja extra umbenannt, dass es über den normalen Namen (außen) nicht benutzbar ist...
Verfasst: Donnerstag 9. Juli 2009, 21:27
von Leonidas
Und wenn es umbenannt ist, dann ist es wie geschützt? Es ist genauso zugreifbar wie wenn ein _ davor steht, nur ist es unangenehmer zu tippen und macht den Quellcode letztendlich nur hässlicher.
Verfasst: Donnerstag 9. Juli 2009, 21:34
von ms4py
In meinem Eclipse-Outline werden sie richtig schön als private Methoden angezeigt.

Das ist ja auch nur eine persönliche Ansichtssache...
Ich bleib da bei, oder gibt es was offizielles, was dagegen spricht?
Verfasst: Donnerstag 9. Juli 2009, 21:38
von feldmaus
Leonidas hat geschrieben:Und wenn es umbenannt ist, dann ist es wie geschützt? Es ist genauso zugreifbar wie wenn ein _ davor steht, nur ist es unangenehmer zu tippen und macht den Quellcode letztendlich nur hässlicher.
Gut das sehe ich schon ein. Allerdings wenn ich als Python Programmierer in einem Gruppen Projekt ein Python Modul benutzen soll, dass von anderen erstellt wurde, dann werde ich unter Umständen mal schauen, was das Ding so kann um meine Aufgabe zu erfüllen, allerdings ist es vielleicht gar nicht erwünscht das ich einige Methoden benutzen soll. Methoden die privat sind, sagen sogar mir als Python Anfänger, vorsicht diese Methode oder Eigenschaft darfst Du nicht direkt benutzen. Anders ist es, wenn dies eine Public Methode ist. Ich weiss als Programmierer nicht eindeutig, ob ich sie benutzen darf oder nicht. Da ich allerdings alles privat gemacht habe, sollte jedem klar sein, das ich nicht will, dass er diese Methoden der Klasse benutzt.
Verfasst: Donnerstag 9. Juli 2009, 21:43
von Leonidas
Die Nutzer des Moduls sollte die Dokumentation lesen und wenn dort steht dass die Methode nicht benutzt werden sollte (oder gar nicht in der Dokumentation erwähnt wird, so wie Django das macht, als Beispiel für ein umfangreiches Framework) dann sollten sie auch wissen dass das eben keine gute Idee ist sie trotzdem zu nuten, da sie unter Umständen damit Probleme haben könnten.
Und Dokumentation muss man sowieso lesen, egal ob die Sprache nun ``private``-Keywords hat oder nicht.
Verfasst: Donnerstag 9. Juli 2009, 21:46
von cofi
ice2k3 hat geschrieben:In meinem Eclipse-Outline werden sie richtig schön als private Methoden angezeigt.

Das ist ja auch nur eine persönliche Ansichtssache...
Ich bleib da bei, oder gibt es was offizielles, was dagegen spricht?
PEP8 bezeichnet Namen mit einem fuehrenden `_` eindeutig als ``private`` und empfiehlt ``__`` nur, um Namenskonflikte zu vermeiden.
Um das ganze nochmal hervorzuheben: ``__`` loest NUR ein Name Mangling aus, dh der Name ist danach immernoch ueber ``_classname__name`` zugaenglich.
Verfasst: Donnerstag 9. Juli 2009, 22:15
von feldmaus
Leonidas hat geschrieben:Und Dokumentation muss man sowieso lesen, egal ob die Sprache nun ``private``-Keywords hat oder nicht.
Also würdest Du public oder schwach privat empfehlen ?