import operator
import unittest

from sklearn import preprocessing

from featurebox.symbol.calculation.coefficient import try_add_coef
from featurebox.symbol.calculation.translate import general_expr
from featurebox.symbol.functions.dimfunc import dless

from featurebox.symbol.base import CalculatePrecisionSet
from featurebox.symbol.base import SymbolSet
from featurebox.symbol.base import SymbolTree
from featurebox.symbol.gp import cxOnePoint, varAnd, genGrow, staticLimit, mutShrink, selKbestDim
from featurebox.tools.packbox import Toolbox


import time

from numpy import random
from sklearn.datasets import load_boston

from featurebox.symbol.base import SymbolSet, SymbolTree, CalculatePrecisionSet
from featurebox.symbol.functions.dimfunc import dless, Dim
from featurebox.symbol.functions.npfunc import np_map
from featurebox.symbol.calculation.scores import compile_context, calculate_y


if __name__ == "__main__":
    # data
    data = load_boston()
    x = data["data"]
    y = data["target"]
    c = [6, 3, 4]
    # unit
    from sympy.physics.units import kg

    x_u = [kg] * 13
    y_u = kg
    c_u = [dless, dless, dless]

    x, x_dim = Dim.convert_x(x, x_u, target_units=None, unit_system="SI")
    y, y_dim = Dim.convert_xi(y, y_u)
    c, c_dim = Dim.convert_x(c, c_u)

    sc = preprocessing.MinMaxScaler((1,2))
    x = sc.fit_transform(x)
    t  = time.time()

    # symbolset
    pset0 = SymbolSet()
    pset0.add_features(x, y, x_dim=x_dim, y_dim=y_dim, x_group=2,
                       feature_name=["Ss%i" % i for i in range(13)])
    pset0.add_constants(c, c_dim=c_dim, c_prob=None)
    pset0.add_operations(power_categories=(2,3,4),
                         categories=("Add", "Mul", "Sub", "Div", "ln","exp"),
                         self_categories=None)


    pset0 = CalculatePrecisionSet(pset0, scoring=None, score_pen=(1,), filter_warning=True, cal_dim=False,
                                  dim_type=None,
                                  fuzzy=False, add_coef=False, inter_add=True,
                                  inner_add=False, n_jobs=1, batch_size=20,
                                  tq=True)
    sl = [SymbolTree.genGrow(pset0, 3, 4) for _ in range(50)]
    sll =[compile_context(o, pset0.context, pset0.gro_ter_con, simplify=True) for o  in sl]

    slll =[try_add_coef(i, pset0.data_x, pset0.y, pset0.terminals_and_constants_repr,
                 filter_warning=True, inter_add=True, inner_add=False, vector_add=True, np_maps=np_map())[1]
                for i in sll]
    sllll = [general_expr(o, pset0, simplifying=False) for o in slll]
    # tree="MSub(exp(gx5))"
    # sll = compile_context(tree, pset0.context, pset0.gro_ter_con, simplify=True)
    # slll = try_add_coef(sll, pset0.data_x, pset0.y, pset0.terminals_and_constants_repr,
    #               filter_warning=True, inter_add=False, inner_add=False, vector_add=True, np_maps=np_map())[1]
    # sllll=general_expr(slll, pset0, simplifying=False)
