4 """Run a full evolution of keyboard layouts."""
6 from optparse
import OptionParser
10 #: The number of new layouts to create. Can be overwritten with the -n parameter.
13 #: The output filename. Can be overwritten with the -o parameter.
14 filename
= "output.txt" # None for shell output
16 #: The number of random evolution steps to take.
19 #: The number of random mutations to do before the evolution to get a random layout
22 #: Should we always do the locally best step (very slow and *not* optimal)
25 #: Should we spout out information on the shell? (Windows users disable this. Your shell can’t take Unicode)
28 #: Should we give additional statistics for the final layout?
31 #: Should we finalize the layout with as many controlled steps as needed, so a single keyswitch can’t improve it further?
32 controlled_tail
= True
34 #: Should we use annealing? How many steps? Per step it adds one switch, so anneal 5 starts with 6 switches aka changing half the layout (12 keys).
36 #: The number of iterations to spend in one anneal level. The first anneal * anneal_step iterations are spent in simulated annealing.
39 #: The layout to use as base for mutations. If you want a given starting layout, also set prerandomize = 0.
40 STARTING_LAYOUT
= """xvlcw khgfqß´
45 ### Parse console arguments
47 parser
= OptionParser(usage
= "evolutionary running script", version
= "0.1")
48 parser
.add_option("-o", "--output", type="string", dest
="filename", default
=filename
, help="set outputfile")
49 parser
.add_option("-n", "--number", type="int", dest
="evolution_steps", default
=num_layouts
, help="number of steps")
50 parser
.add_option("-f", "--file", type="string", dest
="data",
51 default
=None, help="use the given textfile as korpus instead of the ngram files.", metavar
="filepath")
53 (options
, args
) = parser
.parse_args()
56 with
open(options
.data
) as f
:
57 options
.data
= f
.read()
61 # Hack to make the script output to a file instead of the shell (necessary for windows users).
62 # MUST come before the imports from check_neo.
63 if filename
is not None:
66 sys
.argv
.append(options
.filename
)
68 from check_neo
import evolve_a_layout
, string_to_layout
70 from datetime
import timedelta
71 STARTING_LAYOUT
= string_to_layout(STARTING_LAYOUT
)
73 print("# Starting the evolution.")
76 for step
in range(options
.evolution_steps
):
77 evolve_a_layout(steps
,
83 starting_layout
=STARTING_LAYOUT
,
86 anneal_step
= anneal_step
)
87 print(step
+1, "/", options
.evolution_steps
,
88 timedelta(seconds
=time()-t
))