I want to make a small Molecular Weight calculator. If the user for instance enters the molecular formula for dichloro-benzoic acid as "C6H3Cl2COOH", I would like to split it into a list like so I can then combine all the carbons, chlorines, oxygens and hydrogens and go on to the calculation.

Any good ideas how to do the splitting?

A split on a number followed by a letter is the obvious place to start. It would be nice if all of the symbols were camel case, but I don't think you can rely on that. For the "OOH" in "C6H3Cl2COOH" (no pun intended), you can look for a match in a dictionary of symbols, but would have to allow for "He" and not stop at the "H". Just some off the top of my head thoughts.

Hello Sneekula, glad to see you back and still using Python for your chemistry problems.

Your problem is a bit more hairy, since you have to parse the string with a look ahead so you can separate it into something useful, like a list of (element, number) tuples. You can then iterate through the list a tuple at a time, look up the element for its atomic weight in a {element:atomic-weight} dictionary (just happen to have one of those laying around). Then multiply the atomic-weight by the number and sum up the results to give you the total molecular weight.

Here is one way to get the list of tuples ...

# molecular weight calculator version 1

mf = "C6H3Cl2COOH"

char_list = list(mf)
# test it ...
print char_list
"""
my result -->
['C', '6', 'H', '3', 'C', 'l', '2', 'C', 'O', 'O', 'H']
"""

temp_list = []
temp_str = ""
temp_num = ""
for x, c in enumerate(char_list):
    #print x, c
    if c.isupper():
        temp_str = ""
        temp_num = ""
    if c.isalpha():
        temp_str += c
    if c.isdigit():
        temp_num += c
    # do your look ahead
    if x+1 < len(char_list):
        if char_list[x+1].isupper() and temp_num == "":
            temp_num = "1"
        if char_list[x+1].isupper():
            temp_list.append((temp_str, int(temp_num)))
    # except for the last element
    else:
        if temp_num == "":
            temp_num = "1"
        temp_list.append((temp_str, int(temp_num)))

# test it ...
print temp_list
"""
my result -->
[('C', 6), ('H', 3), ('Cl', 2), ('C', 1), ('O', 1), ('O', 1), ('H', 1)]
"""

Here is the element_dictionary (from an old Delphi program of mine) ...

# dictionary of element:atomic-weight pairs courtesy of vegaseat
element_dict = {
'Ac': 227.000000,
'Ag': 107.868000,
'Al': 26.981540,
'Am': 243.000000,
'Ar': 39.948000,
'As': 74.921600,
'At': 210.000000,
'Au': 196.966500,
'B': 10.811000,
'Ba': 137.330000,
'Be': 9.012180,
'Bi': 208.980400,
'Br': 79.904000,
'C': 12.011000,
'Ca': 40.078000,
'Cd': 112.410000,
'Ce': 140.120000,
'Cl': 35.452700,
'Co': 58.933200,
'Cr': 51.996000,
'Cs': 132.905400,
'Cu': 63.546000,
'Dy': 162.500000,
'Er': 167.260000,
'Eu': 151.965000,
'F': 18.998400,
'Fe': 55.847000,
'Fr': 223.000000,
'Ga': 69.723000,
'Gd': 157.250000,
'Ge': 72.610000,
'H': 1.007940,
'He': 4.002600,
'Hf': 178.490000,
'Hg': 200.590000,
'Ho': 164.930300,
'I': 126.904500,
'In': 114.820000,
'Ir': 192.220000,
'K': 39.098300,
'Kr': 83.800000,
'La': 138.905500,
'Li': 6.941000,
'Lu': 174.967000,
'Mg': 24.305000,
'Mn': 54.938000,
'Mo': 95.940000,
'N': 14.006700,
'Na': 22.989770,
'Nb': 92.906400,
'Nd': 144.240000,
'Ne': 20.179700,
'Ni': 58.693400,
'Np': 237.048200,
'O': 15.999400,
'Os': 190.200000,
'P': 30.973760,
'Pa': 231.035900,
'Pb': 207.200000,
'Pd': 106.420000,
'Pm': 145.000000,
'Po': 209.000000,
'Pr': 140.907700,
'Pt': 195.080000,
'Pu': 244.000000,
'Ra': 226.025400,
'Rb': 85.467800,
'Re': 186.207000,
'Rh': 102.905500,
'Rn': 222.000000,
'Ru': 101.070000,
'S': 32.066000,
'Sb': 121.757000,
'Sc': 44.955900,
'Se': 78.960000,
'Si': 28.085500,
'Sm': 150.360000,
'Sn': 118.710000,
'Sr': 87.620000,
'Ta': 180.947900,
'Tb': 158.925300,
'Tc': 98.000000,
'Te': 127.600000,
'Th': 232.038100,
'Ti': 47.880000,
'Tl': 204.383000,
'Tm': 168.934200,
'U': 238.029000,
'V': 50.941500,
'W': 183.850000,
'Xe': 131.290000,
'Y': 88.905900,
'Yb': 173.040000,
'Zn': 65.390000,
'Zr': 91.224000,
}

Let us know what you did with it!

Thanks mawe, your Periodic Table program is sweet!

Thanks vegaseat, I will follow your advice for my simple MW calculator. When done, I will put it into the Python snippets.

This question has already been answered. Start a new discussion instead.