From c48cd90050ba8edc389a2081513ae276fcf431cc Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sat, 25 Apr 2020 20:11:05 +0200 Subject: optimize: Allow manual mutations In combination with `-n 0` this allows manual evaluation of changes without using `lulua-write` to re-evaluate the entire corpus. --- lulua/optimize.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/lulua/optimize.py b/lulua/optimize.py index 517f656..facba17 100644 --- a/lulua/optimize.py +++ b/lulua/optimize.py @@ -260,6 +260,12 @@ def parsePin (s: Text): pins.append ((layer, button)) return frozenset (pins) +def parseMutation (s: Text): + a, b = s.split (':') + a1, a2 = a.split (',') + b1, b2 = b.split (',') + return (int (a1), a2), (int (b1), b2) + def optimize (): parser = argparse.ArgumentParser(description='Optimize keyboard layout.') parser.add_argument('-l', '--layout', metavar='LAYOUT', help='Keyboard layout name') @@ -271,6 +277,7 @@ def optimize (): parser.add_argument('-r', '--randomize', action='store_true', help='Randomize layout before optimizing') parser.add_argument('-p', '--pin', default=[], type=parsePin, help='Pin these layers/buttons') parser.add_argument('-m', '--model', choices=list (models.keys()), default='mod01', help='Carpalx model') + parser.add_argument('-s', '--mutate', type=parseMutation, default=[], action='append', help='Apply these mutations') args = parser.parse_args() @@ -308,6 +315,13 @@ def optimize (): keys.append ((i, k)) values.append ((i, k)) buttonMap = dict (zip (keys, values)) + + # apply mutation + for (i, a), (j, b) in args.mutate: + logging.info (f'mutating {i},{a} to {j},{b}') + a = (i, keyboard[a]) + b = (j, keyboard[b]) + buttonMap[b], buttonMap[a] = buttonMap[a], buttonMap[b] pins = [] for layer, match in args.pin: @@ -333,7 +347,7 @@ def optimize (): except KeyboardInterrupt: logging.info ('interrupted') return 1 - + # plausibility checks: 1:1 mapping for every button assert set (optimalButtonMap.keys ()) == set (optimalButtonMap.values ()) opt._resetEnergy () @@ -345,16 +359,20 @@ def optimize (): for i, l in enumerate (layout.layers): for m in l.modifier: layers[i].modifier.append ([k.name for k in m]) - for k, v in l.layout.items (): + for k in keyboard.keys (): try: (newLayer, newK) = optimalButtonMap[(i, k)] except KeyError: # not found, probably not used and thus not mapped - print ('key', i, k, 'not in mapping table, assuming id()', file=sys.stderr) - layers[i].layout[k.name] = v - else: - assert newK not in layers[newLayer].layout - layers[newLayer].layout[newK.name] = v + logging.warning (f'key {i} {k} not in mapping table, assuming id()') + newLayer, newK = i, k + + assert newK not in layers[newLayer].layout + try: + layers[newLayer].layout[newK.name] = layout.getText (ButtonCombination (layout.layers[i].modifier[0], frozenset ([k]))) + except KeyError: + # key is not used in input layout + logging.info (f'key {i} {k} has no mapping in the original layout') newLayout = GenericLayout (f'{layout.name}-new', layers) print (f'# steps: {args.steps}\n# keyboard: {args.keyboard}\n# layout: {args.layout}\n# triads: {len (triads)}\n# energy: {energy}') -- cgit v1.2.3