def assign_type(mol, force_recalc=False):
    """ PATTY [Bush et al. J. Inf. Comput. Sci 33 (1993) 756-762]
    TODO: not yet implemented

    1:cation 2:anion 3:donor 4:acceptor
    5:polar 6:hydrophobe 7:others
    """
    if 'PATTY' in mol.descriptors and not force_recalc:
        return
    mol.require('Phys_charge')
    for i, atom in mol.atoms_iter():
        nbrcnt = mol.neighbor_count(i)
        if (atom.charge > 0 or atom.charge_phys > 0 or atom.charge_conj > 0 and
            not atom.n_oxide):
            atom.type = 1
        elif atom.charge < 0 or atom.charge_phys < 0 or atom.charge_conj < 0 and not atom.n_oxide:
            atom.type = 2
        elif atom.symbol == 'N':
            if nbrcnt in (1, 2):
                if atom.pi == 2:
                    atom.type = 3
                elif atom.pi == 1:
                    atom.type = 4
        elif atom.symbol == 'O':
            if nbrcnt == 1 and not atom.pi:
                atom.type = 5
            else:
                atom.type = 4
        elif atom.symbol in ('C', 'Si', 'S', 'Se', 'P', 'As'):
            ewg = False
            for n, bond in mol.neighbors(i).items():
                natom = mol.atom(n)
                if natom.symbol in ('N', 'O', 'S') and atom.pi and not (
                    natom.pi == 2 and mol.neighbor_count(n) == 3):
                    ewg = True
                    break
            if not ewg:
                atom.type = 6
        elif atom.symbol in ('F', 'Cl', 'Br', 'I') and nbrcnt == 1:
            atom.type = 6
    mol.descriptors.add('PATTY')
