0

I am reading an excel file and using it to create a dictionary with which I am creating another dictionary using its key and value information. While doing so I have encountered a problem where I don't want single quotes in one of my values of the key literal_str which is a class name in my code and so I dont want it in single quotes. How can I remove the same from the output:

output_rules dictionary:

{'rules': {'VALID_CUSTOMER_ID': {'rule_type': 'REGEX', 'dimension': 'accuracy', 'params': {'pattern': '^[0-9]+$'}}}}

Issue

{'pattern': 'literal_str("^[0-9]+$")'}

Expected:

{'pattern': literal_str("^[0-9]+$")}

My code:

import openpyxl
import yaml
from yaml.representer import SafeRepresenter

class folded_str(str): pass
class literal_str(str): pass
class literal_unicode(str): pass


def change_style(style, representer):
    def new_representer(dumper, data):
        scalar = representer(dumper, data)
        scalar.style = style
        return scalar
    return new_representer

class MyDumper(yaml.Dumper):
    def increase_indent(self, flow=False, indentless=False):
        return super(MyDumper, self).increase_indent(flow, False)

represent_literal_str = change_style('|', SafeRepresenter.represent_str)
yaml.add_representer(literal_str, represent_literal_str)

wb = openpyxl.load_workbook('C:\\Users\\Desktop\\config.xlsx')
ws = wb['rule']
final = {}
excel_read = {}

def iter_rows(active):
    for row in active.iter_rows():
        # data = [cell.value for cell in row]
        # print(type(data))
        yield [cell.value for cell in row]

res = iter_rows(ws)
keys = next(res)

for new in res:
    excel_read = dict(zip(keys, new))
    print(excel_read)

#Create rule for YAML
output_rules = {}
temp = {}
temp['pattern'] = excel_read['pattern']
output_rules = temp.copy()
temp.clear()
temp['params'] = {}
temp['params'] ['pattern'] = output_rules['pattern']
output_rules = temp.copy()
temp.clear()
temp = {
    key: excel_read[key]
    for key in ('rule_type', 'dimension')
}
output_rules = (temp | output_rules)
temp.clear()
# print("The output is:" ,output)
temp[excel_read['rules']] = output_rules
output_rules = temp.copy()
temp.clear()
temp['rules'] = output_rules
output_rules = temp.copy()
temp.clear()

print(literal_str.__name__)

str_rep = str(output_rules['rules'][excel_read['rules']]['params']['pattern'])
print(str_rep.replace(str_rep,f'literal_str("{str_rep}")'))
newstr = str_rep.replace(str_rep,f'{literal_str.__name__}("{str_rep}")')
output_rules['rules'][excel_read['rules']]['params']['pattern'] = newstr
print(output_rules)

output:

{'rules': {'VALID_CUSTOMER_ID': {'rule_type': 'REGEX', 'dimension': 'accuracy', 'params': {'pattern': 'literal_str("^[0-9]+$")'}}}}

Expected output:

{'rules':{'VALID_CUSTOMER_ID':{'rule_type': 'REGEX','dimension':'accuracy','params': {'pattern': literal_str('^[0-9]+$')}}}}
RoxaneFelton
  • 129
  • 7
  • 1
    I think you aren't trying to remove single quotes, you are trying to evaulate a string as python code. That is not best practice and I'd advise you to look for a different solution. If you are still interested in how you could do it check this answer out: https://stackoverflow.com/questions/9383740/what-does-pythons-eval-do – Mahmud Alptekin Dec 29 '22 at 14:46
  • @MahmudAlptekin can you suggest any different approach – RoxaneFelton Dec 29 '22 at 16:02

1 Answers1

0

Maybe this'll work:

... # code before it

output_rules['rules'][excel_read['rules']]['params']['pattern'] = eval(newstr)

... # code after it
Pythoneer
  • 319
  • 1
  • 16
  • I tried evalslike: p = eval(output_rules['rules'][excel_read['rules']]['params']['pattern']) the output is ^[0-9]+$....what I would want is literal_str("^[0-9]+$") – RoxaneFelton Dec 29 '22 at 16:06
  • Oh sorry, I don't know your code well, but I know for sure somewhere in there you have to use eval: so for example, lets say `word = 'list(range(3))'`. If you use `print(word)` the output will be `list(range(3))`, but if you use `print(eval(word))` the output will be `[0, 1, 2]`, as `eval()` does what is inside. Can you please tell me where in the nested dictionary the `pattern` key is defined so I can change my answer. Thanks in advance. – Pythoneer Dec 29 '22 at 17:21
  • If you see the last part of the nested Dictionary you will find 'pattern': 'literal_str("^[0-9]+$")'. in my Input I am getting "^[0-9]+$" but inorder to allow the conersion to happen when i convert the dictionary to YAML i have to update the value of the KEY 'pattern' to the value literal_str("^[0-9]+$"). Thanks in Advance – RoxaneFelton Dec 29 '22 at 17:43
  • Where do I find it in the code? (line number) – Pythoneer Dec 29 '22 at 17:48
  • You can find that in the last 5 lines of the code where I am accessing the value of the key in Line number 68 and updating it in Line 70 – RoxaneFelton Dec 29 '22 at 17:54
  • I have also edited the question to add the output_rules dictionary which i am trying to modify for your reference – RoxaneFelton Dec 29 '22 at 18:03