Iterate through nested dict in django template - python

I found some solutions to iterate through dict in django templates (such as How to iterate over nested dictionaries in django templates) but it's always for a defined depth.
For instance, if I have this dict :
{'a':{'b':'c',
'd':'e',
'f':'g',
'h':{'i':'j',
'k':'l',
'm':'n'
}
}
'o':'p'
}
But I can also have :
{'a':{'b':{'c':{'d':'e',
'f':'g'
}
}
}
}
Is there another way than the recursive one to do this ? If not, is it possible to do recursion in django templates ?
The only way to do this I think is to create custom filters such as get_sons and has_son and work with it. Is it the good way to do this ?
Additional informations :
I have the structure stored in a model such as :
class XMLStructure(Model.models):
node_name = models.CharField()
parent = models.ForeignKey('XMLStructure')
#staticmethod
def get_root(self):
# return the root of the structure
def has_children(self):
# return true / false if it's a leaf
#staticmethod
def get_leaves(self):
# return all leaves of my xml
and a function build who generate the xml structure as a dict.
I tried to use code from Django Snippets but I cannot make them work (Always got an RuntimeError: maximum recursion depth exceeded while calling a Python object)
I though it would be easier to transform my dict into a list. My first dict would be :
dict_as_list = ['a','/','b','d','f','h','/','i','k','m','\','\','o','\']
and then store the values into a dict. As you can see, I'm pretty desperate.
Thanks

Related

Converting a QTreeWidget to a nested dictionary in PyQt

The reason I want to do this is to allow the user to create a file tree using a QTreeWidget, then I want to extract that tree in to a nested dict structure, and save it some how. I've thought about using a txt file and eval aproach to simply load all the saved schemes into some array or just another dict where the key is the name of the scheme, so the user can then simply select a scheme or edit it if they wish. This naturally leads to me having to then convert that saved dict back into a QTreeWidget after the user has selected edit.
For now though here's my problem.
I've been able to successfully navigate the QTreeWidget using a recursive a function. What I struggle with is the logic behind creating the nested dict.
Below is what i have come up with so far:
def tree_to_dict(self, parent, key):
for i in range(parent.childCount()):
cur_par = parent.child(i)
if cur_par.childCount() == 0:
try:
if type(self.scheme[key]) is dict :
self.scheme[key][cur_par.text(0)] = 'E'
except KeyError:
key = cur_par.text(0)
self.scheme[key] = 'E'
else:
key = cur_par.text(0)
self.scheme[key] = {}
self.tree_to_dict(cur_par, key)
I know this is wrong. It's why I need help.
The above code generates the following dict form the following QTreeWidget
a
b
a
c
{'a':'E', 'b':{'a':'E', 'c':'E'}}
But it should be:
{'a':'E', 'b':{'a':'E'}, 'c':'E'}
The E simply means that there will be no further subdirectories.
I've seen some other implementations of this but their horribly confusing and I don't quite get their logic. This is a near duplicate of the question I'm asking here, but it's yet to be answered. I've tried adapting his implementation but it's (to me anyway) convoluted and hard to fit into the structure of my program.
Your implementation is probably too complex than required.
Since each item is the key, you need to iterate recursively and return the values for that key.
If the item has no children, it will return 'E', otherwise will it will call the function again with the given child, and so on.
The function doesn't need the key argument, as it will be created by the recursive call.
def tree_to_dict(parent):
childCount = parent.childCount()
if not childCount:
return 'E'
content = {}
for row in range(childCount):
child = parent.child(row)
content[child.text(0)] = tree_to_dict(child)
return content
Then, just call the function using the invisibleRootItem().

Apache Beam Python: How to implement MapState in the python apache beam sdk?

I am trying to create a stateful ParDo in apache beam that stores a dict of values and updates that dict with data from subsequent windows.
The equivalent being MapState in java.
I have tried to implement it using a custom CombineFn
class DictCombineFn(beam.CombineFn):
def create_accumulator(self):
return {}
def add_input(self, accumulator, element):
accumulator[element["key"]] = element["value"]
return accumulator
def merge_accumulators(self, accumulators):
return accumulators
def extract_output(self, accumulator):
return accumulator
Which is used in the CombiningValueStateSpec of the following ParDo:
class EnrichDoFn(beam.DoFn):
DICT_STATE = CombiningValueStateSpec(
'dict',
PickleCoder(),
DictCombineFn()
)
def process(
self,
element,
w=beam.DoFn.WindowParam,
dict_state=beam.DoFn.StateParam(DICT_STATE)
):
asks_state.add(element)
However I get the following error during :
TypeError: '_ConcatIterable' object does not support item assignment
I think this might be as a result of using the wrong coder?
What would be the optimal strategy to implement the aforementioned logic?
Thanks
I am not 100% sure about what this error means, but it does feel like dict type is not supported somehow in this particular process. Did you try to get a list of string i.e. "key:value", and then parse and convert it to a dict in one shot?
Merge accumulators should return one element, not iterable like in your case. You would do similar processing like in add element.

Appending a dict from another program in Python

I have a dictionary in program A where I want program B to add new contents into. Is this something I can accomplish? I tried googling but it was all about appending a dictionary within the same code, and I really want to be able to do it from within a different program if at all possible.
I am trying to add entries to a dictionary which contains {user : password, user2 : password2} for any new users. This is not to be registered to as only an admin should be able to add users. This is where the other program idea came into play. But I am open to any solution!
If you want to achieve this using functions, you can use the dict.update function.
def combine_dicts(x, y):
x.update(y)
return x
def get_passwords():
dict = {"a":"test", "b":"testa"}
return dict
firstDict = {"this":"is", "a":"test"}
secondDict = get_passwords()
combinedDict = combine_dicts(firstDict, secondDict)
Note: The parameter you use of dict.update() will override existing value/key pairs.

Python dictionary with base content

I am looking for the "good pythonic" way to define a dictionary with base elements. Let me explain:
I have a serie of key:value that configure my system. A group of key:value represent a configuration. Each configuration must have several common base elements. On the other hand each configuration has the possibility to define extra elements.
I could use python dictionaries but I do not think that could enforce the user to define "Mandatory_Elt_1" & "Mandatory_Elt_2" (or is it?):
Config_1 = { 'Mandatory_Elt_1':1,
'Mandatory_Elt_2':2,
'Optional_Elt_3':3 }
Config_2 = { 'Mandatory_Elt_1':5,
'Mandatory_Elt_2':6,
'Optional_Elt_4':7 }
A second option would be to subclass dict and define a specific constructor method where I would require the mandatory elements:
Config = MyDict( { 'Mandatory_Elt_1':5,
'Mandatory_Elt_2':6,
'Optional_Elt_4':7 } )
A third possibility would be to review the "input interface" such that other coders would not directly touch the base data. Instead, they would need to pass through a sanitization API. Or should I move to a databse based system altogether?
Are there any other alternatives? What would be the "lowest friction" way to force some elements to be defined in a dictionary?
If you need some mandatory elements in final dictionary,
you may use a basic dictionary and then update it with the user's dictionary.
E.g.
base_config = {'m1':1, 'm2': 2}
user_config = {'m1':3, 'new_param':4}
base_config.update(user_config)
final_config = base_config
>>> print final_config
{'new_param': 4, 'm1': 3, 'm2': 2}

How to retrieve dictionary values in Python?

I have a dictionary of methods in Python that is inside of a definition. This def is called outside of the class using an object. Whenever the def is called I am returned the results of the last item in the dictionary. In this case I am returned the results of def spc_summary:.
def setStyles(self):
# Assign function to file
functions = {
'app_server.php':self.app_server(),
'dcrm2nlyte.php':self.dcrm2nlyte(),
'export.php':self.export(),
'host_server.php':self.host_server(),
'spc.php':self.spc(),
'spc_approved.php':self.spc_approved(),
'spc_approved_by_dc.php':self.spc_approved_by_dc(),
'spc_by_dc.php':self.spc_by_dc(),
'spc_complete.php':self.spc_complete(),
'spc_summary.php':self.spc_summary()
}
filename = self.phpfile
functions.get(filename)
Can someone please explain what is happening here? Let me know if more detail is required. Thanks!
Let me add some detail:
The functions.get(filename) is retreiving the last dictionary item reguardless of what filename is. I have done this => functions('spc.php') and it still returned results for `def spc_summary'. And those def's should not have the same results.
Your function dict seems to be doing the wrong thing. While defining your dict you are mapping the keys to the function result instead of the function object. If you map it to the function object the function gets called when you invoke functions.get(filename)()
Your dict should probably be like below:
functions = {
'app_server.php':self.app_server,
'dcrm2nlyte.php':self.dcrm2nlyte,
'export.php':self.export,
'host_server.php':self.host_server,
'spc.php':self.spc,
'spc_approved.php':self.spc_approved,
'spc_approved_by_dc.php':self.spc_approved_by_dc,
'spc_by_dc.php':self.spc_by_dc,
'spc_complete.php':self.spc_complete,
'spc_summary.php':self.spc_summary
}
Dictionaries are unordered, so the last object returned from iterating over a dict will probably not be the last item inserted into that dict.
functions.get(filename) is going to take the current value of filename and look it up in functions. filename gets its value from self.phpfile, so in your example self.phpfile must be set to 'spc_summary.php'.

Categories

Resources