Ruby -- How to require user input while simultaneously showing a countdown - ruby

(Warning: I'm relatively new to Ruby.)
I'm writing a simple math script that will help my kids learn their addition facts. I want to show a countdown that they need to beat with their answers. So, for instance, while they're watching a countdown go from 5 to 0, they need to press '6 + enter' in order to correctly answer 3 + 3 = ?. The '6 + enter' should stop the countdown and advance them to the next question.
Currently, this is the code for my countdown:
5.downto(0) do |i|
print "\r00:00:#{'%02d' % i}"
sleep 1
end
This works, as far as it goes. It gives me the countdown that I want. The problem is that I need to solicit an answer from the user that will interrupt this countdown -- while the countdown process is still running. As it stands, I could put a
answer = gets.chomp
after the countdown, but that's obviously not going to help me very much.
Any ideas? I've tried to read up on how to run simultaneous processes, but the explanations have been a bit difficult to follow, and none of the ones that I read about seemed to allow the kind of user interaction I'm after.
Thanks in advance for your help.!

Threading is the answer. Here's what I did. It isn't perfect, but it gets the job done.
student_answer = nil
timer = Thread.new do
5.downto(0) do |i|
puts "\r00:00:#{'%02d' % i}"
sleep 1
end
puts 'Time is up'
end
answer = Thread.new do
puts 'What is your answer?'
student_answer = gets.chomp
end
answer.join(5)
timer.join
if $answer.nil?
puts 'No Answer'
else
puts "Your answer is #{student_answer }"
end
This code will produce the following output
What is your answer?
00:00:05
00:00:04
00:00:03
00:00:02
00:00:01
00:00:00
Time is up
No Answer
Of course, you can enter your answer at anytime, but the answer thread is killed about 5 seconds, and you can no longer enter any answer.
Unfortunately, I can not figure out how to kill the timer thread once an answer is inputted. If anyone have any ideas, please let me know.

Related

how to assign specific time pop up message in uipath with message box

I want to use message box as good morning message at 8:00 everyday but I couldnt assign the time interval. Can anyone help me to assign specicif time in uipath for message box
A couple of options:
While Loop
Rather than a delay you could use a while loop to check the time.
So your sequence would be
While Date.Now.Hour <> 8
End While
Message Box "Good Morning"
Obviously doing this you won't be able to do anything while the loop is running so isn't really going to work properly
While Loop in Parallel
The benefit this has over the above solution is that it can run while something else is running too
Parallel
While True
If Date.Now.Hour = 8
Message Box "Good Morning"
End If
End While
End Parallel

Executing command after time has passed

I want to know how to execute a function after a certain amount of time has passed. The user will enter a duration, say 30 minutes, and after 30 minutes they will be given a message, along with other code being done. I am new to Ruby, and can't figure out the best way to do it.
If you don't want to block IO you can use threads:
time = gets.to_i # time in seconds
Thread.new do
sleep time
# your code here
end
Or just:
time = gets.to_i # time in seconds
sleep time
# your code here
You could look into gems like DelayedJob or Resque.

Getting Thread not to run until join in ruby

I am getting into ruby and have been using threads for a little while now with out fully understanding them. I notice that when adding a thread to an array and if I add a sleep() command as the first command the thread does not run until I do a join which is mostly what I want. So I have 2 questions.
1.Is that suppose to happen?
2.Is there a better way to do that other then the way I'm doing it. Here is a sample code that I have to show what I'm talking about.
job = Array.new
10.times do |n|
job << Thread.new do
sleep 0.001
puts "done #{n}"
end
end
#job.each do |t|
#t.join
#end
puts "End of script"
Output is
End of script
If I remove the comments output is
done 1
done 0
done 7
done 6
done 5
done 4
done 3
done 2
done 9
done 8
End of script
So I use this now but I don't understand why it does that. Sometimes I notice even doing something like `echo hi` instead of sleep does the trick.
Thanks in advance.
Timing of threads isn't a defined behavior. Once you put them to sleep, they will be put in a queue to be run later. You can't ever expect it to run one way or another.
Your main program doesn't take very long to run, so it is likely to happen to finish before your other threads get picked back up to run again. Really, when you think about it, 0.001 seconds is quite a long time to computer, so spinning off 10 threads in that time is likely to happen -- but even if it takes longer, there is no guarantee the thread will resume immediately after .001 seconds. Often there's really no guarantee it won't start before .001 seconds, either, but sleep calls usually don't end early.
When you add the join calls, you are introducing additional time into your main thread which allows the other threads time to run, so this behavior is expected.

how to delay 'say' actions in siri proxy plugin

I've started to play with Ruby on Rails to make some plugins for Siri Proxy Server.
I am inexperienced with Ruby but have manage the basics.
what I have done:
################ Commands
listen_for (/show a demo to (.*)/i) do |name|
show_demo
request_completed
end
################ Actions
def show_demo(name)
say "Hi #{name}, let me do a quick demo for You."
say "For example if You tell me 'Turn on sidelight' I will turn the sidelights in Living room like now..."
system "/usr/local/bin/tdtool --on 2"
say "That was the sidelights, and now if like I can turn on the gallery for You, just tell me 'turn on gallery' like so... "
system "/usr/local/bin/tdtool --on 3"
say "This only part of things I can do after mod."
say "Now I will turn all devices off..."
system "/usr/local/bin/tdtool --off 3"
system "/usr/local/bin/tdtool --off 2"
say " Thank You #{name}, and goodbye."
end
The problem is when I'll start the demo all the actionssystem "..." are executed before Siri start to say anything .
How can I delay above action to put them in right place in time to execute them right after words I want?
Thank You in advance.
The problem is that say won't wait for Siri to actually say the words, it just sends a packet over to your iDevice and then goes on. The simplest approach i can think of would be to wait a few seconds, depending on how long the text is. So first we need a method that gives us the duration to wait (in seconds). I tried with the OSX built-in say command and got the following results:
$ time say "For example if You tell me 'Turn on sidelight' I will turn the sidelights in Living room like now..."
say 0,17s user 0,05s system 3% cpu 6,290 total
$ time say "That was the sidelights, and now if like I can turn on the gallery for You, just tell me 'turn on gallery' like so... "
say 0,17s user 0,06s system 2% cpu 8,055 total
$ time say "This only part of things I can do after mod."
say 0,13s user 0,04s system 5% cpu 2,996 total
So this means we have the following data:
# Characters w/o whitespace | Seconds to execute
------------------------------+---------------------
77 | 6.290
87 | 8.055
34 | 2.996
This leaves us with an average of about 0.0875 seconds per character. You may need to evaluate the average time for your scenario yourself and with more samples. This function will wrap say and then wait until the text was spoken out by Siri:
def say_and_wait text, seconds_per_char=0.0875
say text
num_speakable_chars = text.gsub(/[^\w]/,'').size
sleep num_speakable_chars * seconds_per_char
end
where gsub(/[^\w]/,'') will remove any non-word characters from the string. Now you can use this to simply say something and wait for it to be spoken out:
say_and_wait "This is a test, just checking if 0.875 seconds per character are a good fit."
Or you can also override the duration in special cases:
say_and_wait "I will wait for ten seconds here...", 10
Let me know if it works for you.

Ruby, simple "threading" example to update progress in console app

I am trying to implement a simple console app that will do lots of long processes. During these processes I want to update progress.
I cannot find a SIMPLE example of how to do this anywhere!
I am still "young" in terms of Ruby knowledge and all I can seem to find are debates about Thread vs Fibers vs Green Threads, etc.
I'm using Ruby 1.9.2 if that helps.
th = Thread.new do # Here we start a new thread
Thread.current['counter']=0
11.times do |i| # This loops and increases i each time
Thread.current['counter']=i
sleep 1
end
return nil
end
while th['counter'].to_i < 10 do
# th is the long running thread and we can access the same variable as from inside the thread here
# keep in mind that this is not a safe way of accessing thread variables, for reading status information
# this works fine though. Read about Mutex to get a better understanding.
puts "Counter is #{th['counter']}"
sleep 0.5
end
puts "Long running process finished!"
Slightly smaller variation, and you don't need to read about Mutex.
require "thread"
q = Queue.new
Thread.new do # Here we start a new thread
11.times do |i| # This loops and increases i each time
q.push(i)
sleep 1
end
end
while (i = q.pop) < 10 do
puts "Counter is #{i}"
end
puts "Long running process finished!"

Resources