0

I am having some problems retrieving data from a dictionary that is created in a for loop. In my code I have two dictionaries created and updated periodically, one from a machine database and one from a global database. The problem I am having is that i need to evaluate each of them in a separate for loop based on machine number. I can create the dictionaries no problem, but I am struggling with the code to retrieve a different dictionary tag per iteration of the for loop.

This is the code that creates the dictionaries:

# sets machines that need error checking performed
workcenters = ['25294', '25296', '25331', '25334', '25335', '25336']

# Queries local machine database
for index in range(len(workcenters)):
    result = EEDBConnect.connect(workcenters[index])
    globals()["a" + str(workcenters[index])] = result

# Returns a different dictionary for each machine in the form of:
a25294 = {'Line_Status':None, 'Order_ID':None}
a25296 = {'Line_Status':None, 'Order_ID':None}
a25331 = {'Line_Status':None, 'Order_ID':None}
ect....
ect....

# Queries global machine database
for index in range(len(workcenters)):
    result = GBDBConnect.connect(workcenters[index])
    globals()["b" + str(workcenters[index])] = result

# Returns a different dictionary for each machine in the form of: 
b25294 = {'Line_Status':None, 'Order_ID':None}
b25296 = {'Line_Status':None, 'Order_ID':None}
b25331 = {'Line_Status':None, 'Order_ID':None}
ect....
ect....

Now the part I am having issues with, how do I go about looking up those dictionaries in a for loop? Below is just an example in code of what I am trying to do.

(I know it is completely the wrong way to write it but i can't find a better way to describe it)

****** Updated ******

for index in range(len(workcenters)):
    a = #here is where i need to assign the a##### dictionary 
    b = #here is where i need to assign the b##### dictionary

    stat[str(workcenters[index])] = a['Line_Status'] == b['Line_Status']
    ordr[str(workcenters[index])] = a['Order_ID'] == b['Order_ID'] 

I have tried multiple ways to get the desired result and I have been stuck on this problem for about a week now. I'm sure it is something really stupid that I am missing, but I just started writing python this year for this project and any help would be greatly appreciated. Thanks!

Andrew
  • 11
  • 5
  • 4
    Why, WHY would you ever do something like this: `globals()["a" + str(workcenters[index])] = result`??? – juanpa.arrivillaga Dec 13 '16 at 17:05
  • 1
    But leaving that aside, your question is pretty good for a first question, but it would be better if you described what output you are getting with your attempt, and how that differs from the output you are looking for. – juanpa.arrivillaga Dec 13 '16 at 17:09
  • 1
    Also, just a tip, in python, you can generally iterate over the items in a container directly. so instead of `for index in range(len(some_list))` you can do `for item in some_list:` – juanpa.arrivillaga Dec 13 '16 at 17:12
  • Have an upvote, a nice first question. – noɥʇʎԀʎzɐɹƆ Dec 13 '16 at 17:22
  • Or possibly, duplicate of http://stackoverflow.com/q/1373164/2823755 - its accepted answer might do what you want. – wwii Dec 13 '16 at 17:51
  • juanpa.arrivillaga what I have here is a fairly dumbed down version of what I have in my project. But I needed a global variable that is dynamically built as there are literally 100 machines that are being called and besides the for loop that is cross-checking the a##### and b##### there are also sections of the GUI that are populated with the a##### and b##### dictionaries. That was the easiest way I found to dump the list that the query called into a dynamic global variable..... if that makes any sense. I am going through the solutions. I will give a check or solution when verified. – Andrew Dec 13 '16 at 19:31
  • 2
    @Andrew you can still just use a `dict`. Don't abuse the `globals` dict that way. – juanpa.arrivillaga Dec 13 '16 at 19:52
  • @juanpa.arrivillaga I am trying that way now. I got a little sidetracked. i guess i was selfishly trying not to nest the created dictionary in a dictionary, why? I don't know....... It works great, Thanks for all the help! – Andrew Dec 13 '16 at 20:20

2 Answers2

0

I will assume you wanted to save the dictionaries created in your second for loop with the prefix b, since you seem to use them that way as seen from the code of the last loop.

And there lies your problem, because as seen from your current code, you create no variables with the prefix b:

# Queries global database
for index in range(len(workcenters)):
    result = GBDBConnect.connect(workcenters[index])
    globals()["b" + str(workcenters[index])] = result  # originally 'a' + ...

Also, avoid using globals. While it might look easy and fun, using a dictionary to store your dynamic variables would prove better, easier and safer.

machine_results = {}
...
machine_results["b" + str(workcenters[index])] = result

P.S. In the last loop,

if a['Line_Status'] == b['Line_Status']:
    result = True
if a['Line_Status'] != b['Line_Status']:
    result = False

can be reduced to

result = a['Line_Status'] == b['Line_Status']
Uriel
  • 15,579
  • 6
  • 25
  • 46
  • yes, you are correct, it was a simple copy paste error. I was in a hurry. Thanks for the better formatted result line. That works great. – Andrew Dec 13 '16 at 20:01
0

This is a terrible way to do things. Instead of storing automatically-generated items in the globals() workspace, where so many other variables also hang out, simply store them in purpose-built namespaces. In other words, store your a* variables in one dict (called a, perhaps?) and your b* variables in another dict (perhaps called b?). The two dicts themselves can be global variables if necessary. I can think of no situation in which a variable absolutely has to be referred to as a1234 as opposed to a[1234] (or a['1234'], whichever makes more sense).

If you must assign your variables directly in globals(), which is excusable if and only if a psychopath has a gun to your head and insists on it, then the problem is simply one of iterating over a dictionary and discarding the keys that don't match your expected convention (or only processing the ones that do). This can be done as follows:

import re
for name, value in globals().items():
    if re.match(r'a[0-9]+', name):
        print 'found an a* variable:', name, value

    if re.match(r'b[0-9]+', name):
        print 'found a b* variable:', name, value
jez
  • 14,867
  • 5
  • 37
  • 64