periodictable icon indicating copy to clipboard operation
periodictable copied to clipboard

Surprising result from formula()

Open bjodah opened this issue 8 years ago • 5 comments

I would expect this to output 4, not 3:

>>> periodictable.formula('NH3 + H{+}').atoms[periodictable.H]
3

Py 2.7, periodictable 1.4.1

bjodah avatar Sep 11 '15 15:09 bjodah

So there is a distinction between ions and elements, I wrote a small utility function to get the elements of a formula:

from collections import defaultdict
def elements(formula):                                                                                        
    d = defaultdict(int)
    for atm, n in formula.atoms.items():
        try:
            d[atm.element] += n
        except AttributeError:
            d[atm] += n
    return d

Would it be of interest to have such a method in formulas.Formula? (I could open a PR)

bjodah avatar Sep 12 '15 21:09 bjodah

The H+ is indexed as an ion:

>>> f = periodictable.formula('NH3 + H{+}')
>>> f.atoms
{H: 3, N: 1, H.ion[1]: 1}
>>> f.hill
formula('H3H{+}N')

It was easy enough to have ions treated as elements as far as counting is concerned:

>>> f = periodictable.formula('NH3 + D{+}')
>>> f.atoms
{H: 4, N: 1}
>>> f.isotopes
{H: 3, N: 1, H[2]: 1}
>>> f.ions
{H: 3, N: 1, H[2].ion[1]: 1}
>>> f.hill
formula('H4N')
>>> f.charge
1

I haven't checked it in yet. Before doing so I need to cross check the rest of the code base for whether f.atoms should change to f.isotopes or f.ions.

pkienzle avatar Sep 14 '15 18:09 pkienzle

Looking at your alternative, leaving f.atoms alone and adding f.elements and f.isotopes is another way to go. This has the advantage of not changing the existing interface, but with the disadvantage of a more confusing naming scheme.

pkienzle avatar Sep 14 '15 18:09 pkienzle

I understand your dilemma between backwards compatibility and API cleanliness, nobody likes getting code broken..

On an unrelated note (didn't know if it's worth adding an issue for it): periodictable.formula('H{-}') raises a ValueError claiming -1 is not a valid charge for H, even though this is the hydride anion. Other physically sound examples raises this exception, e.g. He{+}.

bjodah avatar Sep 14 '15 19:09 bjodah

I didn't document my source of oxidation states. I'll add a ticket saying some are missing.

pkienzle avatar Sep 14 '15 21:09 pkienzle

I added count_elements() to accumulate across isotopes/ions.

pkienzle avatar Feb 26 '24 21:02 pkienzle