def assign_valence(mol):
    """Assign pi electron and hydrogens"""
    for u, v, bond in mol.bonds_iter():
        if bond.order == 2:
            mol.atom(u).pi = 1
            mol.atom(v).pi = 1
            if mol.atom(u).symbol == 'O' and not mol.atom(u).charge:
                mol.atom(v).carbonyl_C = 1
            if mol.atom(v).symbol == 'O' and not mol.atom(v).charge:
                mol.atom(u).carbonyl_C = 1
        elif bond.order == 3:
            mol.atom(u).pi = mol.atom(v).pi = 2
    max_nbr = {'C': 4, 'Si': 4, 'N': 3, 'P': 3, 'As': 3, 'O': 2, 'S': 2,
        'Se': 2, 'F': 1, 'Cl': 1, 'Br': 1, 'I': 1}
    for i, nbrs in mol.neighbors_iter():
        atom = mol.atom(i)
        if len(nbrs) == 2 and all(bond.order == 2 for bond in nbrs.values()):
            atom.pi = 2
        if atom.symbol in max_nbr:
            h_cnt = max_nbr[atom.symbol] - len(nbrs) - atom.pi + atom.charge
            if h_cnt > 0:
                mol.atom(i).add_hydrogen(h_cnt)
    mol.descriptors.add('Valence')
