cw 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.cw_config +18 -0
- data/.gitignore +10 -1
- data/LICENSE +2 -1
- data/README.md +212 -96
- data/Rakefile +15 -2
- data/VERSION +1 -1
- data/Vagrantfile +45 -0
- data/cw.gemspec +6 -1
- data/data/text/book_to_read.txt +4 -0
- data/data/text/english.txt +10000 -0
- data/example.rb +172 -106
- data/lib/cw.rb +10 -126
- data/lib/cw/alphabet.rb +53 -46
- data/lib/cw/audio_player.rb +83 -72
- data/lib/cw/book.rb +160 -185
- data/lib/cw/book_details.rb +38 -49
- data/lib/cw/cl.rb +101 -95
- data/lib/cw/common_words.rb +76 -0
- data/lib/cw/config.rb +50 -0
- data/lib/cw/current_word.rb +23 -24
- data/lib/cw/cw_dsl.rb +264 -131
- data/lib/cw/cw_encoding.rb +63 -69
- data/lib/cw/cw_stream.rb +86 -82
- data/lib/cw/cw_threads.rb +132 -22
- data/lib/cw/element.rb +60 -54
- data/lib/cw/file_details.rb +26 -11
- data/lib/cw/key_input.rb +53 -35
- data/lib/cw/numbers.rb +26 -19
- data/lib/cw/os.rb +13 -0
- data/lib/cw/play.rb +92 -0
- data/lib/cw/print.rb +102 -100
- data/lib/cw/process.rb +3 -0
- data/lib/cw/progress.rb +20 -17
- data/lib/cw/randomize.rb +56 -52
- data/lib/cw/repeat_word.rb +59 -66
- data/lib/cw/reveal.rb +32 -31
- data/lib/cw/rss.rb +52 -48
- data/lib/cw/sentence.rb +83 -76
- data/lib/cw/speak.rb +8 -4
- data/lib/cw/spoken.rb +8 -4
- data/lib/cw/str.rb +62 -30
- data/lib/cw/test_letters.rb +20 -28
- data/lib/cw/test_words.rb +25 -31
- data/lib/cw/tester.rb +219 -226
- data/lib/cw/text_helpers.rb +19 -15
- data/lib/cw/timing.rb +63 -67
- data/lib/cw/tone_generator.rb +176 -153
- data/lib/cw/tone_helpers.rb +15 -23
- data/lib/cw/voice.rb +12 -8
- data/lib/cw/words.rb +136 -106
- data/run_script_tests.rb +165 -0
- data/test/my_words.txt +1 -0
- data/test/test_common_words.rb +71 -0
- data/test/test_config.rb +98 -0
- data/test/test_current_word.rb +62 -0
- data/test/test_cw.rb +87 -120
- data/test/test_cw_threads.rb +123 -0
- data/test/test_filtering.rb +439 -0
- data/test/test_params.rb +28 -0
- data/test/test_play.rb +51 -0
- data/test/test_stream.rb +83 -83
- data/test/test_tester.rb +9 -27
- data/test/test_timing.rb +212 -0
- metadata +94 -12
- data/lib/cw/config_file.rb +0 -69
- data/lib/cw/monitor_keys.rb +0 -37
- data/lib/cw/params.rb +0 -104
data/lib/cw/element.rb
CHANGED
@@ -1,73 +1,79 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
return @last_element - 1 if type == :last
|
5
|
-
first = @last_element - @active_region - 1
|
6
|
-
first < 0 ? 0 : first
|
7
|
-
end
|
3
|
+
module CWG
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
first
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
module Element
|
6
|
+
|
7
|
+
def element type
|
8
|
+
return @last_element - 1 if type == :last
|
9
|
+
first = @last_element - @active_region - 1
|
10
|
+
first < 0 ? 0 : first
|
11
|
+
end
|
12
|
+
|
13
|
+
def match_first_active_element match
|
14
|
+
if ! stream_empty?
|
15
|
+
found = false
|
16
|
+
first = element(:first)
|
17
|
+
first.upto element(:last) do |ele|
|
18
|
+
if found
|
19
|
+
first.upto found - 1 do |failed|
|
20
|
+
@success[failed] = false # unless @success[ele]
|
21
|
+
end
|
22
|
+
break
|
23
|
+
elsif((@stream[ele] == match) && (! @success[ele]))
|
24
|
+
@success[ele], found = true, ele
|
25
|
+
else
|
26
|
+
@success[first] = false
|
17
27
|
end
|
18
|
-
break
|
19
|
-
elsif((@stream[ele] == match) && (! @success[ele]))
|
20
|
-
@success[ele], found = true, ele
|
21
|
-
else
|
22
|
-
@success[first] = false
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
26
|
-
end
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
def match_last_active_element(match)
|
33
|
+
process_last_active_element(match) unless stream_empty?
|
34
|
+
end
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
def process_last_active_element(match)
|
37
|
+
first = get_first
|
38
|
+
last = get_last
|
39
|
+
check_last_element_success(match, first, last)
|
40
|
+
end
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
def check_last_element_success(match, first, last)
|
43
|
+
found = false
|
44
|
+
last.downto(first) do |element|
|
45
|
+
if found
|
46
|
+
@success[element] = false unless @success[element]
|
47
|
+
elsif((@stream[element] == match) && (! @success[element]))
|
48
|
+
@success[element], found = true, true
|
49
|
+
else
|
50
|
+
@success[first] = false
|
51
|
+
end
|
47
52
|
end
|
48
53
|
end
|
49
|
-
end
|
50
54
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
55
|
+
def get_first
|
56
|
+
first = @last_element - @active_region - 1
|
57
|
+
first = 0 if(first < 0)
|
58
|
+
first
|
59
|
+
end
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
61
|
+
def get_last
|
62
|
+
@last_element - 1
|
63
|
+
end
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
def count
|
66
|
+
@last_element - @first_element
|
67
|
+
end
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
|
69
|
+
def inc_last_element
|
70
|
+
@last_element += 1
|
71
|
+
end
|
72
|
+
|
73
|
+
def inc_first_element
|
74
|
+
@first_element += 1
|
75
|
+
end
|
68
76
|
|
69
|
-
def inc_first_element
|
70
|
-
@first_element += 1
|
71
77
|
end
|
72
78
|
|
73
79
|
end
|
data/lib/cw/file_details.rb
CHANGED
@@ -1,16 +1,31 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
HERE = File.dirname(__FILE__) + '/'
|
5
|
-
TEXT = HERE + '../../data/text/'
|
6
|
-
AUDIO = HERE + '../../audio/'
|
3
|
+
module CWG
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
module FileDetails
|
6
|
+
HERE = File.dirname(__FILE__)
|
7
|
+
ROOT = File.expand_path File.join(HERE,'..','..')
|
8
|
+
TEXT = File.join(ROOT,'data','text')
|
9
|
+
AUDIO = File.join(ROOT,'audio')
|
10
|
+
|
11
|
+
ENGLISH_DICT = File.join TEXT, "english.txt"
|
12
|
+
ABBREVIATIONS = File.join TEXT, "abbreviations.txt"
|
13
|
+
Q_CODES = File.join TEXT, "q_codes.txt"
|
14
|
+
DOT_FILENAME = File.join AUDIO, "dot.wav"
|
15
|
+
DASH_FILENAME = File.join AUDIO, "dash.wav"
|
16
|
+
SPACE_FILENAME = File.join AUDIO, "space.wav"
|
17
|
+
E_SPACE_FILENAME = File.join AUDIO, "e_space.wav"
|
18
|
+
CONFIG_FILENAME = File.join ROOT, ".cw_config"
|
15
19
|
|
20
|
+
def init_filenames
|
21
|
+
@repeat_tone = File.join(AUDIO, "rpt.mp3")
|
22
|
+
@r_tone = File.join(AUDIO, "r.mp3")
|
23
|
+
@text_folder = TEXT
|
24
|
+
@progress_file = 'progress.txt'
|
25
|
+
end
|
26
|
+
|
27
|
+
def expand path
|
28
|
+
File.expand_path path
|
29
|
+
end
|
30
|
+
end
|
16
31
|
end
|
data/lib/cw/key_input.rb
CHANGED
@@ -1,53 +1,71 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
module CWG
|
4
4
|
|
5
|
-
|
6
|
-
@quit_ary = Array.new(4)
|
7
|
-
end
|
5
|
+
class KeyInput
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
def initialize
|
8
|
+
@quit_count = 0
|
9
|
+
end
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
begin
|
16
|
-
system("stty raw -echo")
|
17
|
-
@chr = STDIN.getc
|
18
|
-
ensure
|
19
|
-
system("stty raw -echo")
|
11
|
+
def char
|
12
|
+
@chr
|
20
13
|
end
|
21
|
-
end
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
def read
|
16
|
+
@chr = nil
|
17
|
+
begin
|
18
|
+
system("stty raw -echo")
|
19
|
+
@chr = STDIN.getc
|
20
|
+
ensure
|
21
|
+
system("stty raw -echo")
|
22
|
+
end
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def is_letter?
|
26
|
+
@chr >= 'a' && @chr <= 'z'
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def is_number?
|
30
|
+
@chr >= '0' && @chr <= '9'
|
31
|
+
end
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
def is_punctuation?
|
34
|
+
[' ', ',', '.', '=', '?'].detect{|letr| letr == @chr}
|
35
|
+
end
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
def is_relevant_char?
|
38
|
+
is_letter? || is_number? || is_punctuation? ? true : false
|
39
|
+
end
|
40
|
+
|
41
|
+
def reset_stdin
|
42
|
+
system("stty -raw echo")
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def push_to_quit_maybe
|
47
|
+
if @chr == 'q'
|
48
|
+
@quit_count += 1
|
49
|
+
else
|
50
|
+
@quit_count = 0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_quit?
|
55
|
+
@quit_count >= 4
|
56
|
+
end
|
42
57
|
|
43
|
-
|
44
|
-
|
45
|
-
@quit_ary[3] = @chr
|
46
|
-
quit_str = @quit_ary.join.downcase
|
47
|
-
if quit_str == 'qqqq'
|
58
|
+
def quit
|
59
|
+
Cfg.config.params["exit"] = true
|
48
60
|
reset_stdin
|
49
61
|
return true
|
50
62
|
end
|
63
|
+
|
64
|
+
def quit_input?
|
65
|
+
push_to_quit_maybe
|
66
|
+
return quit if is_quit?
|
67
|
+
end
|
68
|
+
|
51
69
|
end
|
52
70
|
|
53
71
|
end
|
data/lib/cw/numbers.rb
CHANGED
@@ -1,29 +1,36 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
module CWG
|
4
4
|
|
5
|
-
class Numbers
|
5
|
+
#class Numbers provides the Number Testing functionality
|
6
6
|
|
7
|
-
|
8
|
-
@options = options
|
9
|
-
end
|
7
|
+
class Numbers
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
def initialize(options = {})
|
10
|
+
@options = options
|
11
|
+
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
def number_list
|
14
|
+
'1234567890'
|
15
|
+
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
def reverse_numbers_maybe
|
18
|
+
@numbers.reverse! if @options[:reverse]
|
19
|
+
end
|
20
|
+
|
21
|
+
def shuffle_numbers_maybe
|
22
|
+
unless(ENV["CW_ENV"] == "test")
|
23
|
+
@numbers = @numbers.split('').shuffle.join if @options[:shuffle]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate
|
28
|
+
@numbers = number_list
|
29
|
+
shuffle_numbers_maybe
|
30
|
+
reverse_numbers_maybe
|
31
|
+
@numbers.split('').join(' ')
|
32
|
+
end
|
22
33
|
|
23
|
-
def generate
|
24
|
-
@numbers = number_list
|
25
|
-
shuffle_numbers_maybe
|
26
|
-
reverse_numbers_maybe
|
27
|
-
@numbers.split('').join(' ')
|
28
34
|
end
|
35
|
+
|
29
36
|
end
|
data/lib/cw/os.rb
ADDED
data/lib/cw/play.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CWG
|
4
|
+
|
5
|
+
class Play
|
6
|
+
|
7
|
+
def initialize words
|
8
|
+
@words = words
|
9
|
+
end
|
10
|
+
|
11
|
+
def quit?
|
12
|
+
if Cfg.config["quit"].nil?
|
13
|
+
Cfg.config.params["quit"] = false
|
14
|
+
Cfg.config["quit"]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def audio
|
19
|
+
@audio ||= AudioPlayer.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def init_play_words_timeout
|
23
|
+
@start_play_time, @delay_play_time = Time.now, 2.0
|
24
|
+
end
|
25
|
+
|
26
|
+
def play_words_timeout?
|
27
|
+
(Time.now - @start_play_time) > @delay_play_time
|
28
|
+
end
|
29
|
+
|
30
|
+
def start_sync
|
31
|
+
@start_sync = true
|
32
|
+
end
|
33
|
+
|
34
|
+
def start_sync?
|
35
|
+
if @start_sync
|
36
|
+
@start_sync = nil
|
37
|
+
true
|
38
|
+
else
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def wait_player_startup_delay
|
44
|
+
sleep 0.2
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_space words
|
48
|
+
str = ''
|
49
|
+
words.to_array.collect { |word| str << word + ' '}
|
50
|
+
str
|
51
|
+
end
|
52
|
+
|
53
|
+
def play
|
54
|
+
audio.play
|
55
|
+
end
|
56
|
+
|
57
|
+
def play_audio
|
58
|
+
audio.convert_words add_space @words
|
59
|
+
start_sync()
|
60
|
+
play
|
61
|
+
end
|
62
|
+
|
63
|
+
def play_words_exit
|
64
|
+
# puts "play_words_exit"
|
65
|
+
init_play_words_timeout
|
66
|
+
loop do
|
67
|
+
break if quit?
|
68
|
+
break if play_words_timeout?
|
69
|
+
if Cfg.config["exit"]
|
70
|
+
audio.stop
|
71
|
+
break
|
72
|
+
end
|
73
|
+
sleep 0.01
|
74
|
+
end
|
75
|
+
Cfg.config["exit"] = true
|
76
|
+
sleep 0.1
|
77
|
+
end
|
78
|
+
|
79
|
+
def play_words_until_quit
|
80
|
+
play_audio
|
81
|
+
play_words_exit unless Cfg.config["print_letters"]
|
82
|
+
end
|
83
|
+
|
84
|
+
def still_playing?
|
85
|
+
audio.still_playing?
|
86
|
+
end
|
87
|
+
|
88
|
+
def stop
|
89
|
+
audio.stop
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/cw/print.rb
CHANGED
@@ -3,136 +3,138 @@
|
|
3
3
|
require 'paint'
|
4
4
|
require 'io/console'
|
5
5
|
|
6
|
-
|
6
|
+
module CWG
|
7
7
|
|
8
|
-
class
|
9
|
-
def colour
|
10
|
-
:yellow
|
11
|
-
end
|
8
|
+
class Print
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
STDOUT.puts Paint[x, colour]
|
18
|
-
end
|
10
|
+
class ProgressPrint
|
11
|
+
def colour
|
12
|
+
:yellow
|
13
|
+
end
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
def print x
|
16
|
+
STDOUT.print Paint[x, colour]
|
17
|
+
end
|
18
|
+
def puts x
|
19
|
+
STDOUT.puts Paint[x, colour]
|
20
|
+
end
|
21
|
+
|
22
|
+
def flush
|
23
|
+
STDOUT.flush
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
def tty?
|
27
|
+
true
|
28
|
+
end
|
26
29
|
end
|
27
|
-
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def initialize
|
32
|
+
update_console_size
|
33
|
+
reset
|
34
|
+
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def console_size
|
37
|
+
IO.console.winsize
|
38
|
+
rescue LoadError
|
39
|
+
[Integer(`tput li`), Integer(`tput co`)]
|
40
|
+
end
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
# printf "%d rows by %d columns\n", @rows, @cols
|
43
|
-
|
42
|
+
def update_console_size
|
43
|
+
@rows, @cols = console_size
|
44
|
+
# printf "%d rows by %d columns\n", @rows, @cols
|
45
|
+
end
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def reset
|
48
|
+
@print_count = 0
|
49
|
+
puts "\r"
|
50
|
+
end
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
def newline
|
53
|
+
reset
|
54
|
+
update_console_size
|
55
|
+
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
def force_newline_maybe
|
58
|
+
if @print_count >= (@cols - 1)
|
59
|
+
newline
|
60
|
+
true
|
61
|
+
end
|
59
62
|
end
|
60
|
-
end
|
61
63
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
def newline_maybe word
|
65
|
+
@print_count += word.size unless force_newline_maybe
|
66
|
+
return if((word.size == 1) && (word != ' '))
|
67
|
+
if @print_count > (@cols - 10)
|
68
|
+
newline
|
69
|
+
true
|
70
|
+
end
|
68
71
|
end
|
69
|
-
end
|
70
72
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
73
|
+
def results popped, type = :pass_and_fail
|
74
|
+
if popped
|
75
|
+
value = popped[:value]
|
76
|
+
success = popped[:success]
|
75
77
|
|
76
|
-
|
78
|
+
newline_maybe value
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
print Paint["#{value} ", success_colour] if success
|
81
|
+
print Paint["#{value} ", fail_colour ] unless (success || type == :pass_only)
|
82
|
+
return true
|
83
|
+
end
|
81
84
|
end
|
82
|
-
end
|
83
85
|
|
84
|
-
|
85
|
-
|
86
|
-
|
86
|
+
def paint(value, colour)
|
87
|
+
Paint[value, colour]
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
def paint_success_failure(popped)
|
91
|
+
print paint(popped[:value], success_colour) if popped[:success]
|
92
|
+
print paint(popped[:value], fail_colour ) unless popped[:success]
|
93
|
+
end
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
def char_result popped
|
96
|
+
unless newline_maybe popped[:value]
|
97
|
+
popped[:value] = '_' if((popped[:value] == ' ') && (popped[:success] != true))
|
98
|
+
paint_success_failure(popped)
|
99
|
+
return true
|
100
|
+
end
|
98
101
|
end
|
99
|
-
end
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
103
|
+
def heading
|
104
|
+
"Current Sentence is duration: secs".length.times do
|
105
|
+
print paint('*', list_colour)
|
106
|
+
puts
|
107
|
+
end
|
105
108
|
end
|
106
|
-
end
|
107
109
|
|
108
|
-
|
109
|
-
|
110
|
-
|
110
|
+
def fail word
|
111
|
+
print paint("#{word}", fail_colour)
|
112
|
+
end
|
111
113
|
|
112
|
-
|
113
|
-
|
114
|
-
|
114
|
+
def list word
|
115
|
+
print paint("#{word}", list_colour)
|
116
|
+
end
|
115
117
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
118
|
+
def success word
|
119
|
+
newline_maybe word
|
120
|
+
return if(@print_count == 0 && word == ' ')
|
121
|
+
print paint("#{word}", success_colour)
|
122
|
+
end
|
121
123
|
|
122
|
-
|
123
|
-
|
124
|
-
|
124
|
+
def success_colour
|
125
|
+
Cfg.config["success_colour"].to_sym || :blue
|
126
|
+
end
|
125
127
|
|
126
|
-
|
127
|
-
|
128
|
-
|
128
|
+
def fail_colour
|
129
|
+
Cfg.config["fail_colour"].to_sym || :red
|
130
|
+
end
|
129
131
|
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
def list_colour
|
133
|
+
Cfg.config["list_colour"].to_sym || :default
|
134
|
+
end
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
+
def print_advice name
|
137
|
+
puts "#{name}: Press Q 4 times to Exit"
|
138
|
+
end
|
136
139
|
end
|
137
|
-
|
138
140
|
end
|