"""Authored fitted one-feature stumps, frozen during exhaustive column permutations."""
from itertools import permutations
from fractions import Fraction as F
import json
TRAIN_X=[(x,x,i%2) for i,x in enumerate([-4,-3,-2,-1,1,2,3,4])]
TRAIN_Y=[0,0,0,0,1,1,1,1]
VALID_X=[(-3,-3,0),(-.5,-.5,1),(.5,.5,0),(3,3,1)]
VALID_Y=[0,0,1,1]
def fit_one_feature(j):
    values=sorted({r[j] for r in TRAIN_X});choices=[]
    for a,b in zip(values,values[1:]):
        t=(a+b)/2
        for low,high in [(0,1),(1,0)]:
            errors=sum((low if row[j]<=t else high)!=y for row,y in zip(TRAIN_X,TRAIN_Y))
            choices.append((errors,t,low,high))
    errors,t,low,high=min(choices)
    return j,t,low,high
def score(model,rows):
    j,t,lo,hi=model
    return F(sum((lo if row[j]<=t else hi)==y for row,y in zip(rows,VALID_Y)),len(VALID_Y))
def inspect(model):
    base=score(model,VALID_X);columns=[]
    for j in range(3):
        scores=[]
        for order in permutations(range(4)):
            changed=[tuple(VALID_X[order[i]][k] if k==j else VALID_X[i][k] for k in range(3)) for i in range(4)]
            scores.append(score(model,changed))
        mean=sum(scores,F(0))/len(scores)
        columns.append({'column':j,'permutations':len(scores),'mean_shuffled_accuracy':str(mean),'importance_accuracy_drop':str(base-mean)})
    return {'model':model,'baseline_validation_accuracy':str(base),'columns':columns}
def demo():
    a=fit_one_feature(0);b=fit_one_feature(1);before=(a,b);ra,rb=inspect(a),inspect(b)
    assert a==(0,0.0,0,1) and b==(1,0.0,0,1)
    assert [x['importance_accuracy_drop'] for x in ra['columns']]==['1/2','0','0']
    assert [x['importance_accuracy_drop'] for x in rb['columns']]==['0','1/2','0']
    assert (a,b)==before
    predict=lambda m:[m[2] if row[m[0]]<=m[1] else m[3] for row in VALID_X]
    assert predict(a)==predict(b)==VALID_Y
    return {'train_rows':8,'validation_rows':4,'fixture_is_authored':True,'perfectly_correlated_columns':[0,1],'model_A':ra,'model_B':rb,'model_fit_calls':2,'refit_during_permutation':False,'permutation_evaluations':144,'causal_effect_measured':False}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=False,indent=2))
