import collections
import itertools
import random

from deap import base, creator, tools, algorithms

import actor
import keyboard


def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = itertools.tee(iterable)
    next(b, None)
    return zip(a, b)


### INTERNAL Stuff ###

kb = keyboard.SixKey()
keys = sorted(kb.keys)
ac = actor.SingleFinger()
alphabet = 'abcdef'

text = ''.join(random.choice(alphabet) for _ in range(2**10))
corpus = collections.Counter(pairwise(text))


### DEAP Stuff ###
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)

toolbox = base.Toolbox()
toolbox.register("attr_layout", lambda: random.sample(range(len(alphabet)), len(alphabet)))
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_layout)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("evaluate", lambda l: (ac.evaluate(kb, l, alphabet, corpus),))
toolbox.register("mate", tools.cxPartialyMatched)
toolbox.register("mutate", tools.mutShuffleIndexes, indpb=0.1)
toolbox.register("select", tools.selTournament, tournsize=3)


def main():
    import numpy
    pop = toolbox.population(n=50)
    hof = tools.HallOfFame(1)
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", numpy.mean)
    stats.register("min", numpy.min)
    stats.register("max", numpy.max)

    pop, logbook = algorithms.eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=10, stats=stats, halloffame=hof, verbose=True)

    return pop, logbook, hof

if __name__ == "__main__":
    pop, log, hof = main()
    print("Best individual is: %s\nwith fitness: %s" % (hof[0], hof[0].fitness))

    import matplotlib.pyplot as plt
    gen, avg, min_, max_ = log.select("gen", "avg", "min", "max")
    plt.plot(gen, avg, label="average")
    plt.plot(gen, min_, label="minimum")
    plt.plot(gen, max_, label="maximum")
    plt.xlabel("Generation")
    plt.ylabel("Fitness")
    plt.legend(loc="lower right")
    plt.show()

@@ -130,20 +130,18 @@
 d%0A%0A%0Adef 
-pair
+n_
 wise(ite
@@ -149,99 +149,179 @@
 able
+, n
 ):%0A    
-%22s -%3E (s0,s1), (s1,s2), (s2, s3), ...%22%0A    a, b = itertools.tee(iterable)%0A    next(b
+iterables = itertools.tee(iterable, n)%0A    for i in range(1, n):%0A        to_be_advanced = iterables%5Bi%5D%0A        for _ in range(i):%0A            next(to_be_advanced
 , No
@@ -343,12 +343,18 @@
 zip(
-a, b
+*iterables
 )%0A%0A%0A
@@ -565,12 +565,10 @@
 ter(
-pair
+n_
 wise
@@ -572,16 +572,19 @@
 ise(text
+, 2
 ))%0A%0A%0A###

Change pairwise function to allow n_wise iteration