How to get a stopwatch program running?
Asked Answered
A

4

1

I borrowed some code from a site, but I don't know how to get it to display.

class Stopwatch
  def start
    @accumulated = 0 unless @accumulated
    @elapsed = 0
    @start = Time.now
    @mybutton.configure('text' => 'Stop')
    @mybutton.command { stop }
    @timer.start
  end

  def stop
    @mybutton.configure('text' => 'Start')
    @mybutton.command { start }
    @timer.stop
    @accumulated += @elapsed
  end

  def reset
    stop
    @accumulated, @elapsed = 0, 0
    @mylabel.configure('text' => '00:00:00.00.000')
  end

  def tick
    @elapsed = Time.now - @start
    time = @accumulated + @elapsed
    h = sprintf('%02i', (time.to_i / 3600))
    m = sprintf('%02i', ((time.to_i % 3600) / 60))
    s = sprintf('%02i', (time.to_i % 60))
    mt = sprintf('%02i', ((time - time.to_i)*100).to_i)
    ms = sprintf('%04i', ((time - time.to_i)*10000).to_i)
    ms[0..0]=''
    newtime = "#{h}:#{m}:#{s}.#{mt}.#{ms}"
    @mylabel.configure('text' => newtime)
  end
end

How would I go about getting this running? Thanks

Alicealicea answered 13/5, 2009 at 16:29 Comment(2)
What framework were you planning to use this with?Maloy
Shoes. Unless you can recommend a better one. I'm kinda a beginner.Alicealicea
M
4

Based upon the additional code rkneufeld posted, this class requires a timer that is specific to Tk. To do it on the console, you could just create a loop that calls tick over and over. Of course, you have to remove all the code that was related to the GUI:

class Stopwatch
  def start
    @accumulated = 0 unless @accumulated
    @elapsed = 0
    @start = Time.now
#    @mybutton.configure('text' => 'Stop')
#    @mybutton.command { stop }
#    @timer.start
  end

  def stop
#    @mybutton.configure('text' => 'Start')
#    @mybutton.command { start }
#    @timer.stop
    @accumulated += @elapsed
  end

  def reset
    stop
    @accumulated, @elapsed = 0, 0
#    @mylabel.configure('text' => '00:00:00.00.000')
  end

  def tick
    @elapsed = Time.now - @start
    time = @accumulated + @elapsed
    h = sprintf('%02i', (time.to_i / 3600))
    m = sprintf('%02i', ((time.to_i % 3600) / 60))
    s = sprintf('%02i', (time.to_i % 60))
    mt = sprintf('%02i', ((time - time.to_i)*100).to_i)
    ms = sprintf('%04i', ((time - time.to_i)*10000).to_i)
    ms[0..0]=''
    newtime = "#{h}:#{m}:#{s}.#{mt}.#{ms}"
#    @mylabel.configure('text' => newtime)
  end
end

watch = Stopwatch.new
watch.start
1000000.times do
  puts watch.tick
end

You'll end up with output like this:

00:00:00.00.000
00:00:00.00.000
00:00:00.00.000
...
00:00:00.00.000
00:00:00.00.000
00:00:00.01.160
00:00:00.01.160
...

Not particularly useful, but there it is. Now, if you're looking to do something similar in Shoes, try this tutorial that is very similar.

Maloy answered 13/5, 2009 at 17:59 Comment(0)
L
1

I believe you have found the example on this site

I'm repeating what is already on the site but you are missing:

require 'tk'

as well as initialization code:

 def initialize
        root =  TkRoot.new { title 'Tk Stopwatch' }

        menu_spec = [
                     [
                      ['Program'],
                      ['Start', lambda { start } ],
                      ['Stop', lambda { stop } ],
                      ['Exit', lambda { exit } ]
                     ],
                     [
                      ['Reset'], ['Reset Stopwatch', lambda { reset } ]
                     ]
                    ]

        @menubar = TkMenubar.new(root, menu_spec, 'tearoff' => false)
        @menubar.pack('fill'=>'x', 'side'=>'top')

        @myfont = TkFont.new('size' => 16, 'weight' => 'bold')

        @mylabel = TkLabel.new(root)
        @mylabel.configure('text' => '00:00:00.0', 'font' => @myfont)
        @mylabel.pack('padx' => 10, 'pady' => 10)
        @mybutton =  TkButton.new(root)
        @mybutton.configure('text' => 'Start')
        @mybutton.command { start }
        @mybutton.pack('side'=>'left', 'fill' => 'both')


        @timer = TkAfter.new(1, -1, proc { tick })

        Tk.mainloop
      end
    end

    Stopwatch.new

I would suggest reading through the rest of the site to understand what is all going on.

Loverly answered 13/5, 2009 at 16:50 Comment(1)
Yeah i know that. I want to use Shoes instead and was trying to convert it as such. I would preferably just like it to return something, even just in the terminal.Alicealicea
H
1

I was searching for a quick and dirty stop watch class to avoid coding such and came upon the site where the original code was posted and this site as well.

In the end, I modified the code until it met what I think that I was originally searching for.

In case anyone is interested, the version that I have ended up thus far with is as follows (albeit that I have yet to apply it in the application that I am currently updating and for which I want to make use of such functionality).

#    REFERENCES
#       1. https://mcmap.net/q/1920485/-how-to-get-a-stopwatch-program-running
#       2. http://codeidol.com/other/rubyckbk/User-Interface/Creating-a-GUI-Application-with-Tk/
#       3. http://books.google.com.au/books?id=bJkznhZBG6gC&pg=PA806&lpg=PA806&dq=ruby+stopwatch+class&source=bl&ots=AlH2e7oWWJ&sig=KLFR-qvNfBfD8WMrUEbVqMbN_4o&hl=en&ei=WRjOTbbNNo2-uwOkiZGwCg&sa=X&oi=book_result&ct=result&resnum=8&ved=0CEsQ6AEwBw#v=onepage&q=ruby%20stopwatch%20class&f=false
#       4. http://4loc.wordpress.com/2008/09/24/formatting-dates-and-floats-in-ruby/


module Utilities
  class StopWatch
    def new()
      @watch_start_time = nil           #Time (in seconds) when the stop watch was started (i.e. the start() method was called).
      @lap_start_time   = nil           #Time (in seconds) when the current lap started.
    end  #def new


    def start()
      myCurrentTime = Time.now()        #Current time in (fractional) seconds since the Epoch (January 1, 1970 00:00 UTC)

      if (!running?) then    
        @watch_start_time = myCurrentTime         
        @lap_start_time   = @watch_start_time
      end  #if

      myCurrentTime - @watch_start_time;
    end  #def start


    def lap_time_seconds()
      myCurrentTime = Time.now()
      myLapTimeSeconds = myCurrentTime - @lap_start_time
      @lap_start_time  = myCurrentTime
      myLapTimeSeconds
    end  #def lap_time_seconds


    def stop()
      myTotalSecondsElapsed = Time.now() - @watch_start_time
      @watch_start_time = nil

      myTotalSecondsElapsed
    end  #def stop


    def running?()
      !@watch_start_time.nil?
    end  #def
  end  #class StopWatch
end  #module Utilities






def kill_time(aRepeatCount)
  aRepeatCount.times do
    #just killing time
  end  #do
end  #def kill_time



elapsed_time_format_string = '%.3f'

myStopWatch = Utilities::StopWatch.new()
puts 'total time elapsed: ' + elapsed_time_format_string % myStopWatch.start() + ' seconds'

kill_time(10000000)
puts 'lap time:           ' + elapsed_time_format_string % myStopWatch.lap_time_seconds() + ' seconds'

kill_time(20000000)
puts 'lap time:           ' + elapsed_time_format_string % myStopWatch.lap_time_seconds() + ' seconds'

kill_time(30000000)
puts 'lap time:           ' + elapsed_time_format_string % myStopWatch.lap_time_seconds() + ' seconds'
puts 'total time elapsed: ' + elapsed_time_format_string % myStopWatch.stop() + ' seconds'
Heurlin answered 15/5, 2011 at 9:40 Comment(0)
T
0

Simple stopwatch script:

# pass the number of seconds as the parameter

seconds = eval(ARGV[0]).to_i
start_time = Time.now

loop do
  elapsed = Time.now - start_time
  print "\e[D" * 17
  print "\033[K"

  if elapsed > seconds
    puts "Time's up!"
    exit
  end

  print Time.at(seconds - elapsed).utc.strftime('%H:%M:%S.%3N')
  sleep(0.05)
end

Run like this in your terminal (to mark a lap, just tap enter):

# 10 is the number of seconds
ruby script.rb 10 
# you can even do this:
ruby script.rb "20*60" # 20 minutes
Thenceforward answered 13/5, 2014 at 20:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.