human
1.6. Extending CGRtools
You can easily customize CGRtools for your tasks.
CGRtools is OOP-oriented library with subclassing and inheritance support.
As an example, we show how special marks on atoms for ligand donor centers can be added."
Please write code following the instructions in jupyter notebook style.

=====
What is a code to 1?
assistant
#Here is code to 1.

from CGRtools.periodictable import Core, C, O

class Marked(Core):
    __slots__ = '__mark' # all new attributes should be slotted!

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__mark = None # set default value for added attribute

    @property
    def mark(self):        # created new property 
        return self.__mark

    @mark.setter
    def mark(self, mark):
        # do some checks and calculations
        self.__mark = mark
    
    def __repr__(self):
        if self.__isotope:
            return f'{self.__class__.__name__[6:]}({self.__isotope})'
        return f'{self.__class__.__name__[6:]}()'
    
    @property
    def atomic_symbol(self) -> str:
        return self.__class__.__name__[6:]

class MarkedC(Marked, C):
    pass

class MarkedO(Marked, O):
    pass

m = MoleculeContainer() # create newly developed container MarkedMoleculeContainer
m.add_atom(MarkedC())   # add custom atom C
m.add_atom(MarkedO())   # add custom atom O
m.add_bond(1, 2, 1)

m.atom(2).mark = 1  # set mark on atom.

print(m)
m.clean2d()
m

m.atom(2).mark # one can return mark