Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Dictionary using path.
#1
I have a dictionary:

{'Q_MGR_NAME': 'BOBBEE2', 'START_DATE': '2024-08-21', 'START_TIME': '05.08.47', 'END_DATE': '2024-08-21', 'END_TIME': '05.09.47', 'COMMAND_LEVEL': 940, 'OBJECT_COUNT': 2, 'Q_STATISTICS_DATA': {'SYSTEM.ADMIN.COMMAND.QUEUE': {'Q_NAME': 'SYSTEM.ADMIN.COMMAND.QUEUE', 'CREATION_DATE': '2023-04-18', 'CREATION_TIME': '12.32.19', 'Q_TYPE': 'LOCAL', 'DEFINITION_TYPE': 'PREDEFINED', 'Q_MIN_DEPTH': 0, 'Q_MAX_DEPTH': 0, 'AVG_Q_TIME': [0, 0], 'PUTS': [17, 0], 'PUTS_FAILED': 0, 'PUT1S': [0, 0], 'PUT1S_FAILED': 0, 'PUT_BYTES': [1512, 0], 'GETS': [17, 0], 'GET_BYTES': [1512, 0], 'GETS_FAILED': 0, 'BROWSES': [0, 0], 'BROWSE_BYTES': [0, 0], 'BROWSES_FAILED': 0, 'MSGS_NOT_QUEUED': 17, 'MSGS_EXPIRED': 0, 'MSGS_PURGED': 0}, 'PYMQI': {'Q_NAME': 'PYMQI', 'CREATION_DATE': '2024-08-14', 'CREATION_TIME': '07.39.31', 'Q_TYPE': 'LOCAL', 'DEFINITION_TYPE': 'PREDEFINED', 'Q_MIN_DEPTH': 40, 'Q_MAX_DEPTH': 60, 'AVG_Q_TIME': [0, 0], 'PUTS': [20, 0], 'PUTS_FAILED': 0, 'PUT1S': [0, 0], 'PUT1S_FAILED': 0, 'PUT_BYTES': [20480, 0], 'GETS': [0, 0], 'GET_BYTES': [0, 0], 'GETS_FAILED': 0, 'BROWSES': [0, 0], 'BROWSE_BYTES': [0, 0], 'BROWSES_FAILED': 0, 'MSGS_NOT_QUEUED': 0, 'MSGS_EXPIRED': 0, 'MSGS_PURGED': 0}}}

I have a routine that gives me the PATH to the two nested dictionaries with Q_NAME elements:

Value SYSTEM.ADMIN.COMMAND.QUEUE found at ['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']['Q_NAME']
Value PYMQI found at ['Q_STATISTICS_DATA']['PYMQI']['Q_NAME']

I use this to try to get the list of keys, but get the following error:

print('Keys of = ", new_test_dict.Q_STATISTICS_DATA.SYSTEM.ADMIN.COMMAND.QUEUE.keys())

AttributeError: 'dict' object has no attribute 'Q_STATISTICS_DATA'
Reply
#2
(Aug-22-2024, 06:30 PM)Bobbee Wrote: I have a dictionary:

{'Q_MGR_NAME': 'BOBBEE2', 'START_DATE': '2024-08-21', 'START_TIME': '05.08.47', 'END_DATE': '2024-08-21', 'END_TIME': '05.09.47', 'COMMAND_LEVEL': 940, 'OBJECT_COUNT': 2, 'Q_STATISTICS_DATA': {'SYSTEM.ADMIN.COMMAND.QUEUE': {'Q_NAME': 'SYSTEM.ADMIN.COMMAND.QUEUE', 'CREATION_DATE': '2023-04-18', 'CREATION_TIME': '12.32.19', 'Q_TYPE': 'LOCAL', 'DEFINITION_TYPE': 'PREDEFINED', 'Q_MIN_DEPTH': 0, 'Q_MAX_DEPTH': 0, 'AVG_Q_TIME': [0, 0], 'PUTS': [17, 0], 'PUTS_FAILED': 0, 'PUT1S': [0, 0], 'PUT1S_FAILED': 0, 'PUT_BYTES': [1512, 0], 'GETS': [17, 0], 'GET_BYTES': [1512, 0], 'GETS_FAILED': 0, 'BROWSES': [0, 0], 'BROWSE_BYTES': [0, 0], 'BROWSES_FAILED': 0, 'MSGS_NOT_QUEUED': 17, 'MSGS_EXPIRED': 0, 'MSGS_PURGED': 0}, 'PYMQI': {'Q_NAME': 'PYMQI', 'CREATION_DATE': '2024-08-14', 'CREATION_TIME': '07.39.31', 'Q_TYPE': 'LOCAL', 'DEFINITION_TYPE': 'PREDEFINED', 'Q_MIN_DEPTH': 40, 'Q_MAX_DEPTH': 60, 'AVG_Q_TIME': [0, 0], 'PUTS': [20, 0], 'PUTS_FAILED': 0, 'PUT1S': [0, 0], 'PUT1S_FAILED': 0, 'PUT_BYTES': [20480, 0], 'GETS': [0, 0], 'GET_BYTES': [0, 0], 'GETS_FAILED': 0, 'BROWSES': [0, 0], 'BROWSE_BYTES': [0, 0], 'BROWSES_FAILED': 0, 'MSGS_NOT_QUEUED': 0, 'MSGS_EXPIRED': 0, 'MSGS_PURGED': 0}}}

I have a routine that gives me the PATH to the two nested dictionaries with Q_NAME elements:

Value SYSTEM.ADMIN.COMMAND.QUEUE found at ['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']['Q_NAME']
Value PYMQI found at ['Q_STATISTICS_DATA']['PYMQI']['Q_NAME']

I use this to try to get the list of keys, but get the following error:

print('Keys of = ", new_test_dict.Q_STATISTICS_DATA.SYSTEM.ADMIN.COMMAND.QUEUE.keys())

AttributeError: 'dict' object has no attribute 'Q_STATISTICS_DATA'
Reply
#3
If I print the keys for the entire DICT I get

Keys of patho = dict_keys(['Q_MGR_NAME', 'START_DATE', 'START_TIME', 'END_DATE', 'END_TIME', 'COMMAND_LEVEL', 'OBJECT_COUNT', 'Q_STATISTICS_DATA'])

Q_STATISTICS_DATA is a nested dictionary. I was expecting if I pointed to this I could get the keys of the nested dictionary. NO?
Reply
#4
This should help on how to use the nested dictionary.
test_dict = {
    'Q_MGR_NAME': 'BOBBEE2',
    'START_DATE': '2024-08-21',
    'START_TIME': '05.08.47',
    'END_DATE': '2024-08-21',
    'END_TIME': '05.09.47',
    'COMMAND_LEVEL': 940,
    'OBJECT_COUNT': 2,
    'Q_STATISTICS_DATA': {
        'SYSTEM.ADMIN.COMMAND.QUEUE': {
            'Q_NAME': 'SYSTEM.ADMIN.COMMAND.QUEUE',
            'CREATION_DATE': '2023-04-18',
            'CREATION_TIME': '12.32.19',
            'Q_TYPE': 'LOCAL',
            'DEFINITION_TYPE': 'PREDEFINED',
            'Q_MIN_DEPTH': 0,
            'Q_MAX_DEPTH': 0,
            'AVG_Q_TIME': [0, 0],
            'PUTS': [17, 0],
            'PUTS_FAILED': 0,
            'PUT1S': [0, 0],
            'PUT1S_FAILED': 0,
            'PUT_BYTES': [1512, 0],
            'GETS': [17, 0],
            'GET_BYTES': [1512, 0],
            'GETS_FAILED': 0,
            'BROWSES': [0, 0],
            'BROWSE_BYTES': [0, 0],
            'BROWSES_FAILED': 0,
            'MSGS_NOT_QUEUED': 17,
            'MSGS_EXPIRED': 0,
            'MSGS_PURGED': 0
        },
        'PYMQI': {
            'Q_NAME': 'PYMQI',
            'CREATION_DATE': '2024-08-14',
            'CREATION_TIME': '07.39.31',
            'Q_TYPE': 'LOCAL',
            'DEFINITION_TYPE': 'PREDEFINED',
            'Q_MIN_DEPTH': 40,
            'Q_MAX_DEPTH': 60,
            'AVG_Q_TIME': [0, 0],
            'PUTS': [20, 0],
            'PUTS_FAILED': 0,
            'PUT1S': [0, 0],
            'PUT1S_FAILED': 0,
            'PUT_BYTES': [20480, 0],
            'GETS': [0, 0],
            'GET_BYTES': [0, 0],
            'GETS_FAILED': 0,
            'BROWSES': [0, 0],
            'BROWSE_BYTES': [0, 0],
            'BROWSES_FAILED': 0,
            'MSGS_NOT_QUEUED': 0,
            'MSGS_EXPIRED': 0,
            'MSGS_PURGED': 0
        }
    }
}

# Accessing the nested dictionary
q_statistics = test_dict['Q_STATISTICS_DATA'].keys()
print(f"Keys of Q_STATISTICS_DATA = {q_statistics}")

# Accessing PUT_BYTES for SYSTEM.ADMIN.COMMAND.QUEUE
put_bytes = test_dict['Q_STATISTICS_DATA']['SYSTEM.ADMIN.COMMAND.QUEUE']['PUT_BYTES']
print(f"PUT_BYTES for SYSTEM.ADMIN.COMMAND.QUEUE <{put_bytes}>")

# Using nested-lookup at PyPi
# pip install nested-lookup
from nested_lookup import nested_lookup
print(nested_lookup('Q_MAX_DEPTH', test_dict))
Output:
Keys of Q_STATISTICS_DATA = dict_keys(['SYSTEM.ADMIN.COMMAND.QUEUE', 'PYMQI']) PUT_BYTES for SYSTEM.ADMIN.COMMAND.QUEUE <[1512, 0]> [0, 60]
Reply
#5
Classes use "." to get an attribute. Dictionaries use [].

Why would you think that new_test_dict.Q_STATISTICS_DATA should give you new_test_dict["Q_STATISTICS_DATA"]? Is new_test_dict a dictionary like you have in your post, or is it some other thing? There is a python package named attrdict that lets you use "." index a dictionary instead of []. A roll your own version.
data = {
    "Q_MGR_NAME": "BOBBEE2",
    "START_DATE": "2024-08-21",
    "START_TIME": "05.08.47",
    "END_DATE": "2024-08-21",
    "END_TIME": "05.09.47",
    "COMMAND_LEVEL": 940,
    "OBJECT_COUNT": 2,
    "Q_STATISTICS_DATA": {
        "SYSTEM.ADMIN.COMMAND.QUEUE": {
            "Q_NAME": "SYSTEM.ADMIN.COMMAND.QUEUE",
            "CREATION_DATE": "2023-04-18",
            "CREATION_TIME": "12.32.19",
            "Q_TYPE": "LOCAL",
            "DEFINITION_TYPE": "PREDEFINED",
            "Q_MIN_DEPTH": 0,
            "Q_MAX_DEPTH": 0,
            "AVG_Q_TIME": [0, 0],
            "PUTS": [17, 0],
            "PUTS_FAILED": 0,
            "PUT1S": [0, 0],
            "PUT1S_FAILED": 0,
            "PUT_BYTES": [1512, 0],
            "GETS": [17, 0],
            "GET_BYTES": [1512, 0],
            "GETS_FAILED": 0,
            "BROWSES": [0, 0],
            "BROWSE_BYTES": [0, 0],
            "BROWSES_FAILED": 0,
            "MSGS_NOT_QUEUED": 17,
            "MSGS_EXPIRED": 0,
            "MSGS_PURGED": 0,
        },
        "PYMQI": {
            "Q_NAME": "PYMQI",
            "CREATION_DATE": "2024-08-14",
            "CREATION_TIME": "07.39.31",
            "Q_TYPE": "LOCAL",
            "DEFINITION_TYPE": "PREDEFINED",
            "Q_MIN_DEPTH": 40,
            "Q_MAX_DEPTH": 60,
            "AVG_Q_TIME": [0, 0],
            "PUTS": [20, 0],
            "PUTS_FAILED": 0,
            "PUT1S": [0, 0],
            "PUT1S_FAILED": 0,
            "PUT_BYTES": [20480, 0],
            "GETS": [0, 0],
            "GET_BYTES": [0, 0],
            "GETS_FAILED": 0,
            "BROWSES": [0, 0],
            "BROWSE_BYTES": [0, 0],
            "BROWSES_FAILED": 0,
            "MSGS_NOT_QUEUED": 0,
            "MSGS_EXPIRED": 0,
            "MSGS_PURGED": 0,
        },
    },
}


class AttributeDictionary:
    def __init__(self, dictionary):
        self.dictionary = dictionary

    def __getattr__(self, attribute):
        part = self.dictionary[attribute]
        if isinstance(part, dict):
            return AttributeDictionary(part)
        return part

    def __str__(self):
        return str(self.dictionary)

    def __repr__(self):
        return repr(self.dictionary)


attr_dict = AttributeDictionary(data)
print(attr_dict.Q_STATISTICS_DATA.PYMQI.PUT_BYTES[0])
print(data["Q_STATISTICS_DATA"]["PYMQI"]["PUT_BYTES"][0])
Or if you just want a dictionary where you can provide a path, that is easier.
data = {
    "Q_MGR_NAME": "BOBBEE2",
    "START_DATE": "2024-08-21",
    "START_TIME": "05.08.47",
    "END_DATE": "2024-08-21",
    "END_TIME": "05.09.47",
    "COMMAND_LEVEL": 940,
    "OBJECT_COUNT": 2,
    "Q_STATISTICS_DATA": {
        "SYSTEM.ADMIN.COMMAND.QUEUE": {
            "Q_NAME": "SYSTEM.ADMIN.COMMAND.QUEUE",
            "CREATION_DATE": "2023-04-18",
            "CREATION_TIME": "12.32.19",
            "Q_TYPE": "LOCAL",
            "DEFINITION_TYPE": "PREDEFINED",
            "Q_MIN_DEPTH": 0,
            "Q_MAX_DEPTH": 0,
            "AVG_Q_TIME": [0, 0],
            "PUTS": [17, 0],
            "PUTS_FAILED": 0,
            "PUT1S": [0, 0],
            "PUT1S_FAILED": 0,
            "PUT_BYTES": [1512, 0],
            "GETS": [17, 0],
            "GET_BYTES": [1512, 0],
            "GETS_FAILED": 0,
            "BROWSES": [0, 0],
            "BROWSE_BYTES": [0, 0],
            "BROWSES_FAILED": 0,
            "MSGS_NOT_QUEUED": 17,
            "MSGS_EXPIRED": 0,
            "MSGS_PURGED": 0,
        },
        "PYMQI": {
            "Q_NAME": "PYMQI",
            "CREATION_DATE": "2024-08-14",
            "CREATION_TIME": "07.39.31",
            "Q_TYPE": "LOCAL",
            "DEFINITION_TYPE": "PREDEFINED",
            "Q_MIN_DEPTH": 40,
            "Q_MAX_DEPTH": 60,
            "AVG_Q_TIME": [0, 0],
            "PUTS": [20, 0],
            "PUTS_FAILED": 0,
            "PUT1S": [0, 0],
            "PUT1S_FAILED": 0,
            "PUT_BYTES": [20480, 0],
            "GETS": [0, 0],
            "GET_BYTES": [0, 0],
            "GETS_FAILED": 0,
            "BROWSES": [0, 0],
            "BROWSE_BYTES": [0, 0],
            "BROWSES_FAILED": 0,
            "MSGS_NOT_QUEUED": 0,
            "MSGS_EXPIRED": 0,
            "MSGS_PURGED": 0,
        },
    },
}


class PathDictionary:
    def __init__(self, dictionary):
        self.dictionary = dictionary

    def __getitem__(self, path):
        value = self.dictionary
        for part in path.split("."):
            value = value[part]
        return value


path_dict = PathDictionary(data)
print(path_dict["Q_STATISTICS_DATA.PYMQI.PUT_BYTES"][0])
print(data["Q_STATISTICS_DATA"]["PYMQI"]["PUT_BYTES"][0])
Reply
#6
Thanks, I played with what you presented and it is working. I changed a few things to see if my understanding was correct and that worked. Let me play a little. I eventually want to capture the key/values under each queue and add to them the DEQ and ENQ stats from a Q REST and push them out as CSV to be loaded into an EXCEL sheet whit charts to track. What you gave me helped alot.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  WebDriverException: Message: 'PATH TO CHROME DRIVER' executable needs to be in PATH Led_Zeppelin 1 3,120 Sep-09-2021, 01:25 PM
Last Post: Yoriz
  .pth file does not show up in sys.path when configuring path. arjunsingh2908 2 7,449 Jul-03-2018, 11:16 AM
Last Post: arjunsingh2908

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020