Calculate Field with Code Block Python Script?

11338
15
Jump to solution
11-14-2018 01:46 PM
ZacharyHart
Occasional Contributor III

I've spent quite a bit of time looking at all the similar issues on GeoNet and Stack Exchange but I still can't find an answer. I'm sure that someone will be quick to say that I should use a cursor, but this exact same code works in ModelBuilder just fine!

Is there the potential for a carriage return or something? I copied and pasted my codeblock so that might be a possibility.  Here's my code (the FC in question does indeed have a field called 'BEARING'):

# Add Quandrant Bearing Field
arcpy.AddField_management(BoundSplit, "Q_BEARING", "TEXT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

# Calculate Quadrant Bearing
expression = """ DD_DMS_Line(!BEARING!,{0}) """.format(correction)
arcpy.AddMessage(expression)
codeblock = """def DD_DMS_Line(bearing, correction=0):
 value = bearing + correction
 if value <= 90:
 numb = value
 prefix = "N"
 suffix = "E"
 elif value > 90 and value < 180:
 numb = 180 - value
 prefix = "S"
 suffix = "E"
 elif value >= 180 and value < 270:
 numb = value - 180
 prefix = "S"
 suffix = "W"
 elif value > 270 and value <= 360:
 numb = 360 - value
 prefix = "N"
 suffix = "W"
 elif value > 360:
 numb = value - 360
 prefix = "N"
 suffix = "E"

 degrees = int(numb)
 submin = abs( (numb - int(numb) ) * 60)
 minutes = int(submin)
 subseconds = abs((submin-int(submin)) * 60)
 notation = prefix + str(degrees) + u"\u00b0" + str(minutes) + "\'" +\
 str(subseconds)[0:5] + "\"" + suffix
 return notation"""

arcpy.CalculateField_management(BoundSplit, "Q_BEARING", expression, "PYTHON", codeblock)

My expression appears to be fine (highlighted in this image).

ugh, been banging my head against the wall on this one!

1 Solution

Accepted Solutions
DanPatterson_Retired
MVP Emeritus

try triple single quotes to enclose you code block because you are using double quotes throughout the scripts, it is probably fouled up 

'''

your script block

'''

or change all your double quotes to single quotes in the script... (the former is probably quicker )

View solution in original post

15 Replies
DanPatterson_Retired
MVP Emeritus

try triple single quotes to enclose you code block because you are using double quotes throughout the scripts, it is probably fouled up 

'''

your script block

'''

or change all your double quotes to single quotes in the script... (the former is probably quicker )

ZacharyHart
Occasional Contributor III

Dan Patterson‌ After a really long day I came home to try your fix, but to no avail. I was very hopeful on this one too! Same error.

i wonder if i try to format my notation statement? too bad because it did work in the model builder prototype but it's probably some kinda issue with quote escaping (although that lingering thing about copying and pasting the code block is bugging me too, i'll redo that but remote access is slow tonight).

0 Kudos
DanPatterson_Retired
MVP Emeritus

Zachary, Jive (that which runs GeoNet) is having issues with code formatting, so I assumed that was the issue with your code block indentation... which is totally off)

Lines 9, 10, 11, 12  need to be indented by 4 spaces

repeate for every section of an if, elif, elif, else portion of your code

like so... I set the font to Courier New.

Notice the indentations are multiples of 4 spaces

'''
def DD_DMS_Line(bearing, correction=0):
    # comment line
     value = bearing + correction
     if value <= 90:
         numb = value
         prefix = "N"
         suffix = "E"
     elif value > 90 and value < 180:
         numb = 180 - value
         prefix = "S"
         suffix = "E"
     elif value >= 180 and value < 270:
         numb = value - 180
         prefix = "S"
         suffix = "W"
     elif value > 270 and value <= 360:
         numb = 360 - value
         prefix = "N"
         suffix = "W"
     elif value > 360:
         numb = value - 360
         prefix = "N"
         suffix = "E"
     degrees = int(numb)
     submin = abs( (numb - int(numb) ) * 60)
     minutes = int(submin)
     subseconds = abs((submin-int(submin)) * 60)
     notation = prefix + str(degrees) + u"\u00b0" + str(minutes) + "\'" +\
     str(subseconds)[0:5] + "\"" + suffix
     return notation
 '''

0 Kudos
ZacharyHart
Occasional Contributor III

Dan thanks for the heads-up on the Jive formatting. I looked back at my code and I do have the indentations. However, I did modify the beginning and end of the codeblock a bit. I know images are generally frowned upon when relaying code, but given the formatting issue I'm adding this for verification. Still have the same error:

UPDATE: after much picking away it does appear that something is wrong with the 'notation' statement or at least something isn't happy there. If I reduce it down to just  notation = prefix + str(degrees) the output is fine. Admittedly the output is a bit over-complicated (but it works in model builder) .

Is there a way to insert another string formatting statement w/in the codeblock? I may try that fresh in the AM.

0 Kudos
DanPatterson_Retired
MVP Emeritus

Ok... it boils down to whether Q_BEARING or BEARING is the expression section.

and try single quotes around expression 

" DD_DMS_Line(!BEARING!,{0}) ".format(correction)

I use a totally different method instead of adding fields and using code blocks (we won't go into that now )

0 Kudos
ZacharyHart
Occasional Contributor III

 Thanks Dan!

We're calculating a field called Q_BEARING, with BEARING being one the inputs to the epression.

Not sure if you cought my last blurb but it does indeed appear to be a problem with my notation statement (if I simplify that things work). Can I embed an additional string formatter within the codeblock? 

0 Kudos
DanPatterson_Retired
MVP Emeritus

ok... too many bearings, I am losing track

just be careful about inserting format blocks within code blocks that you don't upset the single/double quote balance.  A good python IDE will pick up those issues

just recheck the examples in

Calculate Field—Data Management toolbox | ArcGIS Desktop 

ZacharyHart
Occasional Contributor III

Thanks Dan.

I'm not firing on all cylinders but I'm gonna try to tackle this again in the AM.

I'm also nervous about the format block in the code block. I just wish I knew why this worked in MB. (,I even tried to yank out converted script. I even built a stand alone function that does this same part that works!) Thanks again

0 Kudos
ZacharyHart
Occasional Contributor III

Dan Patterson‌ Dan, are you familiar with the proverb For Want of a Nail?

Notice that one slight change I underlined? jeez...

And the output:

Thanks for sticking with me on this one! In the end you were right...it was ultimately about quotes