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:
ret.append(item)
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:
sorted(
itemCount for itemCount in collections.Counter(names).items() if count > 0,
key=lambda x: x[1],
reverse=True
)
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!
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