|
1
|
|
|
import tkinter as tk |
|
2
|
|
|
from numpy import sqrt |
|
3
|
|
|
from numpy import log as ln |
|
4
|
|
|
from numpy import pi |
|
5
|
|
|
from numpy import exp |
|
6
|
|
|
import numpy as np |
|
7
|
|
|
import time |
|
8
|
|
|
|
|
9
|
|
|
class TypingSimulator(tk.Tk): |
|
10
|
|
|
def __init__(self): |
|
11
|
|
|
super().__init__() |
|
12
|
|
|
|
|
13
|
|
|
# Build interface |
|
14
|
|
|
row = 0 |
|
15
|
|
|
tk.Button(self, |
|
16
|
|
|
text="Start simulation", |
|
17
|
|
|
command=self.simulate).grid(row=row, |
|
18
|
|
|
padx=10, |
|
19
|
|
|
pady=10) |
|
20
|
|
|
|
|
21
|
|
|
self.textbox = tk.Text(self) |
|
22
|
|
|
row += 1 |
|
23
|
|
|
self.textbox.grid(row=row, |
|
24
|
|
|
padx=10, |
|
25
|
|
|
pady=10) |
|
26
|
|
|
|
|
27
|
|
|
# Build the texts |
|
28
|
|
|
self.texts = [] |
|
29
|
|
|
self.texts.append(SimulationText("""Typing of text is individual. """, |
|
30
|
|
|
0.277, 0.23)) |
|
31
|
|
|
self.texts.append(SimulationText("""Some people type faster, """, |
|
32
|
|
|
0.06, 0.04)) |
|
33
|
|
|
self.texts.append(SimulationText("""whereas some quite sloowwly...""", |
|
34
|
|
|
0.4, 0.3)) |
|
35
|
|
|
self.texts.append(SimulationText(""" The interval between ket\by presses by human being can be consideeed \b\b\b\bred as a random variable. The interval can be simulated as a variable, whose logarithm is normally distributed. However, I don't know whether this is really true... One should study it... or maybe someone knows it already? Anyway, if you want to find out your typing statistics, you can try this little app. Have fun!""", |
|
36
|
|
|
0.15, 0.17)) |
|
37
|
|
|
|
|
38
|
|
|
def simulate(self): |
|
39
|
|
|
# Clear the text box |
|
40
|
|
|
self.textbox.delete(1.0, tk.END) |
|
41
|
|
|
|
|
42
|
|
|
# set text and intervals |
|
43
|
|
|
whole = "" |
|
44
|
|
|
intervals = np.array([]) |
|
45
|
|
|
for text in self.texts: |
|
46
|
|
|
whole += text.get_text() |
|
47
|
|
|
intervals = np.concatenate((intervals, self.random_lognormal_delay(text.get_mu(), |
|
48
|
|
|
text.get_sigma(), |
|
49
|
|
|
len(text.get_text())))) |
|
50
|
|
|
|
|
51
|
|
|
|
|
52
|
|
|
# Run the simulation |
|
53
|
|
|
for i in range(len(whole)): |
|
54
|
|
|
# Backspace |
|
55
|
|
|
if whole[i] == chr(8): |
|
56
|
|
|
self.textbox.delete('%s-2c' % tk.END, tk.END) |
|
57
|
|
|
else: |
|
58
|
|
|
self.textbox.insert(tk.END, whole[i]) |
|
59
|
|
|
self.update() |
|
60
|
|
|
time.sleep(intervals[i]) |
|
61
|
|
|
|
|
62
|
|
|
|
|
63
|
|
|
|
|
64
|
|
|
def random_lognormal_delay(self, m, sd, n): |
|
65
|
|
|
# calculate mu and sigma |
|
66
|
|
|
mu = ln(m/sqrt(1+sd**2/m**2)) |
|
67
|
|
|
sigma = sqrt(ln(1+sd**2/m**2)) |
|
68
|
|
|
return exp(sigma * np.random.randn(n) + mu) |
|
69
|
|
|
|
|
70
|
|
|
class SimulationText: |
|
71
|
|
|
def __init__(self, text, mu, sigma): |
|
72
|
|
|
self.text = text |
|
73
|
|
|
self.mu = mu |
|
74
|
|
|
self.sigma = sigma |
|
75
|
|
|
|
|
76
|
|
|
def get_text(self): |
|
77
|
|
|
return self.text |
|
78
|
|
|
|
|
79
|
|
|
def get_mu(self): |
|
80
|
|
|
return self.mu |
|
81
|
|
|
|
|
82
|
|
|
def get_sigma(self): |
|
83
|
|
|
return self.sigma |
|
84
|
|
|
|
|
85
|
|
|
app = TypingSimulator() |
|
86
|
|
|
app.mainloop() |
|
87
|
|
|
|