Quantify labels with Names in them

Is there a way for me to take tags/components that have names in them and quantify them? In the pic below youll see that Jerome Smith appears in 5 areas, how do I make that into a memory tag that tells me that?


Where are the names in the labels coming from? Are they tag bindings, or what?

They are tag bindings

Sounds like you would write a script to read all your tags and loop over the results to create a list of duplicate values.

a = [1,2,3,2,1,5,6,5,5,5]

import collections
print([item for item, count in collections.Counter(a).items() if count > 1])

> [1, 2, 5]

Looks like a start, thanks

So, I have this, which is a start

names = [
	system.tag.readBlocking("[default]Phase 1 Extrusion/L31/L31_Pos1/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L31/L31_Pos2/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L31/L31_Pos3/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L31/L31_Pos4/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L11/L11_Pos1/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L11/L11_Pos1/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L11/L11_Pos2/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L11/L11_Pos3/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L11/L11_Pos4/Assigned Operator Name")[0].value,
	system.tag.readBlocking("[default]Phase 1 Extrusion/L11/L11_Pos5/Assigned Operator Name")[0].value,

import collections

print ([item for item, count in collections.Counter(names).items() if count > 0])

It returns this, which is good

[u'Neta Justice', u'Jerome Smith']

Is there a way for it to tell me how many names are there?

First, don't ever issue a whole bunch of separate readBlocking calls in a row like that. It's terrible for performance.
Second, collections.Counter().items() returns an iterable of (item, count) tuples. In @dkhayes117's code, that iterable is being used in a list comprehension and simultaneously unpacked into just the item return value; that's this line:

[item for item, count in collections.Counter(names).items() if count > 0]

If it helps, you can think of that list comprehension as being this imperative loop:

ret = []
for item, count in collections.Counter(names).items():
	if count > 0:

So if you wanted to return both the name and the count, you have to decide on a different structural representation. There's a lot of options, but one simple one that allows you to return things with some sort order would be a list of tuples. To sort, you can use the sorted builtin; and since you (potentially) want the highest count first, you could add the reverse flag:

	itemCount for itemCount in collections.Counter(names).items() if count > 0,
	key=lambda x: x[1],

system.tag.readBlocking() works much faster if you use it only once and pass a list into it
About your Return, if i got it correctly, Counter will return only uniques so in the end you just need to count how many elements are, maybe just adding a len() solves it, basically:

names = [tag.value for tag in system.tag.readBlocking(["[default]Phase 1 Extrusion/L31/L31_Pos1/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L31/L31_Pos2/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L31/L31_Pos3/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L31/L31_Pos4/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L11/L11_Pos1/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L11/L11_Pos1/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L11/L11_Pos2/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L11/L11_Pos3/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L11/L11_Pos4/Assigned Operator Name",
														  "[default]Phase 1 Extrusion/L11/L11_Pos5/Assigned Operator Name"])]
import collections

print len([item for item, count in collections.Counter(names).items() if count > 0])

Here is a version that uses the Counter constructor.

Note that your original code has an extra L11_Pos1 path, I've removed that.

import collections

paths = ["[default]Phase 1 Extrusion/L31/L31_Pos1/Assigned Operator Name","[default]Phase 1 Extrusion/L31/L31_Pos2/Assigned Operator Name","[default]Phase 1 Extrusion/L31/L31_Pos3/Assigned Operator Name","[default]Phase 1 Extrusion/L31/L31_Pos4/Assigned Operator Name","[default]Phase 1 Extrusion/L11/L11_Pos1/Assigned Operator Name","[default]Phase 1 Extrusion/L11/L11_Pos2/Assigned Operator Name","[default]Phase 1 Extrusion/L11/L11_Pos3/Assigned Operator Name","[default]Phase 1 Extrusion/L11/L11_Pos4/Assigned Operator Name","[default]Phase 1 Extrusion/L11/L11_Pos5/Assigned Operator Name"]

cnt = collections.Counter([tag.value for tag in system.tag.readBlocking(paths)])

print cnt

Thats good to know about the readBlockings, thanks

Thats correct. thanks.

Thank you sir!

1 Like

You can also get fancy and generate your paths programmatically, since they (in this case) follow a very simple structure:

levels = {"L31": 4, "L11": 5}

ret = [
	"[default]Phase 1 Extrusion/{level}/{level}_Pos{position}/Assigned Operator Name".format(level=level, position=position + 1)
	for level, positions in levels.items()
	for position in xrange(positions)
print ret

One reason why I do not like to do this is if you (or more problematically) someone else is searching for the full tag path because something is going on in the scripting, it will not appear. Tag paths are one thing I think should always be written out in full but maybe I'm wrong.

There is honestly nothing I loath more than typing 90% of the same string in a list over and over again.

Even here, I copied the original code and deleted the things needed to make it a properly formed list. Generally I would use the approach that @PGriffith shows.

Perhaps I'm just lazy.


With you entirely. The opportunity for typos when repeatedly spelling such things out far outweighs any full path search options.


All this discussion was great, thanks alot guys!

Is there a way to remove the "u'" before the names: [u'Neta Justice', u'Jerome Smith']

That 'u' isn't "real"; it's only there because you're printing a list directly.

l = [u'Neta Justice', u'Jerome Smith']
print l
for name in l:
	print name
[u'Neta Justice', u'Jerome Smith']
Neta Justice
Jerome Smith

Oh, ok, good to know sir. thanks