I am struggling a bit with debugging my code, over something that seems very simple. I am using an update cursor to copy and convert existing string data into a new float column of my shapefile's attribute data. In the original column titled "DIRECTION_" consists of strings with the following values: n, e, s, w, ne, nw, se, sw; 0-360; and finally, just blank entries. See the figure below.
Original column in attribute data, when right clicking on column ArcMAP says type is a string
Here is a picture of my code, with a typo in the comment. (TYPO = "short integer field", when should be "float type"). This code results in all other values inputted as zero except of NSEW.
I have tried to change the type of the new field to FLOAT, LONG, SHORT. And I have tried the following else statements at the end of my for loop, all resulting in type errors.
else:
row[1] == float(row[0]) #gives Value error: could not convert string to float
else:
row[1] == row(0)
else:
row[1] == int(row[0]) #gives error: The value type is incompatible with the field type
else:
row[1] = row[0] #gives RuntimeError: The value type is incompatible with the field type
-
1Welcome to GIS SE! Please use the edit button beneath your question to include that code as text in preference to as a picture so that it can be both searched and copy/pasted for testing.PolyGeo– PolyGeo ♦2016年03月05日 19:59:49 +00:00Commented Mar 5, 2016 at 19:59
-
1Using multiple ifs can be confusing at least, replacing them by 2 lists or even better by dictionary, e.g. gis.stackexchange.com/questions/177479/… will make your code work faster and easier to debug. Hyperlink points to near identical questionFelixIP– FelixIP2016年03月06日 03:46:36 +00:00Commented Mar 6, 2016 at 3:46
1 Answer 1
In your code snippet above you have a double equals ==
rather than single in your else
else:
row[1] == row[0] #if entry has a number, copy that number into the new DIR_int column
This won't work. You need to use
else:
row[1] = row[0] #if entry has a number, copy that number into the new DIR_int column
But probably what is breaking your code is that you're not checking for empty values (or values with spaces) rather than Null values. The following code snippet should work. It checks that there is a value in the cell, and if it is that it isn't a space. Any spaces, empty cells, or Nulls are transferred into the new column as a Null value.
cursor = da.UpdateCursor(points, ["DIRECTION_", "DIR_int"])
for row in cursor:
if not row[0] == None and len(row[0]) > 0: # Check if row[0] has a value
rowValue = row[0].strip() # Strips any leading/trailing spaces
if rowValue == 'n':
row[1] = 0
elif rowValue == 'e':
row[1] = 90
elif rowValue == 's':
row[1] = 180
elif rowValue == 'w':
row[1] = 270
elif rowValue == 'ne':
row[1] = 45
elif rowValue == 'nw':
row[1] = 315
elif rowValue == 'se':
row[1] = 135
elif rowValue == 'sw':
row[1] = 225
elif rowValue.isnumeric(): # Checks if the value is a number
row[1] = rowValue
else: # If it still doesn't work, make it a Null
row[1] = None
else: # If row[0] doesn't have a value, then set row[1] to Null
row[1] = None
cursor.updateRow(row)
Here is a screenshot of my output - I've used your values (as far as I can tell regarding empty values) plus added a few more to test.
EDIT:
Working on FelixIP's suggestion above about using a Dictionary, the following looks a lot easier to read (and edit):
cursor = da.UpdateCursor(points, ["DIRECTION_", "DIR_int"])
def directions(value):
dirDict = {
'n': 0,
'e': 90,
's': 180,
'w': 270,
'ne': 45,
'nw': 315,
'se': 135,
'sw': 225
}
return dirDict.get(value, None)
for row in cursor:
if row[0] and len(row[0]) > 0: # Check if row[0] has a value
rowValue = row[0].strip().lower() # Strips any leading/trailing spaces
if rowValue.isnumeric(): # If it's numeric, just use the existing value
row[1] = rowValue
else: # If it's not numeric, then look it up in the dictionary
row[1] = directions(rowValue)
else: # If row[0] doesn't have a value, then set row[1] to Null
row[1] = None
cursor.updateRow(row)
-
I just spotted the issue. You don't have Nulls, you have some kind of value (perhaps
' '
- a space)2016年03月05日 21:20:21 +00:00Commented Mar 5, 2016 at 21:20 -
Updated to check for empty/space values2016年03月05日 21:38:30 +00:00Commented Mar 5, 2016 at 21:38
-
Updated again to include code snippet with dictionary2016年03月06日 23:48:02 +00:00Commented Mar 6, 2016 at 23:48
-
Hi friends, off of Midavalo's answer I got the following error:Traceback (most recent call last): File "C:/Users/jenboyer/Desktop/Spatial Spread W.Hyacinth/182 project/buffscript_3.8.py", line 92, in <module> cursor.updateRow(row) RuntimeError: The field is not nullable. [DIR_int]Jebo– Jebo2016年03月08日 22:14:27 +00:00Commented Mar 8, 2016 at 22:14
-
Problem resolved: changed return dirDict.get(value, None) to --> return dirDict.get(value, 0) and it worked just fine. Thank you thank you!Jebo– Jebo2016年03月08日 22:59:15 +00:00Commented Mar 8, 2016 at 22:59