diff options
Diffstat (limited to 'lulua')
| -rw-r--r-- | lulua/carpalx.py | 103 | ||||
| -rw-r--r-- | lulua/optimize.py | 11 | ||||
| -rw-r--r-- | lulua/plot.py | 4 | ||||
| -rw-r--r-- | lulua/stats.py | 4 | ||||
| -rw-r--r-- | lulua/test_carpalx.py | 4 | 
5 files changed, 113 insertions, 13 deletions
diff --git a/lulua/carpalx.py b/lulua/carpalx.py index 3e104bb..e17b6e4 100644 --- a/lulua/carpalx.py +++ b/lulua/carpalx.py @@ -43,8 +43,9 @@ from .keyboard import Button  ModelParams = namedtuple ('ModelParams', ['kBPS', 'k123S',          'w0HRF', 'pHand', 'pRow', 'pFinger', 'fHRF', 'baselineEffort']) +models = dict (  # model parameters mod_01 from http://mkweb.bcgsc.ca/carpalx/?model_parameters -model01 = ModelParams ( +mod01 = ModelParams (      # k_b, k_p, k_s      kBPS = (0.3555, 0.6423, 0.4268),      # k_1, k_2, k_3 plus extension k_S (weight for simultaneous key presses) @@ -132,7 +133,105 @@ model01 = ModelParams (          'Fr_altgr': 4.0, # XXX: dito          }, -    ) +    ), + +# from paper “Ergonomic Keyboard Layout Designed for the Filipino Language” +salvo = ModelParams ( +    # k_b, k_p, k_s +    # XXX: unchanged from original? +    kBPS = (0.3555, 0.6423, 0.4268), +    # k_1, k_2, k_3 plus extension k_S (weight for simultaneous key presses) +    # XXX: unchanged from original? +    k123S = (1.0, 0.367, 0.235, 1.0), +    # w0, wHand, wRow, wFinger +    # XXX: unchanged from original? +    w0HRF = (0.0, 1.0, 1.3088, 2.5948), +    pHand = {LEFT: 0.0, RIGHT: 0.0}, +    # numbers, top, base, bottom, control (XXX not part of original model) +    # XXX: unchanged from original? +    pRow = (1.5, 0.5, 0.0, 1.0, 1.5), +    # symmetric penalties +    # normalized as suggested by https://normanlayout.info/about.html +    pFinger = { +        LEFT: { +            THUMB: 0.0, # XXX: not part of the original model +            INDEX: 1-(6.09/6.57), +            MIDDLE: 1-(5.65/6.57), +            RING: 1-(4.54/6.57), +            LITTLE: 1-(3.77/6.57), +            }, +        RIGHT: { +            THUMB: 0.0, # XXX: not part of the original model +            INDEX: 1-(6.57/6.57), +            MIDDLE: 1-(6.37/6.57), +            RING: 1-(5.08/6.57), +            LITTLE: 1-(4.27/6.57), +            }, +        }, +    # fHand, fRow, fFinger +    fHRF = (1.0, 0.3, 0.3), +    # baseline key effort +    baselineEffort = { +        # XXX: from model 01, not part of the paper +        'Bl1': 5.0, +        'Bl2': 5.0, +        'Bl3': 4.0, +        'Bl4': 4.0, +        'Bl5': 4.0, +        'Bl6': 3.5, +        'Bl7': 4.5, +        'Br6': 4.0, +        'Br5': 4.0, +        'Br4': 4.0, +        'Br3': 4.0, +        'Br2': 4.0, +        'Br1': 4.5, + +        'Cl1': 2.0, +        'Cl2': 2.0, +        'Cl3': 2.0, +        'Cl4': 2.0, +        'Cl5': 2.3, +        'Cr7': 3.0, +        'Cr6': 1.9, +        'Cr5': 2.0, +        'Cr4': 2.0, +        'Cr3': 2.2, +        'Cr2': 4.0, # XXX: dito +        'Cr1': 6.0, + +        'Dl_caps': 2.0, # XXX: dito +        'Dl1': 0.0, +        'Dl2': 0.0, +        'Dl3': 0.0, +        'Dl4': 0.0, +        'Dl5': 1.8, +        'Dr7': 1.8, +        'Dr6': 0.0, +        'Dr5': 0.0, +        'Dr4': 0.0, +        'Dr3': 0.0, +        'Dr2': 2.0, # XXX: dito +        'Dr1': 4.0, # XXX: dito + +        'El_shift': 4.0,  # XXX: dito +        'El1': 4.0, # XXX: dito +        'El2': 2.0, +        'El3': 2.0, +        'El4': 2.0, +        'El5': 2.0, +        'El6': 3.5, +        'Er5': 2.0, +        'Er4': 2.0, +        'Er3': 2.0, +        'Er2': 2.0, +        'Er1': 2.0, +        'Er_shift': 4.0, # XXX: dito + +        'Fr_altgr': 4.0, # XXX: dito +        }, +    ), +)  def madd (a, b):      """ Given indexables a and b, computes a[0]*b[0]+a[1]*b[1]+… """ diff --git a/lulua/optimize.py b/lulua/optimize.py index 879f531..281f0ab 100644 --- a/lulua/optimize.py +++ b/lulua/optimize.py @@ -32,8 +32,7 @@ tqdm.get_lock().locks = []  import yaml  from .layout import defaultLayouts, ButtonCombination, Layer, KeyboardLayout, GenericLayout -from .carpalx import Carpalx -from .carpalx import model01 as cmodel01 +from .carpalx import Carpalx, models, ModelParams  from .writer import Writer  from .util import first  from .keyboard import defaultKeyboards, LetterButton @@ -147,8 +146,9 @@ class LayoutOptimizer (Annealer):              triads: List[Tuple[ButtonCombination]],              layout: KeyboardLayout,              pins: FrozenSet[Tuple[int, Optional[Text]]], -            writer: Writer): -        carpalx = Carpalx (cmodel01, writer) +            writer: Writer, +            model: ModelParams): +        carpalx = Carpalx (model, writer)          super ().__init__ (LayoutOptimizerState (carpalx, buttonMap))          self.triads = triads @@ -256,6 +256,7 @@ def optimize ():      parser.add_argument('-n', '--steps', type=int, default=10000, help='Number of iterations')      parser.add_argument('-r', '--randomize', action='store_true', help='Randomize layout before optimizing')      parser.add_argument('-p', '--pin', type=parsePin, help='Pin these layers/buttons') +    parser.add_argument('-m', '--model', choices=list (models.keys()), default='mod01', help='Carpalx model')      args = parser.parse_args() @@ -296,7 +297,7 @@ def optimize ():      pins = [(x, keyboard[y] if y else None) for x, y in args.pin] -    opt = LayoutOptimizer (buttonMap, triads, layout, pins, writer) +    opt = LayoutOptimizer (buttonMap, triads, layout, pins, writer, model=models[args.model])      if args.randomize:          logging.info ('randomizing initial layout')          for i in range (len (buttonMap)*2): diff --git a/lulua/plot.py b/lulua/plot.py index 453c6eb..14b9732 100644 --- a/lulua/plot.py +++ b/lulua/plot.py @@ -28,7 +28,7 @@ from .layout import *  from .keyboard import defaultKeyboards  from .util import limit, displayText  from .writer import Writer -from .carpalx import Carpalx, model01 +from .carpalx import Carpalx, models  def letterfreq (args):      """ Map key combinations to their text, bin it and plot sorted distribution """ @@ -124,7 +124,7 @@ def triadfreq (args):      # letter-based binning, in case multiple buttons are mapped to the same      # letter. -    binned = defaultdict (lambda: dict (weight=0, effort=Carpalx (model01, writer), textTriad=None)) +    binned = defaultdict (lambda: dict (weight=0, effort=Carpalx (models['mod01'], writer), textTriad=None))      weightSum = 0      for triad, weight in stats['triads'].triads.items ():          textTriad = tuple (layout.getText (t) for t in triad) diff --git a/lulua/stats.py b/lulua/stats.py index 6689616..4cd20bd 100644 --- a/lulua/stats.py +++ b/lulua/stats.py @@ -26,7 +26,7 @@ from collections import defaultdict  from .layout import *  from .keyboard import defaultKeyboards  from .writer import SkipEvent, Writer -from .carpalx import Carpalx, model01 as cmodel01 +from .carpalx import Carpalx, models  from .plot import letterfreq, triadfreq  def updateDictOp (a, b, op): @@ -217,7 +217,7 @@ def pretty (args):      for triad, count in sorted (stats['triads'].triads.items (), key=itemgetter (1)):          print (f'{triad} {count:10d}') -    effort = Carpalx (cmodel01, writer) +    effort = Carpalx (models['mod01'], writer)      effort.addTriads (stats['triads'].triads)      print ('total effort (carpalx)', effort.effort) diff --git a/lulua/test_carpalx.py b/lulua/test_carpalx.py index ac72a14..1d07763 100644 --- a/lulua/test_carpalx.py +++ b/lulua/test_carpalx.py @@ -20,7 +20,7 @@  import pytest -from .carpalx import Carpalx, model01, ModelParams +from .carpalx import Carpalx, models, ModelParams  from .keyboard import defaultKeyboards  from .layout import defaultLayouts, LEFT, RIGHT, INDEX, MIDDLE, RING, LITTLE  from .writer import Writer @@ -101,7 +101,7 @@ def test_strokePath (t, i, expect):      keyboard = defaultKeyboards['ibmpc105']      layout = defaultLayouts['ar-linux'].specialize (keyboard)      writer = Writer (layout) -    c = Carpalx (model01, writer) +    c = Carpalx (models['mod01'], writer)      t = tuple (map (keyboard.find, t))      assert c._strokePath (t)[i] == expect  | 
