Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

display stuff based on systemclock

by Wire64 (Initiate)
on Jul 09, 2009 at 15:01 UTC ( [id://778585]=perlquestion: print w/replies, xml ) Need Help??

Wire64 has asked for the wisdom of the Perl Monks concerning the following question:

Hi wisdom monks,
Im trying to write someting that will a number of display messages based on systemclock, ill try to explain.

Say i got 10 messages and i want to show one every 5 seconds. so 1 message shows when the time is between 0:00 and 0:04seconds;
2nd message will show 0:05 <-> 0:09 seconds. ... message 10 will show 0:45 <-> 0:49.
then message 1 will show again from 0:50 <-> 0:54. 2 will be 0:55 <-> 0:59
when minute 1 starts i want it to start with message 3, thats 1:00 <-> 1:04
My question is how do i calculate this :)
hope this makes sence, thanks in advanced,
Wire64

dont have much that will do the above but will show you where i'am at now.
#!/usr/bin/perl # # display stuff on systemclock use Switch; # Get current date & time my ($tsec,$tmin,$thour,$tday,$tmonth,$tyear,$twday,$tyday,$tisdst) = l +ocaltime(time); $showitems=10; $delay=5; $totalshowtime=$showitems*$delay; #calulate how many minutes it will take to complete $showminutes = $totalshowtime / 60; #remove everthing behind the . so we get a round number $showminutes =~ s/(\d)\.\d*/$1/; switch ($showminutes) { case /0/ { my $number= $tsec / ($showitems * $delay) ; print "$number\n"; #print "0\n"; } case /1/ {print "1\n"; } else {print "-$showminutes- did not match any\n";} } print "$showminutes | $totalshowtime = $showitems * $delay"; print "\n$tsec $tmin";

Replies are listed 'Best First'.
Re: display stuff based on systemclock
by ikegami (Patriarch) on Jul 09, 2009 at 15:55 UTC

    Something like this?

    my @mesages = (...); my $pass = 0; for my $message (@messages) { sleep(5) if !$pass++; print($message); }

    sleep is interruptible and drift can occur if the loop body is non-trivial, so maybe the following would be better:

    use Time::HiRes qw( time sleep ); # Optional sub sleep_until { my ($e_time) = @_; for (;;) { my $dur = $e_time - time; last if $dur <= 0; sleep($dur); } } my @mesages = (...); my $s_time = time; for my $i (@messages) { sleep_until($s_time + 5*$i); print($message); }
      no i dont want it to use sleep, i want the program to exit after displaying the message.
      So when i execute the program at 7:05:02 i get a message and if i execute the program at 7:05:06 i get the next message. Should have explained that sorry. and i dont want to write to disk either.
        Forgetting we're dealing with times for a second, that's usually done using by subtracting the remainder of a division by your slot size.
        $ perl -e'printf "%-3s %2d\n", "$_:", $_ - ($_ % 5) for 0..19' 0: 0 1: 0 2: 0 3: 0 4: 0 5: 5 6: 5 7: 5 8: 5 9: 5 10: 10 11: 10 12: 10 13: 10 14: 10 15: 15 16: 15 17: 15 18: 15 19: 15

        The same trick can be applied to times.

        $ perl -MPOSIX -le'@lt = localtime; $lt[0] -= $lt[0] % 5; print strfti +me "%Y-%m-%dT%H:%M:%S", @lt' 2009-07-09T12:14:40 $ perl -MPOSIX -le'@lt = localtime; $lt[0] -= $lt[0] % 5; print strfti +me "%Y-%m-%dT%H:%M:%S", @lt' 2009-07-09T12:14:40 $ perl -MPOSIX -le'@lt = localtime; $lt[0] -= $lt[0] % 5; print strfti +me "%Y-%m-%dT%H:%M:%S", @lt' 2009-07-09T12:14:45 $ perl -MPOSIX -le'@lt = localtime; $lt[0] -= $lt[0] % 5; print strfti +me "%Y-%m-%dT%H:%M:%S", @lt' 2009-07-09T12:14:45

        The question is what do you want to happen if 60 isn't divisible by $delay?

Re: display stuff based on systemclock
by ramlight (Friar) on Jul 09, 2009 at 17:49 UTC
    If I understand your problem correctly, you just want to display one of a number of messages based on the current time, then quit.

    UPDATE: As noted by Ikegami below, this is wrong!
    "So take the current time in seconds; mod it by the total number of seconds in a message cycle, and divide the results by the number of messages you have:"

    The correct formula (Thanks to Ikegami again) is (time / message-display-time) mod number-of-messages.

    # See correct version of this by ikegami below! @message = ("Message 1", "Message 2", "Message 3", "Message 4", "Message 5", "Message 6", "Message 7", "Message 8", "Message 9", "Message 10"); $num_msgs = @message; $msg_time = 5; $total_time = $num_msgs * $msg_time; $msg_num = int((time() % $total_time) / $num_msgs); print $message[$msg_num], "\n";

      Ah! That's what the OP meant. Unfortunately, there's a bug in your formula.

      It displays the first $msg_time messages for $num_msgs seconds.
      It should display the $num_msgs messages for $msg_time seconds.

      Fixed:

      my @message = ( "Message 1", "Message 2", "Message 3", "Message 4", "Message 5", "Message 6", "Message 7", "Message 8", "Message 9", "Message 10", ); my $msg_time = 5; print $message[ time / $msg_time % @message ], "\n";
        You are, of course, right. A little more time spent verifying my results would definitely have been worth while!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://778585]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2025-05-23 18:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.