Instruction:
Explain what the following Python 3 code does
def multifuncrs(X, funs, eps=1E-6,
                nswp=10,
                kickrank=5,
                y0=None,
                rmax=999999,  # TODO:infinity \
                kicktype='amr-two',        \
                pcatype='svd',             \
                trunctype='fro',           \
                d2=1,                      \
                do_qr=False,               \
                verb=1):
    """Cross approximation of a (vector-)function of several TT-tensors.

    :param X: tuple of TT-tensors
    :param funs: multivariate function
    :param eps: accuracy
    """

    dtype = np.float64
    if len([x for x in X if x.is_complex]) > 0:
        dtype = np.complex128

    y = y0
    wasrand = False

    nx = len(X)
    d = X[0].d
    n = X[0].n
    rx = np.transpose(np.array([ttx.r for ttx in X]))
    #crx = [tt.tensor.to_list(ttx) for x in X]
    #crx = zip(*crx)
    crx = np.transpose(np.array([tt.tensor.to_list(ttx)
                                 for ttx in X], dtype=np.object))
    crx = np.empty((nx, d), dtype=np.object)
    i = 0
    for ttx in X:
        v = tt.tensor.to_list(ttx)
        j = 0
        for w in v:
            crx[i, j] = w
            j = j + 1
        i = i + 1
    crx = crx.T
    if y is None:
        ry = d2 * np.ones((d + 1,), dtype=np.int32)
        ry[0] = 1
        y = tt.rand(n, d, ry)
        wasrand = True

    ry = y.r
    cry = tt.tensor.to_list(y)

    Ry = np.zeros((d + 1, ), dtype=np.object)
    Ry[0] = np.array([[1.0]], dtype=dtype)
    Ry[d] = np.array([[1.0]], dtype=dtype)
    Rx = np.zeros((d + 1, nx), dtype=np.object)
    Rx[0, :] = np.ones(nx, dtype=dtype)
    Rx[d, :] = np.ones(nx, dtype=dtype)

    block_order = [+d, -d]

    # orth
    for i in range(0, d - 1):
        cr = cry[i]
        cr = reshape(cr, (ry[i] * n[i], ry[i + 1]))
        cr, rv = np.linalg.qr(cr)
        cr2 = cry[i + 1]
        cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
        cr2 = np.dot(rv, cr2)  # matrix multiplication
        ry[i + 1] = cr.shape[1]
        cr = reshape(cr, (ry[i], n[i], ry[i + 1]))
        cry[i + 1] = reshape(cr2, (ry[i + 1], n[i + 1], ry[i + 2]))
        cry[i] = cr

        Ry[i + 1] = np.dot(Ry[i], reshape(cr, (ry[i], n[i] * ry[i + 1])))
        Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
        curind = []
        if wasrand:
            # EVERY DAY I'M SHUFFLIN'
            curind = np.random.permutation(n[i] * ry[i])[:ry[i + 1]]
        else:
            curind = maxvol(Ry[i + 1])
        Ry[i + 1] = Ry[i + 1][curind, :]
        for j in range(0, nx):
            try:
                Rx[i + 1, j] = reshape(crx[i, j],
                                       (rx[i, j], n[i] * rx[i + 1, j]))
            except:
                pass
            Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
            Rx[i + 1, j] = reshape(Rx[i + 1, j], (ry[i] * n[i], rx[i + 1, j]))
            Rx[i + 1, j] = Rx[i + 1, j][curind, :]

    d2 = ry[d]
    ry[d] = 1
    cry[d - 1] = np.transpose(cry[d - 1], [2, 0, 1])  # permute

    last_sweep = False
    swp = 1

    dy = np.zeros((d, ))
    max_dy = 0

    cur_order = copy.copy(block_order)
    order_index = 1
    i = d - 1
    # can't use 'dir' identifier in python
    dirn = int(math.copysign(1, cur_order[order_index]))

    # DMRG sweeps
    while swp <= nswp or dirn > 0:

        oldy = reshape(cry[i], (d2 * ry[i] * n[i] * ry[i + 1],))

        if not last_sweep:
            # compute the X superblocks
            curbl = np.zeros((ry[i] * n[i] * ry[i + 1], nx), dtype=dtype)
            for j in range(0, nx):
                cr = reshape(crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                cr = np.dot(Rx[i, j], cr)
                cr = reshape(cr, (ry[i] * n[i], rx[i + 1, j]))
                cr = np.dot(cr, Rx[i + 1, j])
                curbl[:, j] = cr.flatten('F')
            # call the function
            newy = funs(curbl)
            # multiply with inverted Ry
            newy = reshape(newy, (ry[i], n[i] * ry[i + 1] * d2))
            newy = np.linalg.solve(Ry[i], newy)  # y = R \ y
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            newy = reshape(np.transpose(newy), (d2 * ry[i] * n[i], ry[i + 1]))
            newy = np.transpose(np.linalg.solve(
                np.transpose(Ry[i + 1]), np.transpose(newy)))  # y=y/R
            newy = reshape(newy, (d2 * ry[i] * n[i] * ry[i + 1],))
        else:
            newy = oldy

        dy[i] = np.linalg.norm(newy - oldy) / np.linalg.norm(newy)
        max_dy = max(max_dy, dy[i])

        # truncation
        if dirn > 0:  # left-to-right
            newy = reshape(newy, (d2, ry[i] * n[i] * ry[i + 1]))
            newy = reshape(np.transpose(newy), (ry[i] * n[i], ry[i + 1] * d2))
        else:
            newy = reshape(newy, (d2 * ry[i], n[i] * ry[i + 1]))

        r = 0  # defines a variable in global scope

        if kickrank >= 0:
            u, s, v = np.linalg.svd(newy, full_matrices=False)
            v = np.conj(np.transpose(v))
            if trunctype == "fro" or last_sweep:
                r = my_chop2(s, eps / math.sqrt(d) * np.linalg.norm(s))
            else:
                # truncate taking into account the (r+1) overhead in the cross
                # (T.S.: what?)
                cums = abs(s * np.arange(2, len(s) + 2)) ** 2
                cums = np.cumsum(cums[::-1])[::-1]
                cums = cums / cums[0]
                ff = [i for i in range(len(cums)) if cums[i] < eps ** 2 / d]
                if len(ff) == 0:
                    r = len(s)
                else:
                    r = np.amin(ff)
            r = min(r, rmax, len(s))
        else:
            if dirn > 0:
                u, v = np.linalg.qr(newy)
                v = np.conj(np.transpose(v))
                r = u.shape[1]
                s = np.ones((r, ))
            else:
                v, u = np.linalg.qr(np.transpose(newy))
                v = np.conj(v)
                u = np.transpose(u)
                r = u.shape[1]
                s = np.ones((r, ))

        if verb > 1:
            print('=multifuncrs=   block %d{%d}, dy: %3.3e, r: %d' % (i, dirn, dy[i], r))

        # kicks and interfaces
        if dirn > 0 and i < d - 1:
            u = u[:, :r]
            v = np.dot(v[:, :r], np.diag(s[:r]))

            # kick
            radd = 0
            rv = 1
            if not last_sweep and kickrank > 0:
                uk = None
                if kicktype == 'amr-two':
                    # AMR(two)-like kick.

                    # compute the X superblocks
                    ind2 = np.unique(np.random.randint(
                        0, ry[i + 2] * n[i + 1], ry[i + 1]))
                    #ind2 = np.unique(np.floor(np.random.rand(ry[i + 1]) * (ry[i + 2] * n[i + 1])))
                    rkick = len(ind2)
                    curbl = np.zeros((ry[i] * n[i] * rkick, nx), dtype=dtype)
                    for j in range(nx):
                        cr1 = reshape(
                            crx[i, j], (rx[i, j], n[i] * rx[i + 1, j]))
                        cr1 = np.dot(Rx[i, j], cr1)
                        cr1 = reshape(cr1, (ry[i] * n[i], rx[i + 1, j]))
                        cr2 = reshape(
                            crx[i + 1, j], (rx[i + 1, j] * n[i + 1], rx[i + 2, j]))
                        cr2 = np.dot(cr2, Rx[i + 2, j])
                        cr2 = reshape(
                            cr2, (rx[i + 1, j], n[i + 1] * ry[i + 2]))
                        cr2 = cr2[:, ind2]
                        curbl[:, j] = reshape(
                            np.dot(cr1, cr2), (ry[i] * n[i] * rkick,))
                    # call the function
                    uk = funs(curbl)
                    uk = reshape(uk, (ry[i], n[i] * rkick * d2))
                    uk = np.linalg.solve(Ry[i], uk)
                    uk = reshape(uk, (ry[i] * n[i], rkick * d2))
                    if pcatype == 'svd':
                        uk, sk, vk = np.linalg.svd(uk, full_matrices=False)
                        vk = np.conj(np.transpose(vk))
                        uk = uk[:, :min(kickrank, uk.shape[1])]
                    else:
                        # uk = uchol(np.transpose(uk), kickrank + 1) # TODO
                        uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1]
                else:
                    uk = np.random.rand(ry[i] * n[i], kickrank)
                u, rv = np.linalg.qr(np.concatenate((u, uk), axis=1))
                radd = uk.shape[1]
            v = np.concatenate(
                (v, np.zeros((ry[i + 1] * d2, radd), dtype=dtype)), axis=1)
            v = np.dot(rv, np.conj(np.transpose(v)))
            r = u.shape[1]

            cr2 = cry[i + 1]
            cr2 = reshape(cr2, (ry[i + 1], n[i + 1] * ry[i + 2]))
            v = reshape(v, (r * ry[i + 1], d2))
            v = reshape(np.transpose(v), (d2 * r, ry[i + 1]))
            v = np.dot(v, cr2)

            ry[i + 1] = r

            u = reshape(u, (ry[i], n[i], r))
            v = reshape(v, (d2, r, n[i + 1], ry[i + 2]))

            cry[i] = u
            cry[i + 1] = v

            Ry[i + 1] = np.dot(Ry[i], reshape(u, (ry[i], n[i] * ry[i + 1])))
            Ry[i + 1] = reshape(Ry[i + 1], (ry[i] * n[i], ry[i + 1]))
            curind = maxvol(Ry[i + 1])
            Ry[i + 1] = Ry[i + 1][curind, :]
            for j in range(nx):
                Rx[i + 1, j] = reshape(crx[i, j],
                                       (rx[i, j], n[i] * rx[i + 1, j]))
                Rx[i + 1, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i + 1, j] = reshape(Rx[i + 1, j],
                                       (ry[i] * n[i], rx[i + 1, j]))
                Rx[i + 1, j] = Rx[i + 1, j][curind, :]
        elif dirn < 0 and i > 0:
            u = np.dot(u[:, :r], np.diag(s[:r]))
            v = np.conj(v[:, :r])

            radd = 0
            rv = 1
            if not last_sweep and kickrank > 0:
                if kicktype == 'amr-two':
                    # compute the X superblocks
                    ind2 = np.unique(np.random.randint(
                        0, ry[i - 1] * n[i - 1], ry[i]))
                    rkick = len(ind2)
                    curbl = np.zeros(
                        (rkick * n[i] * ry[i + 1], nx), dtype=dtype)
                    for j in range(nx):
                        cr1 = reshape(
                            crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                        cr1 = np.dot(cr1, Rx[i + 1, j])
                        cr1 = reshape(cr1, (rx[i, j], n[i] * ry[i + 1]))
                        cr2 = reshape(
                            crx[i - 1, j], (rx[i - 1, j], n[i - 1] * rx[i, j]))
                        cr2 = np.dot(Rx[i - 1, j], cr2)
                        cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], rx[i, j]))
                        cr2 = cr2[ind2, :]
                        curbl[:, j] = reshape(
                            np.dot(cr2, cr1), (rkick * n[i] * ry[i + 1],))
                    # calling the function
                    uk = funs(curbl)
                    uk = reshape(uk, (rkick * n[i] * ry[i + 1], d2))
                    uk = reshape(np.transpose(
                        uk), (d2 * rkick * n[i], ry[i + 1]))
                    uk = np.transpose(np.linalg.solve(
                        np.transpose(Ry[i + 1]), np.transpose(uk)))
                    uk = reshape(uk, (d2 * rkick, n[i] * ry[i + 1]))
                    if pcatype == 'svd':
                        vk, sk, uk = np.linalg.svd(uk, full_matrices=False)
                        uk = np.conj(np.transpose(uk))
                        # TODO: refactor
                        uk = uk[:, :min(kickrank, uk.shape[1])]
                    else:
                        # uk = uchol(uk, kickrank + 1) # TODO
                        uk = uk[:, :max(uk.shape[1] - kickrank + 1, 1):-1]
                else:
                    uk = np.random.rand(n[i] * ry[i + 1], kickrank)
                v, rv = np.linalg.qr(np.concatenate((v, uk), axis=1))
                radd = uk.shape[1]
            u = np.concatenate(
                (u, np.zeros((d2 * ry[i], radd), dtype=dtype)), axis=1)
            u = np.dot(u, np.transpose(rv))
            r = v.shape[1]
            cr2 = cry[i - 1]
            cr2 = reshape(cr2, (ry[i - 1] * n[i - 1], ry[i]))
            u = reshape(u, (d2, ry[i] * r))
            u = reshape(np.transpose(u), (ry[i], r * d2))
            u = np.dot(cr2, u)

            u = reshape(u, (ry[i - 1] * n[i - 1] * r, d2))
            u = reshape(np.transpose(u), (d2, ry[i - 1], n[i - 1], r))
            v = reshape(np.transpose(v), (r, n[i], ry[i + 1]))

            ry[i] = r
            cry[i - 1] = u
            cry[i] = v

            Ry[i] = np.dot(reshape(v, (ry[i] * n[i], ry[i + 1])), Ry[i + 1])
            Ry[i] = reshape(Ry[i], (ry[i], n[i] * ry[i + 1]))
            curind = maxvol(np.transpose(Ry[i]))
            Ry[i] = Ry[i][:, curind]
            for j in range(nx):
                Rx[i, j] = reshape(crx[i, j], (rx[i, j] * n[i], rx[i + 1, j]))
                Rx[i, j] = np.dot(Rx[i, j], Rx[i + 1, j])
                Rx[i, j] = reshape(Rx[i, j], (rx[i, j], n[i] * ry[i + 1]))
                Rx[i, j] = Rx[i, j][:, curind]
        elif dirn > 0 and i == d - 1:
            newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])),
                          np.conj(np.transpose(v[:, :r])))
            newy = reshape(newy, (ry[i] * n[i] * ry[i + 1], d2))
            cry[i] = reshape(np.transpose(newy), (d2, ry[i], n[i], ry[i + 1]))
        elif dirn < 0 and i == 0:
            newy = np.dot(np.dot(u[:, :r], np.diag(s[:r])),
                          np.conj(np.transpose(v[:, :r])))
            newy = reshape(newy, (d2, ry[i], n[i], ry[i + 1]))
            cry[i] = newy

        i = i + dirn
        cur_order[order_index] = cur_order[order_index] - dirn
        if cur_order[order_index] == 0:
            order_index = order_index + 1
            if verb > 0:
                print('=multifuncrs= sweep %d{%d}, max_dy: %3.3e, erank: %g' % (swp, order_index, max_dy,
                                                                                math.sqrt(np.dot(ry[:d], n * ry[1:]) / np.sum(n))))

            if last_sweep:
                break
            if max_dy < eps and dirn < 0:
                last_sweep = True
                kickrank = 0

            if order_index >= len(cur_order):
                cur_order = copy.copy(block_order)
                order_index = 0
                if last_sweep:
                    cur_order = [d - 1]

                max_dy = 0
                swp = swp + 1

            dirn = int(math.copysign(1, cur_order[order_index]))
            i = i + dirn

    cry[d - 1] = np.transpose(cry[d - 1][:, :, :, 0], [1, 2, 0])
    y = tt.tensor.from_list(cry)
    return y

Response: Cross approximation of a multivariate function of several TT - tensors.


Instruction:
Create a Python 3 function to
generate TT - vectorr object from a list of TT cores.

Response:
def from_list(a, order='F'):
        """Generate TT-vectorr object from given TT cores.

        :param a: List of TT cores.
        :type a: list
        :returns: vector -- TT-vector constructed from the given cores.

        """
        d = len(a)  # Number of cores
        res = vector()
        n = _np.zeros(d, dtype=_np.int32)
        r = _np.zeros(d+1, dtype=_np.int32)
        cr = _np.array([])
        for i in xrange(d):
            cr = _np.concatenate((cr, a[i].flatten(order)))
            r[i] = a[i].shape[0]
            r[i+1] = a[i].shape[2]
            n[i] = a[i].shape[1]
        res.d = d
        res.n = n
        res.r = r
        res.core = cr
        res.get_ps()
        return res


Instruction:
Explain what the following Python 3 code does
def r2c(self):
        tmp = self.copy()
        newcore = _np.array(tmp.core, dtype=_np.complex)
        cr = newcore[tmp.ps[-2] - 1:tmp.ps[-1] - 1]
        cr = cr.reshape((tmp.r[-2], tmp.n[-1], tmp.r[-1]), order='F')
        cr[:, 1, :] *= 1j
        newcore[tmp.ps[-2] - 1:tmp.ps[-1] - 1] = cr.flatten('F')
        tmp.core = newcore
        return sum(tmp, axis=tmp.d - 1)

Response: Get complex vector. from real one made by tensor. c2r. r2c.


Instruction:
Implement a Python 3 function for
returning full array of in - memory entries.

Response:
def full(self, asvector=False):
        """Returns full array (uncompressed).

        .. warning::
           TT compression allows to keep in memory tensors much larger than ones PC can handle in
           raw format. Therefore this function is quite unsafe; use it at your own risk.

       :returns: numpy.ndarray -- full tensor.

       """
        # Generate correct size vector
        sz = self.n.copy()
        if self.r[0] > 1:
            sz = _np.concatenate(([self.r[0]], sz))
        if self.r[self.d] > 1:
            sz = _np.concatenate(([self.r[self.d]], sz))
        if (_np.iscomplex(self.core).any()):
            a = _tt_f90.tt_f90.ztt_to_full(
                self.n, self.r, self.ps, self.core, _np.prod(sz))
        else:
            a = _tt_f90.tt_f90.dtt_to_full(
                self.n, self.r, self.ps, _np.real(
                    self.core), _np.prod(sz))
        a = a.reshape(sz, order='F')
        if asvector:
            a=a.flatten(order='F')
        return a


Instruction:
Create a Python 3 function for
applying TT rounding procedure to the TT - vector and returns rounded tensor.

Response:
def round(self, eps=1e-14, rmax=1000000):
        """Applies TT rounding procedure to the TT-vector and **returns rounded tensor**.

        :param eps: Rounding accuracy.
        :type eps: float
        :param rmax: Maximal rank
        :type rmax: int
        :returns: tensor -- rounded TT-vector.

        Usage example:

        >>> a = tt.ones(2, 10)
        >>> b = a + a
        >>> print b.r
        array([1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1], dtype=int32)
        >>> b = b.round(1E-14)
        >>> print b.r
        array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int32)

        """
        c = vector()
        c.n = _np.copy(self.n)
        c.d = self.d
        c.r = _np.copy(self.r)
        c.ps = _np.copy(self.ps)
        if (_np.iscomplex(self.core).any()):
            _tt_f90.tt_f90.ztt_compr2(c.n, c.r, c.ps, self.core, eps, rmax)
            c.core = _tt_f90.tt_f90.zcore.copy()
        else:
            _tt_f90.tt_f90.dtt_compr2(c.n, c.r, c.ps, self.core, eps, rmax)
            c.core = _tt_f90.tt_f90.core.copy()
        _tt_f90.tt_f90.tt_dealloc()
        return c


Instruction:
How would you explain what the following Python 3 function does
def rmean(self):
        if not _np.all(self.n):
            return 0
        # Solving quadratic equation ar^2 + br + c = 0;
        a = _np.sum(self.n[1:-1])
        b = self.n[0] + self.n[-1]
        c = - _np.sum(self.n * self.r[1:] * self.r[:-1])
        D = b ** 2 - 4 * a * c
        r = 0.5 * (-b + _np.sqrt(D)) / a
        return r

Response: Calculates the mean rank of a TT - vector.


Instruction:
Can you generate the documentation for the following Python 3 function
def qtt_fft1(self,tol,inverse=False, bitReverse=True):

        d = self.d
        r = self.r.copy()
        y = self.to_list(self)

        if inverse:
            twiddle =-1+1.22e-16j # exp(pi*1j)
        else:
            twiddle =-1-1.22e-16j # exp(-pi*1j)

        for i in range(d-1, 0, -1):

            r1= y[i].shape[0]   # head r
            r2= y[i].shape[2]   # tail r
            crd2 = _np.zeros((r1, 2, r2), order='F',  dtype=complex)
            # last block +-
            crd2[:,0,:]= (y[i][:,0,:] + y[i][:,1,:])/_np.sqrt(2)
            crd2[:,1,:]= (y[i][:,0,:] - y[i][:,1,:])/_np.sqrt(2)
            # last block twiddles
            y[i]= _np.zeros((r1*2, 2, r2),order='F',dtype=complex)
            y[i][0:r1,    0, 0:r2]= crd2[:,0,:]
            y[i][r1:r1*2, 1, 0:r2]= crd2[:,1,:]
            #1..i-1 block twiddles and qr
            rv=1;

            for j in range(0, i):

                cr=y[j]
                r1= cr.shape[0]   # head r
                r2= cr.shape[2]   # tail r
                if j==0:
                    r[j]=r1
                    r[j+1] = r2*2
                    y[j] = _np.zeros((r[j], 2, r[j+1]),order='F',dtype=complex)
                    y[j][0:r1, :, 0:r2] = cr
                    y[j][0:r1, 0, r2 :r[j+1]] = cr[:,0,:]
                    y[j][0:r1, 1, r2 :r[j+1]] = twiddle**(1.0/(2**(i-j)))*cr[:,1,:]
                else:
                    r[j]=r1*2
                    r[j+1] = r2*2
                    y[j] = _np.zeros((r[j], 2, r[j+1]),order='F',dtype=complex)
                    y[j][0:r1, :, 0:r2] = cr
                    y[j][r1:r[j], 0, r2 :r[j+1]] = cr[:,0,:]
                    y[j][r1:r[j], 1, r2 :r[j+1]] = twiddle**(1.0/(2**(i-j)))*cr[:,1,:]

                y[j] = _np.reshape(y[j],( r[j], 2*r[j+1]),order='F')
                y[j] = _np.dot(rv,y[j])
                r[j] = y[j].shape[0]
                y[j] = _np.reshape(y[j],( 2*r[j],  r[j+1]),order='F')

                y[j], rv = _np.linalg.qr(y[j])
                y[j] = _np.reshape(y[j], (r[j], 2, rv.shape[0]),order='F')

            y[i] = _np.reshape(y[i], (r[i], 2*r[i+1]),order='F')
            y[i] = _np.dot(rv,y[i])
            r[i] = rv.shape[0]
            # backward svd
            for j in range(i, 0,-1):
                u,s,v = _np.linalg.svd(y[j], full_matrices=False)
                rnew = my_chop2(s, _np.linalg.norm(s)*tol/_np.sqrt(i))
                u=_np.dot(u[:, 0:rnew], _np.diag(s[0:rnew]))
                v= v[0:rnew, :]
                y[j] = _np.reshape(v, (rnew, 2, r[j+1]),order='F' )
                y[j-1] = _np.reshape(y[j-1], (r[j-1]*2,r[j] ),order='F' )
                y[j-1] = _np.dot(y[j-1], u)
                r[j] = rnew
                y[j-1] = _np.reshape(y[j-1], (r[j-1],r[j]*2 ),order='F' )

            y[0] = _np.reshape(y[0], (r[0],2, r[1]), order='F' )

        # FFT on the first block
        y[0]=_np.transpose(y[0],(1,0,2))
        y[0]=_np.reshape(y[0],(2, r[0]*r[1]),order='F')
        y[0]= _np.dot( _np.array([[1,1],[1,-1]]), y[0])/_np.sqrt(2)
        y[0]=_np.reshape(y[0],(2, r[0], r[1]),order='F')
        y[0]=_np.transpose(y[0],(1,0,2))

        if bitReverse:
            # Reverse the train
            y2=[None]*d
            for i in range(d):
                y2[d-i-1]= _np.transpose(y[i],(2,1,0))

            y=self.from_list(y2)
        else: # for multi-dimensional qtt_fft
            y=self.from_list(y)
        return y

Response: Compute 1D discrete Fourier transform in the QTT format.


Instruction:
Can you write a function in Python 3 where it
approximates computation of minimal eigenvalues in tensor train format

Response:
def eigb(A, y0, eps, rmax=150, nswp=20, max_full_size=1000, verb=1):
    """ Approximate computation of minimal eigenvalues in tensor train format
    This function uses alternating least-squares algorithm for the computation of several
    minimal eigenvalues. If you want maximal eigenvalues, just send -A to the function.

    :Reference:

        S. V. Dolgov, B. N. Khoromskij, I. V. Oseledets, and D. V. Savostyanov.
        Computation of extreme eigenvalues in higher dimensions using block tensor train format. Computer Phys. Comm.,
        185(4):1207-1216, 2014. http://dx.doi.org/10.1016/j.cpc.2013.12.017

    :param A: Matrix in the TT-format
    :type A: matrix
    :param y0: Initial guess in the block TT-format, r(d+1) is the number of eigenvalues sought
    :type y0: tensor
    :param eps: Accuracy required
    :type eps: float
    :param rmax: Maximal rank
    :type rmax: int
    :param kickrank: Addition rank, the larger the more robus the method,
    :type kickrank: int
    :rtype: A tuple (ev, tensor), where ev is a list of eigenvalues, tensor is an approximation to eigenvectors.

    :Example:

        >>> import tt
        >>> import tt.eigb
        >>> d = 8; f = 3
        >>> r = [8] * (d * f + 1); r[d * f] = 8; r[0] = 1
        >>> x = tt.rand(n, d * f, r)
        >>> a = tt.qlaplace_dd([8, 8, 8])
        >>> sol, ev = tt.eigb.eigb(a, x, 1e-6, verb=0)
        Solving a block eigenvalue problem
        Looking for 8 eigenvalues with accuracy 1E-06
        swp: 1 er = 35.93 rmax:19
        swp: 2 er = 4.51015E-04 rmax:18
        swp: 3 er = 1.87584E-12 rmax:17
        Total number of matvecs: 0
        >>> print ev
        [ 0.00044828  0.00089654  0.00089654  0.00089654  0.0013448   0.0013448
                  0.0013448   0.00164356]

    """
    ry = y0.r.copy()
    lam = tt_eigb.tt_block_eig.tt_eigb(y0.d, A.n, A.m, A.tt.r, A.tt.core, y0.core, ry, eps,
                                       rmax, ry[y0.d], 0, nswp, max_full_size, verb)
    y = tensor()
    y.d = y0.d
    y.n = A.n.copy()
    y.r = ry
    y.core = tt_eigb.tt_block_eig.result_core.copy()
    tt_eigb.tt_block_eig.deallocate_result()
    y.get_ps()
    return y, lam


Instruction:
Explain what the following Python 3 code does
def GMRES(A, u_0, b, eps=1e-6, maxit=100, m=20, _iteration=0, callback=None, verbose=0):
    maxitexceeded = False
    converged = False

    if verbose:
        print('GMRES(m=%d, _iteration=%d, maxit=%d)' % (m, _iteration, maxit))
    v = np.ones((m + 1), dtype=object) * np.nan
    R = np.ones((m, m)) * np.nan
    g = np.zeros(m)
    s = np.ones(m) * np.nan
    c = np.ones(m) * np.nan
    v[0] = b - A(u_0, eps=eps)
    v[0] = v[0].round(eps)
    resnorm = v[0].norm()
    curr_beta = resnorm
    bnorm = b.norm()
    wlen = resnorm
    q = m
    for j in range(m):
        _iteration += 1

        delta = eps / (curr_beta / resnorm)

        if verbose:
            print("it = %d delta = " % _iteration, delta)

        v[j] *= 1.0 / wlen
        v[j + 1] = A(v[j], eps=delta)
        for i in range(j + 1):
            R[i, j] = tt.dot(v[j + 1], v[i])
            v[j + 1] = v[j + 1] - R[i, j] * v[i]
        v[j + 1] = v[j + 1].round(delta)

        wlen = v[j + 1].norm()
        for i in range(j):
            r1 = R[i, j]
            r2 = R[i + 1, j]
            R[i, j] = c[i] * r1 - s[i] * r2
            R[i + 1, j] = c[i] * r2 + s[i] * r1
        denom = np.hypot(wlen, R[j, j])
        s[j] = wlen / denom
        c[j] = -R[j, j] / denom
        R[j, j] = -denom

        g[j] = c[j] * curr_beta
        curr_beta *= s[j]

        if verbose:
            print("it = {}, ||r|| = {}".format(_iteration, curr_beta / bnorm))

        converged = (curr_beta / bnorm) < eps or (curr_beta / resnorm) < eps
        maxitexceeded = _iteration >= maxit
        if converged or maxitexceeded:
            q = j + 1
            break

    y = la.solve_triangular(R[:q, :q], g[:q], check_finite=False)
    for idx in range(q):
        u_0 += v[idx] * y[idx]

    u_0 = u_0.round(eps)

    if callback is not None:
        callback(u_0)

    if converged or maxitexceeded:
        return u_0, resnorm / bnorm
    return GMRES(A, u_0, b, eps, maxit, m, _iteration, callback=callback, verbose=verbose)

Response: Flexible TT GMRES algorithm for non - linear system


Instruction:
Can you create a Python 3 function that
computes the row of the Kronecker product between left and right - orthogonal cores.

Response:
def getRow(leftU, rightV, jVec):
    '''
    Compute X_{\geq \mu}^T \otimes X_{leq \mu}
    X_{\geq \mu} = V_{\mu+1}(j_{\mu}) \ldots V_{d} (j_{d}) [left interface matrix]
    X_{\leq \mu} = U_{1} (j_{1}) \ldots U_{\mu-1}(j_{\mu-1}) [right interface matrix]

    Parameters:
        :list of numpy.arrays: leftU
            left-orthogonal cores from 1 to \mu-1
        :list of numpy.arrays: rightV
            right-orthogonal cores from \mu+1 to d
        :list, tuple, np.array: jVec
            indices for each dimension n[k]
    Returns:
        :numpy.array: result
            Kronecker product between left and right interface
            matrices. Left matrix is transposed.
    '''
    jLeft = None
    jRight = None
    if len(leftU) > 0:
        jLeft = jVec[:len(leftU)]
    if len(rightV) > 0:
        jRight = jVec[-len(rightV):]

    multU = np.ones([1,1])
    for k in xrange(len(leftU)):
        multU = np.dot(multU, leftU[k][:, jLeft[k], :])
    multV= np.ones([1,1])
    for k in xrange(len(rightV)-1, -1, -1):
        multV = np.dot(rightV[k][:, jRight[k], :], multV)

    result = np.kron(multV.T, multU)
    return result


Instruction:
Can you create a Python 3 function that
computes functional J for a given x and a dictionary of functional values.

Response:
def computeFunctional(x, cooP):
    '''
    Compute value of functional J(X) = ||PX - PA||^2_F,
    where P is projector into index subspace of known elements,
          X is our approximation,
          A is original tensor.

    Parameters:
        :tt.vector: x
            current approximation [X]
        :dict: cooP
            dictionary with two records
                - 'indices': numpy.array of P x d shape,
                contains index subspace of P known elements;
                each string is an index of one element.
                - 'values': numpy array of size P,
                contains P known values.

    Returns:
        :float: result
            value of functional
    '''
    indices = cooP['indices']
    values = cooP['values']

    [P, d] = indices.shape
    assert P == len(values)

    result = 0
    for p in xrange(P):
        index = tuple(indices[p, :])
        result += (x[index] - values[p])**2
    result *= 0.5
    return result


Instruction:
Here you have a function in Python 3, explain what it does
def ttSparseALS(cooP, shape, x0=None, ttRank=1, tol=1e-5, maxnsweeps=20, verbose=True, alpha=1e-2):
    '''
    TT completion via Alternating Least Squares algorithm.

    Parameters:
        :dict: cooP
            dictionary with two records
                - 'indices': numpy.array of P x d shape,
                contains index subspace of P known elements;
                each string is an index of one element.
                - 'values': numpy array of size P,
                contains P known values.
        :list, numpy.array: shape
            full-format shape of tensor to be completed [dimensions]
        :tt.vector: x0 = None
            initial approximation of completed tensor
            If it is specified, parameters 'shape' and 'ttRank' will be ignored
        :int, numpy.array: ttRank = 1
            assumed rank of completed tensor
        :float: tol = 1e-5
            tolerance for functional value
        :int: maxnsweeps = 20
            maximal number of sweeps [sequential optimization of all d cores
            in right or left direction]
        :boolean: verbose = True
            switcher of messages from function
        :float: alpha: = 1e-2
            regularizer of least squares problem for each slice of current TT core.
            [rcond parameter for np.linalg.lstsq]

    Returns:
        :tt.vector: xNew
            completed TT vector
        :list: fit
            list of functional values at each sweep
    '''
    indices = cooP['indices']
    values = cooP['values']

    [P, d] = indices.shape
    assert P == len(values)

    timeVal = time.clock()
    if x0 is None:
        x = tt.rand(shape, r = ttRank)
        x = x.round(0.)
        x = (1./x.norm())*x
    else:
        x = copy.deepcopy(x0)
    assert d == x.d
    # TODO: also check if cooP indices are aligned with shape
    normP = np.linalg.norm(values)
    values /= normP
    fitList = []
    sweepTimeList = []
    initTime = time.clock() - timeVal

    timeVal = time.clock()
    coreList = tt.vector.to_list(x)
    #coreList = orthLRFull(coreList, mu = d, splitResult = False)
    # orthTime = time.clock() - timeVal

    if verbose:
        print("Initialization time: %.3f seconds (proc.time)" % (initTime))
        # print "Orthogonalizing time: %.3f seconds (proc.time)" % (orthTime)

    for sweep in xrange(maxnsweeps):
        sweepStart = time.clock()
        # list left + right
        [kStart, kEnd, kStep] = [0, d, 1]
        # select direction of sweep
        '''
        if sweep % 2 == 0: # left to rigth
            [kStart, kEnd, kStep] = [0, d, 1]
        else: # right to left
            [kStart, kEnd, kStep] = [d-1, -1, -1]
        '''
        # fix k-th core to update
        for k in xrange(kStart, kEnd, kStep):
            [r1, n, r2] = coreList[k].shape
            core = np.zeros([r1, n, r2])
            leftU = []
            rightV = []
            if k > 0:
                leftU = coreList[:k]
            if k < d-1:
                rightV = coreList[k+1:]
            for i in xrange(n):
                thetaI = np.where(indices[:, k] == i)[0]
                if len(thetaI) > 0:
                    A = np.zeros([len(thetaI), r1*r2])
                    for j in xrange(len(thetaI)):
                        tmp = getRow(leftU, rightV, indices[thetaI[j], :])
                        A[j:j+1, :] += tmp   # .flatten(order = 'F')
                    vecCoreSlice, _, _, _ = np.linalg.lstsq(A, values[thetaI])#, rcond = alpha)
                    # 0.5*np.linalg.norm(np.dot(A, vecCoreSlice) - values[thetaI])**2.
                    core[:, i, :] += reshape(vecCoreSlice, [r1, r2]) ####
            '''
            if k < (d-1):
                core = reshape(core, [r1*n, r2])
                Q, R = np.linalg.qr(core)
                rnew = Q.shape[1]
                core = reshape(Q, [r1, n, rnew])
                coreList[k+1] = np.einsum('ijk,li->ljk', coreList[k+1], R)
            '''
            coreList[k] = core.copy()
            '''
            else:
                if (k > 0):
                    core = reshape(core, [r1, n*r2])
                    Q, R = np.linalg.qr(core.T)
                    rnew = Q.shape[1]
                    core = reshape(Q.T, [rnew, n, r2])
                    coreList[k-1] = np.einsum('ijk,lk->ijl', coreList[k-1], R)
            '''

        xNew = tt.vector.from_list(coreList)
        fit = computeFunctional(xNew, cooP)
        fitList.append(fit)
        if fit < tol:
            break
        if sweep > 0:
            if abs(fit - fitList[-2]) < tol:
                break
        sweepTimeList.append(time.clock() - sweepStart)
        if verbose:
            print("sweep %d/%d\t fit value: %.5e\t time: %.3f seconds (proc.time)" % (sweep+1, maxnsweeps, fit, sweepTimeList[-1]))
    if verbose:
        print("Total sweep time: %.3f seconds (proc.time)\t Total time: %.3f seconds (proc.time)" % (sum(sweepTimeList), sum(sweepTimeList) + initTime))# + orthTime)
    info = {'fit': fitList, 'initTime': initTime,  'sweepTime': sweepTimeList} # 'orthTime': orthTime,
    xNew *= normP
    values *= normP

    return xNew, info

Response: This function is used to generate a new TT vector for a set of functional values in a set of states.


Instruction:
Create a Python 3 function for
updating icon image and hover text

Response:
def update(self, icon=None, hover_text=None):
        """ update icon image and/or hover text """
        if icon:
            self._icon = icon
            self._load_icon()
        if hover_text:
            self._hover_text = hover_text
        self._refresh_icon()


Instruction:
Write a Python 3 script for
encoding text items for system locale.

Response:
def encode_for_locale(s):
    """
    Encode text items for system locale. If encoding fails, fall back to ASCII.
    """
    try:
        return s.encode(LOCALE_ENCODING, 'ignore')
    except (AttributeError, UnicodeDecodeError):
        return s.decode('ascii', 'ignore').encode(LOCALE_ENCODING)


Instruction:
Can you tell what is the following Python 3 function doing
def fib(n):
    v = n.value
    return v if v < 2 else fib2(PythonInt(v-1)) + fib(PythonInt(v-2))

Response: Terrible Fibonacci number generator.


Instruction:
Create a Python 3 function to
run Fibonacci generator r times.

Response:
def run_fib_with_clear(r):
    """ Run Fibonacci generator r times. """
    for i in range(r):
        if randint(RAND_MIN, RAND_MAX) == RAND_MIN:
            fib.cache_clear()
            fib2.cache_clear()
        res = fib(PythonInt(FIB))
        if RESULT != res:
            raise ValueError("Expected %d, Got %d" % (RESULT, res))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def run_fib_with_stats(r):
    for i in range(r):
        res = fib(PythonInt(FIB))
        if RESULT != res:
            raise ValueError("Expected %d, Got %d" % (RESULT, res))

Response: Run Fibonacci generator r times.


Instruction:
Create a Python 3 function for
parsing the datetime information out of a string.

Response:
def parse(self, input_str, reference_date=""):
        """Parses datetime information out of string input.

        It invokes the SUTimeWrapper.annotate() function in Java.

        Args:
            input_str: The input as string that has to be parsed.
            reference_date: Optional reference data for SUTime.

        Returns:
            A list of dicts with the result from the SUTimeWrapper.annotate()
                call.
        """
        if not jpype.isThreadAttachedToJVM():
            jpype.attachThreadToJVM()
        if reference_date:
            return json.loads(self._sutime.annotate(input_str, reference_date))
        return json.loads(self._sutime.annotate(input_str))


Instruction:
Can you write a function in Python 3 where it
formats a user s message for safe processing.

Response:
def format_message(self, msg, botreply=False):
        """Format a user's message for safe processing.

        This runs substitutions on the message and strips out any remaining
        symbols (depending on UTF-8 mode).

        :param str msg: The user's message.
        :param bool botreply: Whether this formatting is being done for the
            bot's last reply (e.g. in a ``%Previous`` command).

        :return str: The formatted message.
        """

        # Make sure the string is Unicode for Python 2.
        if sys.version_info[0] < 3 and isinstance(msg, str):
            msg = msg.decode()

        # Lowercase it.
        msg = msg.lower()

        # Run substitutions on it.
        msg = self.substitute(msg, "sub")

        # In UTF-8 mode, only strip metacharacters and HTML brackets
        # (to protect from obvious XSS attacks).
        if self.utf8:
            msg = re.sub(RE.utf8_meta, '', msg)
            msg = re.sub(self.master.unicode_punctuation, '', msg)

            # For the bot's reply, also strip common punctuation.
            if botreply:
                msg = re.sub(RE.utf8_punct, '', msg)
        else:
            # For everything else, strip all non-alphanumerics.
            msg = utils.strip_nasties(msg)
            msg = msg.strip() # Strip leading and trailing white space
            msg = RE.ws.sub(" ",msg) # Replace the multiple whitespaces by single whitespace
        return msg


Instruction:
Implement a Python 3 function for
preparing a regular expression for the reply of a user.

Response:
def reply_regexp(self, user, regexp):
        """Prepares a trigger for the regular expression engine.

        :param str user: The user ID invoking a reply.
        :param str regexp: The original trigger text to be turned into a regexp.

        :return regexp: The final regexp object."""

        if regexp in self.master._regexc["trigger"]:
            # Already compiled this one!
            return self.master._regexc["trigger"][regexp]

        # If the trigger is simply '*' then the * there needs to become (.*?)
        # to match the blank string too.
        regexp = re.sub(RE.zero_star, r'<zerowidthstar>', regexp)

        # Filter in arrays.
        arrays = re.findall(RE.array, regexp)
        for array in arrays:
            rep = ''
            if array in self.master._array:
                rep = r'(?:' + '|'.join(self.expand_array(array)) + ')'
            regexp = re.sub(r'\@' + re.escape(array) + r'\b', rep, regexp)

        # Simple replacements.
        regexp = regexp.replace('*', '(.+?)')   # Convert * into (.+?)
        regexp = regexp.replace('#', '(\d+?)')  # Convert # into (\d+?)
        regexp = regexp.replace('_', '(\w+?)')  # Convert _ into (\w+?)
        regexp = re.sub(RE.weight, '', regexp)  # Remove {weight} tags, allow spaces before the bracket
        regexp = regexp.replace('<zerowidthstar>', r'(.*?)')

        # Optionals.
        optionals = re.findall(RE.optionals, regexp)
        for match in optionals:
            parts = match.split("|")
            new = []
            for p in parts:
                p = r'(?:\\s|\\b)+{}(?:\\s|\\b)+'.format(p.strip())
                new.append(p)

            # If this optional had a star or anything in it, make it
            # non-matching.
            pipes = '|'.join(new)
            pipes = pipes.replace(r'(.+?)', r'(?:.+?)')
            pipes = pipes.replace(r'(\d+?)', r'(?:\d+?)')
            pipes = pipes.replace(r'([A-Za-z]+?)', r'(?:[A-Za-z]+?)')

            regexp = re.sub(r'\s*\[' + re.escape(match) + '\]\s*',
                '(?:' + pipes + r'|(?:\\s|\\b))', regexp)

        # _ wildcards can't match numbers!
        regexp = re.sub(RE.literal_w, r'[^\\s\\d]', regexp)

        # Filter in bot variables.
        bvars = re.findall(RE.bot_tag, regexp)
        for var in bvars:
            rep = ''
            if var in self.master._var:
                rep = self.format_message(self.master._var[var])
            regexp = regexp.replace('<bot {var}>'.format(var=var), rep)

        # Filter in user variables.
        uvars = re.findall(RE.get_tag, regexp)
        for var in uvars:
            rep = ''
            value = self.master.get_uservar(user, var)
            if value not in [None, "undefined"]:
                rep = utils.strip_nasties(value)
            regexp = regexp.replace('<get {var}>'.format(var=var), rep)

        # Filter in <input> and <reply> tags. This is a slow process, so only
        # do it if we have to!
        if '<input' in regexp or '<reply' in regexp:
            history = self.master.get_uservar(user, "__history__")
            for type in ['input', 'reply']:
                tags = re.findall(r'<' + type + r'([0-9])>', regexp)
                for index in tags:
                    rep = self.format_message(history[type][int(index) - 1])
                    regexp = regexp.replace('<{type}{index}>'.format(type=type, index=index), rep)
                regexp = regexp.replace('<{type}>'.format(type=type),
                                        self.format_message(history[type][0]))
                # TODO: the Perl version doesn't do just <input>/<reply> in trigs!

        if self.utf8:
            return re.compile(r'^' + regexp.lower() + r'$', re.UNICODE)
        else:
            return re.compile(r'^' + regexp.lower() + r'$')


Instruction:
Can you tell what is the following Python 3 function doing
def do_expand_array(self, array_name, depth=0):
        if depth > self.master._depth:
            raise Exception("deep recursion detected")
        if not array_name in self.master._array:
            raise Exception("array '%s' not defined" % (array_name))
        ret = list(self.master._array[array_name])
        for array in self.master._array[array_name]:
            if array.startswith('@'):
                ret.remove(array)
                expanded = self.do_expand_array(array[1:], depth+1)
                ret.extend(expanded)

        return set(ret)

Response: Do recurrent expansion of an array.


Instruction:
Here you have a function in Python 3, explain what it does
def expand_array(self, array_name):
        ret = self.master._array[array_name] if array_name in self.master._array else []
        try:
            ret = self.do_expand_array(array_name)
        except Exception as e:
            self.warn("Error expanding array '%s': %s" % (array_name, str(e)))
        return ret

Response: Expand variables and return a list of keywords.


Instruction:
Here you have a function in Python 3, explain what it does
def process_tags(self, user, msg, reply, st=[], bst=[], depth=0, ignore_object_errors=True):
        stars = ['']
        stars.extend(st)
        botstars = ['']
        botstars.extend(bst)
        if len(stars) == 1:
            stars.append("undefined")
        if len(botstars) == 1:
            botstars.append("undefined")

        matcher = re.findall(RE.reply_array, reply)
        for match in matcher:
            name = match
            if name in self.master._array:
                result = "{random}" + "|".join(self.master._array[name]) + "{/random}"
            else:
                result = "\x00@" + name + "\x00"
            reply = reply.replace("(@"+name+")", result)
        reply = re.sub(RE.ph_array, r'(@\1)', reply)

        # Tag shortcuts.
        reply = reply.replace('<person>', '{person}<star>{/person}')
        reply = reply.replace('<@>', '{@<star>}')
        reply = reply.replace('<formal>', '{formal}<star>{/formal}')
        reply = reply.replace('<sentence>', '{sentence}<star>{/sentence}')
        reply = reply.replace('<uppercase>', '{uppercase}<star>{/uppercase}')
        reply = reply.replace('<lowercase>', '{lowercase}<star>{/lowercase}')

        # Weight and <star> tags.
        reply = re.sub(RE.weight, '', reply)  # Leftover {weight}s
        if len(stars) > 0:
            reply = reply.replace('<star>', text_type(stars[1]))
            reStars = re.findall(RE.star_tags, reply)
            for match in reStars:
                if int(match) < len(stars):
                    reply = reply.replace('<star{match}>'.format(match=match), text_type(stars[int(match)]))
        if len(botstars) > 0:
            reply = reply.replace('<botstar>', botstars[1])
            reStars = re.findall(RE.botstars, reply)
            for match in reStars:
                if int(match) < len(botstars):
                    reply = reply.replace('<botstar{match}>'.format(match=match), text_type(botstars[int(match)]))

        # <input> and <reply>
        history = self.master.get_uservar(user, "__history__")
        if type(history) is not dict:
            history = self.default_history()
        reply = reply.replace('<input>', history['input'][0])
        reply = reply.replace('<reply>', history['reply'][0])
        reInput = re.findall(RE.input_tags, reply)
        for match in reInput:
            reply = reply.replace('<input{match}>'.format(match=match),
                                  history['input'][int(match) - 1])
        reReply = re.findall(RE.reply_tags, reply)
        for match in reReply:
            reply = reply.replace('<reply{match}>'.format(match=match),
                                  history['reply'][int(match) - 1])

        # <id> and escape codes.
        reply = reply.replace('<id>', user)
        reply = reply.replace('\\s', ' ')
        reply = reply.replace('\\n', "\n")
        reply = reply.replace('\\#', '#')

        # Random bits.
        reRandom = re.findall(RE.random_tags, reply)
        for match in reRandom:
            output = ''
            if '|' in match:
                output = utils.random_choice(match.split('|'))
            else:
                output = utils.random_choice(match.split(' '))
            reply = reply.replace('{{random}}{match}{{/random}}'.format(match=match), output, 1) # Replace 1st match

        # Person Substitutions and String Formatting.
        for item in ['person', 'formal', 'sentence', 'uppercase',  'lowercase']:
            matcher = re.findall(r'\{' + item + r'\}(.+?)\{/' + item + r'\}', reply)
            for match in matcher:
                output = None
                if item == 'person':
                    # Person substitutions.
                    output = self.substitute(match, "person")
                else:
                    output = utils.string_format(match, item)
                reply = reply.replace('{{{item}}}{match}{{/{item}}}'.format(item=item, match=match), output)

        # Handle all variable-related tags with an iterative regex approach,
        # to allow for nesting of tags in arbitrary ways (think <set a=<get b>>)
        # Dummy out the <call> tags first, because we don't handle them right
        # here.
        reply = reply.replace("<call>", "{__call__}")
        reply = reply.replace("</call>", "{/__call__}")
        while True:
            # This regex will match a <tag> which contains no other tag inside
            # it, i.e. in the case of <set a=<get b>> it will match <get b> but
            # not the <set> tag, on the first pass. The second pass will get the
            # <set> tag, and so on.
            match = re.search(RE.tag_search, reply)
            if not match: break  # No remaining tags!

            match = match.group(1)
            parts  = match.split(" ", 1)
            tag    = parts[0].lower()
            data   = parts[1] if len(parts) > 1 else ""
            insert = ""  # Result of the tag evaluation

            # Handle the tags.
            if tag == "bot" or tag == "env":
                # <bot> and <env> tags are similar.
                target = self.master._var if tag == "bot" else self.master._global
                if "=" in data:
                    # Setting a bot/env variable.
                    parts = data.split("=")
                    self.say("Set " + tag + " variable " + text_type(parts[0]) + "=" + text_type(parts[1]))
                    target[parts[0]] = parts[1]
                else:
                    # Getting a bot/env variable.
                    insert = target.get(data, "undefined")
            elif tag == "set":
                # <set> user vars.
                parts = data.split("=")
                self.say("Set uservar " + text_type(parts[0]) + "=" + text_type(parts[1]))
                self.master.set_uservar(user, parts[0], parts[1])
            elif tag in ["add", "sub", "mult", "div"]:
                # Math operator tags.
                parts = data.split("=")
                var   = parts[0]
                value = parts[1]
                curv  = self.master.get_uservar(user, var)

                # Sanity check the value.
                try:
                    value = int(value)
                    if curv in [None, "undefined"]:
                        # Initialize it.
                        curv = 0
                except:
                    insert = "[ERR: Math can't '{}' non-numeric value '{}']".format(tag, value)

                # Attempt the operation.
                try:
                    orig = int(curv)
                    new  = 0
                    if tag == "add":
                        new = orig + value
                    elif tag == "sub":
                        new = orig - value
                    elif tag == "mult":
                        new = orig * value
                    elif tag == "div":
                        new = orig // value
                    self.master.set_uservar(user, var, new)
                except:
                    insert = "[ERR: Math couldn't '{}' to value '{}']".format(tag, curv)
            elif tag == "get":
                insert = self.master.get_uservar(user, data)
            else:
                # Unrecognized tag.
                insert = "\x00{}\x01".format(match)

            reply = reply.replace("<{}>".format(match), text_type(insert))

        # Restore unrecognized tags.
        reply = reply.replace("\x00", "<").replace("\x01", ">")

        # Streaming code. DEPRECATED!
        if '{!' in reply:
            self._warn("Use of the {!...} tag is deprecated and not supported here.")

        # Topic setter.
        reTopic = re.findall(RE.topic_tag, reply)
        for match in reTopic:
            self.say("Setting user's topic to " + match)
            self.master.set_uservar(user, "topic", match)
            reply = reply.replace('{{topic={match}}}'.format(match=match), '')

        # Inline redirecter.
        reRedir = re.findall(RE.redir_tag, reply)
        for match in reRedir:
            self.say("Redirect to " + match)
            at = match.strip()
            subreply = self._getreply(user, at, step=(depth + 1))
            reply = reply.replace('{{@{match}}}'.format(match=match), subreply)

        # Object caller.
        reply = reply.replace("{__call__}", "<call>")
        reply = reply.replace("{/__call__}", "</call>")
        reCall = re.findall(r'<call>(.+?)</call>', reply)
        for match in reCall:
            parts  = re.split(RE.ws, match)
            output = ''
            obj    = parts[0]
            args   = []
            if len(parts) > 1:
                args = parts[1:]

            # Do we know this object?
            if obj in self.master._objlangs:
                # We do, but do we have a handler for that language?
                lang = self.master._objlangs[obj]
                if lang in self.master._handlers:
                    # We do.
                    try:
                        output = self.master._handlers[lang].call(self.master, obj, user, args)
                    except python.PythonObjectError as e:
                        self.warn(str(e))
                        if not ignore_object_errors:
                            raise ObjectError(str(e))
                        output = RS_ERR_OBJECT
                else:
                    if not ignore_object_errors:
                        raise ObjectError(RS_ERR_OBJECT_HANDLER)
                    output = RS_ERR_OBJECT_HANDLER
            else:
                if not ignore_object_errors:
                    raise ObjectError(RS_ERR_OBJECT_MISSING)
                output = RS_ERR_OBJECT_MISSING

            reply = reply.replace('<call>{match}</call>'.format(match=match), output)

        return reply

Response: Process tags in a message.


Instruction:
Can you create a Python 3 function that
runs a kind of substitution on a message.

Response:
def substitute(self, msg, kind):
        """Run a kind of substitution on a message.

        :param str msg: The message to run substitutions against.
        :param str kind: The kind of substitution to run,
            one of ``subs`` or ``person``.
        """

        # Safety checking.
        if 'lists' not in self.master._sorted:
            raise RepliesNotSortedError("You must call sort_replies() once you are done loading RiveScript documents")
        if kind not in self.master._sorted["lists"]:
            raise RepliesNotSortedError("You must call sort_replies() once you are done loading RiveScript documents")

        # Get the substitution map.
        subs = None
        if kind == 'sub':
            subs = self.master._sub
        else:
            subs = self.master._person

        # Make placeholders each time we substitute something.
        ph = []
        i  = 0

        for pattern in self.master._sorted["lists"][kind]:
            result = subs[pattern]

            # Make a placeholder.
            ph.append(result)
            placeholder = "\x00%d\x00" % i
            i += 1

            cache = self.master._regexc[kind][pattern]
            msg = re.sub(cache["sub1"], placeholder, msg)
            msg = re.sub(cache["sub2"], placeholder + r'\1', msg)
            msg = re.sub(cache["sub3"], r'\1' + placeholder + r'\2', msg)
            msg = re.sub(cache["sub4"], r'\1' + placeholder, msg)

        placeholders = re.findall(RE.placeholder, msg)
        for match in placeholders:
            i = int(match)
            result = ph[i]
            msg = msg.replace('\x00' + match + '\x00', result)

        # Strip & return.
        return msg.strip()


Instruction:
Implement a function in Python 3 to
load a Python object from a list of code lines.

Response:
def load(self, name, code):
        """Prepare a Python code object given by the RiveScript interpreter.

        :param str name: The name of the Python object macro.
        :param []str code: The Python source code for the object macro.
        """
        # We need to make a dynamic Python method.
        source = "def RSOBJ(rs, args):\n"
        for line in code:
            source = source + "\t" + line + "\n"

        source += "self._objects[name] = RSOBJ\n"

        try:
            exec(source)
            # self._objects[name] = RSOBJ
        except Exception as e:
            print("Failed to load code from object", name)
            print("The error given was: ", e)


Instruction:
Can you tell what is the following Python 3 function doing
def call(self, rs, name, user, fields):
        # Call the dynamic method.
        if name not in self._objects:
            return '[ERR: Object Not Found]'
        func = self._objects[name]
        reply = ''
        try:
            reply = func(rs, fields)
            if reply is None:
                reply = ''
        except Exception as e:
            raise PythonObjectError("Error executing Python object: " + str(e))
        return text_type(reply)

Response: Invoke a previously loaded object macro.


Instruction:
Here you have a function in Python 3, explain what it does
def get_topic_triggers(rs, topic, thats, depth=0, inheritance=0, inherited=False):

    # Break if we're in too deep.
    if depth > rs._depth:
        rs._warn("Deep recursion while scanning topic inheritance")

    # Keep in mind here that there is a difference between 'includes' and
    # 'inherits' -- topics that inherit other topics are able to OVERRIDE
    # triggers that appear in the inherited topic. This means that if the top
    # topic has a trigger of simply '*', then NO triggers are capable of
    # matching in ANY inherited topic, because even though * has the lowest
    # priority, it has an automatic priority over all inherited topics.
    #
    # The getTopicTriggers method takes this into account. All topics that
    # inherit other topics will have their triggers prefixed with a fictional
    # {inherits} tag, which would start at {inherits=0} and increment if this
    # topic has other inheriting topics. So we can use this tag to make sure
    # topics that inherit things will have their triggers always be on top of
    # the stack, from inherits=0 to inherits=n.

    # Important info about the depth vs inheritance params to this function:
    # depth increments by 1 each time this function recursively calls itrs.
    # inheritance increments by 1 only when this topic inherits another
    # topic.
    #
    # This way, '> topic alpha includes beta inherits gamma' will have this
    # effect:
    #  alpha and beta's triggers are combined together into one matching
    #  pool, and then those triggers have higher matching priority than
    #  gamma's.
    #
    # The inherited option is True if this is a recursive call, from a topic
    # that inherits other topics. This forces the {inherits} tag to be added
    # to the triggers. This only applies when the top topic 'includes'
    # another topic.
    rs._say("\tCollecting trigger list for topic " + topic + "(depth="
        + str(depth) + "; inheritance=" + str(inheritance) + "; "
        + "inherited=" + str(inherited) + ")")

    # topic:   the name of the topic
    # depth:   starts at 0 and ++'s with each recursion

    # Topic doesn't exist?
    if not topic in rs._topics:
        rs._warn("Inherited or included topic {} doesn't exist or has no triggers".format(
            topic
        ))
        return []

    # Collect an array of triggers to return.
    triggers = []

    # Get those that exist in this topic directly.
    inThisTopic = []
    if not thats:
        # The non-that structure is {topic}->[array of triggers]
        if topic in rs._topics:
            for trigger in rs._topics[topic]:
                inThisTopic.append([ trigger["trigger"], trigger ])
    else:
        # The 'that' structure is: {topic}->{cur trig}->{prev trig}->{trig info}
        if topic in rs._thats.keys():
            for curtrig in rs._thats[topic].keys():
                for previous, pointer in rs._thats[topic][curtrig].items():
                    inThisTopic.append([ pointer["trigger"], pointer ])

    # Does this topic include others?
    if topic in rs._includes:
        # Check every included topic.
        for includes in rs._includes[topic]:
            rs._say("\t\tTopic " + topic + " includes " + includes)
            triggers.extend(get_topic_triggers(rs, includes, thats, (depth + 1), inheritance, True))

    # Does this topic inherit others?
    if topic in rs._lineage:
        # Check every inherited topic.
        for inherits in rs._lineage[topic]:
            rs._say("\t\tTopic " + topic + " inherits " + inherits)
            triggers.extend(get_topic_triggers(rs, inherits, thats, (depth + 1), (inheritance + 1), False))

    # Collect the triggers for *this* topic. If this topic inherits any
    # other topics, it means that this topic's triggers have higher
    # priority than those in any inherited topics. Enforce this with an
    # {inherits} tag.
    if topic in rs._lineage or inherited:
        for trigger in inThisTopic:
            rs._say("\t\tPrefixing trigger with {inherits=" + str(inheritance) + "}" + trigger[0])
            triggers.append(["{inherits=" + str(inheritance) + "}" + trigger[0], trigger[1]])
    else:
        triggers.extend(inThisTopic)

    return triggers

Response: Recursively scans a topic and returns a list of all triggers that are allowed to be added to the top of the hierarchy.


Instruction:
Given the following Python 3 function, write the documentation
def get_topic_tree(rs, topic, depth=0):

    # Break if we're in too deep.
    if depth > rs._depth:
        rs._warn("Deep recursion while scanning topic trees!")
        return []

    # Collect an array of all topics.
    topics = [topic]

    # Does this topic include others?
    if topic in rs._includes:
        # Try each of these.
        for includes in sorted(rs._includes[topic]):
            topics.extend(get_topic_tree(rs, includes, depth + 1))

    # Does this topic inherit others?
    if topic in rs._lineage:
        # Try each of these.
        for inherits in sorted(rs._lineage[topic]):
            topics.extend(get_topic_tree(rs, inherits, depth + 1))

    return topics

Response: Given one topic get the list of all included and inherited topics.


Instruction:
Make a summary of the following Python 3 code
def word_count(trigger, all=False):
    words = []
    if all:
        words = re.split(RE.ws, trigger)
    else:
        words = re.split(RE.wilds_and_optionals, trigger)

    wc = 0  # Word count
    for word in words:
        if len(word) > 0:
            wc += 1

    return wc

Response: Count the number of words that are not wildcards or options in a trigger.


Instruction:
Can you tell what is the following Python 3 function doing
def string_format(msg, method):
    if method == "uppercase":
        return msg.upper()
    elif method == "lowercase":
        return msg.lower()
    elif method == "sentence":
        return msg.capitalize()
    elif method == "formal":
        return string.capwords(msg)

Response:
Format a string (upper, lower, formal, sentence).

    :param str msg: The user's message.
    :param str method: One of ``uppercase``, ``lowercase``,
        ``sentence`` or ``formal``.

    :return str: The reformatted string.


Instruction:
Create a Python 3 function for
preparing a Perl code object given by the RS interpreter.

Response:
def load(self, name, code):
        """Prepare a Perl code object given by the RS interpreter."""

        source = "\n".join(code)
        self._objects[name] = source


Instruction:
How would you code a function in Python 3 to
receive an inbound SMS and send a reply from RiveScript.

Response:
def hello_rivescript():
    """Receive an inbound SMS and send a reply from RiveScript."""

    from_number = request.values.get("From", "unknown")
    message     = request.values.get("Body")
    reply       = "(Internal error)"

    # Get a reply from RiveScript.
    if message:
        reply = bot.reply(from_number, message)

    # Send the response.
    resp = twilio.twiml.Response()
    resp.message(reply)
    return str(resp)


Instruction:
Implement a function in Python 3 to
fetch a reply from RiveScript.

Response:
def reply():
    """Fetch a reply from RiveScript.

    Parameters (JSON):
    * username
    * message
    * vars
    """
    params = request.json
    if not params:
        return jsonify({
            "status": "error",
            "error": "Request must be of the application/json type!",
        })

    username = params.get("username")
    message  = params.get("message")
    uservars = params.get("vars", dict())

    # Make sure the required params are present.
    if username is None or message is None:
        return jsonify({
            "status": "error",
            "error": "username and message are required keys",
        })

    # Copy and user vars from the post into RiveScript.
    if type(uservars) is dict:
        for key, value in uservars.items():
            bot.set_uservar(username, key, value)

    # Get a reply from the bot.
    reply = bot.reply(username, message)

    # Get all the user's vars back out of the bot to include in the response.
    uservars = bot.get_uservars(username)

    # Send the response.
    return jsonify({
        "status": "ok",
        "reply": reply,
        "vars": uservars,
    })


Instruction:
Write a Python 3 script to
return an example curl command.

Response:
def index(path=None):
    """On all other routes, just return an example `curl` command."""
    payload = {
        "username": "soandso",
        "message": "Hello bot",
        "vars": {
            "name": "Soandso",
        }
    }
    return Response(r"""Usage: curl -i \
    -H "Content-Type: application/json" \
    -X POST -d '{}' \
    http://localhost:5000/reply""".format(json.dumps(payload)),
    mimetype="text/plain")


Instruction:
Can you create a Python 3 function that
translates a username into a key for Redis.

Response:
def _key(self, username, frozen=False):
        """Translate a username into a key for Redis."""
        if frozen:
            return self.frozen + username
        return self.prefix + username


Instruction:
Explain what the following Python 3 code does
def _get_user(self, username):
        data = self.client.get(self._key(username))
        if data is None:
            return None
        return json.loads(data.decode())

Response: Custom helper method to retrieve a user s data from Redis.


Instruction:
Here you have a function in Python 3, explain what it does
def sort_trigger_set(triggers, exclude_previous=True, say=None):
    if say is None:
        say = lambda x: x

    # KEEP IN MIND: the `triggers` array is composed of array elements of the form
    # ["trigger text", pointer to trigger data]
    # So this code will use e.g. `trig[0]` when referring to the trigger text.

    # Create a list of trigger objects map.
    trigger_object_list = []
    for index, trig in enumerate(triggers):

        if exclude_previous and trig[1]["previous"]:
            continue

        pattern = trig[0]  # Extract only the text of the trigger, with possible tag of inherit

        # See if it has a weight tag
        match, weight = re.search(RE.weight, trig[0]), 0
        if match:  # Value of math is not None if there is a match.
            weight = int(match.group(1))  # Get the weight from the tag ``{weight}``

        # See if it has an inherits tag.
        match = re.search(RE.inherit, pattern)
        if match:
            inherit = int(match.group(1))  # Get inherit value from the tag ``{inherit}``
            say("\t\t\tTrigger belongs to a topic which inherits other topics: level=" + str(inherit))
            triggers[index][0] = pattern = re.sub(RE.inherit, "", pattern)  # Remove the inherit tag if any
        else:
            inherit = sys.maxsize  # If not found any inherit, set it to the maximum value, to place it last in the sort

        trigger_object_list.append(TriggerObj(pattern, index, weight, inherit))

    # Priority order of sorting criteria:
    # weight, inherit, is_empty, star, pound, under, option, wordcount, len, alphabet
    sorted_list = sorted(trigger_object_list,
                         key=attrgetter('weight', 'inherit', 'is_empty', 'star', 'pound',
                                        'under', 'option', 'wordcount', 'len', 'alphabet'))
    return [triggers[item.index] for item in sorted_list]

Response: Sort a group of triggers in optimal sorting order.


Instruction:
Can you generate the documentation for the following Python 3 function
def sort_list(items):

    # Track by number of words.
    track = {}

    def by_length(word1, word2):
        return len(word2) - len(word1)

    # Loop through each item.
    for item in items:
        # Count the words.
        cword = utils.word_count(item, all=True)
        if cword not in track:
            track[cword] = []
        track[cword].append(item)

    # Sort them.
    output = []
    for count in sorted(track.keys(), reverse=True):
        sort = sorted(track[count], key=len, reverse=True)
        output.extend(sort)

    return output

Response: Sort a simple list by number of words and length.


Instruction:
Here you have a function in Python 3, explain what it does
def load_directory(self, directory, ext=None):
        self._say("Loading from directory: " + directory)

        if ext is None:
            # Use the default extensions - .rive is preferable.
            ext = ['.rive', '.rs']
        elif type(ext) == str:
            # Backwards compatibility for ext being a string value.
            ext = [ext]

        if not os.path.isdir(directory):
            self._warn("Error: " + directory + " is not a directory.")
            return

        for root, subdirs, files in os.walk(directory):
            for file in files:
                for extension in ext:
                    if file.lower().endswith(extension):
                        # Load this file.
                        self.load_file(os.path.join(root, file))
                        break

Response: Load RiveScript documents from a directory.


Instruction:
Explain what the following Python 3 code does
def load_file(self, filename):
        self._say("Loading file: " + filename)

        fh    = codecs.open(filename, 'r', 'utf-8')
        lines = fh.readlines()
        fh.close()

        self._say("Parsing " + str(len(lines)) + " lines of code from " + filename)
        self._parse(filename, lines)

Response: Load and parse a RiveScript file.


Instruction:
Can you generate the documentation for the following Python 3 function
def stream(self, code):
        self._say("Streaming code.")
        if type(code) in [str, text_type]:
            code = code.split("\n")
        self._parse("stream()", code)

Response: Stream in RiveScript source code dynamically.


Instruction:
How would you explain what the following Python 3 function does
def _parse(self, fname, code):

        # Get the "abstract syntax tree"
        ast = self._parser.parse(fname, code)

        # Get all of the "begin" type variables: global, var, sub, person, ...
        for kind, data in ast["begin"].items():
            internal = getattr(self, "_" + kind)  # The internal name for this attribute
            for name, value in data.items():
                if value == "<undef>":
                    del internal[name]
                else:
                    internal[name] = value

                # Precompile substitutions.
                if kind in ["sub", "person"]:
                    self._precompile_substitution(kind, name)

        # Let the scripts set the debug mode and other special globals.
        if self._global.get("debug"):
            self._debug = str(self._global["debug"]).lower() == "true"
        if self._global.get("depth"):
            self._depth = int(self._global["depth"])

        # Consume all the parsed triggers.
        for topic, data in ast["topics"].items():
            # Keep a map of the topics that are included/inherited under this topic.
            if not topic in self._includes:
                self._includes[topic] = {}
            if not topic in self._lineage:
                self._lineage[topic] = {}
            self._includes[topic].update(data["includes"])
            self._lineage[topic].update(data["inherits"])

            # Consume the triggers.
            if not topic in self._topics:
                self._topics[topic] = []
            for trigger in data["triggers"]:
                self._topics[topic].append(trigger)

                # Precompile the regexp for this trigger.
                self._precompile_regexp(trigger["trigger"])

                # Does this trigger have a %Previous? If so, make a pointer to
                # this exact trigger in _thats.
                if trigger["previous"] is not None:
                    if not topic in self._thats:
                        self._thats[topic] = {}
                    if not trigger["trigger"] in self._thats[topic]:
                        self._thats[topic][trigger["trigger"]] = {}
                    self._thats[topic][trigger["trigger"]][trigger["previous"]] = trigger

        # Load all the parsed objects.
        for obj in ast["objects"]:
            # Have a handler for it?
            if obj["language"] in self._handlers:
                self._objlangs[obj["name"]] = obj["language"]
                self._handlers[obj["language"]].load(obj["name"], obj["code"])

Response: Parse the RiveScript source code into memory.


Instruction:
Can you write a function in Python 3 where it
dumps the in - memory RiveScript brain as a JSON - serializable Python data structure.

Response:
def deparse(self):
        """Dump the in-memory RiveScript brain as a Python data structure.

        This would be useful, for example, to develop a user interface for
        editing RiveScript replies without having to edit the RiveScript
        source code directly.

        :return dict: JSON-serializable Python data structure containing the
            contents of all RiveScript replies currently loaded in memory.
        """

        # Data to return.
        result = {
            "begin": {
                "global":   {},
                "var":      {},
                "sub":      {},
                "person":   {},
                "array":    {},
                "triggers": [],
            },
            "topics":  {},
        }

        # Populate the config fields.
        if self._debug:
            result["begin"]["global"]["debug"] = self._debug
        if self._depth != 50:
            result["begin"]["global"]["depth"] = 50

        # Definitions
        result["begin"]["var"]    = self._var.copy()
        result["begin"]["sub"]    = self._sub.copy()
        result["begin"]["person"] = self._person.copy()
        result["begin"]["array"]  = self._array.copy()
        result["begin"]["global"].update(self._global.copy())

        # Topic Triggers.
        for topic in self._topics:
            dest = None  # Where to place the topic info

            if topic == "__begin__":
                # Begin block.
                dest = result["begin"]
            else:
                # Normal topic.
                if topic not in result["topics"]:
                    result["topics"][topic] = {
                        "triggers": [],
                        "includes": {},
                        "inherits": {},
                    }
                dest = result["topics"][topic]

            # Copy the triggers.
            for trig in self._topics[topic]:
                dest["triggers"].append(copy.deepcopy(trig))

            # Inherits/Includes.
            for label, mapping in {"inherits": self._lineage, "includes": self._includes}.items():
                if topic in mapping and len(mapping[topic]):
                    dest[label] = mapping[topic].copy()

        return result


Instruction:
Explain what the following Python 3 code does
def write(self, fh, deparsed=None):

        # Passed a string instead of a file handle?
        if type(fh) is str:
            fh = codecs.open(fh, "w", "utf-8")

        # Deparse the loaded data.
        if deparsed is None:
            deparsed = self.deparse()

        # Start at the beginning.
        fh.write("// Written by rivescript.deparse()\n")
        fh.write("! version = 2.0\n\n")

        # Variables of all sorts!
        for kind in ["global", "var", "sub", "person", "array"]:
            if len(deparsed["begin"][kind].keys()) == 0:
                continue

            for var in sorted(deparsed["begin"][kind].keys()):
                # Array types need to be separated by either spaces or pipes.
                data = deparsed["begin"][kind][var]
                if type(data) not in [str, text_type]:
                    needs_pipes = False
                    for test in data:
                        if " " in test:
                            needs_pipes = True
                            break

                    # Word-wrap the result, target width is 78 chars minus the
                    # kind, var, and spaces and equals sign.
                    # TODO: not implemented yet.
                    # width = 78 - len(kind) - len(var) - 4

                    if needs_pipes:
                        data = self._write_wrapped("|".join(data), sep="|")
                    else:
                        data = " ".join(data)

                fh.write("! {kind} {var} = {data}\n".format(
                    kind=kind,
                    var=var,
                    data=data,
                ))
            fh.write("\n")

        # Begin block.
        if len(deparsed["begin"]["triggers"]):
            fh.write("> begin\n\n")
            self._write_triggers(fh, deparsed["begin"]["triggers"], indent="\t")
            fh.write("< begin\n\n")

        # The topics. Random first!
        topics = ["random"]
        topics.extend(sorted(deparsed["topics"].keys()))
        done_random = False
        for topic in topics:
            if topic not in deparsed["topics"]: continue
            if topic == "random" and done_random: continue
            if topic == "random": done_random = True

            tagged = False  # Used > topic tag

            data = deparsed["topics"][topic]

            if topic != "random" or len(data["includes"]) or len(data["inherits"]):
                tagged = True
                fh.write("> topic " + topic)

                if data["inherits"]:
                    fh.write(" inherits " + " ".join(sorted(data["inherits"].keys())))
                if data["includes"]:
                    fh.write(" includes " + " ".join(sorted(data["includes"].keys())))

                fh.write("\n\n")

            indent = "\t" if tagged else ""
            self._write_triggers(fh, data["triggers"], indent=indent)

            if tagged:
                fh.write("< topic\n\n")

        return True

Response: Writes the currently parsed RiveScript data into a file.


Instruction:
Can you generate the documentation for the following Python 3 function
def _write_triggers(self, fh, triggers, indent=""):

        for trig in triggers:
            fh.write(indent + "+ " + self._write_wrapped(trig["trigger"], indent=indent) + "\n")
            d = trig

            if d.get("previous"):
                fh.write(indent + "% " + self._write_wrapped(d["previous"], indent=indent) + "\n")

            for cond in d["condition"]:
                fh.write(indent + "* " + self._write_wrapped(cond, indent=indent) + "\n")

            if d.get("redirect"):
                fh.write(indent + "@ " + self._write_wrapped(d["redirect"], indent=indent) + "\n")

            for reply in d["reply"]:
                fh.write(indent + "- " + self._write_wrapped(reply, indent=indent) + "\n")

            fh.write("\n")

Response: Writes a list of triggers to a file handle.


Instruction:
How would you explain what the following Python 3 function does
def _write_wrapped(self, line, sep=" ", indent="", width=78):

        words = line.split(sep)
        lines = []
        line  = ""
        buf   = []

        while len(words):
            buf.append(words.pop(0))
            line = sep.join(buf)
            if len(line) > width:
                # Need to word wrap!
                words.insert(0, buf.pop())  # Undo
                lines.append(sep.join(buf))
                buf = []
                line = ""

        # Straggler?
        if line:
            lines.append(line)

        # Returned output
        result = lines.pop(0)
        if len(lines):
            eol = ""
            if sep == " ":
                eol = "\s"
            for item in lines:
                result += eol + "\n" + indent + "^ " + item

        return result

Response: Word - wrap a line of text for being written to a file.


Instruction:
Make a summary of the following Python 3 code
def sort_replies(self, thats=False):
        # (Re)initialize the sort cache.
        self._sorted["topics"] = {}
        self._sorted["thats"]  = {}
        self._say("Sorting triggers...")

        # Loop through all the topics.
        for topic in self._topics.keys():
            self._say("Analyzing topic " + topic)

            # Collect a list of all the triggers we're going to worry about.
            # If this topic inherits another topic, we need to recursively add
            # those to the list as well.
            alltrig = inherit_utils.get_topic_triggers(self, topic, False)

            # Sort them.
            self._sorted["topics"][topic] = sorting.sort_trigger_set(alltrig, True, self._say)

            # Get all of the %Previous triggers for this topic.
            that_triggers = inherit_utils.get_topic_triggers(self, topic, True)

            # And sort them, too.
            self._sorted["thats"][topic] = sorting.sort_trigger_set(that_triggers, False, self._say)

        # And sort the substitution lists.
        if not "lists" in self._sorted:
            self._sorted["lists"] = {}
        self._sorted["lists"]["sub"] = sorting.sort_list(self._sub.keys())
        self._sorted["lists"]["person"] = sorting.sort_list(self._person.keys())

Response: Sort the loaded triggers in memory and the associated topic and person triggers.


Instruction:
Implement a function in Python 3 to
define a custom language handler for RiveScript objects.

Response:
def set_handler(self, language, obj):
        """Define a custom language handler for RiveScript objects.

        Pass in a ``None`` value for the object to delete an existing handler (for
        example, to prevent Python code from being able to be run by default).

        Look in the ``eg`` folder of the rivescript-python distribution for
        an example script that sets up a JavaScript language handler.

        :param str language: The lowercased name of the programming language.
            Examples: python, javascript, perl
        :param class obj: An instance of an implementation class object.
            It should provide the following interface::

                class MyObjectHandler:
                    def __init__(self):
                        pass
                    def load(self, name, code):
                        # name = the name of the object from the RiveScript code
                        # code = the source code of the object
                    def call(self, rs, name, fields):
                        # rs     = the current RiveScript interpreter object
                        # name   = the name of the object being called
                        # fields = array of arguments passed to the object
                        return reply
        """

        # Allow them to delete a handler too.
        if obj is None:
            if language in self._handlers:
                del self._handlers[language]
        else:
            self._handlers[language] = obj


Instruction:
Can you generate the documentation for the following Python 3 function
def set_subroutine(self, name, code):

        # Do we have a Python handler?
        if 'python' in self._handlers:
            self._handlers['python']._objects[name] = code
            self._objlangs[name] = 'python'
        else:
            self._warn("Can't set_subroutine: no Python object handler!")

Response: Define a Python object from your program.


Instruction:
Implement a Python 3 function for
setting a global variable.

Response:
def set_global(self, name, value):
        """Set a global variable.

        Equivalent to ``! global`` in RiveScript code.

        :param str name: The name of the variable to set.
        :param str value: The value of the variable.
            Set this to ``None`` to delete the variable.
        """
        if value is None:
            # Unset the variable.
            if name in self._global:
                del self._global[name]
        self._global[name] = value


Instruction:
Implement a function in Python 3 to
set a bot variable.

Response:
def set_variable(self, name, value):
        """Set a bot variable.

        Equivalent to ``! var`` in RiveScript code.

        :param str name: The name of the variable to set.
        :param str value: The value of the variable.
            Set this to ``None`` to delete the variable.
        """
        if value is None:
            # Unset the variable.
            if name in self._var:
                del self._var[name]
        self._var[name] = value


Instruction:
Create a Python 3 function to
set a substitution. Equivalent to ``! sub`` in RiveScript code. :param str what: The original text to replace. :param str rep: The text to replace it with. Set this to ``None`` to delete the substitution.

Response:
def set_substitution(self, what, rep):
        """Set a substitution.

        Equivalent to ``! sub`` in RiveScript code.

        :param str what: The original text to replace.
        :param str rep: The text to replace it with.
            Set this to ``None`` to delete the substitution.
        """
        if rep is None:
            # Unset the variable.
            if what in self._subs:
                del self._subs[what]
        self._subs[what] = rep


Instruction:
Can you generate a brief explanation for the following Python 3 code
def set_person(self, what, rep):
        if rep is None:
            # Unset the variable.
            if what in self._person:
                del self._person[what]
        self._person[what] = rep

Response: Set a person substitution.


Instruction:
Create a Python 3 function for
setting a variable for a user.

Response:
def set_uservar(self, user, name, value):
        """Set a variable for a user.

        This is like the ``<set>`` tag in RiveScript code.

        :param str user: The user ID to set a variable for.
        :param str name: The name of the variable to set.
        :param str value: The value to set there.
        """
        self._session.set(user, {name: value})


Instruction:
Write a Python 3 function that can
set many variables for a user or many users.

Response:
def set_uservars(self, user, data=None):
        """Set many variables for a user, or set many variables for many users.

        This function can be called in two ways::

            # Set a dict of variables for a single user.
            rs.set_uservars(username, vars)

            # Set a nested dict of variables for many users.
            rs.set_uservars(many_vars)

        In the first syntax, ``vars`` is a simple dict of key/value string
        pairs. In the second syntax, ``many_vars`` is a structure like this::

            {
                "username1": {
                    "key": "value",
                },
                "username2": {
                    "key": "value",
                },
            }

        This way you can export *all* user variables via ``get_uservars()``
        and then re-import them all at once, instead of setting them once per
        user.

        :param optional str user: The user ID to set many variables for.
            Skip this parameter to set many variables for many users instead.
        :param dict data: The dictionary of key/value pairs for user variables,
            or else a dict of dicts mapping usernames to key/value pairs.

        This may raise a ``TypeError`` exception if you pass it invalid data
        types. Note that only the standard ``dict`` type is accepted, but not
        variants like ``OrderedDict``, so if you have a dict-like type you
        should cast it to ``dict`` first.
        """

        # Check the parameters to see how we're being used.
        if type(user) is dict and data is None:
            # Setting many variables for many users.
            for uid, uservars in user.items():
                if type(uservars) is not dict:
                    raise TypeError(
                        "In set_uservars(many_vars) syntax, the many_vars dict "
                        "must be in the format of `many_vars['username'] = "
                        "dict(key=value)`, but the contents of many_vars['{}']"
                        " is not a dict.".format(uid)
                    )

                self._session.set(uid, uservars)

        elif type(user) in [text_type, str] and type(data) is dict:
            # Setting variables for a single user.
            self._session.set(user, data)

        else:
            raise TypeError(
                "set_uservars() may only be called with types ({str}, dict) or "
                "(dict<{str}, dict>) but you called it with types ({a}, {b})"
                .format(
                    str="unicode" if sys.version_info[0] < 3 else "str",
                    a=type(user),
                    b=type(data),
                ),
            )


Instruction:
Implement a Python 3 function for
getting a user variable about a user.

Response:
def get_uservar(self, user, name):
        """Get a variable about a user.

        :param str user: The user ID to look up a variable for.
        :param str name: The name of the variable to get.

        :return: The user variable, or ``None`` or ``"undefined"``:

            * If the user has no data at all, this returns ``None``.
            * If the user doesn't have this variable set, this returns the
              string ``"undefined"``.
            * Otherwise this returns the string value of the variable.
        """
        if name == '__lastmatch__':  # Treat var `__lastmatch__` since it can't receive "undefined" value
            return self.last_match(user)
        else:
            return self._session.get(user, name)


Instruction:
Can you create a Python 3 function that
gets all the user variables about a user.

Response:
def get_uservars(self, user=None):
        """Get all variables about a user (or all users).

        :param optional str user: The user ID to retrieve all variables for.
            If not passed, this function will return all data for all users.

        :return dict: All the user variables.

            * If a ``user`` was passed, this is a ``dict`` of key/value pairs
              of that user's variables. If the user doesn't exist in memory,
              this returns ``None``.
            * Otherwise, this returns a ``dict`` of key/value pairs that map
              user IDs to their variables (a ``dict`` of ``dict``).
        """

        if user is None:
            # All the users!
            return self._session.get_all()
        else:
            # Just this one!
            return self._session.get_any(user)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def clear_uservars(self, user=None):

        if user is None:
            # All the users!
            self._session.reset_all()
        else:
            # Just this one.
            self._session.reset(user)

Response: Delete all variables about a user or all users.


Instruction:
Can you tell what is the following Python 3 function doing
def trigger_info(self, trigger=None, dump=False):
        if dump:
            return self._syntax

        response = None

        # Search the syntax tree for the trigger.
        for category in self._syntax:
            for topic in self._syntax[category]:
                if trigger in self._syntax[category][topic]:
                    # We got a match!
                    if response is None:
                        response = list()
                    fname, lineno = self._syntax[category][topic][trigger]['trigger']
                    response.append(dict(
                        category=category,
                        topic=topic,
                        trigger=trigger,
                        filename=fname,
                        line=lineno,
                    ))

        return response

Response: Get information about a specific trigger.


Instruction:
Can you generate the documentation for the following Python 3 function
def current_user(self):
        if self._brain._current_user is None:
            # They're doing it wrong.
            self._warn("current_user() is meant to be used from within a Python object macro!")
        return self._brain._current_user

Response: Retrieve the user ID of the current user talking to your bot.


Instruction:
Implement a function in Python 3 to
fetch a reply from the RiveScript brain.

Response:
def reply(self, user, msg, errors_as_replies=True):
        """Fetch a reply from the RiveScript brain.

        Arguments:
            user (str): A unique user ID for the person requesting a reply.
                This could be e.g. a screen name or nickname. It's used internally
                to store user variables (including topic and history), so if your
                bot has multiple users each one should have a unique ID.
            msg (str): The user's message. This is allowed to contain
                punctuation and such, but any extraneous data such as HTML tags
                should be removed in advance.
            errors_as_replies (bool): When errors are encountered (such as a
                deep recursion error, no reply matched, etc.) this will make the
                reply be a text representation of the error message. If you set
                this to ``False``, errors will instead raise an exception, such as
                a ``DeepRecursionError`` or ``NoReplyError``. By default, no
                exceptions are raised and errors are set in the reply instead.

        Returns:
            str: The reply output.
        """
        return self._brain.reply(user, msg, errors_as_replies)


Instruction:
Can you tell what is the following Python 3 function doing
def _precompile_substitution(self, kind, pattern):
        if pattern not in self._regexc[kind]:
            qm = re.escape(pattern)
            self._regexc[kind][pattern] = {
                "qm": qm,
                "sub1": re.compile(r'^' + qm + r'$'),
                "sub2": re.compile(r'^' + qm + r'(\W+)'),
                "sub3": re.compile(r'(\W+)' + qm + r'(\W+)'),
                "sub4": re.compile(r'(\W+)' + qm + r'$'),
            }

Response: Pre - compile the regexp for a substitution pattern.


Instruction:
Can you generate the documentation for the following Python 3 function
def _dump(self):
        pp = pprint.PrettyPrinter(indent=4)

        print("=== Variables ===")
        print("-- Globals --")
        pp.pprint(self._global)
        print("-- Bot vars --")
        pp.pprint(self._var)
        print("-- Substitutions --")
        pp.pprint(self._sub)
        print("-- Person Substitutions --")
        pp.pprint(self._person)
        print("-- Arrays --")
        pp.pprint(self._array)

        print("=== Topic Structure ===")
        pp.pprint(self._topics)
        print("=== %Previous Structure ===")
        pp.pprint(self._thats)

        print("=== Includes ===")
        pp.pprint(self._includes)

        print("=== Inherits ===")
        pp.pprint(self._lineage)

        print("=== Sort Buffer ===")
        pp.pprint(self._sorted)

        print("=== Syntax Tree ===")
        pp.pprint(self._syntax)

Response: For debugging dump the entire data structure.