def test_gene_to_frames(self):
        fdm = FrameDistanceClipMocker()
        gfd = GeneticFrameDistance(fdm, 1, 10)

        self.assertEqual(gfd.min_f, 30)
        self.assertEqual(gfd.max_f, 300)

        # frames =  3 000 000
        # min_f  =         30
        # max_f  =        300
        # fps    =         30
        #
        # n1 =    507 065 614
        # n2 =         18 829
        #
        # m1 = n1 mod frames          = 65 614
        # m2 = n2 mod (max_f - min_f) =    199
        #
        # f1 = m1         = 65 614
        # f2 = m2 _ min_f =    229
        #
        # t1 = f1 / fps        = 2187.1333
        # t2 = (f1 + f2) / fps = 2194.7667
        frames = gfd.gene_to_frames(0b000111100011100100110101000011100100100110001101)
        self.assertAlmostEqual(frames[0], 2187.1333, delta=1e-04)
        self.assertAlmostEqual(frames[1], 2194.7667, delta=1e-04)
        print(gfd.gene_to_frames(0))
class GeneticGifFinder(object):

    def __init__(self,
                 clip,
                 min_d=None,
                 max_d=None,
                 threshold=None,
                 max_gen=None,
                 popsize=None,
                 mutation_rate=None,
                 elites=None):
        self.clip = mpy.VideoFileClip(clip).resize(width=20)
        self.min_d = 1 if min_d is None else min_d
        self.max_d = 5 if max_d is None else max_d
        self.threshold = 40 if threshold is None else threshold
        self.max_gen = 50 if max_gen is None else max_gen
        self.popsize = 20 if popsize is None else popsize
        self.mutation_rate = 0.001 if mutation_rate is None else mutation_rate
        self.elites = 1 if mutation_rate is None else elites
        self.f = GeneticFrameDistance(self.clip, self.min_d, self.max_d)
        self.selector = ParentSelector(self.popsize)
        self.population = None

    def run(self):
        logging.info("generating population...")
        self.population = GeneticPopulation(self.popsize, self.f)
        generations = 0
        logging.info("starting...")

        # Run first generation without elitism
        self.population.next_generation(self.mutation_rate, self.selector)
        logging.info("Generation {0}: \n{1}\n".format(generations, self.population.generation))
        best_value = self.population.generation.individuals[0].get_y()
        generations += 1

        while generations < self.max_gen and best_value > self.threshold:
            self.population.next_generation(self.mutation_rate, self.selector, self.elites)
            logging.info("Generation {0}: \n{1}\n".format(generations, self.population.generation))
            best_value = self.population.generation.individuals[0].get_y()
            generations += 1

        logging.info("Best clips: \n{0}".format(self.population.generation))
        logging.info("Everything that happened: \n{0}".format(self.population.generations))

    def results_to_gif(self, prefix):
        for i in range(10):
            self.clip.subclip(
                *self.f.gene_to_frames(self.population.generation.individuals[i].x)
            ).write_gif("{0}_{1}.gif".format(prefix, i))
 def __init__(self,
              clip,
              min_d=None,
              max_d=None,
              threshold=None,
              max_gen=None,
              popsize=None,
              mutation_rate=None,
              elites=None):
     self.clip = mpy.VideoFileClip(clip).resize(width=20)
     self.min_d = 1 if min_d is None else min_d
     self.max_d = 5 if max_d is None else max_d
     self.threshold = 40 if threshold is None else threshold
     self.max_gen = 50 if max_gen is None else max_gen
     self.popsize = 20 if popsize is None else popsize
     self.mutation_rate = 0.001 if mutation_rate is None else mutation_rate
     self.elites = 1 if mutation_rate is None else elites
     self.f = GeneticFrameDistance(self.clip, self.min_d, self.max_d)
     self.selector = ParentSelector(self.popsize)
     self.population = None