vorhandene Tupel werden nicht übernommen

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.
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Problem ist hier beschrieben.

Hallo alle miteinander,

ich hab ein kleines (vielleicht auch großes) Problem mit einer while-schleife.

Ich habe 4 geordnete Zahlenpaare gegeben (Koordinaten), diese sind wie ein Rechteck angeordnet. Nun sollen auf den senkrechten Achsen Zwischenpunkte berechnet werden, die für später wichtig sind. Also auf den y-Wert der Punkte 1 und 2 soll ein bestimmter Wert m addiert werden und das ganze, n mal. D.h. solange, bis man bei der Addition von dem y-Wert und m den Y-Wert vom Punkt 3 oder 4 erreicht hat.

Eckpunkte des Rechtecks, schematisch:

Code: Alles auswählen

p1        p2
m         m'
m+1       m'+1

...

p3        p4
Ich hab mir jetzt folgenden Code mir zusammen geschrieben:

Code: Alles auswählen

def Zwischenpunkte_erstellen():
    #Abstand 
    spur = 50
    #Punktekoordinaten
    punkt1 = [-8003, 4150]
    punkt2 = [5002, 4140]
    punkt3 = [-7980, -3506]
    punkt4 = [4988, -3189]
    
    #Mit Werte sind die Zwischenwerte gemeint
    Werte = punkt1, punkt2
    print Werte # nur zur überprüfung

    #hier soll geprüft werden, ob der Y-Wert von Punkt1 kleiner gleich dem Y-Wert von Punkt3 ist  
    #UND AUCH der Y-Wert von Punkt2 kleiner gleich dem Y-Wert von Puntk4
    while punkt1[1] <= punkt3[1] and punkt2[1] <= punkt4[1]:
        #Neuberechnung der Y-Koordinaten der Punkte 1 und 2 mit dem Wert für die Spur/Abstand
        punkt1[1] += spur
        punkt2[1] += spur
        Werte.append(punkt1, punkt2)
        print Werte
        
        return Werte
Jedenfalls wenn ich es ausführe, wird mir nur Zeile 12 bzw. 11 angezeigt. Die while-schleife wird komplett ignoriert.
Nur kann ich mir nicht wirklich erklären, woran das liegt, da ja nur die angegebenen Werte verglichen werden sollen.

Ich hab auch schon versucht die Indizes rauszunehmen, nur mit dem selben Ergebnis.

Kann es vielleicht sein, dass man bei einer while-schleife keine "doppelten" Bedingungen angeben kann bzw. die vielleicht anders verknüpft werden, als mit ''and''?

Vielen Dank schon mal im Vorraus.

LG

Daniela
Zuletzt geändert von Daniela am Donnerstag 10. Juli 2008, 08:22, insgesamt 3-mal geändert.
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Ohne mir die while-Schleife genauer angeschaut zu haben, tut es nicht eventuell eine einfache Rechnung anstatt der While-Schleife?
Division -> Rest * m + y
Edit: Schau dir mal genau die Bedingung ein. Ersetz die Variablen durch die Zahlen, die die Variablen representieren. Fällt dir vielleicht auf, dass die Schleife nie betreten wird? Es wird ja auch nie das print-Statement ausgeführt.
Zuletzt geändert von Karl am Dienstag 8. Juli 2008, 13:49, insgesamt 1-mal geändert.
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Theoretisch für einmal rechnen bestimmt, aber das ganze soll ja n-mal durchgeführt werden. wobei nicht bekannt ist, wie oft.

Das ganze kann schon nach 3 mal abgeschlossen sein, aber vielleicht auch nach 50 Rechnungen. Kommt eben drauf an.
Und das soll ja für 2 verschiedene Punkte in einem Schritt getan werden. dann das Ergebnis in eine Variable schreiben (Werte) und dann soll sich das Ganze wiederholen, von daher fand ich eine while-schleife ganz praktisch.
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Ahh, sorry.
Du willst die Zwischenpunkte ja alle haben.
Klar, dann ist eine Schleife natürlich angebracht :)
Aber dann guck dir trotzdem nochmal an, was du mit der Bedingung in der While-Schleife machst.

Sorry nochmal, ich hab wohl irgendwas falsch verstanden beim ersten Lesen. Liegt vielleicht daran, dass ich nicht geschlafen hab :)
Edit: Und zu deiner Frage, ob das ``and`` richtig ist:
Die Schleife hört auf, sobald eine der beiden Koordinaten fertig ist. Da dann ja nicht mehr das ``and`` zutrifft.
Da würde ein ``or`` zwar noch zutreffen, aber dann würde die andere Variable ja trotzdem noch überflüssige "Zwischenschritte" generieren. Vielleicht solltest du das dann inerhalb der Schleife nochmal mit einem if-Statement für jede Variable einzeln regeln und wenn beide Variablen fertig bearbeitet sind, die Schleife beenden.
Dann müsstest du die Bedingung in der While-Schleife umgekehrt definieren, solange beide Variablen NICHT >= sind ;)
Zuletzt geändert von Karl am Dienstag 8. Juli 2008, 14:03, insgesamt 1-mal geändert.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Daniela hat geschrieben: punkt1 = [-8003, 4150]
punkt2 = [5002, 4140]
punkt3 = [-7980, -3506]
punkt4 = [4988, -3189]
[...]
while punkt1[1] <= punkt3[1] and punkt2[1] <= punkt4[1]:
Hi Daniela!

Soviel ich weiß ist 4150 (punkt1[1]) bereits > -3506 (punkt3[1]), womit der erste Term Deiner Bedingung nicht erfüllt ist und die Schleife gar nicht erst betreten wird.

Nur nebenbei: konzeptionell wird die Struktur von Koordinatenpaaren eher durch Tupels repräsentiert. Oder hast Du vor, die Koordinaten zu sortieren? ;-)

[edit]
Noch etwas: sobald die Schleifen betreten wird, wird es bald wieder rumsen. Denn in Zeile 11 hast Du Werte als Tupel aus zwei Listen definiert, welches die in Zeile 20 aufgerufene append-Methode nicht unterstützt.
Aus meiner Sicht solltest Du es anders herum machen. Also Punkte als Tupel und Werte als Liste.

Code: Alles auswählen

    punkt1 = -8003, 4150
    punkt2 = 5002, 4140
    Werte = [punkt1, punkt2]
[/edit]

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

@Karl:

danke für den Tipp


@ Michael Schneider:


Also zur Schleifen-Bedingung:

ich glaub ich hab mich bei der Rechenart geirrt, also statt Addition muss Subtraktion durchgeführt werden. Dann ist mir auch klar, warum das nicht so geht, wie es gehen soll.

Die Koordinaten sind aber schon jeweils als Liste gegeben.
Nachher am Ende soll das dann als ein großes Tupel zusammen gefasst werden. Damit sichergestellt ist, dass die jeweiligen Koordinaten auch zusammen gehören.

Am Ende sollte sowas wie das folgende rauskommen:

Code: Alles auswählen

Werte =[[punkt1], [punkt2], [punkt1'], [punkt2'], [punkt1''], punkt2''],...]
wobei sich 
punkt1 aus (x,y) zusammsetzt.
Wie kann ich an eine Liste jetzt neue werte ranhängen? einfach mit '+' oder gibt es da auch eine Funktion wie append() bei Tupeln?

Danke schon mal für eure Hilfe

Daniela
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hallo Daniela!
Daniela hat geschrieben:Die Koordinaten sind aber schon jeweils als Liste gegeben.
Nachher am Ende soll das dann als eine große Liste zusammen gefasst werden, können aber auch eigentlich Tupel sein. Da bin ich noch nicht wirklich festgelegt.

Hauptsache am Ende kommt ungefähr so was wie das folgende raus:

Code: Alles auswählen

Werte =[[punkt1], [punkt2], [punkt1'], [punkt2'], [punkt1''], punkt2''],...]
Ich fürchte, mit Deinem aktuellen Schleifencode wird das nichts, gerade weil Du die Punkte als Listen gegeben. Denn Listen sind veränderlich. Wenn Du die Koordinaten Deiner Listen Punkt1 und Punkt2 in der Schleife änderst, dann ändern sich immer wieder dieselben beiden Objekte. Und immer wieder hängst Du dieselben Objekte an. Du erhältst also sowas wie

Code: Alles auswählen

Werte =[[punkt1''], [punkt2''], [punkt1''], [punkt2''], [punkt1''], punkt2''],...]
... denn die bereits zu Werte hinzugefügten Listen (immer dasselbe Objekt) werden sozusagen "rückwirkend" geändert. Das geht übrigens nur, wenn Werte eine Liste ist, kein Tupel!
Daniela hat geschrieben:Wie kann ich an eine Liste jetzt neue werte ranhängen? einfach mit '+' oder gibt es da auch eine Funktion wie append() bei Tupeln?
Nein, nein, Tupel haben haben keine append-Methode, sondern die Listen. Tupel sind feste Datensätze, die sich nicht mehr ändern können. Wenn ein Tupel als (x, y) definiert wird während x=1 und y=2 ist, dann bleibt das Tupel immer (1, 2), auch wenn sich x oder y später ändern bzw. es führt zu einer Ausnahme, wenn Du einen Teil des Tupels per Index oder Slice zu ändern versuchst. Das ist genau das, was Du willst.
Bei Listen gibt es append(x) um das Element x anzuhängen, extend(seq) um die Liste um die Elemente der Sequenz seq zu erweitern und +liste2 um die Liste um die Elemente von liste2 zu erweitern.

Es ist vielleicht das beste, wenn Du Dich mit dem genauen Unterschied zwischen Listen und Tupeln auseinandersetzt. Das hilft bei der Wahl des geeigneten Typs.

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Ich hab jetzt verstanden, worauf die hinaus wolltest, von wegen Listen und Tupeln.

Dadurch dass mir die Koordinaten von einer anderen Methode übergeben wurden, hab ich nicht so drauf geachtet, als was sie übergeben werden.

Das hab ich jetzt erstmal so geändert, dass Tupel übergeben werden.

Nun dürfte es doch eigentlich nicht so schwer sein, an die vorhandenen Koordinaten weitere an den Endwert dranzuhängen, oder???
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi Daniela,

wenn Du für die Punkte Tupel verwendest und für Werte eine Liste, dann bist Du auf dem richtigen Weg.

Ich würde getrennt von P1 zu P3 und von P2 zu P4 wandern - übrigens, möchtest Du wirklich nur in y-Richtung gehen und nicht zufällig direkt auf die Zielpunkte zu?
Dabei würde ich keine while-Schleife verwenden, sondern eine for-Schleife über ein xrange objekt.
Etwa so (Koordinaten angepasst, damit sie aufsteigend sind):

Code: Alles auswählen

#Punktekoordinaten
punkt1 = -8003, -4150
punkt2 = 5002, -4140
punkt3 = -7980, 3506
punkt4 = 4988, 3189
werte = []
x, y = 0, 1
for start, end in ((punkt1, punkt3), (punkt2, punkt4)):
    werte.extend([(start[x], curr_y) for curr_y in xrange(start[y], end[y], spur)])
print werte
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Letztendlich wäre ein direktes "hingehen" von P1 zu P3 nicht schlecht, aber dabei brauch ich eben diese Zwischenpunkte zwischen P1 und P3 in einem bestimmten Abstand in Y-Richtung. Wenn es da leichte Abweichungen zwischen den jeweiligen X-Koordinaten gibt, ist das auch zu verschmerzen.

Die Punkte stellen sozusagen die "Wendepunkte" einer Strecke dar, die durch die 4 gegebenen Koordinaten des Rechteckes abgelaufen werden soll.

Letztlich werden die Punkte dann noch geordnet um eine Art schlangenförmige Bewegung darzustellen.
Meine Idee war nun, erstmal von den beiden oberen Punkten mir die weiteren Y-Koordinaten berechnen zu lassen, in dem vordefinierten Abstand.
Hier mal eine kleine schematische Skizze, damit man sich vorstellen kann, was ich meine:

Code: Alles auswählen

p1-----------------p2
                   |
                   |
*-------------------*
|
|
*-------------------*
                   |
                   |
*-------------------*
|
|
p3-----------------p4

So sieht es jedenfalls aus.

Ich könnte natürlich auch mir 2 Listen erstellen, wo in einer Liste die Punkte berechnet werden zwischen P1 zu P3 und dann nochmal für P2 zu P4. Wäre vielleicht einfacher.

Ich hab grad den Code von Michael ausprobiert und es funktioniert genauso, wie ich es mir gedacht habe.
Nur bei dem was da rauskommt, glaub ich, dass das ordnen in der Reihenfolge, die ich haben will schwieriger ist, da ja erst irgendwann in der Mitte der Ausgabe die Werte für P2 bis P4 sind. Demzufolge wären 2 separate Listen doch besser.
Bei 2 Listen, brauch ich später nur jeweils abwechselnd 2 Werte aus der einen Liste rausnehmen und dann wieder 2 aus der anderen Liste.

Ich versuch mich dann mal mit dem Umwandeln von 1 Liste in 2.

Oder kann man in der Ergebnisliste nach einem bestimmten Wert suchen, dort an dieser Stelle die Liste "abschneiden" und dann alles was dahinter kommt in einer extra Liste abspeichern?
Wobei man ja ungefähr sagen kann, dass in der Mitte der Liste der Wechsel stattfindet.

Edit:

hab jetzt mir 2 Listen erstellen lassen, damit die Koordinaten für p1 zu p3 getrennt von p2 zu p4 sind.

Dazu habe ich in der for-schleife den zweiten Parameter weggelassen

Code: Alles auswählen

for start, end in ((punkt2, punkt4), ):
So nun muss ich nur noch die Punktkoordinaten in die Reihenfolge bekommen, in die ich die haben will.

Ach ja ich hab noch ne klitzekleine Frage zu dem Code von Michael:

Code: Alles auswählen

werte = [] # ist klar Liste wird erstellt
x, y = 0, 1 # festlegen, dass x und y in den Tupeln die Indexe 0 bzw. 1 haben???
for start, end in ((punkt1, punkt3), ): #, (punkt2, punkt4)): 
    werte.extend([(start[x], curr_y) for curr_y in xrange(start[y], end[y], spur)])# ???
Vor allem die letzte Zeile kann ich mir nicht wirklich erklären.
Ich versteh das so:
An die Liste (werte) wird von der Startkoordinate der X-Wert und der momentane y-Wert angehängt. Dieser y-Wert setzt sich zusammen aus einem Xrange-Objekt welches die Berechnungen vom Y-Startwert und dem Y-Endwert ausgibt, mit dem Abstand/Differenz von dem 3 Parameter (in diesem Fall der Spur).

Richtig???
Ist vielleicht nicht das beste Deutsch, aber so ungefähr verstehe ich das.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi Daniela
Daniela hat geschrieben:Letztlich werden die Punkte dann noch geordnet um eine Art schlangenförmige Bewegung darzustellen.
Meine Idee war nun, erstmal von den beiden oberen Punkten mir die weiteren Y-Koordinaten berechnen zu lassen, in dem vordefinierten Abstand.

Ich könnte natürlich auch mir 2 Listen erstellen, wo in einer Liste die Punkte berechnet werden zwischen P1 zu P3 und dann nochmal für P2 zu P4. Wäre vielleicht einfacher.
Das wäre es gewiss, denn es erfordert extra Bemühungen, die beiden Listen nach ihrer Berechnung zusammenzufügen, als sie getrennt zu belassen. Von daher hättest Du einiges an Zeit und Schreibarbeit sparen können, wenn Du Dein Ziel von vornherein vorgestellt hättest.

Es ist nämlich erheblich einfacher, die Strecke punkt1-punkt3 einfach in n Abschnitte zu unterteilen:

Code: Alles auswählen

punkt1 = 50, -200
punkt3 = 66, 120
x, y = 0, 1
def subdivide(start, end, sections=2):
	result = [start]
	
	#  Differenz pro Schritt
	sect = {x:float(end[x] - start[x]) / sections,
	        y:float(end[y] - start[y]) / sections}

	#  Interpolationspunkte berechnen
	for step in xrange(1, sections):
		result.append((start[x]+round(sect[x]*step), 
					start[y]+round(sect[y]*step)))
		
	#  Endpunkt hinzufuegen
	result.append(end)
	return result
	
print subdivide(punkt1, punkt3, sections=2)
print subdivide(punkt1, punkt3, sections=4)
Daniela hat geschrieben:Nur bei dem was da rauskommt, glaub ich, dass das ordnen in der Reihenfolge, die ich haben will schwieriger ist, da ja erst irgendwann in der Mitte der Ausgabe die Werte für P2 bis P4 sind. Demzufolge wären 2 separate Listen doch besser.
Richtig. Aber die Anforderung war, dass Du alle Punkte in einer Liste hast.

Also wie gesagt, möglichst immer die Endbedingungen angeben. Sonst verbiegt man sich für eine wenig optimale Zwischenlösungen und muss den Code danach sowieso wieder anpassen.
Daniela hat geschrieben:Bei 2 Listen, brauch ich später nur jeweils abwechselnd 2 Werte aus der einen Liste rausnehmen und dann wieder 2 aus der anderen Liste.
Geh am besten von Deiner Zielstellung aus. Also: wie willst Du die Daten später nutzen? Möchtest Du eine Wegbeschreibung generieren? Möchtest Du eine Skizze zeichnen (dann solltest Du die Liste in eine Form bringen, die vom GUI-Tool für die Ausgabe benötigt wird), usw.
Daniela hat geschrieben:Oder kann man in der Ergebnisliste nach einem bestimmten Wert suchen, dort an dieser Stelle die Liste "abschneiden" und dann alles was dahinter kommt in einer extra Liste abspeichern?
Das kann man tun. Aber wenn man zwei Listen benötigt, dann braucht man sie vorher einfach nicht zu einer zusammenfassen. :-)
Daniela hat geschrieben:

Code: Alles auswählen

x, y = 0, 1 # festlegen, dass x und y in den Tupeln die Indexe 0 bzw. 1 haben???
Exact, das sollte die Lesbarkeit verbessern.
Daniela hat geschrieben:

Code: Alles auswählen

for start, end in ((punkt1, punkt3), ): #, (punkt2, punkt4)): 
    werte.extend([(start[x], curr_y) for curr_y in xrange(start[y], end[y], spur)])# ???
Vor allem die letzte Zeile kann ich mir nicht wirklich erklären.
Ich versteh das so: ...
Ja, das hast Du richtig interpretiert. Der Ausdruck in eckigen Klammern schimpft sich "list comprehension" und erzeugt eine neue Liste.
Der Term vor dem "for" beschreibt die Form des Listenelements - in meinem Fall ein Tupel aus x-Koordinate des Startpunktes und einem Zwischenwert auf der Gerade zwischen punkt1[y] und punkt3[y].
Das "for" selbst gehört zu einer handelsüblichen for-Schleife, die über dynamisch erzeugte Elemente von xrange iteriert.
Die erzeugten Werte beginnen mit start[y] und werden so lange um spur hochgezählt, bis das Ergebnis größer ist als end[y]. In diesem Fall wird der Schleifekörper nicht mehr betreten.
Für List Comprehensions siehe auch 1. Antwort zu
http://www.python-forum.de/topic-15302.html

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Hi Michael,

Ziel dieser Übung ist es, dass ein Pfad erstellt wird, auf dem später eine Art Roboter lang fährt.
Der Bereich in dem dieser fahren soll, ist durch die 4 Punkte vordefiniert. Diese 4 Punkte werden in einem XML-File gespeichert.
Das Auslesen der Punkte hab ich schon bewerkstelligt bekommen. Die Punkte liegen mir als Rückgabewerte in einem Tupel in einzelnen Methoden vor.

Nun soll dieser Roboter in dem aufgespannten Rechteck sich schlangeförmig bewegen, dazu benötige ich wie gesagt die Koordinaten für die Zwischenpunkte, da diese die Wendepunkte markieren. (vgl. dazu die Skizze aus dem Post davor)
Die Koordinaten sollen dann nachdem sie berechnet wurden in ein XML-File geschrieben werden.
Hierbei ist aber zu beachten, dass nicht einfach die Koordinaten hingeschrieben werden, wie sie kommen, sondern eben in der Reihenfolge, wie der Roboter den Weg abfahren soll (Skizze).

Wenn ich mir jetzt für die Punkte zwischen 1 und 3 eine Liste erstelle, und eine zweite für die Punkte zwischen 2 und 4, funktioniert das nur, wenn ich die jeweiligen Koordinaten direkt übergebe:

Code: Alles auswählen

punkt1 = 123, 456
punkt3 = 789, 123
sollen nun die Werte von einer anderen Funktion in einem anderen Modul übernommen werden, bleibt die Liste am Ende leer.

Code: Alles auswählen

punkt1 = Coordinates.get_Punkt1()
punkt3 = Coordinates.get_Punkt3()
Nur erklären kann ich mir das nicht. denn wenn ich mal zur Kontrolle ein print auf punkt1 mache, dann wird mir auch der Punkt1 angezeigt

Code: Alles auswählen

punkt1 = Coordinates.get_Punkt1()
punkt3 = Coordinates.get_Punkt3()
print punkt1
print type(punkt1)
Ausgabe:

Code: Alles auswählen

(-8003, 4150)
<type 'tuple'>
Und das ist ja auch eindeutig ein Tupel. Selbst wenn ich mit ``type()`` nochmals schaue, welchen Typ punkt1 hat, wird mir <tuple> angezeigt.
Deshalb verstehe ich nicht, warum das nicht übernommen wird



Das ist ja eigentlich genau das, was ich haben will, nur warum wird das nicht in die for-schleife übernommen?
Die sieht jetzt übrigens so aus:

Code: Alles auswählen

for start, end in ((punkt1, punkt3), ): #ohne etwas hinter dem Koma
    werte.extend([(start[x], curr_y) for curr_y in xrange(start[y], end[y], spur)])
Zu deinem letzten Skript:

Von der Idee her, find ich das mit der Interpolation wirklich total genial. Nur man müsste in dem Fall "sections" dann dynamisch generieren, weil wie viele Koordinaten jeweils gebraucht werden, ist von der Spurbreite abhängig. Diese würde man aber durch einfaches Dividieren raus bekommen.

Grüße

Daniela
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Daniela hat geschrieben: Wenn ich mir jetzt für die Punkte zwischen 1 und 3 eine Liste erstelle, und eine zweite für die Punkte zwischen 2 und 4, funktioniert das nur, wenn ich die jeweiligen Koordinaten direkt übergebe:

Code: Alles auswählen

punkt1 = 123, 456
punkt3 = 789, 123
sollen nun die Werte von einer anderen Funktion in einem anderen Modul übernommen werden, bleibt die Liste am Ende leer.

Code: Alles auswählen

punkt1 = Coordinates.get_Punkt1()
punkt3 = Coordinates.get_Punkt3()
Ich hab meinen Fehler gefunden. Juchu!!!

Ich hab nicht beachtet, dass spur-Wert in der for-schleife auf den ersten Wert addiert(!!!) wird und nicht subtrahiert.
Einfach ein " - " for den spur-Parameter und schon macht die Funktion das, was ich haben will.
*freu*

######
Sorry für den Doppelpost, aber ich wollte meinen alten Betrag nicht editieren, weil hier ja jetzt die Lösung mehr oder weniger knapp geschildert ist, und der letzte Beitrag von mir ja auch ein bisschen sehr lang schon war.


So jetzt kann ich mich darin machen, die Koordinatenpaare aus den 2 Listen in die richtige Reihenfolge zu bringen, jeweils abwechselnd und teilweise vertauscht.
Na mal sehen, was mir da so schönes einfällt. ;-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Wenn ich das angestrebte Ziel richtig verstanden habe, dann könnte eine Lösung so aussehen:

Code: Alles auswählen

# Pseudopunkte erzeugen
liste_P1P3 = ["P1P3-%02i" %i for i in xrange(6)]
liste_P2P4 = ["P2P4-%02i" %i for i in xrange(6)]
# Listen zusammenfuehren
listen = [liste_P1P3,liste_P2P4]
liste_komplett = [liste_P1P3.pop(0)]
erste_liste = False
while True:
    erste_liste = not erste_liste
    liste = listen[+erste_liste]
    p_anz = 2 if len(liste)>1 else 1
    liste_komplett.extend(liste[:p_anz])
    del(liste[:p_anz])
    if not liste:
        liste_komplett.extend(listen[+(not erste_liste)])
        break
# Pseudopunkte ausgeben
for punkt in liste_komplett:
    print punkt
Irgendwie werde ich das Gefühl aber nicht los, dass das auch WESENTLICH eleganter geht und es bestimmt irgendeine schon fertige Funktion gibt, mit der man das viiiieeel kürzer und garantiert schöner hinbekommt ... :?
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Wow ich bin geplättet!!!

Das ist wirklich das, was ich haben wollte!

Vielen Dank dafür, dass du dir solche Gedanken gemacht hast um mein Problem.

Nur versteh ich nicht so richtig den Quellcode. :oops:

Hier mal das kommentiert, was ich verstehe, oder zu mindestens glaube zu verstehen.

Code: Alles auswählen

# Listen zusammenfuehren
listen = [liste_P1P3,liste_P2P4] # besteht aus den beiden Listen 1 und 2 [(lange Liste 1)(lange Liste 2)]
liste_komplett = [liste_P1P3.pop(0)] # in die komplette Liste wird das erste Element aus dem Index 0 ausgelesen/rausgeholt und eingefügt
erste_liste = False # Sinn erschließt sich mir noch nicht, false hat ja bekanntlich den wert 1
while True: # Endlosschleife, da sich nie die Bedingung innerhalb ändert, kann nur abgebrochen werden
    erste_liste = not erste_liste # Die Zeile versteh ich erstmal noch nicht
    liste = listen[+erste_liste] # hier wird der Index 1 (beim ersten durchlauf) angesprochen, beim 2. Durchlauf der Index 0 usw.
    p_anz = 2 if len(liste)>1 else 1 # erschließt sich im Zusammenhang mit der nächsten Zeile
    liste_komplett.extend(liste[:p_anz])#an die bisher erstellte Liste werden 2 Werte aus der anderen Liste angehängt, sofern noch Werte vorhanden sind,
# ansonsten wird nur 1 Wert genommen 
    del(liste[:p_anz]) # löschen der bisher entnommenden Werte UM die Anzahl 2 oder 1, ist dazu da, dass neue Elemente immer am Anfang stehen
    if not liste: # wenn eine der beiden Listen nicht forhanden ist, soll der Wert von der anderen Liste, der noch übrig ist angehängt werden
        liste_komplett.extend(listen[+(not erste_liste)]) #   
        break # Abbruch der Schleife
So würde ich das jetzt jedenfalls interpretieren.

Wenn ich das ganze jetzt in eine Funktion packe, die einen Rückgabe Wert liefert, wo müsste der denn stehen?
Eigentlich hinter dem break, oder? aber wenn ich es dort einfüge, werden mir beim Aufruf der Funktion nur die ersten 3 Werte zurück gegeben.


Jedenfalls nochmal VIELEN DANK an numerix und Michael Schneider für die großartige Hilfe bis hierhin.


Liebe Grüße

Daniela
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Daniela hat geschrieben:Vielen Dank dafür, dass du dir solche Gedanken gemacht hast um mein Problem.
Sowas hält den Geist fit ...
Daniela hat geschrieben:Nur versteh ich nicht so richtig den Quellcode.
Da abwechselnd mit beiden Listen immer das gleiche gemacht wird - nämlich jeweils die beiden nächsten Punkte an die endgültige Liste anzuhängen - habe ich eine Liste "liste" genommen, in die ich die beiden Teillisten packe. Die Boolsche Variable erste_liste sorgt nun durch den alternierenden Wert dafür, dass jeweils abwechselnd eine der beiden Listen mit den Punkten ausgewählt wird. Das unäre "+" sorgt dafür, dass aus dem boolschen Wert eine 0 oder 1 gemacht wird als Index für "liste". Wie ich eben festgestellt habe, ist das verzichtbar - geht auch ohne.

Das Löschen der jeweils an die Endliste angehängten Punkte aus den beiden Teillisten wäre natürlich verzichtbar, hat aber m.E. den Vorteil, dass man auf diese Weise die beiden Teillisten nicht mit einem mitzuführenden Index durchlaufen muss, sondern einfach immer die ersten beiden Punkte nimmt.

Je nachdem, ob die Anzahl der Punkte in den Listen gerade oder ungerade ist, verläuft der letzte Zug von P3 nach P4 oder eben andersherum. Am Ende befindet sich also in der noch nicht leeren Liste nur noch 1 Punkt (statt zweien), der als letzter Punkt anzuhängen ist.

Und während ich das gerade aufschreibe, fällt mir auf, dass die Geschichte mit dem p_anz überflüssig ist. Die Zeile "p_anz = ..." kann weg, in den folgenden Zeilen kann p_anz einfach durch den Wert 2 ersetzt werden.

Etwas "geglättet" nun also so:

Code: Alles auswählen

# Pseudopunkte erzeugen
liste_P1P3 = ["P1P3-%02i" %i for i in xrange(7)]
liste_P2P4 = ["P2P4-%02i" %i for i in xrange(7)]
# Listen zusammenfuehren
listen = [liste_P1P3,liste_P2P4]
liste_komplett = [liste_P1P3.pop(0)]
erste_liste = False
while True:
    erste_liste = not erste_liste
    liste = listen[erste_liste]
    liste_komplett.extend(liste[:2])
    del(liste[:2])
    if not liste:
        liste_komplett.extend(listen[not erste_liste])
        break
# Pseudopunkte ausgeben
for punkt in liste_komplett:
    print punkt
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

numerix hat geschrieben:
Daniela hat geschrieben:Vielen Dank dafür, dass du dir solche Gedanken gemacht hast um mein Problem.
Sowas hält den Geist fit ...
Na dann. Ist doch schön wenn man dabei helfen kann, das keine Gehirnzellen ungenutzt bleiben. ;-)

Das was ich angemerkt hatte wegen einem Rückgabewert, kann ignoriert werden, da ich es bei mir an die falsche Stelle geschrieben hatte. (zu sehr eingerückt).

Daniela
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Jetzt weiß ich, dass mein ungutes Gefühl über die Qualität meines Codes berechtigt war. So gefällt es mir besser:

Code: Alles auswählen

# Pseudopunkte erzeugen
liste_P1P3 = ["P1P3-%02i" %i for i in xrange(6)]
liste_P2P4 = ["P2P4-%02i" %i for i in xrange(6)]
# Listen zusammenfuehren
liste_komplett = [liste_P1P3.pop(0)]
for k in xrange(0,len(liste_P2P4),2):
    liste_komplett.extend(liste_P2P4[k:k+2]+liste_P1P3[k:k+2])
# Pseudopunkte ausgeben
for punkt in liste_komplett:
    print punkt
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Darf man fragen, weswegen du denn ein ungutes Gefühl hattest?

Die while-schleife wurde nun durch eine for-schleife ersetzt. dabei wird dann mit dem Index 0 angefangen, solange, bis die länge von der 2. Liste erreicht ist. Und die Schrittweite beterägt 2.
Nun wird dann in jedem zählschritt aus der 2. Liste 2 Werte entnommen und dann 2 Werte aus der 1. Liste.

naja und zum Schluss dann die Ausgabe.

Hierbei werden bei dem Code, die schon bearbeiteten Tupel in der Liste nicht gelöscht, da durch einen "zählparameter" (k) wird der Index mit jedem Durchgang hochgezählt und somit weiss man auch, an welcher stelle man in der Liste ist.

Richtig???
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Daniela hat geschrieben:Darf man fragen, weswegen du denn ein ungutes Gefühl hattest?
Weil ich 11 Zeilen nicht gerade eleganten Code benötigt habe und es mir einfach zu kompliziert erschien.
Das hat sich dann ja auch bewahrheitet, denn das Gleiche gelingt nun mit 3 relativ transparenten Zeilen Code.
Antworten