shunkuntype 1.0.1a
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +49 -0
- data/Rakefile +18 -0
- data/Rakefile.rb +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config.ru +3 -0
- data/exe/shunkuntype +5 -0
- data/lib/data/STEP-1.txt +1 -0
- data/lib/data/STEP-10.txt +3 -0
- data/lib/data/STEP-11.txt +1 -0
- data/lib/data/STEP-12.txt +2 -0
- data/lib/data/STEP-13.txt +2 -0
- data/lib/data/STEP-14.txt +2 -0
- data/lib/data/STEP-15.txt +3 -0
- data/lib/data/STEP-16.txt +1 -0
- data/lib/data/STEP-17.txt +2 -0
- data/lib/data/STEP-18.txt +2 -0
- data/lib/data/STEP-19.txt +2 -0
- data/lib/data/STEP-2.txt +2 -0
- data/lib/data/STEP-20.txt +2 -0
- data/lib/data/STEP-21.txt +4 -0
- data/lib/data/STEP-22.txt +4 -0
- data/lib/data/STEP-23.txt +3 -0
- data/lib/data/STEP-24.txt +3 -0
- data/lib/data/STEP-25.txt +3 -0
- data/lib/data/STEP-26.txt +2 -0
- data/lib/data/STEP-27.txt +2 -0
- data/lib/data/STEP-28.txt +2 -0
- data/lib/data/STEP-29.txt +2 -0
- data/lib/data/STEP-3.txt +2 -0
- data/lib/data/STEP-30.txt +3 -0
- data/lib/data/STEP-31.txt +2 -0
- data/lib/data/STEP-32.txt +2 -0
- data/lib/data/STEP-33.txt +2 -0
- data/lib/data/STEP-34.txt +2 -0
- data/lib/data/STEP-35.txt +3 -0
- data/lib/data/STEP-36.txt +2 -0
- data/lib/data/STEP-37.txt +2 -0
- data/lib/data/STEP-38.txt +2 -0
- data/lib/data/STEP-39.txt +2 -0
- data/lib/data/STEP-4.txt +2 -0
- data/lib/data/STEP-40.txt +3 -0
- data/lib/data/STEP-41.txt +1 -0
- data/lib/data/STEP-42.txt +2 -0
- data/lib/data/STEP-43.txt +2 -0
- data/lib/data/STEP-44.txt +2 -0
- data/lib/data/STEP-45.txt +2 -0
- data/lib/data/STEP-46.txt +5 -0
- data/lib/data/STEP-47.txt +3 -0
- data/lib/data/STEP-48.txt +3 -0
- data/lib/data/STEP-49.txt +3 -0
- data/lib/data/STEP-5.txt +3 -0
- data/lib/data/STEP-50.txt +3 -0
- data/lib/data/STEP-6.txt +1 -0
- data/lib/data/STEP-7.txt +2 -0
- data/lib/data/STEP-8.txt +2 -0
- data/lib/data/STEP-9.txt +2 -0
- data/lib/data/data.txt +117 -0
- data/lib/data/trans.rb +9 -0
- data/lib/data/trans2.rb +16 -0
- data/lib/data/word.list +52 -0
- data/lib/shunkuntype/db.rb +25 -0
- data/lib/shunkuntype/finished_check.rb +44 -0
- data/lib/shunkuntype/init.rb +24 -0
- data/lib/shunkuntype/mk_summary.rb +74 -0
- data/lib/shunkuntype/options.rb +24 -0
- data/lib/shunkuntype/plot.rb +67 -0
- data/lib/shunkuntype/plot_data.rb +177 -0
- data/lib/shunkuntype/speed.rb +83 -0
- data/lib/shunkuntype/training.rb +89 -0
- data/lib/shunkuntype/version.rb +10 -0
- data/lib/shunkuntype.rb +83 -0
- data/shunkuntype.gemspec +36 -0
- data/tmp1/always_restart.txt +0 -0
- metadata +211 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
class FinishCheck
|
2
|
+
STEPS=[[
|
3
|
+
['frdejuki 1,2,3,4',1,2,3,4],
|
4
|
+
['tgyh 5,6,7,8,9',5,6,7,8,9],
|
5
|
+
['vbc 10,11,12,13,14', 10,11,12,13,14],
|
6
|
+
['mn, 15,16,17,18,19', 15,16,17,18,19],
|
7
|
+
['consol 20,21,22,23,24',20,21,22,23,24],
|
8
|
+
['swx 25,26,27,28,29', 25,26,27,28,29],
|
9
|
+
['lo. 30,31,32,33,34', 30,31,32,33,34],
|
10
|
+
['aqz 35,36,37,38,39', 35,36,37,38,39],
|
11
|
+
[';p 40,41,42,43,44,45',40,41,42,43,44,45],
|
12
|
+
['consol 46,47,48,49,50', 46,47,48,49,50]
|
13
|
+
]]
|
14
|
+
def initialize
|
15
|
+
finish = [[],[]]
|
16
|
+
File.open(Shunkuntype::TRAIN_FILE,'r').each{|line|
|
17
|
+
name = line.chomp.split(',')[1]
|
18
|
+
step = name.scan(/\d+/)[0].to_i
|
19
|
+
finish[0] << step
|
20
|
+
}
|
21
|
+
|
22
|
+
# text=[['Basic','minute'],['GerardStrong','size']]
|
23
|
+
text=[['Basic','minute']]
|
24
|
+
1.times{|i|
|
25
|
+
print display(STEPS[i],finish[i],text[i][0],text[i][1])
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def display(step,finished,title="***",command="***")
|
30
|
+
cont = "You've finished #{title} drills of...\n"
|
31
|
+
cont << sprintf("hour | %-21s | step\n",'contents')
|
32
|
+
step.each_with_index do |ele,indx|
|
33
|
+
cont << sprintf("%4s | %-21s | ",indx,ele[0])
|
34
|
+
ele[1..-1].each {|e2|
|
35
|
+
cont << e2.to_s+"," if finished.include?(e2)
|
36
|
+
}
|
37
|
+
cont<< "\n"
|
38
|
+
end
|
39
|
+
next_step=finished[-1].to_i+1
|
40
|
+
cont << "To continue one minute training: shunkuntype -d #{next_step}.\n\n"
|
41
|
+
return cont
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class InitDataFiles
|
2
|
+
def initialize
|
3
|
+
if File::exist?("./speed_data.txt") then
|
4
|
+
system "mv ./speed_data.txt #{Shunkuntype::SPEED_FILE}"
|
5
|
+
print "moving ./speed_data.txt #{Shunkuntype::SPEED_FILE}.\n"
|
6
|
+
end
|
7
|
+
if File::exist?("./training_data.txt") then
|
8
|
+
system "mv ./training_data.txt #{Shunkuntype::TRAIN_FILE}"
|
9
|
+
print "moving ./training_data.txt #{Shunkuntype::TRAIN_FILE}.\n"
|
10
|
+
end
|
11
|
+
if File::exist?(Shunkuntype::SPEED_FILE) then
|
12
|
+
print "#{Shunkuntype::SPEED_FILE} exits.\n"
|
13
|
+
else
|
14
|
+
File::open(Shunkuntype::SPEED_FILE,'a')
|
15
|
+
print "make #{Shunkuntype::SPEED_FILE}\n"
|
16
|
+
end
|
17
|
+
if File::exist?(Shunkuntype::TRAIN_FILE) then
|
18
|
+
print "#{Shunkuntype::TRAIN_FILE} exits.\n"
|
19
|
+
else
|
20
|
+
File::open(Shunkuntype::TRAIN_FILE,'a')
|
21
|
+
print "make #{Shunkuntype::TRAIN_FILE}\n"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class MkSummary
|
2
|
+
def initialize
|
3
|
+
files = Dir::entries("./mem_data")
|
4
|
+
member = mk_member(files)
|
5
|
+
@scores = take_scores(files,member)
|
6
|
+
end
|
7
|
+
|
8
|
+
def mk_member(files)
|
9
|
+
member = []
|
10
|
+
files.each{|file|
|
11
|
+
if file.include?('training') then
|
12
|
+
name=file.split('_')[0]
|
13
|
+
member << name
|
14
|
+
end
|
15
|
+
}
|
16
|
+
return member
|
17
|
+
end
|
18
|
+
|
19
|
+
def take_scores(files,member)
|
20
|
+
scores = {}
|
21
|
+
member.each{|name|
|
22
|
+
p name
|
23
|
+
speed_file="#{name}_speed_data.txt"
|
24
|
+
if files.include?(speed_file)
|
25
|
+
file = File.readlines("mem_data/#{speed_file}")
|
26
|
+
init= (file[0]!=nil ? file[0].split(",")[2].to_f : 0.0 )
|
27
|
+
cur = (file[-1]!=nil ? file[-1].split(",")[2].to_f : 0.0 )
|
28
|
+
scores[name]=[init,cur]
|
29
|
+
end
|
30
|
+
training_file="#{name}_training_data.txt"
|
31
|
+
if files.include?(training_file)
|
32
|
+
file = File.readlines("mem_data/#{training_file}")
|
33
|
+
work_time = file.inject(0){|sum,line|
|
34
|
+
sec=line.split(',')[3].to_i
|
35
|
+
sec= (sec!=0)? sec : 60
|
36
|
+
sum + sec
|
37
|
+
}
|
38
|
+
step = (file[-1]!=nil ? file[-1].match(/STEP-(\d*)/)[1].to_i : 0 )
|
39
|
+
scores[name] << work_time/60 << step
|
40
|
+
end
|
41
|
+
}
|
42
|
+
return scores
|
43
|
+
end
|
44
|
+
|
45
|
+
def mk_html_table()
|
46
|
+
cont = ""
|
47
|
+
title = "Shunkun typer"
|
48
|
+
cont << "<table border=\"1\">\n<caption>#{title}<caption>\n"
|
49
|
+
cont << "<tr><th></th><th colspan=2>speed[sec]</th><th colspan=2>training</th></tr>\n"
|
50
|
+
cont << "<tr><th></th><th>init</th><th>current</th><th>total time[min]</th><th>step</th></tr>\n"
|
51
|
+
@scores.each_pair{|key,score|
|
52
|
+
cont << "<tr><th>#{key}</th>"
|
53
|
+
score.each{|val| cont << sprintf("<td>%5.2f</td>",val)}
|
54
|
+
cont << "</tr>\n"
|
55
|
+
}
|
56
|
+
cont << "</table>\n"
|
57
|
+
return cont
|
58
|
+
end
|
59
|
+
|
60
|
+
def mk_hiki_table()
|
61
|
+
t= Time.now
|
62
|
+
cont = "!!Shunkun typer #{t.localtime}\n"
|
63
|
+
cont << "|| ||>speed[sec]||>training\n"
|
64
|
+
cont << "||||init||current||total time[min]||step\n"
|
65
|
+
@scores.each_pair{|key,score|
|
66
|
+
cont << "||#{key}"
|
67
|
+
score.each{|val| cont << sprintf("||%5.2f",val)}
|
68
|
+
cont << "\n"
|
69
|
+
}
|
70
|
+
cont << "\n"
|
71
|
+
return cont
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#coding: utf-8
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module Shunkuntype
|
6
|
+
class Command
|
7
|
+
module Options
|
8
|
+
|
9
|
+
def self.parse!(argv)
|
10
|
+
options = {}
|
11
|
+
command_parser = OptionParser.new do |opt|
|
12
|
+
opt.on_head('-v', '--version','Show program version') do |v|
|
13
|
+
puts options.ver
|
14
|
+
opt.version = Shunkuntype::VERSION
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
command_parser.parse!(argv)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
class PlotPersonalData
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
plot_data = read_data()
|
7
|
+
make_data_file(plot_data)
|
8
|
+
|
9
|
+
text=["Typing speed [words/min]","Work minutes [min]"]
|
10
|
+
2.times{|i|
|
11
|
+
opts = {:title=>"Elapsed time vs #{text[i]}",
|
12
|
+
:plot=>"plot \"./tmp.data\" using 1:#{i+2} w st\n",
|
13
|
+
:xlabel=>"Elapsed time[hrs]",:ylabel=>text[i],:xtics=>"0 2"}
|
14
|
+
listplot(opts)
|
15
|
+
}
|
16
|
+
|
17
|
+
opts = {:title=>"Elapsed time vs Finished steps",
|
18
|
+
:xlabel=>"Elapsed time[hrs]",:ylabel=>"Finished steps",:xtics=>"0 2",
|
19
|
+
:plot=>"plot \"./tmp.data\" u 1:4 w st ti \"basic drills\", \\
|
20
|
+
\"./tmp.data\" u 1:5 w st ti \"Gerard Strong drills\""}
|
21
|
+
listplot(opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def read_data
|
25
|
+
today=Time.now.to_s
|
26
|
+
plot_data=[]
|
27
|
+
d_total_min=0
|
28
|
+
d_step=[[0],[0]]
|
29
|
+
File.open(Shunkuntype::TRAIN_FILE,'r'){|file|
|
30
|
+
while line=file.gets do
|
31
|
+
tmp=line.chomp.split(',')
|
32
|
+
d_day = ((Time.parse(tmp[0])-Time.parse(today))/3600/24) #hours
|
33
|
+
tmp << "60" if tmp.size ==3 # for backward consist. to "d,f,w"+",t"
|
34
|
+
d_speed = tmp[2].to_f/tmp[3].to_f*60
|
35
|
+
d_total_min += tmp[3].to_f/60.0 # total_second
|
36
|
+
name = tmp[1]
|
37
|
+
step = name.scan(/\d+/)[0].to_i # extract step from file name
|
38
|
+
name.include?('GerardStrong_data') ? d_step[1] << step : d_step[0] << step
|
39
|
+
plot_data << [d_day,d_speed,d_total_min,d_step[0][-1],d_step[1][-1]]
|
40
|
+
end
|
41
|
+
}
|
42
|
+
return plot_data
|
43
|
+
end
|
44
|
+
|
45
|
+
def make_data_file(outdata)
|
46
|
+
cont=""
|
47
|
+
outdata.each {|idata|
|
48
|
+
idata.each{|ele| cont << sprintf("%7.2f ",ele)}
|
49
|
+
cont << "\n"
|
50
|
+
}
|
51
|
+
File.open("./tmp.data",'w'){|io| io.print(cont)}
|
52
|
+
end
|
53
|
+
|
54
|
+
def listplot(opts)
|
55
|
+
cont = ""
|
56
|
+
cont << "set xrange \[#{opts[:x]}\]\n" if opts.has_key?(:x)
|
57
|
+
cont << "set yrange \[#{opts[:y]}\]\n" if opts.has_key?(:y)
|
58
|
+
cont << "set title \"#{opts[:title]}\"\n" if opts.has_key?(:title)
|
59
|
+
cont << "set xlabel \"#{opts[:xlabel]}\"\n" if opts.has_key?(:xlabel)
|
60
|
+
cont << "set ylabel \"#{opts[:ylabel]}\"\n" if opts.has_key?(:ylabel)
|
61
|
+
cont << "set xtics #{opts[:xtics]} \n" if opts.has_key?(:xtics)
|
62
|
+
cont << "#{opts[:plot]} \n"
|
63
|
+
File.open("./tmp.txt",'w'){|io| io.print(cont)}
|
64
|
+
system "gnuplot ./tmp.txt"
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'time'
|
2
|
+
require "gnuplot"
|
3
|
+
|
4
|
+
class PlotData
|
5
|
+
attr_accessor :data, :title
|
6
|
+
# def initialize()
|
7
|
+
def initialize(file_name="",x_col=nil,y_col=nil,title="")
|
8
|
+
@data=[]
|
9
|
+
read_general_data(file_name,x_col,y_col) if ""!=file_name
|
10
|
+
@title=title if ""!=title
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_general_data(file, x_col, y_col)
|
14
|
+
read_general_data(file, x_col, y_col)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_general_data(file, x_col, y_col)
|
18
|
+
File.open(file,'r'){|file|
|
19
|
+
while line=file.gets do
|
20
|
+
tmp=line.chomp.split(',')
|
21
|
+
@data << [tmp[x_col],tmp[y_col]]
|
22
|
+
end
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_gnuplot()
|
27
|
+
x,y=[],[]
|
28
|
+
@data.each{|ele|
|
29
|
+
x << ele[0]
|
30
|
+
y << ele[1]
|
31
|
+
}
|
32
|
+
return [x,y]
|
33
|
+
end
|
34
|
+
|
35
|
+
def mk_plot_data(x_func,y_func)
|
36
|
+
tmp_data=[]
|
37
|
+
@data.each{|ele|
|
38
|
+
x_data = x_func.call(ele[0])
|
39
|
+
y_data = y_func.call(ele[1])
|
40
|
+
tmp_data << [x_data,y_data]
|
41
|
+
}
|
42
|
+
@data = tmp_data
|
43
|
+
end
|
44
|
+
|
45
|
+
def sum_data
|
46
|
+
tmp_data=[]
|
47
|
+
y_data=0
|
48
|
+
@data.each{|ele| tmp_data << [ele[0], y_data+=ele[1]]}
|
49
|
+
@data = tmp_data
|
50
|
+
end
|
51
|
+
|
52
|
+
def sort
|
53
|
+
@data.sort!{|x,y| x[0] <=> y[0]}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class MkPlots
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@source_dir='mem_data'
|
61
|
+
@mem_names=[]
|
62
|
+
mk_mem_names()
|
63
|
+
work_all()
|
64
|
+
speed_all()
|
65
|
+
end
|
66
|
+
|
67
|
+
def work_all
|
68
|
+
all_data= @mem_names.inject([]){|all,name| all << work_view(name) }
|
69
|
+
text="Work minutes [min]"
|
70
|
+
plot(all_data,text)
|
71
|
+
plot(all_data,text,opts={:png=>true})
|
72
|
+
# system 'cp res.png ~/Sites/nishitani0/Internal/data/cache/attach/ShunkunTyper2015/work.png'
|
73
|
+
system 'mv res.png work.png'
|
74
|
+
end
|
75
|
+
|
76
|
+
def speed_all
|
77
|
+
mk_mem_names
|
78
|
+
all_data= @mem_names.inject([]){|all,name| all << speed_view(name) }
|
79
|
+
text="Typing speed [sec/20 words]"
|
80
|
+
plot(all_data,text)
|
81
|
+
plot(all_data,text,opts={:png=>true})
|
82
|
+
system 'mv res.png speed.png'
|
83
|
+
end
|
84
|
+
|
85
|
+
def speed_view(name)
|
86
|
+
p name1 = "#{@source_dir}/#{name}_speed_data.txt"
|
87
|
+
data0 = PlotData.new(name1, 0, 2, name)
|
88
|
+
# start=Time.parse(data0.data[0][0])
|
89
|
+
start=Time.parse(Time.now.to_s)
|
90
|
+
x_func = proc{|x| ((Time.parse(x)-start)/3600/24) }
|
91
|
+
y_func = proc{|x| x }
|
92
|
+
data0.mk_plot_data(x_func,y_func)
|
93
|
+
return data0
|
94
|
+
end
|
95
|
+
|
96
|
+
def mk_mem_names
|
97
|
+
names = Dir.entries(@source_dir)
|
98
|
+
names.each{|name|
|
99
|
+
title = name.split('_')[0]
|
100
|
+
@mem_names << title if (!@mem_names.include?(title) and title.match(/\w/))
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
def work_view(name)
|
105
|
+
p name0 = "#{@source_dir}/#{name}_training_data.txt"
|
106
|
+
p name1 = "#{@source_dir}/#{name}_speed_data.txt"
|
107
|
+
data0 = PlotData.new(name0,0,3,name)
|
108
|
+
data0.add_general_data(name1, 0, 2)
|
109
|
+
start=Time.parse(Time.now.to_s)
|
110
|
+
x_func = proc{|x| ((Time.parse(x)-start)/3600/24) }
|
111
|
+
y_func = proc{|x| x.to_f/60.0 }
|
112
|
+
data0.mk_plot_data(x_func,y_func)
|
113
|
+
data0.sort
|
114
|
+
data0.sum_data
|
115
|
+
return data0
|
116
|
+
end
|
117
|
+
|
118
|
+
def plot(data,text0,opts={})
|
119
|
+
Gnuplot.open do |gp|
|
120
|
+
Gnuplot::Plot.new( gp ) do |plot|
|
121
|
+
plot.title "Elapsed time vs #{text0}"
|
122
|
+
plot.ylabel text0
|
123
|
+
plot.xlabel "Elapsed time[days]"
|
124
|
+
plot.xtics "0 7"
|
125
|
+
if true==opts.has_key?(:png) then
|
126
|
+
plot.term "pngcairo enhanced size 480,360"
|
127
|
+
plot.output "res.png"
|
128
|
+
end
|
129
|
+
|
130
|
+
plot.data = []
|
131
|
+
data.each{|ele|
|
132
|
+
plot.data << Gnuplot::DataSet.new( ele.to_gnuplot ) do |ds|
|
133
|
+
ds.with = "line"
|
134
|
+
if ""==ele.title then
|
135
|
+
ds.notitle
|
136
|
+
else
|
137
|
+
ds.title=ele.title
|
138
|
+
end
|
139
|
+
end
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
if __FILE__ == $0 then
|
147
|
+
data0 = PlotData.new()
|
148
|
+
data0.read_general_data(ARGV[0], 0, 3)
|
149
|
+
data0.add_general_data(ARGV[1], 0, 2)
|
150
|
+
|
151
|
+
start=Time.parse(data0.data[0][0])
|
152
|
+
x_func = proc{|x| ((Time.parse(x)-start)/3600/24) }
|
153
|
+
y_func = proc{|x| x.to_f/60.0 }
|
154
|
+
data0.mk_plot_data(x_func,y_func)
|
155
|
+
data0.sort
|
156
|
+
data0.sum_data
|
157
|
+
|
158
|
+
text="Work minutes [min]"
|
159
|
+
Gnuplot.open do |gp|
|
160
|
+
Gnuplot::Plot.new( gp ) do |plot|
|
161
|
+
plot.title "Elapsed time vs #{text}"
|
162
|
+
plot.ylabel text
|
163
|
+
plot.xlabel "Elapsed time[days]"
|
164
|
+
plot.xtics "0 2"
|
165
|
+
x,y = data0.to_gnuplot
|
166
|
+
|
167
|
+
plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
|
168
|
+
ds.with = "line"
|
169
|
+
ds.notitle
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
class SpeedCheck
|
3
|
+
attr_reader :number, :period
|
4
|
+
|
5
|
+
# print key positions
|
6
|
+
def print_keyboard
|
7
|
+
content = <<-EOF
|
8
|
+
q \\ w \\ e \\ r t \\ y u \\ i \\ o \\ p
|
9
|
+
a \\ s \\ d \\ f g \\ h j \\ k \\ l \\ ; enter
|
10
|
+
sh z \\ x \\ c \\ v b \\ n m \\ , \\\ . \\ shift
|
11
|
+
EOF
|
12
|
+
print content
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@number = 20 #default 20
|
17
|
+
@period = 60
|
18
|
+
check_data_files
|
19
|
+
data = mk_random_words
|
20
|
+
t0,t1,count = exec_speed_check(data)
|
21
|
+
keep_record(t0,t1,count)
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_data_files
|
25
|
+
begin
|
26
|
+
file=open(Shunkuntype::SPEED_FILE,"r")
|
27
|
+
if file
|
28
|
+
puts "#{Shunkuntype::SPEED_FILE} opened succcessfully"
|
29
|
+
end
|
30
|
+
rescue
|
31
|
+
puts "#{Shunkuntype::SPEED_FILE} does not exist in this directory. --init or try in another dir."
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
def mk_random_words
|
36
|
+
data=[]
|
37
|
+
data_dir=File.expand_path('../../../lib/data', __FILE__)
|
38
|
+
file=open("#{data_dir}/word.list",'r')
|
39
|
+
while word=file.gets do
|
40
|
+
data << word.chomp
|
41
|
+
end
|
42
|
+
data.shuffle!
|
43
|
+
data.each do |word|
|
44
|
+
print word+" "
|
45
|
+
end
|
46
|
+
return data
|
47
|
+
end
|
48
|
+
|
49
|
+
def exec_speed_check(data)
|
50
|
+
print "\n\n"+number.to_s+" words should be cleared."
|
51
|
+
print "\nType return-key to start."
|
52
|
+
line=$stdin.gets
|
53
|
+
|
54
|
+
t0=Time.now
|
55
|
+
count=0
|
56
|
+
@number.times do |i|
|
57
|
+
print_keyboard()
|
58
|
+
puts (i+1).to_s
|
59
|
+
word = data[i]
|
60
|
+
count+=word.length
|
61
|
+
while line!=word do
|
62
|
+
puts word
|
63
|
+
line=$stdin.gets.chomp
|
64
|
+
end
|
65
|
+
end
|
66
|
+
t1=Time.now
|
67
|
+
return t0,t1,count
|
68
|
+
end
|
69
|
+
|
70
|
+
def keep_record(t0,t1,count)
|
71
|
+
statement = t0.to_s+","
|
72
|
+
statement << @number.to_s+","
|
73
|
+
statement << (t1-t0).to_s+","
|
74
|
+
icount=@period/(t1-t0)*count
|
75
|
+
statement << icount.to_s+"\n"
|
76
|
+
data_file=open(Shunkuntype::SPEED_FILE,"a+")
|
77
|
+
data_file << statement
|
78
|
+
p statement
|
79
|
+
|
80
|
+
printf("%5.3f sec\n",Time.now-t0)
|
81
|
+
printf("%4d characters.\n",icount)
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
class Training
|
2
|
+
def initialize(val_i)
|
3
|
+
val_i ||= 47
|
4
|
+
data_dir=File.expand_path('../../../lib/data', __FILE__)
|
5
|
+
base_name="STEP-#{val_i}.txt"
|
6
|
+
file_name=File.join(data_dir,base_name)
|
7
|
+
|
8
|
+
@period = 60
|
9
|
+
@counter = 0
|
10
|
+
|
11
|
+
@time_flag=true
|
12
|
+
print_keyboard
|
13
|
+
start_time,data=init_proc(file_name)
|
14
|
+
#size_training(file_name,data,start_time)
|
15
|
+
time_training(base_name,data,start_time)
|
16
|
+
end
|
17
|
+
|
18
|
+
# count correct spelling
|
19
|
+
def counter(word1,word2)
|
20
|
+
ws1=word1.split(/\s+/)
|
21
|
+
ws2=word2.split(/\s+/)
|
22
|
+
i,j=0,0
|
23
|
+
while (i < ws1.length) && (j < ws2.length) do
|
24
|
+
if ws1[i] == ws2[j] then
|
25
|
+
@counter+=1
|
26
|
+
end
|
27
|
+
i+=1
|
28
|
+
j+=1
|
29
|
+
end
|
30
|
+
puts @counter
|
31
|
+
end
|
32
|
+
|
33
|
+
# time loop
|
34
|
+
def loop_thread(sec)
|
35
|
+
Thread.start(sec) do |wait_time|
|
36
|
+
sleep wait_time
|
37
|
+
puts "\a Time up. Type return-key to finish.."
|
38
|
+
@time_flag=false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# print key positions
|
43
|
+
def print_keyboard
|
44
|
+
content = <<-EOF
|
45
|
+
q \\ w \\ e \\ r t \\ y u \\ i \\ o \\ p
|
46
|
+
a \\ s \\ d \\ f g \\ h j \\ k \\ l \\ ; enter
|
47
|
+
sh z \\ x \\ c \\ v b \\ n m \\ , \\\ . \\ shift
|
48
|
+
EOF
|
49
|
+
print content
|
50
|
+
end
|
51
|
+
|
52
|
+
def init_proc(file_name)
|
53
|
+
data=File.readlines(file_name)
|
54
|
+
data.each{|word| print word }
|
55
|
+
print "\nRepeat above sentences. Type return-key to start."
|
56
|
+
line=STDIN.gets
|
57
|
+
start_time = Time.now
|
58
|
+
return start_time,data
|
59
|
+
end
|
60
|
+
|
61
|
+
def keep_record(start_time,file_name,period)
|
62
|
+
data_file=open(Shunkuntype::TRAIN_FILE,"a")
|
63
|
+
data_file << "#{start_time},#{file_name},#{@counter},#{period}\n"
|
64
|
+
exit
|
65
|
+
end
|
66
|
+
|
67
|
+
def type_loop(data)
|
68
|
+
data.each do |sentence|
|
69
|
+
break if @time_flag == false
|
70
|
+
puts sentence
|
71
|
+
line=STDIN.gets.chomp
|
72
|
+
counter(sentence,line)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def size_training(file_name,data,start_time)
|
77
|
+
type_loop(data)
|
78
|
+
exit_proc(start_time,file_name,(Time.now-start_time).to_i)
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
def time_training(base_name,data,start_time)
|
83
|
+
loop_thread(@period)
|
84
|
+
data2=[]
|
85
|
+
20.times{ data2 << data }
|
86
|
+
type_loop(data2.flatten)
|
87
|
+
keep_record(start_time,base_name,@period)
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
module Shunkuntype
|
3
|
+
VERSION = "1.0.1a"
|
4
|
+
data_path = File.join(ENV['HOME'], '.shunkuntype')
|
5
|
+
# SPEED_FILE="./shunkuntype_speed_data.txt"
|
6
|
+
SPEED_FILE=File.join(data_path,"speed_data.txt")
|
7
|
+
# TRAIN_FILE="./shunkuntype_training_data.txt"
|
8
|
+
TRAIN_FILE=File.join(data_path,"training_data.txt")
|
9
|
+
SERVER_FILE=File.join(data_path,"server_data.txt")
|
10
|
+
end
|
data/lib/shunkuntype.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require "shunkuntype/version"
|
3
|
+
require "shunkuntype/speed"
|
4
|
+
require "shunkuntype/training"
|
5
|
+
require "shunkuntype/init"
|
6
|
+
require "shunkuntype/finished_check"
|
7
|
+
require "shunkuntype/plot"
|
8
|
+
require "shunkuntype/mk_summary"
|
9
|
+
require "shunkuntype/plot_data"
|
10
|
+
require "shunkuntype/db"
|
11
|
+
require 'systemu'
|
12
|
+
|
13
|
+
module Shunkuntype
|
14
|
+
class Command
|
15
|
+
|
16
|
+
def self.run(argv=[])
|
17
|
+
print "Shunkuntype says 'Hello world'.\n"
|
18
|
+
new(argv).execute
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(argv=[])
|
22
|
+
@argv = argv
|
23
|
+
end
|
24
|
+
|
25
|
+
def execute
|
26
|
+
DB.prepare
|
27
|
+
|
28
|
+
@argv << '--help' if @argv.size==0
|
29
|
+
command_parser = OptionParser.new do |opt|
|
30
|
+
opt.on('-v', '--version','show program Version.') { |v|
|
31
|
+
opt.version = Shunkuntype::VERSION
|
32
|
+
puts opt.ver
|
33
|
+
}
|
34
|
+
opt.on('-i', '--init','Initialize data files') {|v| InitDataFiles.new }
|
35
|
+
opt.on('-c', '--check','Check speed') {|v| SpeedCheck.new }
|
36
|
+
opt.on('-d', '--drill [VAL]','one minute Drill [VAL]', Integer) {|v| Training.new(v) }
|
37
|
+
opt.on('-h', '--history','view training History') {|v| FinishCheck.new }
|
38
|
+
opt.on('-p', '--plot','Plot personal data') { |v| PlotPersonalData.new }
|
39
|
+
opt.on('-s', '--submit','Submit data to dmz0') { |v| report_submit()}
|
40
|
+
opt.on('--review [TAG]',[:html,:hiki],'Review training, TAGs=html or hiki'){|v| data_viewing(v)}
|
41
|
+
end
|
42
|
+
command_parser.parse!(@argv)
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
def report_submit
|
47
|
+
server_info=File.readlines(Shunkuntype::SERVER_FILE)
|
48
|
+
p server_directory=server_info[0].chomp
|
49
|
+
p user_name=server_info[0].split('@')[0]
|
50
|
+
system "scp #{Shunkuntype::TRAIN_FILE} #{server_directory}/#{user_name}_training_data.txt"
|
51
|
+
system "scp #{Shunkuntype::SPEED_FILE} #{server_directory}/#{user_name}_speed_data.txt"
|
52
|
+
end
|
53
|
+
|
54
|
+
def data_viewing(form)
|
55
|
+
server_info=File.readlines(Shunkuntype::SERVER_FILE)
|
56
|
+
p server_directory=server_info[0].chomp
|
57
|
+
system "scp -r #{server_directory} ."
|
58
|
+
# write data to file
|
59
|
+
table = MkSummary.new
|
60
|
+
MkPlots.new
|
61
|
+
p form ||= :html
|
62
|
+
case form
|
63
|
+
when :html then
|
64
|
+
File.open('tmp.html','a'){|f|
|
65
|
+
f.write("<html>\n")
|
66
|
+
f.write(table.mk_html_table())
|
67
|
+
f.write("<p><img src=\"./work.png\" /></p>")
|
68
|
+
f.write("<p><img src=\"./speed.png\" /></p>")
|
69
|
+
f.write("</html>\n")
|
70
|
+
}
|
71
|
+
when :hiki then
|
72
|
+
File.open('tmp.hiki','a'){|f|
|
73
|
+
f.write(table.mk_hiki_table())
|
74
|
+
f.write('||{{attach_view(work.png)}}')
|
75
|
+
f.write('||{{attach_view(speed.png)}}')
|
76
|
+
f.write("\n")
|
77
|
+
}
|
78
|
+
else
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|