# Automating attribute field completion based on closest value in a list

I created the following model based on the fields that is needed for asset valuation. Please see below. I would like to auto-populate the "Code" field basde on certain criteria, for example.

The "size" field determines the Code field: if a pipe is 110mm thick a Code of "P_1" is added to the code field. This is later used to lookup the unit rate of said pipe.

Now here is where i am stuck: I would like to write a python script that will auto populate the Code field for me but the size value is not always constant. In some cases the pipe will be attributed the size of 108mm. I would like the script to then assign the "P_1" code to this pipe as the is a 2mm difference.

Is this possible within Arcmap or will i need to use a post gis program?

• It's possible with Python. Whats your experience level with it? Mar 2, 2016 at 8:52
• Not that great. I know the basics. I assume that some loop function will be used? Mar 2, 2016 at 8:54
• Well, you need to create a switch of an if-statement in a python script. I.e. if pipeThickness > 110 { code = 'P_1' } Mar 2, 2016 at 8:56
• Thank you. Will try that. I do not only have 110mm Pipes. The list is as follows: 50 63 75 90 110 125 140 160 200 250 315 355 400 450 500 550 600 650 700 750 800 850 900 950 1000 1100 1200 1300 1400 1500 1600 1800 The "Code" should be attributed to the closets value. Mar 2, 2016 at 9:02
• So if the value is 108mm it should bump up to 110mm but if the value the is 97 it should get the "90mm" size code and not 110mm code. Mar 2, 2016 at 9:09

This is achievable using the field calculator with Python parser. The simplest way is to define a dictionary which contains the pipe type for each diameter. You could also try using if, then statements, but dictionaries are probably easier and more "pythonic".

There's a Stack Overflow answer which shows how to get the closest value in a list. It can also be applied to dictionaries.

Using your screenshot from the chat, I created a dictionary for all pipe types (Comp ID).

Codeblock:

``````def diameter(n):
diamDict = {50:'W_PIP_1',63:'W_PIP_2',75:'W_PIP_3',90:'W_PIP_4',
110:'W_PIP_5',125:'W_PIP_6',140:'W_PIP_7',160:'W_PIP_8',
200:'W_PIP_9',250:'W_PIP_10',315:'W_PIP_11',355:'W_PIP_12',
400:'W_PIP_13',500:'W_PIP_14',550:'W_PIP_15',600:'W_PIP_16',
650:'W_PIP_17',700:'W_PIP_18',750:'W_PIP_19',800:'W_PIP_20',
850:'W_PIP_21',900:'W_PIP_22',950:'W_PIP_23',1000:'W_PIP_24',
1100:'W_PIP_25',1200:'W_PIP_26',1300:'W_PIP_27',1400:'W_PIP_28',
1500:'W_PIP_29',1600:'W_PIP_30',1700:'W_PIP_31',1800:'W_PIP_32'}

return diamDict[min(diamDict, key=lambda x:abs(x-n))]
``````

Expression:

``````diameter( !Diam!)
`````` I created a few sample lines with varying diameters and ran the field calculator on the Pipe Type field.

The results are below: You can see that a diameter of 97 gets the value for a 90mm pipe (W_PIP_4) and a 108mm pipe gets the value for a 110mm pipe (W_PIP_5).