this started as a totally different question, but as i dug i found more stuff that makes no sense. i was trying to un some spaghetti code, when i managed to get this FINALLY USEFUL mistaken output:
no joke, i wish i could get this kind out outpuyt everytime i want to print() data...
anyway. since i just wanted to extract the email portion of the dict, i started in like so:
userdata = system.user.getUser('', 'ian')
email, sms = ''
ci = userdata.contactInfo # <--- this gives me a list of... what? isn't it a dict?
print(ci) # <--- confirmed. not a dict: [email: ian@no.io, sms: 444]
# should this not be [{'Delete':'','type':'email', ...}]??
for item in ci:
# yeah... i stopped here
system.perspective.print(email)
it's a list! it's a dict! it's a dataset! what the . i do not understand these data structures. it's like working with MongoDB... can someone unpack this for me? are these strings? why aren't they quoted? i know i'm a bit OCD with this stuff, so bear with my exasperation as i try to find some rhyme and reason here. and i'm betting it's either something stupidly simple that i've overlooked, or it's Chtulu's own magic itself.
after reading very closely the docs, this is at odds with what i perceive the output from my loop to be.
from the manual:
user.getContactInfo() - Returns a sequence of ContactInfo objects. Each of these objects will have a contactType and a value property representing the contact information. Both properties are strings.
so userdata.contactInfoshould be an object from which i should be able to reference a property to get a value:
email = [item.value for item in ci if item.contactType == 'email'][0] # <--- !!!
# don't forget the *index* because why would i return a just string??
print(email) # <--- FINALLY!! ian@no.io
so what i'm deducing is that print() is doing something i'm not used to behind the scenes. for example when i first wrote the code, i expected a string output and print() gave me this: [u'ian@no.io'] which threw me for bit. that's not SOP. and it's likely Java's fault...
i think i just have to learn that every thing is crammed into a list. like individually wrapped Lifesavers in a bag: unecessary but that's how they come.
furthermore, how on did email and phone not make the cut as part of user!?!? that's been part of standard user data structure for the last 20+ years. SMH.
Just like objects in Python can have a __str()__ method, objects in Java can have a toString() method that provide an alternative string representation. Introspection via str() is for fools, up your game and use type(), even if just in addition to str().
Slow down and read the docs.
They're types of contact information, which is its own extensible concept inside Ignition.
i don't know Java at all. and i stopped writing C++ decades ago. but making that comparison makes sense to me now. in fact, it's more like __repr__ than anything. and i am trying to slow down to read the docs, but i am on a deadline here. two more weeks and things should downshift dramatically.
this is the first time in my career i've ever come across data structures i don't know the contents of. it's got me flat-footed from the jump. so now i AM actually going back to 'typing' everything... no pun intended.
and still think abstracting contact information is just dumb... IMLTHO.
I still use the introspect() function from my ancientinspect.py script module. You might find it helpful, too. If only as a shortcut to all of the possible java documentation that might apply.
Also, a given user could have one, zero, or more than one of every contact type. And modules are able to provide their own contact info types (like an SMS number, or a slack ID, or whatever).
You could argue the base user class "should" know about the most common contact info types, but then we're using the abstraction wrong in the other direction; why are certain types special but others not?
Slight zombie thread here, but curious any plans to ever add a bit of an IDE to the Python scripting environment in Ignition to make all this stuff slightly less painful? I know the CS majors love typing long debug strings and digging through obscure logs to figure this stuff out, but as a ChemE just trying to automate some stuff, I find it very painful - I’m an old school self taught VBA programmer, so that’s my reference, and I know the CS’s will scold me for this, but I really think the VBA IDE (>20 years old now) with the Locals window where I can just put a breakpoint and SEE all my variables and data structures with a few clicks is far superior to the current Ignition python scripting environment - I enjoy scripting there so much more than in Ignition and I really wish that weren’t the case as I know Ignition is the future and will be where eventually I will need to live more often. Anyway my $0.02 - maybe some other ChemE’s out there will empathize with me a bit on this one. Until then, I will definitely be checking out Phil’s library for exploring the data structures, sounds like it would be very helpful.
One of the most useful tools I’ve found is Gemini (or your AI of choice). Toss your script in there with the prompt:
Don’t change the functionality of this, just add debugging steps so I can see the problem.
AI tends to struggle with generating scripting for Ignition, particularly because it mixes up so many older versions that aren’t supported anymore as well as crawls the forum and intakes incorrect code from posts as part of the LLM. But it is exceptionally good at being used to add data logging steps or even just cleaning up some comments for existing scripting.
Best bet is to break down your functions into tiny business units. This will also keep you sane.
Instead of
def bigBusinessFunction(data):
# 100 lines of code that make with raw databse queries
# to make database record, raw calls to make a pdf print/save to db/local
# and write some tags to a PLC to reset some bit
Etc. Then you can test any smaller part of your big function independently. Also it will make your functions much kinder to read if I can read a series of function calls that can give me overview of what is actually being done from a high level perspective.
The long term plan is to sidestep things entirely and allow you to hook up your own IDE of choice (e.g Visual Studio Code, PyCharm, whatever) to author Ignition scripts, ideally involving debugging of script variables.
There's a variety of problems with how exactly to do that -- remember that an Ignition script may be running on your local designer, or actually on the gateway, and your attempt to debug a script must not by default 'stop the world' for every other script that's potentially running -- but rest assured that we're no happier with the script editing and debugging experience internally than you are.
Paul - I appreciate the reply and it helps to hear I’m not the only one this is a pain point for. I understand that this is not a trivial thing to implement by any means, so I wish you the best in working through this with the team there and look forward to seeing what you all come up with down the road at some point. I don’t do much standalone Python coding, but I’ll definitely check out PyCharm to see what more modern IDE’s are looking like these days.