evolve-keyboard-layout /

#!/usr/bin/env python3
# encoding: utf-8

u"""get all layout results from the results folder.

Depends on the layouts info starting with OA'Evolved Layout'

from __future__ import with_statement
from check_neo import string_to_layout, print_layout_with_statistics, csv_data, get_all_data, find_layout_families, total_cost, split_uppercase_trigrams, format_layer_1_string
from os import listdir, mkdir
from os.path import join, isdir
from subprocess import call
from io import open

def get_all_layouts_in_textfile(textfile):
    u"""Get all layouts in the given textfile.

    @return: a list of layout strings."""
    with open(textfile, encoding=u"utf-8") as f:
            d =
        except UnicodeError:
            print u"can’t open", textfile

    # normal result splitting
    if u"Evolved Layout" in d: 
        e = d.split(u"Evolved Layout")
    else: # splitting for sorted best-XX files.
        e = d.split(u"####")
    layout_strings = []
    for i in e[1:]:

    # all_layouts = []
    # for i in layout_strings:
    #     print(i, textfile)
    #     all_layouts.append(string_to_layout(i))
    all_layouts = []
    for l in layout_strings:
        if l.strip(): 
            try: all_layouts.append(string_to_layout(l))
            except IndexError:
                print u"parsing failed for the layout string:"
                print l
    return all_layouts
def get_all_layouts_in_text_files_in(folder=u"results", namepart=u""):
    u"""get all layouts from check_neo runs saved in the textfile."""
    all_layouts = []
    for i in listdir(folder):
        if not i.endswith(u".txt") or not namepart in i:
        print u"# reading", join(folder, i)
        all_layouts.extend(get_all_layouts_in_textfile(join(folder, i))) 

    return all_layouts

if __name__ == u"__main__":

    from optparse import OptionParser

    parser = OptionParser(description=u"recheck all result layouts with the current config.")
    parser.add_option(u"--file", dest=u"data", type=u"string", default=None,
                      help=u"use the given textfile as korpus", metavar=u"file")
    parser.add_option(u"--namepart", dest=u"namepart", type=u"string", default=u"",
                      help=u"read only files whose names contain the given string", metavar=u"string")
    parser.add_option(u"--folder", dest=u"folder", type=u"string", default=u"results",
                      help=u"search for result files in the given folder (no recursions, requires .txt suffix)", metavar=u"string")

                      action=u"store_true", dest=u"print_csv", default=False,
                      help=u"print a csv instead of the normal layout statistics")
                      action=u"store_true", dest=u"svg", default=None,
                      help=u"save an svg file in the folder svgs/ for every printed layout. Can take a long time. You might want to use --families, too.")
                      action=u"store_true", dest=u"families", default=False,
                      help=u"Sort the layouts into families and print only the best layout in each familiy. ")
    parser.add_option(u"--family-threshold", dest=u"family_threshold", type=u"float", default=0.8,
                      help=u"Treat layouts with at most the given difference as belonging to the same family", metavar=u"max_difference")

    (options, args) = parser.parse_args()

    if options.print_csv: 
        print u"total penalty per word;key position cost;finger repeats;disbalance of fingers;top to bottom or vice versa;handswitching in trigram;(rows²/dist)²;shortcut keys;handswitching after unbalancing;movement pattern"

    all_layouts = get_all_layouts_in_text_files_in(folder=options.folder, namepart = options.namepart)

    letters, number_of_letters, repeats, number_of_bigrams, trigrams, number_of_trigrams = get_all_data(
    trigrams = split_uppercase_trigrams(trigrams)

    if options.families:
        # sort the layouts by value, lowest total cost first.
        lays = []
        for lay in all_layouts:
            cost = total_cost(layout=lay, letters=letters, repeats=repeats, trigrams=trigrams)[0]
            lays.append((cost, lay))
            print format_layer_1_string(lay)
        # remove the cost information again.
        lays = [lay for cost, lay in lays]
        layout_families =  find_layout_families(lays, letters, max_diff=options.family_threshold)
        # all layouts should contain only the best from each family.
        all_layouts = [fam[0] for fam in layout_families]
        # make sure the best is shown last

    for lay in all_layouts:
        if options.print_csv:
            csv = [unicode(i) for i in
                   csv_data(lay, letters=letters, repeats=repeats, number_of_letters=number_of_letters, number_of_bigrams=number_of_bigrams, trigrams=trigrams, number_of_trigrams=number_of_trigrams)]
            print u";".join(csv)
            print u"# Evolved Layout"
            print_layout_with_statistics(lay, verbose=True, letters=letters, repeats=repeats, number_of_letters=number_of_letters, number_of_bigrams=number_of_bigrams, trigrams=trigrams, number_of_trigrams=number_of_trigrams)
                textfile =
                if textfile is None:
                    textfile = "beispieltext-prosa.txt"
                call(["./", "-t", textfile, "-l", format_layer_1_string(lay)])

        if options.svg:
            if not isdir(u"svgs"):
            cost = total_cost(layout=lay, letters=letters, repeats=repeats, trigrams=trigrams)[0]
            cost = unicode(cost)
            cost = u"0"*max(0, 10-len(cost)) + cost
            name_lines = format_layer_1_string(lay).splitlines()
            name = u"-".join((name_lines[1], name_lines[0], name_lines[2])) + u".svg"
            name = name.replace(u" ", u"_")
            name = cost + u"-" + name
            name = join(u"svgs", name)
            from bigramm_statistik import print_bigram_info
            print_bigram_info(layout=lay, number=1000, svg=True, svg_output=name,