If else statement

6813
63
Jump to solution
08-28-2013 04:39 AM
JamesSmith7
Emerging Contributor
I am modifying a script suggested in a prior thread.  http://forums.arcgis.com/threads/90242-Polygon-Centroid?highlight=jsmith0705

I want to be able to select a line, determine if the ARCLENGTH field has a value greater than zero, return that value if greater than zero, if not return the value from the Shape_Length field.

The script runs with no errors or results. 

import arcpy  mxd = arcpy.mapping.MapDocument ("CURRENT") df = arcpy.mapping.ListDataFrames (mxd)[0]  lyr = arcpy.mapping.ListLayers(mxd, "Lot_Lines", df)[0]  for lyr in arcpy.mapping.ListLayers(mxd):  tlyr = lyr  dsc = arcpy.Describe(tlyr)  sel_set = dsc.FIDSet  if dsc.shapeType == "Line":   if len(sel_set) > 0: #If ARCLENGTH value > 0           arcpy.AddMessage(str(ARCLENGTH)) #Return ARCLENGTH value   else:    arcpy.AddMessage(str(Shape_Length)) #Return Shape_Length value
Tags (2)
0 Kudos
63 Replies
RichardFairhurst
MVP Alum
I would have expected an indentation error, but not the name error.  Thanks.


It was only logically wrong, not syntactically wrong.  The level it was at was possible for other lines of code, but the objects referred to in that particular line only come into existence if you make it to the next indent level.
0 Kudos
JamesSmith7
Emerging Contributor
Using Jake's example, I was unable to get any results.  Using, Rich's example, I was able to return either ARCLENGTH or Shape_Length.  But, it only returns one record at a time and the record with the largest OID.  For instance, if I have 3 Shape_Length records selected, Shape_Length = 302.5 is returned.  The script returns only the record with the highest OID value.  Any ideas on how to return all three values?  Something along the lines of:

Shape_Length = 244.5
Shape_Length = 692.9
Shape_Length = 302.5

for lyr in arcpy.mapping.ListLayers(mxd):
 dsc = arcpy.Describe(lyr)
 sel_set = dsc.fidSet.replace(";",",")
 if dsc.shapeType == "Polyline" and dsc.fidSet != "":
  cursor = arcpy.da.SearchCursor(lyr, ["OID@", "ARCLENGTH", "Shape_Length"], "OBJECTID IN (" + sel_set + ")")
  for row in cursor:
   arcLength = row[1]
   shapeLength = row[2]
  if len(arcLength) > 0:
   arcpy.AddMessage("ArcLength = " + arcLength)
  else:
   arcpy.AddMessage("ShapeLength = " + str(shapeLength))
  del row
  del cursor
0 Kudos
RichardFairhurst
MVP Alum
Using Jake's example, I was unable to get any results.  Using, Rich's example, I was able to return either ARCLENGTH or Shape_Length.  But, it only returns one record at a time and the record with the largest OID.  For instance, if I have 3 Shape_Length records selected, Shape_Length = 302.5 is returned.  The script returns only the record with the highest OID value.  Any ideas on how to return all three values?  Something along the lines of:

Shape_Length = 244.5
Shape_Length = 692.9
Shape_Length = 302.5

for lyr in arcpy.mapping.ListLayers(mxd):
 dsc = arcpy.Describe(lyr)
 sel_set = dsc.fidSet.replace(";",",")
 if dsc.shapeType == "Polyline" and dsc.fidSet != "":
  cursor = arcpy.da.SearchCursor(lyr, ["OID@", "ARCLENGTH", "Shape_Length"], "OBJECTID IN (" + sel_set + ")")
  for row in cursor:
   arcLength = row[1]
   shapeLength = row[2]
   if arcLength > '0':
    arcpy.AddMessage("ArcLength = " + arcLength)
   else:
    arcpy.AddMessage("ShapeLength = " + str(shapeLength))
  del row
  del cursor


It is another case of the indent being at the wrong level.  By indenting as I have above the loop includes the message as each record is processed.  Before it only processed once after all rows had been read, so only the last row data was left.

Also, I believe the line that reads if len(arcLength) > 0: should be replaced by the line I have shown above (if arcLength > '0': ) to ensure than even single digit above 0 arclength's are included in the output as an ArcLength.
0 Kudos
JamesSmith7
Emerging Contributor
It is another case of the indent being at the wrong level.  By indenting as I have above the loop includes the message as each record is processed.  Before it only processed once after all rows had been read, so only the last row data was left.

Also, I believe the line that reads if len(arcLength) > 0: should be replaced by the line I have shown above (if arcLength > ' ':) to ensure than even single digit arclength's are included in the output as an ArcLength.


Thanks Richard.  This script is really kicking my butt!

If I leave if len(arcLength) > '': shapeLength is returned if an arcLength is present or not and if len(arcLength) > 0:  either an arcLength value is returned or arcLenth =    .

I am going to try and add a second if statement with  if len(arcLength) > '': and see if that works.
0 Kudos
RichardFairhurst
MVP Alum
Thanks Richard.  This script is really kicking my butt!


I made another mod to the script to change if arcLength > ' ': to if arcLength > '0':.  That will exclude arclengths of ' ' and '0', but include '1'-'9'.
0 Kudos
JamesSmith7
Emerging Contributor
It is another case of the indent being at the wrong level.  By indenting as I have above the loop includes the message as each record is processed.  Before it only processed once after all rows had been read, so only the last row data was left.

Also, I believe the line that reads if len(arcLength) > 0: should be replaced by the line I have shown above (if arcLength > '0': ) to ensure than even single digit above 0 arclength's are included in the output as an ArcLength.


Why does changing the number 0 to a string '0', change the selection from arcLength to shapeLength?  For instance, if len(arcLength) > 0: returns arcLength and if len(arcLength) > '0': returns shapeLength?  The ARCLENGTH field is a string and the Shape_Length field is a double.
0 Kudos
RichardFairhurst
MVP Alum
Why does changing the number 0 to a string '0', change the selection from arcLength to shapeLength?  For instance, if len(arcLength) > 0: returns arcLength and if len(arcLength) > '0': returns shapeLength?  The ARCLENGTH field is a string and the Shape_Length field is a double.


I didn't write if len(arcLength) > '0':.  That is a meaningless piece of code and should return an error, since a it is comparing a number with a string.  The alternative you wrote is also wrong.  if len(arcLength) > 0: should return arclength even if it is ' ', which you don't want.  The version James wrote was if len(arcLength) > 1: and it will not return ' ' through '9', which is also wrong.

I wrote if arcLength > '0':, which compares the string with a string and will return arcLength in all cases except where it is equal to ' ' or '0'.  It will return '1' - '9'.  Use the code I wrote and you will get the most correct results.  (It still could fail if you had values like ' 0' or '00', but I considered that to be too unlikely to add more tests to evaluate.)
0 Kudos
JamesSmith7
Emerging Contributor
Richard,

Thanks for all of your help.  I really appreciate the explanations to go along with the examples.  I learned a lot during the process.
0 Kudos
JamesSmith7
Emerging Contributor
This is quickly becoming the script that would not go away.

I have read through the help on arithmetic operators.  I need to add the selected ArcLength values together and the selected Shape_Length values together.  What is the syntax difference in using + for an arithmetic operator and using the + to concatenate fields?
0 Kudos
RichardFairhurst
MVP Alum
This is quickly becoming the script that would not go away.

I have read through the help on arithmetic operators.  I need to add the selected ArcLength values together and the selected Shape_Length values together.  What is the syntax difference in using + for an arithmetic operator and using the + to concatenate fields?


The difference is if the expressions on each side are both strings or both numbers.  A mix should trigger an error.  So once you have established that you are dealing with an ArcLength that is greater than '0' cast it to a float and then do the addition and then cast back to a string if it has to overwrite the ArcLength field.  So to do all of that it should be:

for lyr in arcpy.mapping.ListLayers(mxd):
 dsc = arcpy.Describe(lyr)
 sel_set = dsc.fidSet.replace(";",",")
 if dsc.shapeType == "Polyline" and dsc.fidSet != "":
  cursor = arcpy.da.SearchCursor(lyr, ["OID@", "ARCLENGTH", "Shape_Length"], "OBJECTID IN (" + sel_set + ")")
  arcLengthTot = 0
  shapeLengthTot = 0
  for row in cursor:
   arcLength = row[1]
   shapeLength = row[2]
   if arcLength > '0':
    arcLengthTot += float(arcLength)
    arcpy.AddMessage("ArcLength = " + arcLength)
   else:
    shapeLengthTot += shapeLength
    arcpy.AddMessage("ShapeLength = " + str(shapeLength))
   arcpy.AddMessage("ArcLengthTot = " + str(arcLengthTot))
   arcpy.AddMessage("ShapeLengthTot = " + str(shapeLengthTot))
  del row
  del cursor
0 Kudos