1

I am using ArcGIS Desktop 10.3.

I have a number of polygons representing exploration licences and a series of attributes including licence name, operator, partners and associated interests (%) within each licence. I am trying to create a stacked label expression that will display in the following order: Licence name, operator and interest, partner(s) name and interest. The way the attribute table is setup is that the percentage interest values are 0 where there is no partner. The dataset is read only and so I can't edit the table to remove the zeros. So far I have the following code:

def FindLabel ([AREABLK] , [Own1] , [Asgnpct1] , [Own2] , [Asgnpct2] , [Own3] , [Asgnpct3] , [Own4] , [Asgnpct4] , [Own5] , [Asgnpct5]):
 if [Own5] is not None:
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")" + "\n" + [Own3] + " (" + [Asgnpct3] + "%" + ")" + "\n" + [Own4] + " (" + [Asgnpct4] + "%" + ")" + "\n" + [Own5] + " (" + [Asgnpct5] + "%" + ")"
 elif ([Own4] is not None and [Own5] is None):
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")" + "\n" + [Own3] + " (" + [Asgnpct3] + "%" + ")" + "\n" + [Own4] + " (" + [Asgnpct4] + "%" + ")"
 elif ([Own3] is not None and [Own4] is None):
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")" + "\n" + [Own3] + " (" + [Asgnpct3] + "%" + ")"
 elif ([Own2] is not None and [Own3] is None):
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")"
 elif [Own2] is None:
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")"

This gives the following output:

enter image description here

The first few rows work fine but where the partner isn't present it still shows the 0 value with the (%) text added.

I would therefore like to ignore the 0 values where there is no partner in the expression.

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Feb 3, 2016 at 14:49
5
  • 4
    Just a note on code readability: You will be doing yourself a favor if you get in the habit of using the .format() function of the string object. Not so many plus symbols. return "{0}\n{1} ({2}%)\n{3} ({4}%)\n{5} ({6}%)\n{7} ({8}%)\n{9} ({10}%)".format([AREABLK], [Own1], [Asgnpct1], [Own2], [Asgnpct2], [Own3], [Asgnpct3], [Own4], [Asgnpct4], [Own5], [Asgnpct5]) Commented Feb 3, 2016 at 19:33
  • Appreciated. That said, it was a label expression for a user so if it works...I'm happy. Scriptwise your notes are valid in this case. Commented Feb 3, 2016 at 19:36
  • Howe - I gotta thank you again for asking this question. The answer we worked up makes labeling in these situations so easy and clean. Commented Feb 10, 2016 at 16:19
  • It does indeed. I've encountered it a lot and this makes me much less annoyed :) Commented Feb 10, 2016 at 16:22
  • Hey, I edited my answer because when I used it for manhole inverts, it wouldn't print some inverts if they had the same value. With the new answer you don't have to worry about data not showing up. Commented Feb 22, 2016 at 22:16

3 Answers 3

3

The code section at the bottom of this answer is better than using dict. The problem with using dict is that the keys must be unique, and in-some cases (not this particular question) they might not be.


I changed your code somewhat but it produces what you want. It checks for owner to be empty or none, then it checks the same for percent. If they both have values it adds them to the label. You can modify any section of this with an else to replace the empty value with something if needed. Yes intial problem was the way you were checking for the value, but I went down a rabbit hole and wanted to post this.

from collections import OrderedDict
def FindLabel ([AREABLK] , [Own1] , [Asgnpct1] , [Own2] , [Asgnpct2] , [Own3] , [Asgnpct3] , [Own4] , [Asgnpct4] , [Own5] , [Asgnpct5]):
 dict = ([Own1],[Asgnpct1]),([Own2],[Asgnpct2]),([Own3],[Asgnpct3]),([Own4],[Asgnpct4]),([Own5],[Asgnpct5])
 dict = OrderedDict(dict)
 x = [AREABLK]
 for k, v in dict.iteritems():
 if k is not None:
 if k.strip() != "":
 if v is not None:
 if v.strip() !="":
 x = x + "\n" + k + " (" + v + "%)"
 return x

Updated code to work around using dictionary for key:values and problems associated with it:

def validate(element):
 return element and element.strip()
def FindLabel ([AREABLK] , [Own1] , [Asgnpct1] , [Own2] , [Asgnpct2] , [Own3] , [Asgnpct3] , [Own4] , [Asgnpct4] , [Own5] , [Asgnpct5]):
 fields = [Own1] , [Asgnpct1] , [Own2] , [Asgnpct2] , [Own3] , [Asgnpct3] , [Own4] , [Asgnpct4] , [Own5] , [Asgnpct5]
 area = [AREABLK]
 label = ["{}".format(area)]
 for i in range(len(fields)/2): 
 f1 = fields[i*2]
 f2 = fields[i*2+1]
 if validate(f1) and validate(f2):
 label.append("{} ({}%)".format(f1,f2))
 return '\n'.join(label)
PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
answered Feb 3, 2016 at 19:21
7
  • Super thanks Barrett. I'll check it out tomorrow. It certainly has more elegance! Commented Feb 3, 2016 at 19:24
  • 1
    Yeah it does, i can use it in my own work so that was my main interest. It works with the table I tested it on. Again, add an else to any one of the checks to replace the null or zero value with something if you need to. BTW you can shorten your code "%" + ")" to "%)". Commented Feb 3, 2016 at 19:26
  • Also, it probably won't label if [AREABLK] is none or empty, so you might add the same checks unless there is no chance of that happening Commented Feb 3, 2016 at 19:34
  • It's always present so not a problem. Commented Feb 3, 2016 at 19:38
  • 1
    hey man i just edited the code. I changed 3 lines: added import, modified the dict = line and then added a new line setting it to ordereddict. Hope this does it for you, it did it with my quick testing Commented Feb 4, 2016 at 16:17
2

Ok so I changed the code somewhat, as inelegant as it is, it works for what I need.

def FindLabel ([AREABLK] , [Own1] , [Asgnpct1] , [Own2] , [Asgnpct2] , [Own3] , [Asgnpct3] , [Own4] , [Asgnpct4] , [Own5] , [Asgnpct5]):
if [Own4] != " " and [Asgnpct5] == '0':
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")" + "\n" + [Own3] + " (" + [Asgnpct3] + "%" + ")" + "\n" + [Own4] + " (" + [Asgnpct4] + "%" + ")"
elif [Own3] != " " and [Asgnpct4] == '0':
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")" + "\n" + [Own3] + " (" + [Asgnpct3] + "%" + ")"
elif [Own2] != " " and [Asgnpct3] == '0':
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")"
elif [Own1] != " " and [Asgnpct2] == '0':
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")"
else:
 return [AREABLK] + "\n" + [Own1] + " (" + [Asgnpct1] + "%" + ")" + "\n" + [Own2] + " (" + [Asgnpct2] + "%" + ")" + "\n" + [Own3] + " (" + [Asgnpct3] + "%" + ")" + "\n" + [Own4] + " (" + [Asgnpct4] + "%" + ")" + "\n" + [Own5] + " (" + [Asgnpct5] + "%" + ")"

enter image description here

answered Feb 3, 2016 at 16:45
2

You never get past the first if statement because you are comparing and empty list to None which will always result in True because it exists - even though it is empty.

An example:

own1 = "own1"
[own1] is not None
> True
own2 = None
[own2] is not None
> True

The second statement is also true because you are using the brackets around own2 that create an empty list.

[] is not None
> True

What you should do instead is test the variables for their existance:

own1 = "own1"
own1 is not None
> True
own2 = None
own2 is not None
> False

edit:

As pointed out by @Howeitzer and @recurvata the brackets are not designating lists as any sane Python user would expect. This answer is therefore mute since I expected ESRI wouldn't dare change something so fundamental to Python as the behaviour of lists!

answered Feb 3, 2016 at 15:11
4
  • Thanks Kersten although I'm not sure I quite follow you. Commented Feb 3, 2016 at 15:50
  • 2
    Where is a list? The brackets in this case are just the field designators. Why the label engine uses [] for python rather than !! I don't know. Commented Feb 3, 2016 at 16:28
  • @recurvata I just rechecked in ArcPy. You're absolutely right. My answer would be valid for any Python distribution except ArcPy. It is beyond me why they would change such a fundamental part of Python. Commented Feb 3, 2016 at 16:52
  • I think it's what the label engine uses for Python, not ArcPy, but I don't know how ESRI implements it. Agree that this is confusing at best. Commented Feb 3, 2016 at 21:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.