Seite 1 von 1

Nicht funktionierende While-Schleife

Verfasst: Sonntag 12. Oktober 2014, 20:13
von Ginfler90
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ß!

Re: Nicht funktionierende While-Schleife

Verfasst: Sonntag 12. Oktober 2014, 20:26
von Sirius3
@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.

Re: Nicht funktionierende While-Schleife

Verfasst: Sonntag 12. Oktober 2014, 20:35
von 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))

Re: Nicht funktionierende While-Schleife

Verfasst: Montag 13. Oktober 2014, 09:25
von Ginfler90
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?

Re: Nicht funktionierende While-Schleife

Verfasst: Montag 13. Oktober 2014, 09:38
von Sirius3
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))