Ways to improve this clock algorithm?

Discussion in 'Python' started by Jacob H, Sep 15, 2003.

  1. Jacob H

    Jacob H Guest

    Hello all,

    I'm close to being a novice programmer and I never was good at math.
    So I'm curious to know ways in which this following code can be made
    more efficient, more elegant. The code just calculates and displays
    elapsed wall clock seconds since initialization.

    class ExampleTimer:
    def __init__(self):
    self.start = time.clock()

    def run(self):
    while 1:
    now = time.clock()
    allseconds = int(now) = int(self.start)
    seconds = 0
    minutes = 0
    hours = 0
    for n in range(1, (allseconds + 1)):
    seconds += 1
    if n % 60 == 0:
    minutes += 1
    seconds = 0
    if n % 3600 == 0:
    hours += 1
    minutes = 0
    print "%s hrs %s min %s sec" % (hours, minutes, seconds)
    time.sleep(1)

    app = ExampleTimer()
    app.run()

    I am grateful for any suggestions and advice. :)

    Jake
    Jacob H, Sep 15, 2003
    #1
    1. Advertising

  2. Jacob H

    Paul Rubin Guest

    (Jacob H) writes:

    > Hello all,
    >
    > I'm close to being a novice programmer and I never was good at math.
    > So I'm curious to know ways in which this following code can be made
    > more efficient, more elegant. The code just calculates and displays
    > elapsed wall clock seconds since initialization.
    >
    > class ExampleTimer:
    > def __init__(self):
    > self.start = time.clock()
    >
    > def run(self):
    > while 1:
    > now = time.clock()
    > allseconds = int(now) = int(self.start)


    I think you mean

    allseconds = int(now) - int(self.start)

    Now you can say

    hours = allseconds // 3600
    minutes = (allseconds // 60) % 60
    seconds = allseconds % 60

    instead of counting up to allseconds. You could also use the divmod
    function for a fancier way to do the same thing, but the above is
    straightforward enough.
    Paul Rubin, Sep 15, 2003
    #2
    1. Advertising

  3. (Jacob H) writes:

    > I am grateful for any suggestions and advice. :)


    import time
    class ExampleTimer(object):
    def __init__(self):
    print "This is my super clock"
    self.run()

    def run(self):
    while 1:
    self.update_time()
    print "%s hrs %s min %s sec" % (self.hours, self.mins, self.secs)
    time.sleep(1)

    def update_time(self):
    # I would use time.localtime() to update the time because doing this I am
    # sure that it is always syncd with my pc time. I think this is the only
    # improvement :). It also removes the need for all that math.
    self.secs = time.localtime()[5]
    self.mins = time.localtime()[4]
    self.hours = time.localtime()[3]

    app = ExampleTimer()
    app.run()



    --
    Valentino Volonghi, Regia SpA, Milan

    Linux User #310274, Debian Sid Proud User
    Valentino Volonghi aka Dialtone, Sep 15, 2003
    #3
  4. Jacob H

    Jeff Epler Guest

    Well, this doesn't run on my system. First, I had to change this line:
    > now = time.clock()

    - allseconds = int(now) = int(self.start)
    + allseconds = int(now) - int(self.start)
    > seconds = 0

    [In all the excerpts, "-" is a line changed/removed from your version,
    and "+" is a line changed/added in my version]

    Then, I had to insert an 'import':
    + import time
    +
    > class ExampleTimer:
    > def __init__(self):


    Then, this program kept printing "0 hrs 0 min 0 sec", because clock()
    returns CPU time (not wall time) on Unix computers. time.time() returns
    seconds on all systems Python supports, according to the online
    documentation. ("import time; help(time.time)")

    > def __init__(self):

    - self.start = time.clock()
    + self.start = time.time()

    > while 1:

    - now = time.clock()
    + now = time.time()

    Finally, I'm not sure what your 'for n in range ...' code is intended to
    do. You can convert the number of seconds into the
    hours/minutes/seconds more easily:
    # (Replacing the whole 'for' loop and the three asignments above it)
    # Take whole minutes and leave the seconds corresponding to the
    # fraction of minutes in seconds
    minutes = allseconds / 60
    seconds = allseconds % 60

    # Take whole hours and leave the minutes corresponding to the
    # fraction of the hour in minutes
    hours = minutes / 60
    minutes = minutes % 60
    You could do this with the built-in function divmod(), as well:
    # (Replacing the whole 'for' loop and the three asignments above it)
    minutes, seconds = divmod(allseconds, 60)
    hours, minutes = divmod(minutes, 60)

    You could test starting at different times by changing init:
    - def __init__(self):
    - self.start = time.clock()
    + def __init__(self, offset=0):
    + self.start = time.clock() - offset

    Now, you can easily see whether the "rollover" to 1 hour works right:
    - app = ExampleTimer()
    + app = ExampleTimer(60*60 - 1)
    > app.run()


    Jeff
    Jeff Epler, Sep 15, 2003
    #4
  5. Jacob H

    Andy Jewell Guest

    On Monday 15 Sep 2003 10:02 pm, Jacob H wrote:
    > Hello all,
    >
    > I'm close to being a novice programmer and I never was good at math.
    > So I'm curious to know ways in which this following code can be made
    > more efficient, more elegant. The code just calculates and displays
    > elapsed wall clock seconds since initialization.
    >
    > class ExampleTimer:
    > def __init__(self):
    > self.start = time.clock()
    >
    > def run(self):
    > while 1:
    > now = time.clock()
    > allseconds = int(now) = int(self.start)
    > seconds = 0
    > minutes = 0
    > hours = 0
    > for n in range(1, (allseconds + 1)):
    > seconds += 1
    > if n % 60 == 0:
    > minutes += 1
    > seconds = 0
    > if n % 3600 == 0:
    > hours += 1
    > minutes = 0
    > print "%s hrs %s min %s sec" % (hours, minutes, seconds)
    > time.sleep(1)
    >
    > app = ExampleTimer()
    > app.run()
    >
    > I am grateful for any suggestions and advice. :)
    >
    > Jake


    Jake,

    Maybe this'll help:
    >>> import time
    >>> start=time.time()
    >>> # waste some time...
    >>> now=time.time()-start
    >>> now

    266.24996101856232
    >>> secs=int(now % 60)
    >>> secs

    26
    >>> mins=int((now-secs) /60)
    >>> mins

    4
    >>> hrs=int((now-secs-mins) /(60*60))
    >>> hrs

    0
    >>>


    -andyj
    Andy Jewell, Sep 15, 2003
    #5
  6. Jacob H

    Jacob H Guest

    Thanks to all for the replies. They did indeed improve my clock algorithm. ;)

    Jake
    Jacob H, Sep 19, 2003
    #6
  7. On Mon, 15 Sep 2003 23:45:55 +0200, Valentino Volonghi aka Dialtone <dialtone#NOSPAM#> wrote:

    > (Jacob H) writes:
    >
    >> I am grateful for any suggestions and advice. :)

    >
    >import time
    >class ExampleTimer(object):
    > def __init__(self):
    > print "This is my super clock"
    > self.run()
    >
    > def run(self):
    > while 1:
    > self.update_time()
    > print "%s hrs %s min %s sec" % (self.hours, self.mins, self.secs)
    > time.sleep(1)
    >
    > def update_time(self):
    > # I would use time.localtime() to update the time because doing this I am
    > # sure that it is always syncd with my pc time. I think this is the only
    > # improvement :). It also removes the need for all that math.
    > self.secs = time.localtime()[5]
    > self.mins = time.localtime()[4]
    > self.hours = time.localtime()[3]

    Sooner or later a second will tick between the above statements and give inconsistent h,m,s.
    Better to get the tuple, slice it and unpack it, e.g., (untested)

    self.hours, self.mins, self.secs = time.localtime()[3:6]

    Also, time.sleep(1) will probably span an epsilon more than one second sometime, and
    when that hits the second updates right you will get a 2-second hiccup in apparent time
    output. As to when it will happen, it's only a matter of time ;-) (Unless you are running
    on some platform that has some underlying synchronization with wall clock seconds going on).

    One way to get around that might be to sync up with the seconds turnover, either with a
    busy wait or with a minimal sleep interval, then sleep say .99 seconds and wait again in
    a minimal sleep loop until the second-value changes (if it has not done so already due
    to extraneous delays). You can fine tune various aspects of this (as an exercise ;-)

    <rant>
    This kind of ugliness results if there's no way to tell the OS a precise wall clock time
    to ready your process/thread after a wait and/or if timers don't have a way of specifying
    accurate intervals that work to the nearest tick and don't accumulate tick resolution errors.
    Relatively simple to provide if you are coding the OS clock stuff, so why is application-level
    timer expiration usually only relative to a precisely unpredictable "now" instead of a time
    coordinate in some time coordinate system?
    </rant>

    >
    >app = ExampleTimer()
    >app.run()
    >
    >
    >
    >--
    >Valentino Volonghi, Regia SpA, Milan
    >
    >Linux User #310274, Debian Sid Proud User


    Regards,
    Bengt Richter
    Bengt Richter, Sep 20, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Valentin Tihomirov

    Are clock and divided clock synchronous?

    Valentin Tihomirov, Oct 23, 2003, in forum: VHDL
    Replies:
    11
    Views:
    3,285
    louis lin
    Oct 28, 2003
  2. Jéjé

    ways to improve compilation?

    Jéjé, Nov 8, 2004, in forum: ASP .Net
    Replies:
    6
    Views:
    393
    Jéjé
    Nov 11, 2004
  3. Replies:
    4
    Views:
    716
    Peter Alfke
    Apr 27, 2006
  4. Replies:
    5
    Views:
    2,159
    Ricardo
    Jun 23, 2006
  5. himassk
    Replies:
    1
    Views:
    1,230
    Paul Uiterlinden
    May 16, 2007
Loading...

Share This Page