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:
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.
3 Answers 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)
-
Super thanks Barrett. I'll check it out tomorrow. It certainly has more elegance!Howeitzer– Howeitzer2016年02月03日 19:24:31 +00:00Commented Feb 3, 2016 at 19:24
-
1Yeah 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 "%)".Barrett– Barrett2016年02月03日 19:26:25 +00:00Commented 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 happeningBarrett– Barrett2016年02月03日 19:34:05 +00:00Commented Feb 3, 2016 at 19:34
-
It's always present so not a problem.Howeitzer– Howeitzer2016年02月03日 19:38:06 +00:00Commented Feb 3, 2016 at 19:38
-
1hey 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 testingBarrett– Barrett2016年02月04日 16:17:10 +00:00Commented Feb 4, 2016 at 16:17
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] + "%" + ")"
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!
-
Thanks Kersten although I'm not sure I quite follow you.Howeitzer– Howeitzer2016年02月03日 15:50:31 +00:00Commented Feb 3, 2016 at 15:50
-
2Where 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.recurvata– recurvata2016年02月03日 16:28:33 +00:00Commented 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.Kersten– Kersten2016年02月03日 16:52:26 +00:00Commented 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.recurvata– recurvata2016年02月03日 21:11:53 +00:00Commented Feb 3, 2016 at 21:11
Explore related questions
See similar questions with these tags.
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])