1

I have been looking for methods for using the value from a str input, where some of the values (of the str) are keys to a dictionary I have. And then calculate with the values the keys have. It's hard to explain, but here is the example:

I have a dictionary for each element of the periodic table (each dictionary contains the mass of the element with the key "Atomic weight" (H has the mass 1.008u.)

I want to calculate the molecular mass when the input string is for example: "H*2+O" which is H20 (18u)

Here is what I have at the moment:

molecularmass = str(input("Write which molecular mass you want f.example: H*2+O this is H2O (water): "))
for sym in element.keys():
    if element[sym]["Sym"] in molecularmass:
    print(element[sym]["Sym"])
    molecularmass.replace(element[sym]["Sym"], str(element[sym]["Atomic weight"]))
return007
  • 823
  • 1
  • 7
  • 19

1 Answers1

0

A quick and easy way to do would be to set each element as a variable which contains it's atomic mass, then use an eval over the input. Modifying your example would lead to:

molecularmass = str(input("Write which molecular mass you want f.example: H*2+O this is H2O (water): "))
        for sym in element.keys():
            if element[sym]["Sym"] in molecularmass:
                print(element[sym]["Sym"])
                molecularmass.replace(element[sym]["Sym"], str(element[sym]["Atomic weight"]))
        print(eval(molecularmass))
      

Eval is evil, it introduces numerous security implications for a program, particularly when using it in this way. I would only advise its use here if this is a program for yourself which you can restart if things go wrong.

The proper way to do this would be to parse the string as a grammar and then run through that. To do that you would need to use a lexer to tokenise your input, then apply a grammar on those tokens to create a parse tree. That does seem like it would be overkill given your question.

For your lexing rules I would use something like [A-Z][a-z]? for the elements.

jhylands
  • 984
  • 8
  • 16