1

I am trying to create a dictionary where the name comes from a variable.

Here is the situation since maybe there is a better way: Im using an API to get attributes of "objects". (Name, Description, X, Y, Z) etc. I want to store this information in a way that keeps the data by "object".

In order to get this info, the API iterates through all the "objects".

So what my proposal was that if the object name is one of the ones i want to "capture", I want to create a dictionary with that name like so:

ObjectName = {'Description': VarDescrption, 'X': VarX.. etc}

(Where I say "Varetc..." that would be the value of that attribute passed by the API.

Now since I know the list of names ahead of time, I CAN use a really long If tree but am looking for something easier to code to accomplish this. (and extensible without adding too much code)

Here is code I have:

def py_cell_object():
    #object counter - unrelated to question
    addtototal()
    #is this an object I want?
    if aw.aw_string (239)[:5] == "TDT3_":
        #If yes, make a dictionary with the object description as the name of the dictionary.
        vars()[aw.aw_string (239)]={'X': aw.aw_int (232), 'Y': aw.aw_int (233), 'Z': aw.aw_int (234), 'No': aw.aw_int (231)}
        #print back result to test
        for key in aw.aw_string (239):
            print 'key=%s, value=%s' % (key, aw.aw_string (239)[key])

here are the first two lines of code to show what "aw" is

from ctypes import *
aw = CDLL("aw")

to explain what the numbers in the API calls are:

231 AW_OBJECT_NUMBER,

232 AW_OBJECT_X,

233 AW_OBJECT_Y,

234 AW_OBJECT_Z,

239 AW_OBJECT_DESCRIPTION,

231-234 are integers and 239 is a string

Anthony Neace
  • 25,013
  • 7
  • 114
  • 129
user2503734
  • 13
  • 1
  • 5
  • Please show the code you have so far, your question is a bit vague – jamylak Jun 20 '13 at 05:20
  • 1
    What does `aw.aw_string(239)` return? You appear to be using it as a dictionary key and also iterating it in a `for` loop for keys. Where did all the magic numbers (239, 232, 233, etc.) come from? Is there a relationship between `aw.aw_string(239)[key]` and `aw.aw_int(232)` (for example)? – rob mayoff Jun 20 '13 at 05:37
  • This is the error I get with that code: Traceback (most recent call last): File "_ctypes/callbacks.c", line 314, in 'calling callback function' File "C:\Users\Derek\Desktop\100\test4.py", line 92, in py_cell_object print 'key=%s, value=%s' % (key, aw.aw_string (239)[key]) TypeError: string indices must be integers, not str – user2503734 Jun 20 '13 at 05:37
  • That error implies that `key` is a string, and `aw.aw_string(239)` is a string. Is that what you expect? – rob mayoff Jun 20 '13 at 05:39
  • those are attributes that are called by attribute ID number. first two linens of my program are: from ctypes import * aw = CDLL("aw") so aw_string() is used to pull a value that is a string and aw_int() likewise is used for integers. the numbers correspond to the attribute I want to pull the value from. – user2503734 Jun 20 '13 at 05:40
  • Is there some method you can call that gives you the list of attribute names (`X`, `Y`, `Z`, `No`), types (`int` or `string`), and ID numbers (232, 233, 234, 231)? – rob mayoff Jun 20 '13 at 05:42
  • @robmayoff I added some info. The server iterates the objects, and in order to manipulate them later, these attributes need to be stored in the program memory to be passed to the server to identify what to change. – user2503734 Jun 20 '13 at 06:03

3 Answers3

2

I deduce that you are using the Active Worlds SDK. It would save time to mention that in the first place in future questions.

I guess your goal is to create a top-level dictionary, where each key is the object description. Each value is another dictionary, storing many of the attributes of that object.

I took a quick look at the AW SDK documentation on the wiki and I don't see a way to ask the SDK for a list of attribute names, IDs, and types. So you will have to hard-code that information in your program somehow. Unless you need it elsewhere, it's simplest to just hard-code it where you create the dictionary, which is what you are already doing. To print it back out, just print the attribute dictionary's repr. I would probably format your method more like this:

def py_cell_object():
    #object counter - unrelated to question
    addtototal()

    description = aw.aw_string(239)
    if description.startswith("TDT3_"):
        vars()[description] = {
            'DESCRIPTION': description,
            'X': aw.aw_int(232),
            'Y': aw.aw_int(233),
            'Z': aw.aw_int(234),
            'NUMBER': aw.aw_int (231),
            ... etc for remaining attributes
        }

        print repr(vars()[description])

Some would argue that you should make named constants for the numbers 232, 233, 234, etc., but I see little reason to do that unless you need them in multiple places, or unless it's easy to generate them automatically from the SDK (for example, by parsing a .h file).

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Well yes thats the structure of the dictionary, but I need a way to separate each object. If I were to use dictionaries, dictionary = {} would have to be dynamic in some way. – user2503734 Jun 20 '13 at 05:23
  • I guess I don't really understand your question. Please edit it to explain what your API gives you in more detail. Be specific. Don't try to describe it in terms of abstract “objects” if your API uses more concrete terms. – rob mayoff Jun 20 '13 at 05:25
  • I am having a hell of a time formatting my code. This is my first question. But I added it there. – user2503734 Jun 20 '13 at 05:29
  • @user2503734 I have updated my answer based on the new information in your question and comments. – rob mayoff Jun 20 '13 at 06:04
  • I havent enumerated the attributes yet is all the .h file has them listed so i should be able to figure out a way to do that (I dont know how yet lol). Yes I should do it because each version of the SDK can change the order of them. I didn't specify what program it was because, well its not exactly the most popular program. But I do understand why a link to the SDK docs wouldve helped even to a stranger to the program. Will try what you gave me real quick! – user2503734 Jun 20 '13 at 06:10
  • Youre my hero! Works the way I want it to! Like the setup on multiple lines too. Awesome awesome! I still spent less time asking this question than doing each object I want by hand! Thanks! – user2503734 Jun 20 '13 at 06:15
  • You might find [`h2py.py`](http://svn.python.org/projects/python/trunk/Tools/scripts/h2py.py) useful for extracting the `#define` constants from the SDK `.h` file. – rob mayoff Jun 20 '13 at 06:17
  • the .h file has 3 or 4 enumerated lists in it. will that work? that .py you gave me is over my level at the moment. the .h file looks like this for each list: typedef enum { AW_LOGIN_NAME, etc } AW_ATTRIBUTE; – user2503734 Jun 20 '13 at 06:24
  • You'll have to find a different way to parse it then. I recommend googling `python import enum`, `python import constants header`, and other variations. – rob mayoff Jun 20 '13 at 06:29
  • i think the way you had it before the edit was closer to what my goal was btw. Well im off to bed, looks like ill be making some progress finally. thanks again. Ill keep looking at the documentation for that h2py. Right now Im making simple stuff to learn Python so its not critical to enumerate the attributes yet. (events and callbacks are the other separate lists in the .h file). py_cell_object() is actually tied to an event number elsewhere. – user2503734 Jun 20 '13 at 06:32
  • Im getting a global not defined error when I try to access the dictionary outside that function.. I cant figure out how to fix that. – user2503734 Jun 21 '13 at 01:19
0

If the variables are defined in the local scope, it's as simple as:

obj_names = {}
while True:
   varname = read_name()
   if not varname: break
   obj_names[varname] = locals()[varname]
shx2
  • 61,779
  • 13
  • 130
  • 153
0

This is actual code I am using in my production environment

hope it helps.

        cveDict = {}
        # StrVul is a python list holding list of vulnerabilities belonging to a report
        report = Report.objects.get(pk=report_id)
        vul = Vulnerability.objects.filter(report_id=report_id)
        strVul = map(str, vul)
        # fill up the python dict, += 1 if cvetype already exists
        for cve in strVul:
            i = Cve.objects.get(id=cve)
            if i.vul_cvetype in cveDict.keys():
                cveDict[i.vul_cvetype] += 1
            else:
                cveDict[i.vul_cvetype] = 1
laycat
  • 5,381
  • 7
  • 31
  • 46