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

I am quite new to Perl and this is my first post here so be gentle. I am using real time in a countdown timer of 60 seconds and need to be able to stop it every 10 seconds and the user must then input whether they would like to continue the countdown or not at each interval of 10. The timer works, I just can't figure out how to pause it for the user to input their response. As basic of an answer as possible would be very welcomed as I do not understand a lot yet. Thank you and here is my code so far.
my $countdown = 1*60; #60 seconds $| = 1; #disable output buffering my $start_time = time; my $end_time = $start_time + $countdown; for (;;) { my $time = time; last if ($time >= $end_time); printf("\r%02d:%02d:%02d", ($end_time - $time) / (1*60), ($end_time - $time) / 60%60, ($end_time - $time) % 60, ); sleep(1); }

Code tags added by GrandFather

Replies are listed 'Best First'.
Re: How do I pause real time in Perl
by ww (Archbishop) on Nov 01, 2013 at 20:35 UTC
    Among the activities which can help you to understand more are:
    1. use strict; use warnings; they're there to help you find typos and other mistakes. Generally, they're a new Perl programmers 2nd best friend (in line right behind perldoc [-c function] | &$91;module&93;) and in this case, were you to replace your printf statement with three separate print statements you'd discovered some problems.
    2. Next time, READ the instructions around the text box where you enter your node). Where you a registered user you could see those instructions immediately below the rendered text were you to re-visit another of the nodes created after registering.
    3. Consider why you have chose to multiply 1*60 and to calculate 60%60 (Hint 1: one times anything is what? Hint 2: anything modulus itself is what?).

    Run this (it's --mostly-- not a 'how-to' but rather an illustration of 'how-not-to-do-it.'); chew on what you see as output for a bit:

    (mostly) BAAAD CODE! #!/usr/bin/perl use 5.016; # implicit use strict; with recent vers +ions of perl use warnings; # 1060823 my $countdown = 1*60; # 60 seconds $| = 1; # disable output buffering my $start_time = time; # use the time function (see perldoc - +f time) say "\t \$start_time: $start_time"; my $end_time = $start_time + $countdown; for (;;) { # empty for clause my $time = time; say $time; last if ($time >= $end_time); # printf("\r%02d:%02d:%02d", ($end_time - $time) / (1*60); ($end_t +ime - $time) / 60%60, ($end_time - $time) % 60); say "Ln 19: " . (($end_time - $time) / (1*60)); say " Ln 20: " . (($end_time - $time) / 60%60); say " Ln 23: " .(($end_time - $time) % 60); sleep(1); }

    Questions? C'mon back with those you can't answer for yourself from the relevant documents, Tutorials here, etc. You'll get quick and friendly responses.

Re: How do I pause real time in Perl
by kcott (Archbishop) on Nov 02, 2013 at 08:06 UTC

    This code does what you want (at least, as far as I can tell from your very hard-to-read posting):

    #!/usr/bin/env perl use strict; use warnings; use Time::HiRes qw{usleep}; use Time::Piece; my ($countdown, $check) = @ARGV; $countdown = 60 unless defined $countdown; $check ||= 10; # Avoid "Illegal modulus zero" error my $countdown_remaining = Time::Piece->strptime(0 => '%S'); $countdown_remaining += $countdown; my $continue_re = qr{(?:^$|^[Yy])}; print_timestamp('Started'); { local $| = 1; do { print_countdown($countdown_remaining); my $seconds_remaining = $countdown_remaining->epoch; print "\n" and last unless $seconds_remaining; if (($countdown - $seconds_remaining) % $check == 0 && $countdown > $seconds_remaining ) { print_timestamp("\nPaused "); print "Continue? ([Y]/n): "; chomp(my $reply = <STDIN>); last unless $reply =~ $continue_re; print_timestamp('Resumed'); } usleep 1_000_000; } while $countdown_remaining--; } print_timestamp("Finished"); sub print_countdown { printf "\r%s" => shift->strftime('%H:%M:%S'); } sub print_timestamp { print shift, ' at: ', scalar(localtime), "\n"; }

    By default, it runs with a 60 second timer and 10 second check:

    $ pm_time_countdown.pl Started at: Sat Nov 2 18:02:36 2013 00:00:50 Paused at: Sat Nov 2 18:02:46 2013 Continue ([Y]/n): Resumed at: Sat Nov 2 18:02:50 2013 ... Paused at: Sat Nov 2 18:03:35 2013 Continue ([Y]/n): Resumed at: Sat Nov 2 18:03:40 2013 00:00:00 Finished at: Sat Nov 2 18:03:50 2013

    You can pass any values on the command line:

    $ pm_time_countdown.pl 3 2 Started at: Sat Nov 2 18:30:23 2013 00:00:01 Paused at: Sat Nov 2 18:30:25 2013 Continue? ([Y]/n): Resumed at: Sat Nov 2 18:30:26 2013 00:00:00 Finished at: Sat Nov 2 18:30:27 2013

    Currently, the countdown needs to be less than a day (you could extend that):

    $ pm_time_countdown.pl 86337 600 Started at: Sat Nov 2 17:44:22 2013 23:48:57 Paused at: Sat Nov 2 17:54:23 2013 Continue ([Y]/n): n Finished at: Sat Nov 2 18:02:00 2013

    The two modules I've used are both builtins: you have them already; there's nothing to install from CPAN.

    Time::HiRes provides high resolution time functions: usleep() is the only one I've used here. The builtin sleep() function is not very accurate: the doco suggests the best you could guarantee might be: 0s < sleep(1) < 2s.

    I've used Time::Piece to handle the countdown value and generate the 'HH:MM:SS' formats. As you can see, this was a much easier way to code it than your multiple '($end_time - $time) ...' technique.

    The rest of the code is pretty straightforward and shouldn't hold any surprises. It should run under Perl v5.8 or later versions.

    -- Ken

Re: How do I pause real time in Perl
by toolic (Bishop) on Nov 01, 2013 at 19:24 UTC
Re: How do I pause real time in Perl
by Old_Gray_Bear (Bishop) on Nov 01, 2013 at 19:45 UTC
    First you get into the Tardis....

    ----
    I Go Back to Sleep, Now.

    OGB

Re: How do I pause real time in Perl
by Kenosis (Priest) on Nov 01, 2013 at 19:24 UTC