Nicht funktionierende While-Schleife

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.
Antworten
Ginfler90
User
Beiträge: 2
Registriert: Sonntag 12. Oktober 2014, 20:09

Hallo Comunity,

ich stehe gerade irgendwie auf dem Schlauch.
Folgendes: Ich arbeite an dem Script zum Ändern der Zellwerte eines
Rasters und benutze folgende While-Schleife(n):

Code: Alles auswählen

i = xminf
j = yminf
zaehler = 0
while(i < xmaxf):

    while(j < ymaxf):
        arcpy.AddMessage("Check in-While, Klappe Nr: " + str(zaehler))
        zaehler += 1
        arcpy.AddMessage(str(i) + " " +str(j))
        j += cellsizef
    i += cellsizef
Damit sollte ich alle UTM-Koordinaten des Rasters auflisten. Allerdings
"tickt" die Variable "i" anscheinend nicht hoch, sodass ich folgenden
Output bekomme:

Check in-While, Klappe Nr: 0
33322321.35 6011434.28
Check in-While, Klappe Nr: 1
33322321.35 6011436.07602
Check in-While, Klappe Nr: 2
33322321.35 6011437.87205
.
.
.
Check in-While, Klappe Nr: 248
33322321.35 6011879.69398
Check in-While, Klappe Nr: 249
33322321.35 6011881.49

Da das Raster 249x249 Zellen besitzt, gehe ich dementsprechend auch nur
Spalte auf der ersten Rasterzelle durch (also 249 Positionen) und die
Variable "i" ändert sich nicht. Ich kann mir im Moment nicht erklären,
warum das so ist.
Kann mir da jemand helfen, vielleicht sehe ich den Wald ja vor lauter Bäumen nicht.

Gruß!
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Ginfler90: Dir ist anscheinend nicht bewußt, wie die beiden while-Schleifen funktionieren.
`i`ändert sich nicht, solange die innere while-Schleife durchlaufen wird. Nachdem die innere while-Schleife durchlaufen war, wird sie nie wieder durchlaufen, weil die Bedinung j<ymax nie wieder wahr ist.
BlackJack

@Ginfler90: Sonstige Anmerkungen: Typen haben in Namen nichts zu suchen, falls das dieses `f` an den Namen bedeuten sollte.

``while`` ist keine Funktion, darum sollte man das auch nicht so schreiben als wäre es eine. Nach dem ``while`` würde man ein Leerzeichen erwarten und die Bedingung muss nicht in völlig unnötige Klammern gesetzt werden.

Gleitkommaarithmetik ist ungenau. Bei jeder Addition kann sich so ein Fehler immer weiter vergrössern. Das umgeht man in dem man über ganze Zahlen iteriert und den entsprechenden Wert daraus dann berechnet. Das kann, und sollte man, in eine Funktion auslagern. Am besten eine Generatorfunktion. Dann kann man eine ``for``-Schleife über die Werte machen.

Falls in dem Projekt sowieso schon das `numpy`-Modul verwendet werden sollte, dann gibt es dort Möglichkeiten entsprechende Werte zu erstellen. Das sollte man selbstgeschriebenen Python-Schleifen vorziehen.

Zeichenketten und Werte mit `str()` und ``+`` zusammen zu setzen ist eher BASIC als Python. In Python verwendet man für so etwas die `format()`-Methode auf Zeichenketten.

Edit (ungetestet):

Code: Alles auswählen

def float_range(start, end, cellsize):
    return (start + i * cellsize for i in xrange(0, (end - start) // cellsize))


def main():
    # ...
    counter = 0
    for x in float_range(xmin, xmaxm, cellsize):
        for y in float_range(ymin, ymax, cellsize):
            arcpy.AddMessage('Check in-While, Klappe Nr.: {0}'.format(counter))
            counter += 1
            arcpy.AddMessage('{0} {1}'.format(x, y))
Ginfler90
User
Beiträge: 2
Registriert: Sonntag 12. Oktober 2014, 20:09

Danke für die Hilfe, habe folgende Lösung erhalten:

Code: Alles auswählen

i = xmin
zaehler = 0

while i < xmax:
    j = ymin
    while j < ymax:
        arcpy.AddMessage("Check in-While, Klappe Nr: " + str(zaehler))
        zaehler += 1
        arcpy.AddMessage(str(i) + " " +str(j))
        j += cellsize
    i += cellsize
Es funktioniert im Moment so, wie ich mir das vorgestellt habe.
For-Schleifen sind in meinem Fall eher schwierig, da die Schrittweite (Zellgröße des Rasters) eine Fließkommazahl ist.
Sehe ich das richtig?
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Ginfler90 hat geschrieben:For-Schleifen sind in meinem Fall eher schwierig, da die Schrittweite (Zellgröße des Rasters) eine Fließkommazahl ist.
Genau das berücksichtigt Blackjacks Lösung.

Bzw. um auch noch das händische zählen des Counters loszuwerden:

Code: Alles auswählen

from itertools import product
def float_range(start, end, cellsize):
    return (start + i * cellsize for i in xrange(0, (end - start) // cellsize))

def main():
    # ...
    for counter, (x,y) in enumerate(product(float_range(xminf, xmaxf, cellsize), float_range(yminf, ymaxf, cellsize))):
        arcpy.AddMessage('Check in-While, Klappe Nr.: {0}'.format(counter))
        arcpy.AddMessage('{0} {1}'.format(x, y))
Antworten