1
\$\begingroup\$

I have a text file where any name followed with sequence word is considered a dictionary. The task is to go through the keys and values of a particular dictionary, which is already identified, and see if any of the key's values is of dictionary datatype. Then, to identify the value is not a dictionary, I scan the file again and see that value followed with sequence word is not there in the file.

If the value is not a dictionary type then it goes inside the excel sheet, searches for that key in a column, extracts its respective value from excel sheet, and adds the key and value found from excel sheet to new_dict which is an empty dictionary.

If the value of a key is there in the file with a suffix word sequence, then it is considered a dictionary datatype. In that scenario, the function has to jump to that dictionary and start doing the earlier process again, and once everything is completed function has to come back to initial position where it has left and then do the process again to complete checking the entire dictionary which is passed initially.

The function is able to handle up to 4 levels of dictionary of dictionaries. I'd like to have the algorithm reviewed.

import re
# keys fetched from excel sheet.
new_cell_obj_other=['message','fuel','speed','mph','kmph','load','name']
# Values fetched from excel sheet.
new_cell_obj=['Hello','solid',100,55,77,'light','world']
old_keys=[]
old_content=[]
new_keys=[]
newer_content=[]
COUNT=0
# Text extracted from the file.
ge='Rocket ::= SEQUENCE      {                                               name      UTF8String (SIZE(1..16)),\
     message   UTF8String DEFAULT  , \
     fuel      ENUMERATED {solid, liquid, gas},\
     speed     INTEGER,\
     mph    INTEGER,kmph   INTEGER  \
     payload   Hello\
     } \
  Hello ::= SEQUENCE       {                                                    name      UTF8String (SIZE(1..16)),\
     message   UTF8String DEFAULT  , \
     fuel      ENUMERATED {solid, liquid, gas},\
     speed     INTEGER,\
     mph    INTEGER,  \
     kmph   INTEGER, \
     load   SEQUENCE OF UTF8String   }     END'
# Text extracted from the file.
ee='Rocket ::= SEQUENCE      {                                               name      UTF8String (SIZE(1..16)),\
     message   UTF8String DEFAULT  , \
     fuel      ENUMERATED {solid, liquid, gas},\
     speed     INTEGER,\
     mph    INTEGER,kmph   INTEGER  \
     payload   Hello\
     } \
  Hello ::= SEQUENCE       {                                                    name      UTF8String (SIZE(1..16)),\
     message   UTF8String DEFAULT  , \
     fuel      ENUMERATED {solid, liquid, gas},\
     speed     INTEGER,\
     mph    INTEGER,  \
     kmph   INTEGER, \
     term   World   }\
   World ::= SEQUENCE       {                                                    name      UTF8String (SIZE(1..16)),\
     message   UTF8String DEFAULT  , \
   }  END'
new_dict={'message':'Hello','fuel':'solid','speeed':100,'mph':55,'kmph':77,'load':'light'}
seq_list=['rocket','hello','world']

condition=['message   UTF8String DEFAULT'  ,
                'fuel      ENUMERATED {solid, liquid, gas}',
                'speed     INTEGER',
                'mph    INTEGER',
                'kmph   INTEGER',
                'term   world']

def check(other_dict=None,ee=ee,non_condition=None,
          from_condition=condition,key=None,
          old_keys=old_keys,
          new_keys=new_keys,
          new_content=newer_content,
          old_content=old_content):
    ee=ee.lower()
    ee=ee.replace('\n','')
    global new_dict
    if not non_condition and not new_keys:
        # Count is incremented when it finds value of a particular key is a dictionary datatype.
        global COUNT
        COUNT+=1
    # from_condition is passed when called from the main function.
    if from_condition:
        k=[]
        for i in from_condition:
            # Removes emty items
            i=i.split(' ')
            # k  will be a list of lists of all keys and values of the dictionary,Each list will have a key and value.
            k.append(filter(None, i))
        # New dictionary is created.
        other_dict={}
    else:
        other_dict={}
        # k  will be a list of lists of all keys and values of the dictionary,Each list will have a key and value.

        k=[non_condition]
    for index_content,content in enumerate(k):

        for index,value in enumerate(content[1:]):
            new_value=value.replace(',','')


            # new_cell_obj_other will have a list of items names which are there in the excel sheet
        # and new_cell_obj indicates its respective value from the excel sheet,seq_list indicates list of dictionaries which are there in the file.
            # Conditions is true if the value of the key is not a dictionary.
            if content[0] in new_cell_obj_other and new_value not in seq_list:

                for item,value in zip(new_cell_obj_other,new_cell_obj):


                    if content[0]==item:
                        other_dict[item]=value
                        break

                else:
                    continue
                break
            else:

                # old contents will be storing the remaining keys and values of a dictionary when one of its key's value is a dictionary.

                for i in k[index_content+1::]:
                    old_content.append(i)

                if old_keys and not non_condition and not new_keys:
                   length=len(old_keys)
                   if length==2:
                        new_dict[old_keys[0]][old_keys[1]]=other_dict
                   elif length==3:
                       new_dict[old_keys[0]][old_keys[1]][old_keys[2]]=other_dict
                   elif length==3:
                       new_dict[old_keys[0]][old_keys[1]][old_keys[2]][old_keys[3]]=other_dict

                elif not old_keys and other_dict:


                    new_dict[key]=other_dict           
                ee=ee.lower()
                ee=ee.replace('\n','')
        #Finds the whole set of data for the corresponding dictionary from the file where content[-1] is the name of the dictionary which we identified.
                reg_value=re.findall(r'{0}\s*::=\s*sequence(.*?)(::=|end)'.format(content[-1]),ee)


                if reg_value:
                    v=reg_value[0][0].split('{')
                    v=v[1].split('}')[0]
                    v=v.split(',')
                    if not old_keys and not non_condition:
                        # Initially append the key whose value is a dictionary datatype.
                        old_keys.append(key)
                    # Appending the subsequent keys whose values are dictionary datatype. 
                    old_keys.append(content[0])
                    # calling the recursive function.
                    return check(other_dict=other_dict,ee=ee,
                                            key=new_content,
                                            from_condition=v,
                                            old_keys=old_keys,
                                            old_content=old_content)

    if old_keys and not new_keys:
        length=len(old_keys)
    # Adding the dictionary inside its respective dictionary
        if length==2:
            new_dict[old_keys[0]][old_keys[1]]=other_dict
        elif length==3:
            new_dict[old_keys[0]][old_keys[1]][old_keys[2]]=other_dict
        elif length==4:
            new_dict[old_keys[0]][old_keys[1]][old_keys[2]][old_keys[3]]=other_dict

        del old_keys[-1]
    if not old_keys and not new_keys and other_dict:
    # Adding the dictionary inside the main dictionary directly
        new_dict[key]=other_dict
    while COUNT>=1 and (old_content or newer_content):
        #new_keys is an empty list which is appended with old_keys and newer_content is an empty list which is appended with old_content
        COUNT-=1

        len_other=len(new_keys)
        for i_key in old_keys:
            if i_key not in new_keys:
                new_keys.append(i_key)
        for j_content in old_content:
            if j_content not in newer_content:
                newer_content.append(j_content)
        length_new=len(new_keys)   
        if length_new==2 and new_keys!=old_keys:
            new_dict[new_keys[0]][new_keys[1]]=other_dict
        elif length_new==3 and new_keys!=old_keys:
            new_dict[new_keys[0]][new_keys[1]][new_keys[2]]=other_dict
        elif length_new==4 and new_keys!=old_keys:
            new_dict[new_keys[0]][new_keys[1]][new_keys[2]][new_keys[3]]=other_dict

        if not len_other==0:
            del newer_content[-1]          
        if not len_other==0:           
            if len_other!=len(new_keys):
                del new_keys[-1]    
            del new_keys[-1]
        if newer_content and new_keys:   
            check(other_dict=other_dict,
                             ee=ee,
                             key=new_keys[-1],
                             non_condition=newer_content[-1],
                             old_keys=[],
                             old_content=[])

    return new_dict    

print check(from_condition=condition,key='payload')

Output:

{'load': 'light', 'speeed': 100, 'mph': 55, 'kmph': 77, 'fuel': 'solid', 'message': 'Hello', 'payload': {'term': {'message': 'Hello', 'name': 'world'}, 'mph': 55, 'kmph': 77, 'fuel': 'solid', 'message': 'Hello', 'speed': 100}}
\$\endgroup\$
  • 1
    \$\begingroup\$ Could you add a python version tag? I know it might be obvious for some experts which version it is just by seeing the API but probably not for all people ;-] \$\endgroup\$ – t3chb0t Sep 26 '18 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.