'append some logging data from `CMAEvolutionStrategy` class instance `es`,
if ``number_of_times_called % modulo`` equals to zero, never if ``modulo==0``.
The sequence ``more_data`` must always have the same length.
When used for a different optimizer class, this function can be
(easily?) adapted by changing the assignments under INTERFACE
in the implemention.'

def add(self, es=None, more_data=[], modulo=None):

    self.counter += 1
    mod = (modulo if (modulo is not None) else self.modulo)
    if ((mod == 0) or ((self.counter > 3) and (self.counter % mod))):
        return
    if (es is None):
        try:
            es = self.es
        except AttributeError:
            raise _Error('call    `add`    with    argument    `es`    or    ``register(es)``    before    ``add()``')
    elif (not self.registered):
        self.register(es)
    if (type(es) is not CMAEvolutionStrategy):
        print((("WARNING:    <type    'CMAEvolutionStrategy'>    expected,    found    " + str(type(es))) + '    in    method    CMADataLogger.add'))
    evals = es.countevals
    iteration = es.countiter
    sigma = es.sigma
    axratio = (es.D.max() / es.D.min())
    xmean = es.mean
    fmean_noise_free = es.fmean_noise_free
    fmean = es.fmean
    try:
        besteverf = es.best.f
        bestf = es.fit.fit[0]
        medianf = es.fit.fit[(es.sp.popsize // 2)]
        worstf = es.fit.fit[(-1)]
    except:
        if (self.counter > 1):
            raise
    try:
        xrecent = es.best.last.x
    except:
        xrecent = None
    maxD = es.D.max()
    minD = es.D.min()
    diagD = es.D
    diagC = ((es.sigma * es.sigma_vec) * sqrt(es.dC))
    more_to_write = es.more_to_write
    es.more_to_write = []
    try:
        if (self.counter > 1):
            fn = (self.name_prefix + 'fit.dat')
            with open(fn, 'a') as f:
                f.write(((((((((((((((((((str(iteration) + '    ') + str(evals)) + '    ') + str(sigma)) + '    ') + str(axratio)) + '    ') + str(besteverf)) + '    ') + ('%.16e' % bestf)) + '    ') + str(medianf)) + '    ') + str(worstf)) + '    ') + '    '.join((str(i) for i in more_to_write))) + '    '.join((str(i) for i in more_data))) + '\n'))
        fn = (self.name_prefix + 'axlen.dat')
        with open(fn, 'a') as f:
            f.write((((((((((((str(iteration) + '    ') + str(evals)) + '    ') + str(sigma)) + '    ') + str(maxD)) + '    ') + str(minD)) + '    ') + '    '.join(map(str, diagD))) + '\n'))
        fn = (self.name_prefix + 'stddev.dat')
        with open(fn, 'a') as f:
            f.write(((((((((str(iteration) + '    ') + str(evals)) + '    ') + str(sigma)) + '    ') + '0    0    ') + '    '.join(map(str, diagC))) + '\n'))
        fn = (self.name_prefix + 'xmean.dat')
        with open(fn, 'a') as f:
            if (iteration < 1):
                f.write((('0    0    0    0    0    ' + '    '.join(map(str, xmean))) + '\n'))
            else:
                f.write(((((((((((str(iteration) + '    ') + str(evals)) + '    ') + '0    ') + str(fmean_noise_free)) + '    ') + str(fmean)) + '    ') + '    '.join(map(str, xmean))) + '\n'))
        fn = (self.name_prefix + 'xrecentbest.dat')
        if ((iteration > 0) and (xrecent is not None)):
            with open(fn, 'a') as f:
                f.write(((((((((((str(iteration) + '    ') + str(evals)) + '    ') + str(sigma)) + '    ') + '0    ') + str(bestf)) + '    ') + '    '.join(map(str, xrecent))) + '\n'))
    except (IOError, OSError):
        if (iteration <= 1):
            print('could    not    open/write    file')
