Class: Typingtutor::Exercise

Inherits:
Object
  • Object
show all
Defined in:
lib/typingtutor/exercise.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, body:, stats:) ⇒ Exercise

instance methods



62
63
64
65
66
# File 'lib/typingtutor/exercise.rb', line 62

def initialize(name:, body:, stats:)
  self.name  = name
  self.body  = body
  self.stats = stats
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body.



3
4
5
# File 'lib/typingtutor/exercise.rb', line 3

def body
  @body
end

#charsObject

Returns the value of attribute chars.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def chars
  @chars
end

#correct_charsObject

Returns the value of attribute correct_chars.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def correct_chars
  @correct_chars
end

#gross_wpmObject

Returns the value of attribute gross_wpm.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def gross_wpm
  @gross_wpm
end

#keystrokesObject

Returns the value of attribute keystrokes.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def keystrokes
  @keystrokes
end

#nameObject

Returns the value of attribute name.



3
4
5
# File 'lib/typingtutor/exercise.rb', line 3

def name
  @name
end

#startObject

Returns the value of attribute start.



3
4
5
# File 'lib/typingtutor/exercise.rb', line 3

def start
  @start
end

#statsObject

Returns the value of attribute stats.



3
4
5
# File 'lib/typingtutor/exercise.rb', line 3

def stats
  @stats
end

#timeObject

Returns the value of attribute time.



3
4
5
# File 'lib/typingtutor/exercise.rb', line 3

def time
  @time
end

#typing_accuracyObject

Returns the value of attribute typing_accuracy.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def typing_accuracy
  @typing_accuracy
end

#word_accuracyObject

Returns the value of attribute word_accuracy.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def word_accuracy
  @word_accuracy
end

#wordsObject

Returns the value of attribute words.



4
5
6
# File 'lib/typingtutor/exercise.rb', line 4

def words
  @words
end

Class Method Details

.available_exercisesObject



31
32
33
34
35
36
37
38
39
# File 'lib/typingtutor/exercise.rb', line 31

def self.available_exercises
  files = Dir[File.join(File.dirname(__FILE__), '..', '..', "exercises", "*.txt")]
  files.map! do |name|
    name = name.split(File::SEPARATOR).last
    name = name.gsub /\.txt/, ''
    name
  end
  files
end

.dictionaryObject



56
57
58
# File 'lib/typingtutor/exercise.rb', line 56

def self.dictionary
  @dictionary ||= Dictionary.new
end

.improve_exercise(stats) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/typingtutor/exercise.rb', line 41

def self.improve_exercise(stats)
  lines = []
  index = 0
  stats.worst_letters.to_h.each do |letter, accuracy|
    next if dictionary.pick_word_with_letter(letter).nil? # no samples to use
    lines << "You have a #{accuracy}% accuracy on letter #{letter}, let's work on that:"
    2.times do
      lines << 8.times.map {|i| dictionary.pick_word_with_letter(letter)}.join(" #{letter * (rand(2)+1)} ").strip
    end
    index += 1
    break if index > 5
  end
  lines
end

.load(name:, stats:) ⇒ Object

class methods



8
9
10
11
12
# File 'lib/typingtutor/exercise.rb', line 8

def self.load(name:, stats:)
  return nil if name.nil?
  body = load_body(name:name, stats:stats)
  return body.nil? ? nil : Exercise.new(name:name, body:body, stats:stats)
end

.load_body(name:, stats:) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/typingtutor/exercise.rb', line 14

def self.load_body(name:, stats:)
  gem_file_name = File.join(File.dirname(__FILE__), '..', '..', "exercises", "#{name}.txt")

  lines ||= dictionary.training_exercise if name == 'training'
  lines ||= improve_exercise(stats) if name == 'improve'
  # load from exercise folder in the gem
  lines ||= IO.read(name).lines if File.exists?(name)
  lines ||= IO.read("#{name}.txt").lines if File.exists?("#{name}.txt")
  lines ||= IO.read(gem_file_name).lines if File.exists?(gem_file_name)

  return if lines.nil?

  lines.each {|line| line.strip!}    # remove extra spaces
  lines.reject! {|line| line.strip.to_s == ""} # remove empty lines
  return lines
end

Instance Method Details

#playObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/typingtutor/exercise.rb', line 68

def play
  @start = Time.now
  results = body.map { |line| Line.new(line:line, stats:stats).play unless line == ""}
  self.time = Time.now - @start
  self.chars = results.map {|s| s[:chars] }.inject(:+)
  self.correct_chars = results.map {|s| s[:correct_chars] }.inject(:+)
  self.words = results.map {|s| s[:words] }.inject(:+)
  self.keystrokes  = results.map {|s| s[:keystrokes] }.inject(:+)
  self.typing_accuracy = (correct_chars.to_f / keystrokes.to_f * 100).to_i
  self.word_accuracy   = (correct_chars.to_f / chars.to_f * 100).to_i # TODO
  self.gross_wpm = words / (time / 60)
  stats.record_exercise(self)
  return results
end


96
97
98
99
100
101
102
103
# File 'lib/typingtutor/exercise.rb', line 96

def print
  puts
  puts "------------------------"
  puts "Time: #{time.round.divmod(60).join('m ')}s (#{words} words)"
  puts "Speed: #{gross_wpm.round} wpm"
  # puts "Word accuracy: #{word_accuracy}%"
  puts "Typing accuracy: #{typing_accuracy}%"
end

#resultsObject



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/typingtutor/exercise.rb', line 83

def results
  {
    time: time,
    chars: chars,
    correct_chars: correct_chars,
    words: words,
    keystrokes: keystrokes,
    typing_accuracy: typing_accuracy,
    word_accuracy: word_accuracy,
    gross_wpm: gross_wpm
  }
end