Sorting contour lines

1653
7
09-24-2012 04:30 AM
AndreasGinau
New Contributor
Dear Python+Arcgis experts,
I want to sort my contour lines.
My table contains the field CONTOURS (double) and sort (double). I want that contours ending with 5 get the value 5 for sort, contours ending with 10 the value 10 and all other contours should get the value 1 for sort.

I tried this code:

def Reclass(contours):
    if contours % 10 == 0:
        !sort! = 10;
    elif contours + 5 % 10 ==0:
        !sort! = 5;
    else:
        !sort! = 1;

Reclass(!Contours!)

but it doesn't word.
I hope you can help me with.
Andreas
Tags (2)
0 Kudos
7 Replies
ChristopherThompson
Occasional Contributor III
How does this 'not work', what are you actually getting when it runs?  I can see part of the problem being that the modulus operation will return 0s for anything divisible by 10 or 5, and that probably isn't precisely what you want.  You may need to isolate the last 2 digits of your contour value and test those individually. Something like the following might work (I haven't tested this so you will want to do that before you try and implement):
test = str(contour)[-2:] #converts the last 2 digits of your contour value to a string
if int(test)/10 == 1:
   then sort = 10
elif % int(test) 5 == 0:
   sort = 5
else:
   sort = 1


if your contour is truly a double and not just an integer stored in a double field you may need to do some additional processing to convert that, and figure out how you want to handle rounding issues.
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Converting to string then back to integers can be tricky.  I ran into to some unsuspected errors when testing this, but I was able to get the following to work:

def Reclass(contour):
  newContour = str(contour) #string will have decimal
  newContour = newContour.split(".")[0]
  try:
    newContour[-2:]
    if newContour[-2:] == '10':
      return 10
  except IndexError:
    pass
  if newContour[-1] == '5':
    return 5
  else:
    return 1


Reclass(!Contour!)
0 Kudos
DarrenWiens2
MVP Honored Contributor
This works for me (am I missing something?):
def reclass(contours):
   if contours % 10 == 0:
     return 10
   elif contours % 5 == 0:
     return 5
   else:
     return 1

reclass( !Contours!)
0 Kudos
ChristopherThompson
Occasional Contributor III
This works for me (am I missing something?)

Part of the problem is that we don't know how the OPs code "doesn't work" since that isn't stated in the original question.  Also returning a value that way still only means that function has to be wrapped into another function that actually updates the Sort field as the OP desires.  Lastly, the statment
if contours % 10 == 0:

won't trap only those contours that end with 10, just those that are evenly divisible by 10 - so the OP would get contours ending in 20, 30, 40, etc.  being reclassified.  Though its a bit unclear, I don't think that is his intention.
Converting to string then back to integers can be tricky. I ran into to some unsuspected errors when testing this...

Jake, can you indicate what kind of errors your encountered involving converting between strings and integers? I'd be interested to know since this is something I do fairly frequently with no issues.  I can see this would be a problem if the original 'double' value was a fractional number and rounding became involved, but if the original number is really an integer, i can't see where that would be a problem.
0 Kudos
DarrenWiens2
MVP Honored Contributor
Part of the problem is that we don't know how the OPs code "doesn't work" since that isn't stated in the original question.
I assume it doesn't work because the statement
 !sort! = 10;
should be
return 10
(and so on for the others).
Also returning a value that way still only means that function has to be wrapped into another function that actually updates the Sort field as the OP desires.
This code is intended to be run in the field calculator (as per the OP).
won't trap only those contours that end with 10, just those that are evenly divisible by 10 - so the OP would get contours ending in 20, 30, 40, etc. being reclassified. Though its a bit unclear, I don't think that is his intention.
You're right - it's unclear. But I assume they want all contours ending with a zero, not literally "10", so they can symbolize those contours differently. I could be wrong...
0 Kudos
ChristopherThompson
Occasional Contributor III
But I assume they want all contours ending with a zero, not literally "10", so they can symbolize those contours differently. I could be wrong...


Two different interpretations of the same problem.... ha!  Thats why its hard to sometimes respond to these sorts of questions adequately, we just don't always see the whole problem.
This code is intended to be run in the field calculator (as per the OP).

I forget about how the code works inside the field calculator as i rarely do this sort of thing in that contex; does this code get run directly against the Sort field then and the returned value is assigned to that field? I was thinking there's still need to be a line of code where Sort is assigned a value.  Seems there wouldn't need to be a function defined in that event.
0 Kudos
DarrenWiens2
MVP Honored Contributor
I forget about how the code works inside the field calculator as i rarely do this sort of thing in that contex; does this code get run directly against the Sort field then and the returned value is assigned to that field? I was thinking there's still need to be a line of code where Sort is assigned a value. Seems there wouldn't need to be a function defined in that event.

You'd get along well with the presenter at the ESRI UC who said, "why UI when you can arcpy?", which I agree makes sense if you're doing it over and over. But, if you're only going to do it once, I find it faster (with my code-writing, at least a few minutes to get everything working) to right-click the column in the table, choose Field calculator and fill it out (as attached). So, "why arcpy when you can UI?" It's basically six one way, half a dozen the other.
0 Kudos