From 0d961f7e58adbf58b3e15800e6625b74dbd4167d Mon Sep 17 00:00:00 2001 From: cbrom abody Date: Fri, 7 Jun 2019 15:04:35 +0300 Subject: [PATCH 1/4] terminal for as you type prediction --- run.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 run.py diff --git a/run.py b/run.py new file mode 100644 index 0000000..140234d --- /dev/null +++ b/run.py @@ -0,0 +1,56 @@ +from __future__ import print_function +import sugartensor as tf +import numpy as np +from prepro import * +from train import ModelGraph +import codecs +import readchar + +def main(): + g = ModelGraph(mode="test") + + with tf.Session() as sess: + tf.sg_init(sess) + + # restore parameters + saver = tf.train.Saver() + saver.restore(sess, tf.train.latest_checkpoint('asset/train')) + print("Restored!") + mname = open('asset/train/checkpoint', 'r').read().split('"')[1] # model name + + char2idx, idx2char = load_char_vocab() + word2idx, idx2word = load_word_vocab() + + + previous = [0]*50 # a stack for previous words + para = "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + ctx = [0]*50 + + while True: + key = readchar.readkey().lower() + + if key == readchar.key.BACKSPACE: + ctx.insert(0, previous.pop()) + ctx.pop() + previous.insert(0, 0) + + elif key == readchar.key.ESC: + break + + else: + key_idx = char2idx[key] + ctx.append(key_idx) + ctx.pop(0) + + logits = sess.run(g.logits, {g.x: np.expand_dims(ctx, 0)}) + preds = logits.argsort()[0][-3:] + # pred = np.argmax(logits, -1)[0] + predword1, predword2, predword3 = [idx2word.get(pred) for pred in preds] + print(predword1, ' ', predword2, ' ', predword3) + + + +if __name__ == '__main__': + main() + print("Done") + From a1e277a268f6db6a869de62016b48ee31d62095c Mon Sep 17 00:00:00 2001 From: cbrom abody Date: Fri, 7 Jun 2019 15:07:22 +0300 Subject: [PATCH 2/4] keyboard adopted from starlordvk/Typing-Assistant --- scss/style.scss | 153 +++++++++++++++++++++++++++++++++++++++++ static/.DS_Store | Bin 0 -> 6148 bytes static/css/style.css | 158 +++++++++++++++++++++++++++++++++++++++++++ static/js/index.js | 158 +++++++++++++++++++++++++++++++++++++++++++ templates/.DS_Store | Bin 0 -> 6148 bytes templates/index.html | 110 ++++++++++++++++++++++++++++++ 6 files changed, 579 insertions(+) create mode 100644 scss/style.scss create mode 100644 static/.DS_Store create mode 100644 static/css/style.css create mode 100644 static/js/index.js create mode 100644 templates/.DS_Store create mode 100644 templates/index.html diff --git a/scss/style.scss b/scss/style.scss new file mode 100644 index 0000000..e847bb1 --- /dev/null +++ b/scss/style.scss @@ -0,0 +1,153 @@ +//Set up some color variables +$darkgray: #53565a; +$midgray: #888b8d; +$lightgray: #a7a8aa; +$yellow: #ffd100; + +//Lots of stuff be flexin' +@mixin flexy { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-line-pack: center; + align-content: center; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +* { + box-sizing: border-box; +} + +body { + //Change this font-size value to resize the keyboard! + font-size: 8px; + @include flexy; + width: 100%; + margin: 0; + box-sizing: border-box; + font-family: Quicksand; + height: 100vh; + max-height: 100vh; + overflow: hidden; + + //The keyboard containing div and all key elements + #keyboard, kbd { + @include flexy; + box-sizing: border-box; + border-radius: 4px; + background: #ccc; + border: .2em solid $midgray; + text-align: center; + font-family: Quicksand; + } + + kbd { + flex: 1; + } + + .keyboard-row { + @include flexy; + width: 100%; + } + + //The box the typed text appears in + div#text { + @include flexy; + align-items: flex-end; + width: 20em; + height: 44vh; + max-height: 44vh; + font-size: 3em; + margin-bottom: 4vh; + text-align: center; + overflow: auto; + align-self: flex-end; + position: relative; + } + + //The div containing the keys + #keyboard { + width: 56em; + padding: .4em .4em .8em; + box-shadow: 0 .4em 0 $midgray; + + //The elements that make up the keys themselves + kbd { + line-height: 3.2em; + height: 3.2em; + width: 3.2em; + margin: .25em; + text-align: center; + color: #fff; + background-color: $darkgray; + transition: background, position, top, box-shadow .1s; + box-shadow: 0px 2px 0px $midgray; + } + + //For slightly wider keys + kbd.long { + flex-grow: 1; + flex: 2; + } + + //For much wider keys + kbd.longer { + flex-grow: 2; + flex: 3; + } + + //For the widest key + kbd.spacebar { + flex-grow: 14; + flex: 6; + } + + //Keep the keys that aren't letters, numbers and punctuation from going to uppercase when shift or capslock is pressed + .operationKey { + text-transform: none!important; + } + + //Styles applied to a currently-pressed key + .pressed { + background: $yellow; + position: relative; + top: 2px; + box-shadow: none; + } + //Applied to the whole keyboard when shift or capslock is pressed + } + pre { + height: 3vh; + line-height: 3vh; + } + .uppercase kbd { + text-transform: uppercase; + } +} + + +//Make keyboard responsive, kinda +@media (min-width: 768px) { + body { + font-size: 10px; + } +} + +@media (min-width: 960px) { + body { + font-size: 12px; + } +} + +@media (min-width: 1080px) { + body { + font-size: 14px; + } +} \ No newline at end of file diff --git a/static/.DS_Store b/static/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b8cbd405ca886ddafd0da66c7ca30f797463d118 GIT binary patch literal 6148 zcmeH~F>V4u3`K3AKuWV^%DDnJ7$H(n=K=^)AtVY!zg>>K`G4#XR!fvF1^Sjef5&6* zXkW3OF*9FZKUQX)nJwW|`{Xb+uG1$r%Lvu^j`LxEI`1*-hGCNZIKbMu9qeM4?diUL z7#Xr=cKkEv@g9nbfCz|y2#A0P{18CTrY&DWHHv@;h`@~i{|^ODt*L!z`*mR8@tx}n zDh_~R$v~b&?xo1VtAAzUNWzy_MuU3-gd@&a%ayQinrYnFD>1?hH4Z6 z5f~Gg$FyVre}n&W{~s4=CITYxR0MpndEcz@N!eQ`AIDx>;5+!YA-APt7##vIVJm*U b%PV|FUQO*oTRGyb9IAr=xyVG|KL~sQ!!|d^ literal 0 HcmV?d00001 diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..594bab1 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,158 @@ +* { + box-sizing: border-box; +} + +#suggestions{ + height: 25px; width:100%; + text-align: center; +} +#pred1, #pred2, #pred3 {display: inline-block; *display: inline; zoom: 1; vertical-align: top; font-size: 20px;} + +body { + font-size: 8px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-line-pack: center; + align-content: center; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + width: 100%; + margin: 0; + box-sizing: border-box; + font-family: Quicksand; + height: 100vh; + max-height: 100vh; + overflow: hidden; +} +body #keyboard, body kbd { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-line-pack: center; + align-content: center; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + box-sizing: border-box; + border-radius: 4px; + background: #ccc; + border: 0.2em solid #888b8d; + text-align: center; + font-family: Quicksand; +} +body kbd { + flex: 1; +} +body .keyboard-row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-line-pack: center; + align-content: center; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + width: 100%; +} +body div#text { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -ms-flex-line-pack: center; + align-content: center; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + align-items: flex-end; + width: 20em; + height: 44vh; + max-height: 44vh; + font-size: 3em; + margin-bottom: 4vh; + text-align: center; + overflow: auto; + align-self: flex-end; + position: relative; +} +body #keyboard { + width: 56em; + padding: .4em .4em .8em; + box-shadow: 0 0.4em 0 #888b8d; +} +body #keyboard kbd { + line-height: 3.2em; + height: 3.2em; + width: 3.2em; + margin: .25em; + text-align: center; + color: #fff; + background-color: #53565a; + transition: background, position, top, box-shadow .1s; + box-shadow: 0px 2px 0px #888b8d; +} +body #keyboard kbd.long { + flex-grow: 1; + flex: 2; +} +body #keyboard kbd.longer { + flex-grow: 2; + flex: 3; +} +body #keyboard kbd.spacebar { + flex-grow: 14; + flex: 6; +} +body #keyboard .operationKey { + text-transform: none !important; +} +body #keyboard .pressed { + background: #ffd100; + position: relative; + top: 2px; + box-shadow: none; +} +body pre { + height: 3vh; + line-height: 3vh; +} +body .uppercase kbd { + text-transform: uppercase; +} + +@media (min-width: 768px) { + body { + font-size: 10px; + } +} +@media (min-width: 960px) { + body { + font-size: 12px; + } +} +@media (min-width: 1080px) { + body { + font-size: 14px; + } +} diff --git a/static/js/index.js b/static/js/index.js new file mode 100644 index 0000000..2a2e21d --- /dev/null +++ b/static/js/index.js @@ -0,0 +1,158 @@ +/* + * There are probably better ways of doing a lot of this, + * but I'm just starting to wade into the deep end of + * of vanilla JavaScript, so ¯\_(ツ)_/¯ + * + * Inspired by day 1 of Wes Bos's 30 Day JavaScript Challenge + * https://javascript30.com/ + */ + +var x = 'x'; +let theTextBox = document.getElementById('enteredText'); +let allTheKeys = document.getElementById('keyboard'); +let changeKeys = document.getElementsByClassName('shifter'); +let capsLockKey = document.getElementById('20'); +let shiftKey = document.getElementById('16'); +var pred1=document.getElementById("pred1"); +var pred2=document.getElementById("pred2"); +var pred3=document.getElementById("pred3"); + +//Store all the original values of the non-alphabetical keys +var originalShifterArray = []; +for (i = 0; i', '?']; + + + + +//Function that clears the text box +function clearText(){ + theTextBox.innerHTML = '
'; +} + + + + +//Function that detects keypresses and does the appropriate things +function highlightAndType(e){ + var keyPressed = e.keyCode; + var charPressed = e.key; + const keys = document.getElementById(keyPressed); + + keys.classList.add('pressed'); + + + if(!charPressed){ + theTextBox.innerHTML = "Sorry, this pen doesn't work in your browser. :(
Try Chrome, Firefox or Opera."; + return; + } + + //If the user presses CapsLock or Shift, make the alphabetical keys uppercase + if (charPressed == 'CapsLock' || charPressed == 'Shift') { + allTheKeys.classList.add('uppercase'); + } + //If the user presses Shift, also replace all non-alphabetical keys with their shifted values + if (charPressed == 'Shift') { + for(i = 0; i')){ + var newText = theTextBox.innerHTML.slice(0, -4); + theTextBox.innerHTML = newText; + } + theTextBox.innerHTML += e.key; + //If a backspace was typed, delete the last character in the text box. If shift was also held, delete all text. + } else if (e.key == 'Backspace'){ + if(shiftKey.classList.contains('pressed')){ + clearText(); + } else { + var newText = theTextBox.innerHTML.slice(0, -1); + theTextBox.innerHTML = newText; + } + //If the Enter key was typed, remove all text from the text box + } else if (e.key == 'Enter'){ + theTextBox.innerHTML += '

'; + } + //if Tab is pressed, don't tab out of the window. Add extra space to the text box instead + if(keyPressed == 9){ + e.preventDefault(); + theTextBox.innerHTML += '  '; + } + if(keyPressed == 32){ + doWork(theTextBox.innerHTML.slice(0, -1), 'pred'); + } + else doWork(theTextBox.innerHTML,'med'); +} + + +function doWork(str, work) { + + + + + // ajax the JSON to the server + $.ajax({ + url:"http://127.0.0.1:5000/output", + type:'GET', + data:{'string':str, + 'work': work}, + //dataType:'json', + + //contentType: 'application/json;charset=UTF-8', + success:function(response){ + console.log(response); + var obj=JSON.parse(response); + pred1.innerHTML=obj[0][0]; + pred2.innerHTML=obj[1][0]; + pred3.innerHTML=obj[2][0]; + + //alert("Success"); + }, + error:function(error){ + console.log(error); + } + + }); + +} + + + +//Function that detects when the user lets off a key and does the appropriate things +function removeKeypress(e){ + var keyDepressed = e.keyCode; + console.log(keyDepressed); + const keys = document.getElementById(keyDepressed); + console.log(keys); + + keys.classList.remove('pressed'); + //If CapsLock or Shift was just let off, and if the other isn't still on, return keys to lowercase + if(keyDepressed == 20 && !shiftKey.classList.contains('pressed') || keyDepressed == 16 && !capsLockKey.classList.contains('pressed')) { + allTheKeys.classList.remove('uppercase'); + } + //If Shift was just let off, replace all non-alphabetical keys with their original values rather than their shifted values + if(keyDepressed == 16 ) { + for(i = 0; iD|DIf);fE4(J0$zJ*^F^XYDIf);z^4NKeQ0#YzHm&8 zPX~u+0f;k(!#Iy#g4jGj> + + + + JavaScript/Flexbox/SCSS Interactive Keyboard + + + + + + + + + + + + +
+
Click here, then start typing!
+
+
+
Pred 1
+ +
Pred 2
+ +
Pred 3
+ +
+
+
+
+ ` + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + - + = + del +
+
+ tab + q + w + e + r + t + y + u + i + o + p + [ + ] + \ +
+
+ caps + a + s + d + f + g + h + j + k + l + ; + ' + return +
+
+ shift + z + x + c + v + b + n + m + , + . + / + shift +
+
+ fn + ctrl + opt + +   + + opt + ctrl + fn +
+
+
+
Click the screen or type shift + delete to clear all text.
+ + + + + From 5b1e1b9171e485129af50c4569af5ff02193b57e Mon Sep 17 00:00:00 2001 From: cbrom abody Date: Fri, 7 Jun 2019 15:08:09 +0300 Subject: [PATCH 3/4] server for responding predictions... --- server.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 server.py diff --git a/server.py b/server.py new file mode 100644 index 0000000..44ea5aa --- /dev/null +++ b/server.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +from __future__ import print_function +import sys +import codecs +import readchar +import simplejson as json +from flask import Flask, render_template,request + +import sugartensor as tf +import numpy as np +from prepro import * +from train import ModelGraph + +app = Flask(__name__) + + +@app.route("/test") +def output(): + return render_template("index.html") + + +@app.route('/output', methods=['GET']) +def worker(): + #print(request, file=sys.stderr) + string = request.args.get('string').lower() + work = request.args.get('work') + words=string.split() + #print(words, file=sys.stderr) + n=len(words) + + latest_50_chars = string[-50:] + para = "E"*(50 - len(latest_50_chars)) + latest_50_chars + ctx = [char2idx[char] for char in para] + + logits = sess.run(g.logits, {g.x: np.expand_dims(ctx, 0)}) + preds = logits.argsort()[0][-3:] + + predword1, predword2, predword3 = [idx2word.get(pred) for pred in preds] + + return json.dumps([(predword1, ), (predword2, ), (predword3, )]) + + +if __name__=="__main__": + g = ModelGraph(mode="test") + + with tf.Session() as sess: + tf.sg_init(sess) + saver = tf.train.Saver() + saver.restore(sess, tf.train.latest_checkpoint('asset/train')) + print('Restored') + + char2idx, idx2char = load_char_vocab() + word2idx, idx2word = load_word_vocab() + + previous = [0]*50 # a stack for previous words + para = "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + ctx = [0]*50 + + + app.run(debug=True) From ac1b49b29dfe3e6c6254485a795249496cbc7b0b Mon Sep 17 00:00:00 2001 From: cbrom abody Date: Fri, 7 Jun 2019 15:12:41 +0300 Subject: [PATCH 4/4] requirement file added --- requirements.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..04a1b82 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +numpy >= 1.11.1 +sugartensor >= 0.0.2.4 +lxml >= 3.6.4. +nltk >= 3.2.1. +regex +readchar \ No newline at end of file