summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--doc/index.html34
-rw-r--r--doc/style.css35
-rwxr-xr-xgen.sh34
-rw-r--r--lulua/stats.py40
5 files changed, 114 insertions, 35 deletions
diff --git a/.gitignore b/.gitignore
index 62a43bc..41a91da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,10 +3,8 @@ __pycache__
.eggs/
.coverage
.mypy_cache/
-doc/*.svg
-doc/*.yaml
-doc/*.xmodmap
-doc/letterfreq.json
+doc/_build
+doc/_temp
.ninja_*
build.ninja
stats/
diff --git a/doc/index.html b/doc/index.html
index e5f7973..f9daf88 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -178,18 +178,9 @@
<figure id="ar-lulua-heat">
<div class="lbox" lang="en">
<img src="ar-lulua-heat.svg">
+ #include "ar-lulua-fingerhand.html"
</div>
-<figcaption class="pure-g flexreverse">
- <div class="pure-u-1 pure-u-md-1-2">
- </div>
- <div class="pure-u-1 pure-u-md-1-2" lang="en">
- <div class="lbox">
- <p>Button heatmap</p>
- </div>
- </div>
-</figcaption>
</figure>
-</section>
<section class="layoutgallery">
<div class="pure-g flexreverse">
@@ -205,6 +196,7 @@
<figure id="ar-asmo663">
<div class="lbox">
<img src="ar-asmo663-heat.svg">
+ #include "ar-asmo663-fingerhand.html"
</div>
<figcaption class="pure-g flexreverse">
<div class="pure-u-1 pure-u-md-1-2">
@@ -229,6 +221,7 @@
<figure id="ar-linux">
<div class="lbox">
<img src="ar-linux-heat.svg">
+ #include "ar-linux-fingerhand.html"
</div>
<figcaption class="pure-g flexreverse">
<div class="pure-u-1 pure-u-md-1-2">
@@ -253,6 +246,7 @@
<figure id="ar-malas">
<div class="lbox">
<img src="ar-malas-heat.svg">
+ #include "ar-malas-fingerhand.html"
</div>
<figcaption class="pure-g flexreverse">
<div class="pure-u-1 pure-u-md-1-2">
@@ -268,10 +262,12 @@
optimized for typing speed only, claiming 35% faster typing compared
to the <a href="#ar-linux">currently used layouts</a>.
<!-- -->
- However the choice to put <bdo dir="ltr" lang="ar">ي</bdo> in the top
- row seems odd and suggests the authors did not take the time to review
- the layout manually, given this letter is the third most frequent one
- even in their own research.
+ However the decision to put <bdo dir="ltr" lang="ar">ي</bdo> in the top
+ row seems odd.
+ <!-- -->
+ Assigning the same left index finger to <bdo dir="ltr" lang="ar">ا
+ ي و</bdo>, which are three of the most frequent letters, heavily
+ strains this particular finger.
</p>
</div>
</div>
@@ -281,6 +277,7 @@
<figure id="ar-osman">
<div class="lbox">
<img src="ar-osman-heat.svg">
+ #include "ar-osman-fingerhand.html"
</div>
<figcaption class="pure-g flexreverse">
<div class="pure-u-1 pure-u-md-1-2">
@@ -313,6 +310,7 @@
<figure>
<div class="lbox">
<img src="ar-khorshid-heat.svg">
+ #include "ar-khorshid-fingerhand.html"
</div>
<figcaption class="pure-g flexreverse">
<div class="pure-u-1 pure-u-md-1-2">
@@ -328,8 +326,11 @@
They claim a 36% improvement over the standard keyboard based on
their criteria for ergonomic layouts.
<!-- -->
- However in their layout from figure 8 both letters <bdo dir="ltr"
- lang="ar">ب ر</bdo> are in suboptimal positions.
+ However in their layout from figure 8 the letters <bdo dir="ltr"
+ lang="ar">ل ب ر</bdo> are in suboptimal positions.
+ <!-- -->
+ Also it seems their algorithm favors the bottom row instead of the
+ easier to use top row.
</p>
</div>
</div>
@@ -339,6 +340,7 @@
<figure>
<div class="lbox">
<img src="ar-phonetic-heat.svg">
+ #include "ar-phonetic-fingerhand.html"
</div>
<figcaption class="pure-g flexreverse">
<div class="pure-u-1 pure-u-md-1-2">
diff --git a/doc/style.css b/doc/style.css
index 5aa9a55..0f137c4 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -106,3 +106,38 @@ div.indepth-card {
.lbox {
margin: 0 5vw;
}
+/* for hand/finger stats */
+div.fingerhandstats {
+ text-align: center;
+ display: flex;
+}
+div.fingerhandstats div.fingers {
+ display: flex;
+}
+div.fingerhandstats div.fingers div {
+ margin: 0.1em;
+ overflow: hidden;
+}
+div.fingerhandstats .left {
+ margin-right: 0.5em;
+}
+div.fingerhandstats .right {
+ margin-left: 0.5em;
+}
+/* keep in sync with render-svg.css */
+div.fingerhandstats .fingers .little {
+ border: 0.1em solid #dc322f; /* red */
+}
+div.fingerhandstats .fingers .ring {
+ border: 0.1em solid #268bd2; /* blue */
+}
+div.fingerhandstats .fingers .middle {
+ border: 0.1em solid #d33682; /* magenta */
+}
+div.fingerhandstats .fingers .index {
+ border: 0.1em solid #6c71c4; /* violet */
+}
+div.fingerhandstats .fingers .thumb {
+ border: 0.1em solid #2aa198; /* cyan */
+}
+
diff --git a/gen.sh b/gen.sh
index b9b9028..77fbf81 100755
--- a/gen.sh
+++ b/gen.sh
@@ -64,9 +64,28 @@ rule mkdir
rule letterfreq
command = lulua-analyze -l ar-lulua letterfreq < \$in > \$out
-### build targets ###
-build \$docdir/letterfreq.json: letterfreq \$statsdir/ar-lulua/all.pickle
+rule analyze-fingerhand
+ command = lulua-analyze -l \$layout fingerhand < \$in > \$out
+
+rule cpp
+ command = gcc -E -x c -nostdinc -MMD -MF \$out.d -C -P -I \$docdir/_temp \$in -o \$out
+ depfile = \$out.d
+ deps = gcc
+
+rule cp
+ command = cp \$in \$out
+### build targets ###
+build \$docdir/_build: mkdir
+build \$docdir/_build/fonts: mkdir
+build \$docdir/_temp: mkdir
+
+build \$docdir/_build/index.html: cpp \$docdir/index.html || \$docdir/_build
+build \$docdir/_build/letterfreq.json: letterfreq \$statsdir/ar-lulua/all.pickle || \$docdir/_build
+build \$docdir/_build/style.css: cp \$docdir/style.css || \$docdir/_build
+build \$docdir/_build/lulua-logo.svg: cp \$docdir/lulua-logo.svg || \$docdir/_build
+build \$docdir/_build/fonts/IBMPlexArabic-Regular.woff2: cp \$docdir/fonts/IBMPlexArabic-Regular.woff2 || \$docdir/_build/fonts
+build \$docdir/_build/fonts/IBMPlexArabic-Thin.woff2: cp \$docdir/fonts/IBMPlexArabic-Thin.woff2 || \$docdir/_build/fonts
EOF
for l in $layouts; do
@@ -87,13 +106,16 @@ build \$statsdir/${l}/arwiki.pickle: write-arwiki \$corpusdir/arwiki/arwiki-2019
build \$statsdir/${l}/all.pickle: combine \$statsdir/${l}/bbcarabic.pickle \$statsdir/${l}/aljazeera.pickle \$statsdir/${l}/tanzil.pickle \$statsdir/${l}/arwiki.pickle || \$statsdir/${l}
-build \$docdir/${l}.svg: render-svg
+build \$docdir/_build/${l}.svg: render-svg || \$docdir/_build
+ layout = ${l}
+
+build \$docdir/_temp/${l}-heat.yaml: analyze-heat \$statsdir/${l}/all.pickle || \$docdir/_temp
layout = ${l}
-build \$docdir/${l}-heat.yaml: analyze-heat \$statsdir/${l}/all.pickle
+build \$docdir/_build/${l}-heat.svg: render-svg-heat \$docdir/_temp/${l}-heat.yaml || \$docdir/_build
layout = ${l}
-build \$docdir/${l}-heat.svg: render-svg-heat \$docdir/${l}-heat.yaml
+build \$docdir/_temp/${l}-fingerhand.html: analyze-fingerhand \$statsdir/${l}/all.pickle || \$docdir/_temp
layout = ${l}
EOF
@@ -101,7 +123,7 @@ done
for l in $layoutsXmodmap; do
cat <<EOF
-build \$docdir/${l}.xmodmap: render-xmodmap
+build \$docdir/_build/${l}.xmodmap: render-xmodmap || \$docdir/_build
layout = ${l}
EOF
diff --git a/lulua/stats.py b/lulua/stats.py
index 7695f39..6da7cc2 100644
--- a/lulua/stats.py
+++ b/lulua/stats.py
@@ -194,15 +194,6 @@ def pretty (args):
for k, v in sorted (stats['simple'].unknown.items (), key=itemgetter (1)):
print (f'{k!r} {v:10d}')
- #print ('fingers')
- #for k, v in sorted (stats['simple'].fingers.items (), key=itemgetter (0)):
- # print (f'{k[0].name:5s} {k[1].name:6s} {v:10d} {v/buttonPresses*100:5.1f}%')
-
- #print ('hands')
- #for hand, fingers in groupby (sorted (stats['simple'].fingers.keys ()), key=itemgetter (0)):
- # used = sum (map (lambda x: stats['simple'].fingers[x], fingers))
- # print (f'{hand.name:5s} {used:10d} {used/buttonPresses*100:5.1f}%')
-
combined = defaultdict (int)
for hand, dist in stats['runlen'].perHandRunlenDist.items ():
print (hand)
@@ -236,6 +227,35 @@ def keyHeatmap (args):
buttons[k.name] = v
yaml.dump (data, sys.stdout)
+def fingerHand (args):
+ stats = pickle.load (sys.stdin.buffer)
+
+ keyboard = defaultKeyboards[args.keyboard]
+ layout = defaultLayouts[args.layout].specialize (keyboard)
+ writer = Writer (layout)
+
+ hands = defaultdict (int)
+ fingers = defaultdict (int)
+ buttonPresses = sum (stats['simple'].buttons.values ())
+ for btn, count in stats['simple'].buttons.items ():
+ hand, finger = writer.getHandFinger (btn)
+ hands[hand] += count
+ fingers[(hand, finger)] += count
+
+ print ('<div class="fingerhandstats" dir="ltr" lang="en">')
+ fingerOrder = {LEFT: list (FingerType), RIGHT: reversed (FingerType)}
+ for hand in Direction:
+ handpct = hands[hand]/buttonPresses*100
+ print (f'<div class="{hand.name.lower()}" style="width: {handpct:.3f}%;">\n\t<div class="hand">{handpct:.2f}%</div>')
+ print ('\t<div class="fingers">')
+ for finger in fingerOrder[hand]:
+ fingerpct = fingers[(hand, finger)]/buttonPresses*100
+ # finger width is relative to parent (i.e. hand)
+ fingerwidth = fingers[(hand, finger)]/hands[hand]*100
+ print (f'\t\t<div class="{finger.name.lower()}" style="width: {fingerwidth:.3f}%;">{fingerpct:.2f}</div>')
+ print ('\t</div>\n\t</div>')
+ print ('</div>')
+
def main ():
parser = argparse.ArgumentParser(description='Process statistics files.')
parser.add_argument('-l', '--layout', metavar='LAYOUT', help='Keyboard layout name')
@@ -256,6 +276,8 @@ def main ():
sp.set_defaults (func=triadfreq)
sp = subparsers.add_parser('keyheatmap')
sp.set_defaults (func=keyHeatmap)
+ sp = subparsers.add_parser('fingerhand')
+ sp.set_defaults (func=fingerHand)
logging.basicConfig (level=logging.INFO)
args = parser.parse_args()