nesting for statements?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • tpcolson@gmail.com

    #1

    nesting for statements?

    I'm not what you'd call a "programmer " of any sort, so perhaps this
    question may seem arcane and result in a plethora of "you idiot"
    threads, but here goes:

    ArcGIS 9.1 has a neat interface with python (2.1-2.4), allowing me to
    do all sorts of spatial operations within python, namely, repetitive
    functions.


    In the below code, I'm trying to iterate thru multiple values of the
    variable "Discretisa tion error factor" using a for statement that
    temporarily populates "Disc", which is used as input in "Discretisa tion
    error factor" in the gp.TopoToRaster ._sa function.


    For each iteration of "Discretisa tion error factor", I'm trying to name
    the output file "outa", "outb", "out...."

    Not quite sure how to implement that. There are lots of examples on
    nested for loops out there, but nothing on combing that with a output
    file naming sheme.

    The gp.TopoToRaster _sa function by itself without all the for
    statements works fine.

    Appreciate any help on this, other wise I have to manually interpolate
    hundreds of LiDAR point clouds, each, 10 times for diff. values of DEF.



    # TopoToRaster_sa mple.py
    # Description: Interpolate a series of point features onto a
    rectangular raster using TopoToRaster
    # Requirements: None
    # Author: ESRI
    # Date: 12\\01\\03

    # Import system modules
    import sys, string, os, win32com.client

    # Create the Geoprocessor object
    from win32com.client import Dispatch
    gp = Dispatch("esriG eoprocessing.Gp Dispatch.1")

    # Check out any necessary licenses
    gp.CheckOutExte nsion("spatial" )

    # Iterate 2 thru 4 in increments of 2 for DEF
    # Name the "2" dem "outa" and the "4" dem "outb"
    for x in range(2,4):
    Disc = int(x)
    names = ["a","b"]
    for y in names:
    Out_Dem = "out"+y


    try:

    # Process: Topo to Raster...
    gp.TopoToRaster _sa("C:\\temp\\ falls_lidar.shp Z PointElevation" ,
    Out_Dem, # Variable for name of output raster.
    This should increment name of output based on the for statement
    "5", # Output raster cell size: each pixel is 5
    feet by 5 feet
    "2103763.27 813746.12 2111850.32 822518.65",
    #extent of raster borders, SPF, NC, NAD83
    "20", # #Grid Margin
    "", #Smallest z value to be used in
    interpolation (optional)
    "", #Largest z value to be used in interpolation
    (optional)
    "NO_ENFORCE ", #Drainage option
    "SPOT", #Spot data option
    "40", #Maximum number of iterations (optional)
    "", #Roughness penalty (optional)
    Disc, #Discretisation error factor: This should
    increment DEF based on the for statement
    "0", #Vertical standard error (optional)
    "", #Tolerance 1 (optional)
    "" #Tolerance 2 (optional)
    )
    except:
    print "ERROR OCCURED"
    print gp.GetMessages( )

  • Paul Watson

    #2
    Re: nesting for statements?

    tpcolson@gmail. com wrote:[color=blue]
    > I'm not what you'd call a "programmer " of any sort, so perhaps this
    > question may seem arcane and result in a plethora of "you idiot"
    > threads, but here goes:
    >
    > ArcGIS 9.1 has a neat interface with python (2.1-2.4), allowing me to
    > do all sorts of spatial operations within python, namely, repetitive
    > functions.
    >
    >
    > In the below code, I'm trying to iterate thru multiple values of the
    > variable "Discretisa tion error factor" using a for statement that
    > temporarily populates "Disc", which is used as input in "Discretisa tion
    > error factor" in the gp.TopoToRaster ._sa function.
    >
    >
    > For each iteration of "Discretisa tion error factor", I'm trying to name
    > the output file "outa", "outb", "out...."
    >
    > Not quite sure how to implement that. There are lots of examples on
    > nested for loops out there, but nothing on combing that with a output
    > file naming sheme.
    >
    > The gp.TopoToRaster _sa function by itself without all the for
    > statements works fine.
    >
    > Appreciate any help on this, other wise I have to manually interpolate
    > hundreds of LiDAR point clouds, each, 10 times for diff. values of DEF.
    >
    >
    >
    > # TopoToRaster_sa mple.py
    > # Description: Interpolate a series of point features onto a
    > rectangular raster using TopoToRaster
    > # Requirements: None
    > # Author: ESRI
    > # Date: 12\\01\\03
    >
    > # Import system modules
    > import sys, string, os, win32com.client
    >
    > # Create the Geoprocessor object
    > from win32com.client import Dispatch
    > gp = Dispatch("esriG eoprocessing.Gp Dispatch.1")
    >
    > # Check out any necessary licenses
    > gp.CheckOutExte nsion("spatial" )
    >
    > # Iterate 2 thru 4 in increments of 2 for DEF
    > # Name the "2" dem "outa" and the "4" dem "outb"
    > for x in range(2,4):
    > Disc = int(x)
    > names = ["a","b"]
    > for y in names:
    > Out_Dem = "out"+y
    >
    >
    > try:
    >
    > # Process: Topo to Raster...
    > gp.TopoToRaster _sa("C:\\temp\\ falls_lidar.shp Z PointElevation" ,
    > Out_Dem, # Variable for name of output raster.
    > This should increment name of output based on the for statement
    > "5", # Output raster cell size: each pixel is 5
    > feet by 5 feet
    > "2103763.27 813746.12 2111850.32 822518.65",
    > #extent of raster borders, SPF, NC, NAD83
    > "20", # #Grid Margin
    > "", #Smallest z value to be used in
    > interpolation (optional)
    > "", #Largest z value to be used in interpolation
    > (optional)
    > "NO_ENFORCE ", #Drainage option
    > "SPOT", #Spot data option
    > "40", #Maximum number of iterations (optional)
    > "", #Roughness penalty (optional)
    > Disc, #Discretisation error factor: This should
    > increment DEF based on the for statement
    > "0", #Vertical standard error (optional)
    > "", #Tolerance 1 (optional)
    > "" #Tolerance 2 (optional)
    > )
    > except:
    > print "ERROR OCCURED"
    > print gp.GetMessages( )[/color]

    I think you want a filename generated for each pass through the loop. I
    would suggest generating the filenames before you ever start the loop in
    a list. Then, reference the filename list while you are in the loop.
    You could also construct the filename while you are in the loop.

    sor = 2 # start of range
    eor = 4 # end of range

    filenames = ['file' + chr((x-sor) + ord('a')) for x in range(sor, eor)]

    for x in range(sor, eor):
    print filenames[x - sor]

    If you do not want to create all of the filenames in memory at one time,
    you could generated them during the loop. However, this will not work
    well when you code is run on a system not using ASCII character encoding.

    for x in range(sor, eor):
    print 'file' + chr((x - sor) + ord('a'))

    Something using string.ascii_lo wercase would work better. My guess is
    that on the mainframe using EBCDIC character encoding that
    string.ascii_lo wercase still contains the LATIN SMALL LETTER characters,
    just as it does on ASCII-based systems.

    Comment

    • tpcolson@gmail.com

      #3
      Re: nesting for statements?

      Hi. Thanks for the tip. However, implementing that example, the script
      will only generate the second output "file", (or it's overwriting the
      first one), so all I get when run is "fileb".

      # Import system modules
      import sys, string, os, win32com.client

      # Create the Geoprocessor object
      from win32com.client import Dispatch
      gp = Dispatch("esriG eoprocessing.Gp Dispatch.1")

      # Check out any necessary licenses
      gp.CheckOutExte nsion("spatial" )

      # Iterate 2 thru 4 in increments of 2 for DEF
      # Name the "2" dem "outa" and the "4" dem "outb"
      sor = 2 # start of range
      eor = 4 # end of range

      filenames = ['file' + chr((x-sor) + ord('a')) for x in range(sor, eor)]

      for x in range(sor, eor):
      Out_Dem = filenames[x - sor]


      try:

      # Process: Topo to Raster...
      gp.TopoToRaster _sa("C:\\temp\\ test.shp Z PointElevation" ,
      "C:\\temp\\"+Ou t_Dem, # Variable for name of
      output raster. This should increment name of output based on the for
      statement
      "5", # Output raster cell size: each pixel is 5
      feet by 5 feet
      "2103763.27 813746.12 2111850.32 822518.65",
      #extent of raster borders, SPF, NC, NAD83
      "20", # #Grid Margin
      "", #Smallest z value to be used in
      interpolation (optional)
      "", #Largest z value to be used in interpolation
      (optional)
      "NO_ENFORCE ", #Drainage option
      "SPOT", #Spot data option
      "40", #Maximum number of iterations (optional)
      "", #Roughness penalty (optional)
      "0" #Discretisation error factor: This should
      increment DEF based on the for statement
      "0", #Vertical standard error (optional)
      "", #Tolerance 1 (optional)
      "" #Tolerance 2 (optional)
      )
      except:
      print "ERROR OCCURED"
      print gp.GetMessages( )

      Comment

      • Peter Otten

        #4
        Re: nesting for statements?

        tpcolson@gmail. com wrote:
        [color=blue]
        > Hi. Thanks for the tip. However, implementing that example, the script
        > will only generate the second output "file", (or it's overwriting the
        > first one), so all I get when run is "fileb".[/color]

        I think your looping code has the structure

        for x in ["a", "b", "c"]:
        pass
        print x

        This will print x once after the loop has completed. By then the value of x
        is "c". To fix it, move the code from /after/ the loop /into/ the loop:

        for x in ["a", "b", "c"]:
        print x

        In the code you give that would mean that you have to indent the

        try:
        # ...
        except:
        # ...

        statement one more level.

        Inside that loop you want a filename and an integer value in lockstep. The
        simplest way to get that is zip():
        [color=blue][color=green][color=darkred]
        >>> for Disc, suffix in zip(xrange(2, 6, 2), "abcdefghijklmn opqrstuvwxyz"):[/color][/color][/color]
        .... Out_Dem = "out" + suffix
        .... print Disc, Out_Dem
        ....
        2 outa
        4 outb

        Again, you have to replace the print statement by your try...except. If you
        fear that you will eventually run out of suffices, here is a function that
        "never" does:
        [color=blue][color=green][color=darkred]
        >>> def gen_suffix(char s):[/color][/color][/color]
        .... for c in chars:
        .... yield c
        .... for c in gen_suffix(char s):
        .... for d in chars:
        .... yield c + d
        ....[color=blue][color=green][color=darkred]
        >>> for i, s in zip(range(20), gen_suffix("abc ")):[/color][/color][/color]
        .... print i, s
        ....
        0 a
        1 b
        2 c
        3 aa
        4 ab
        5 ac
        6 ba
        7 bb
        8 bc
        9 ca
        10 cb
        11 cc
        12 aaa
        13 aab
        14 aac
        15 aba
        16 abb
        17 abc
        18 aca
        19 acb

        That said, reading the tutorial or an introductory book on Python never
        hurts...

        Peter

        Comment

        Working...