wanted: easyest way for field calculation with python

1688
10
12-05-2018 07:08 AM
SilvanStöckli
New Contributor III

Hello,

I'd like to do some complicated field calculation.

I want to calculate the Field 6-value (see table below, representing a FeatureClass table) as follows:

If Field 1 = 617: Field 3-value

Else: Field 2-value

AND

"|"

AND

If Field 4 = ABC:

      If Field 5 is Null:

            "Sometext"

      Else:

            "Someothertext" + Field 5

Else:

I entered the results in Field 6 as an example

Field 1Field 2Field 3Field 4Field 5Field 6
611from July 1April to NovemberTextWith_äöüfrom July 1 |  Sometext
612from July 1April to NovemberABCTextWith_äöüfrom July 1 | Someothertext TextWith_äöü
612from July 15April to NovemberABCfrom July 15 | Someothertext
617from July 1April to NovemberABCApril to November | Someothertext

Up until now, I exported the table and calculated the value with some "when"-statements in Excel. But since I'd like to have the results in GIS i searched for an other solution.

I ended up using "arcpy.CalculateField_management" and something like this:

def compare(class1, class2, class3):

   if class1 in (612, 611):
       return class2
   elif class1 == 617:
       return class3
   else:
       return class1

# Expression below

compare(!some_field!, !another_field!, !another_field2!)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This didn't work quite well because

- the code will become huge (I have more fields and values to compare)

- there seem to be problems with converting/using characters which don't fit into ASCII

- i couldn't figure out how to ask properly if Field 5 is Null

- I could not properly translate the "AND" and the "OR" from Excel to Python (for example: If Field 4 is Null AND Field 5 is Null AND Field 1 is 612, Field 6 = ...)

-...

Is there an other, easyer solution how I can calculate Field 6 value?

Thanks a lot for your help!

10 Replies
LukeWebb
Occasional Contributor III

Hello, 

Most of your issues seem to be 'basic' python issues that can be resolved with a little experience and have mostly been answered.

e.g.

-there seem to be problems with converting/using characters which don't fit into ASCII

- i couldn't figure out how to ask properly if Field 5 is Null

- I could not properly translate the "AND" and the "OR" from Excel to Python (for example: If Field 4 is Null AND Field 5 is Null AND Field 1 is 612, Field 6 = ...)

When it comes to this point, I feel your excel formulaes, or whatever other method you use will require the same amount of code / a big formulae. Do you see this differently? 

- the code will become huge (I have more fields and values to compare)

Anyways, to come from a different angle, answers to date seem to be focused on a more functional programming style. I like to try and break down my problem, and write as much code in more descriptive 'english' as I can, Ill provide a sample code showing what I mean by this but as its hard to work out what your doing it might come across badly!

I tested this in ArcMap and it works great. You do need to add logic for the "Uncaught text"

def compare(code_field, date_field1, date_field2, text_field1, text_field2):
    # -*- coding: latin-1 -*- or # -*- coding: utf-8 -*-
    def get_date_text():
        if code_field == '617':
            return str(date_field2)
        else:
            return str(date_field1)

    def get_sometext_string():
        if text_field1 == 'ABC' and text_field2 is None:
            return "Sometext"

        elif text_field1 == 'ABC' and text_field2:
            return "Someothertext"

        else:
            return "UNCAUGHT_TEXT"


    def get_otherfield_data():
        if text_field1 == 'ABC' and text_field2 is not None:
            return text_field2.encode("UTF-8")
        else:
            return ""



    #First I will work out each of the "Parts" that I need to represent in the output text and make a variable for these
    #(This bit isnt really needed, but helps us picture what we are going to do in our head)

    date_text = ""
    divider = ' | '
    string_about_sometext = ""
    other_field_data = ""


    #Now I know what I need to populate, I can write a function thinknig about each bit seperately, then put it all together later.
    date_text = get_date_text()
    string_about_sometext = get_sometext_string()
    other_field_data = get_otherfield_data()


    #Now I should have everything, ready to combine into an answer
    #(I would normally write this code using other string functions, but to keep it simpler am just combining all the strings and making sure each function returns a string)
    final_text = date_text + divider + string_about_sometext + other_field_data

    return final_text

#Expression

compare( !Field1! , !Field2! , !Field3! , !Field4! , !Field5! )