• Publicidad

Temporización en Perl

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Temporización en Perl

Notapor charlygarza » 2013-05-25 14:22 @640

Necesito su ayuda. Necesito un programa que muestre un mensaje en pantalla de que su tiempo ha terminado al llegar a dos minutos. Hasta aquí todo bien. El problema es que también debe mostrar un mensaje de interrupción si el usuario no presiona una tecla durante diez segundos.

#!/usr/bin/perl

my $countdown = 2*60;

$| = 1;

my $beg_time = time;
my $end_time = $beg_time + $countdown;

for (;;) {
my $time = time;
last if ($time >= $end_time);

printf("\r%02d:%02d:%02d",
($end_time - $time) / (60*60),
($end_time - $time) / ( 60) % 60,
($end_time - $time) % 60,
);

sleep(1);

}
print "Su tiempo ha terminado ";
charlygarza
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2013-05-11 13:22 @598

Publicidad

Re: Temporización en Perl

Notapor explorer » 2013-05-25 21:26 @935

Se podría solucionar con select() o alarm(), pero... depende un poco del sistema operativo en que estés. ¿Cuál es?

En perldoc -f getc tienes un ejemplo de cómo leer el teclado sin que el programa se pare.

Con select(), puedes indicar un tiempo de timeout. Si pones 10 segundos, select() esperará por la entrada de texto durante ese tiempo. Pero, como se dice en getc, eso no quiere decir que select() regrese cuando el usuario pulse cualquier tecla, si no solo cuando pulse además la tecla Entrar.

Una vez tuve que hacer algo parecido. Usé el módulo Curses, ya que permite mandar comandos a la terminal, para indicarle que funcione en modo no bloqueante, y de esa manera, puedo llamar a la función getch() (de Curses) para leer una sola pulsación del teclado, sin que el programa se tenga que parar o que el usuario tenga que pulsar la tecla Entrar.

Algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Curses;
  2.  
  3. # Inicialización de la pantalla
  4. initscr();      # inicialización
  5. noecho();       # no se ve lo que se escribe
  6. cbreak();       # No buffer, el sistema captura señales de parada
  7. nodelay(1);     # getch() no es bloqueante
  8.  
  9. # En caso de parada brusca del programa
  10. $SIG{INT} = sub { done("Ouch!") };
  11. sub done {
  12.     endwin();
  13. #    resetty();
  14.     print "\n@_\n";
  15.     exit;
  16. }
  17.  
  18.  
  19. # Bucle principal
  20. while (1) {
  21.     # si el usuario ha pulsado algo, lo leemos
  22.     while ( (my $key = getch()) ne ERR) {   # usamos un bucle, por si pulso varias veces
  23.         done("Hasta la vista") if $key eq 'q'   # en caso de pulsar la 'q', salimos
  24.     }
  25.  
  26.     ...;   # resto del programa
  27.  
  28.     # Ver teclado
  29.     my ($in, $out) = ('', '');              # canales de entrada y salida
  30.     vec($in,fileno(STDIN),1) = 1;           # marcamos el bit del canal correspondiente a STDIN
  31.  
  32.     # iniciamos un proceso de escucha durante un $lapso de tiempo, de tal manera que siempre estemos en múltiplo de
  33.     # minuto completo con el reloj del sistema. También volverá antes, en caso de que el usuario pulse algo
  34.     select($out = $in, undef, undef, $lapso  -  ($lapso == 60 ? (localtime)[0] : 0) ); # tiempo de espera o pulsación teclado
  35. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Más información en
perldoc -f select
perldoc -f alarm
perldoc -f getc
perldoc perlipc
perldoc Curses
(en caso de estar instalado, claro)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Temporización en Perl

Notapor charlygarza » 2013-05-28 21:20 @930

Buenas noches. Mi plataforma es Windows.

Me da error al intentar correr el programa; imaginé que era porque quizá no estaba instalada la librería curses e intenté instalarla desde CPAN, pero da error.
charlygarza
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2013-05-11 13:22 @598

Re: Temporización en Perl

Notapor explorer » 2013-05-29 05:05 @253

Curses no funciona en Windows de ninguna manera, pero no debes fijarte en este módulo, que solo sirve para interaccionar con la terminal.

En perlfaq8 hay una pregunta sobre este tema, pero dice que Term::ReadKey tiene un soporte limitado en Windows.

Sería algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Term::ReadKey;
  2. ReadMode('cbreak');
  3. $key = ReadKey(10);          # esperar 10 segundos máximo
  4. ReadMode('normal');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Pero debes probarlo en Windows para ver si te funciona.

En este hilo hay comentarios del mismo problema, pero usando Win32::Console. Comentan que es mejor usar GetEvents() para saber si hay alguna pulsación esperando para ser leída. Ejemplo (ver función showAbout en el código).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 38 invitados