• Publicidad

Imprimir en orden claves hash de segundo nivel

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

Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-12 11:00 @500

Hola nuevamente, amigos del foro. Les cuento: tengo el siguiente código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Tie::InsertOrderHash;
  5.  
  6. tie my %Meses,  => 'Tie::InsertOrderHash',
  7.     'Enero'     => 'January',
  8.     'Febrero'   => 'February',
  9.     'Marzo'     => 'March',
  10.     'Abril'     => 'April',
  11.     'Mayo'      => 'May',
  12.     'Junio'     => 'June',
  13.     'Julio'     => 'July',
  14.     'Agosto'    => 'August',
  15.     'Septiembre'=> 'September',
  16.     'Octubre'   => 'October',
  17.     'Noviembre' => 'November',
  18.     'Diciembre' => 'December',
  19. ;
  20.  
  21. for my $mes (keys %Meses ) {
  22. print "$mes\n";
  23. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Lo que hace es imprimir las claves en el orden que yo declaro, pero ¿cómo lo puedo hacer si tengo esto?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $sorthash{'Enero'}{'January'}= '32';
  2. $sorthash{'Febrero'}{'February'}= '29';
  3. $sorthash{'Marzo'}{'March'}= '30';
  4. $sorthash{'Abril'}{'April'}= '30';
  5. $sorthash{'Mayo'}{'May'}= '31';
  6. $sorthash{'Junio'}{'June'}= '30';
  7. $sorthash{'Julio'}{'July'}= '31';
  8. $sorthash{'Agosto'}{'August'}= '31';
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y que imprima en pantalla:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Enero January 32
Febrero February 29
Marzo March 30
Abril April 30
Mayo May 31
Junio June 30
Julio July 31
Agosto August 31
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Gracias por su ayuda, y saludos.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Publicidad

Re: Imprimir en orden claves hash de segundo nivel

Notapor explorer » 2013-12-12 12:26 @560

A ver... a ver... ¿la clave 'Enero' corresponde a una referencia a un hash que solo tiene una clave 'January', y que tiene como valor el número 32?

¿O el hash referenciado por 'Enero' puede tener más claves/valor?
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: Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-12 12:57 @581

Hola Explorer, corresponde a lo segundo, que 'Enero' puede tener más claves/valor.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-12 13:16 @595

Hola otra vez. El siguiente código imprime por pantalla los meses (en español) de forma desordenada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. my (%sorthash,%test) = ();
  7.  
  8. $sorthash{'Enero'}{'January'}= '31';
  9. $sorthash{'Febrero'}{'February'}= '29';
  10. $sorthash{'Marzo'}{'March'}= '30';
  11. $sorthash{'Abril'}{'April'}= '30';
  12. $sorthash{'Mayo'}{'May'}= '31';
  13. $sorthash{'Junio'}{'June'}= '30';
  14. $sorthash{'Julio'}{'July'}= '31';
  15. $sorthash{'Agosto'}{'August'}= '31';
  16.  
  17. for my $keys1 (keys %sorthash )
  18. {
  19.     #print "keys1: $keys1\t";
  20.     %test = %{$sorthash{$keys1}};
  21.     for my $testkeys (sort keys %test)
  22.     {
  23.         print "$keys1\t$testkeys\t";
  24.         print "$test{$testkeys}\n";
  25.     }
  26. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


    Mayo May 31
    Febrero February 29
    Abril April 30
    Marzo March 30
    Agosto August 31
    Enero January 31
    Junio June 30
    Julio July 31

y me gustaría que mostrase por pantalla los meses de enero a agosto, en este caso, de forma ordenada. Eso, gracias.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Imprimir en orden claves hash de segundo nivel

Notapor explorer » 2013-12-12 13:28 @602

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for my $keys1 (qw(Enero Febrero Marzo Abril Mayo Junio Julio Agosto))
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

¿Puedes darnos una pista de lo que realmente quieres hacer?
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: Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-12 16:28 @727

Una vez más, muchas gracias :D
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Imprimir en orden claves hash de segundo nivel

Notapor explorer » 2013-12-12 16:41 @736

Pero... ¿no nos puedes decir qué quieres hacer con todo eso?
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: Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-13 07:01 @334

Es que tengo 12 carpetas (las cuales tienen por nombre los meses del año) y cada carpeta tiene archivos Excel que tienen el nombre de la carpeta pero en inglés. Estos archivos tienen una matriz de horas por días y, como saben, cada mes tiene distinta cantidad de días, para luego guardar estas doce matrices en un solo archivo (año completo). Es por eso que pensé que ésta sería la mejor forma. Este es el código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use Spreadsheet::Read;
  3.  
  4. open my $OUT, '>>', 'datos.txt' or die "ERROR: No puedo escribir en datos.txt: $!\n";
  5.  
  6. my $ruta = "/home/modelacion/Escritorio/excel_perl/DATA_METEOROLOGIA_CAMPAMENTO/2013";
  7.  
  8. my ( %sorthash, %test ) = ();
  9.  
  10. $sorthash{'Enero'}{'January'}        = '31';
  11. $sorthash{'Febrero'}{'February'}     = '29';
  12. $sorthash{'Marzo'}{'March'}          = '30';
  13. $sorthash{'Abril'}{'April'}          = '30';
  14. $sorthash{'Mayo'}{'May'}             = '31';
  15. $sorthash{'Junio'}{'June'}           = '30';
  16. $sorthash{'Julio'}{'July'}           = '31';
  17. $sorthash{'Agosto'}{'August'}        = '31';
  18. $sorthash{'Septiembre'}{'September'} = '30';
  19. $sorthash{'Octubre'}{'October'}      = '31';
  20. $sorthash{'Noviembre'}{'November'}   = '30';
  21. $sorthash{'Diciembre'}{'December'}   = '31';
  22.  
  23. # for my $keys1 (keys %sorthash ) {
  24. for my $keys1 (qw(Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre)) {
  25.  
  26.     my %test = %{ $sorthash{$keys1} };
  27.  
  28.     for my $testkeys ( sort keys %test ) {
  29.  
  30.         my $archivo = 'Inf-Ph-WS-' . $testkeys . '2013.xls';
  31.  
  32.         my $ref  = ReadData("$ruta/$keys1/$archivo");
  33.         my $HOJA = $ref->[1]->{cell};
  34.  
  35.         for my $fila ( 10 .. 57 ) {    # para todas las filas
  36.             for my $columna ( 1 .. $test{$testkeys} ) {    # para todas las columnas
  37.  
  38.                 print $OUT $HOJA->[$columna]->[$fila], " ";
  39.             }
  40.             print $OUT "\n";           # fin de cada línea
  41.         }
  42.         close $OUT;
  43.     }
  44. }
  45.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Aprovechando la instancia :) , me gustaría saber cómo este código podría identificar algunas celdas o casillas de la planilla u hoja de Excel en los cuales hay más de un dato, por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1,13
Dat[-]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

y reemplazarlo por el carácter NaN.

Espero haber sido clara y muchas gracias.
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Re: Imprimir en orden claves hash de segundo nivel

Notapor explorer » 2013-12-13 08:46 @407

Esta es otra forma de resolverlo, me parece que más clara.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use autodie;
  3. use POSIX;
  4. use Spreadsheet::Read;
  5.  
  6. ## Constantes
  7. my $year  = 2013;
  8. my $ruta  = "/home/modelacion/Escritorio/excel_perl/DATA_METEOROLOGIA_CAMPAMENTO/$year";
  9. my @meses = (
  10.     [ 'Enero',           'January',      31 ],
  11.     [ 'Febrero',         'February',     29 ],
  12.     [ 'Marzo',           'March',        31 ],
  13.     [ 'Abril',           'April',        30 ],
  14.     [ 'Mayo',            'May',          31 ],
  15.     [ 'Junio',           'June',         30 ],
  16.     [ 'Julio',           'July',         31 ],
  17.     [ 'Agosto',          'August',       31 ],
  18.     [ 'Septiembre',      'September',    30 ],
  19.     [ 'Octubre',         'October',      31 ],
  20.     [ 'Noviembre',       'November',     30 ],
  21.     [ 'Diciembre',       'December',     31 ],
  22. );
  23.  
  24. ## Proceso
  25. open my $OUT, '>>', 'datos.txt';
  26.  
  27. for my $mes (@meses) {                          # para todos los meses
  28.  
  29.     my($mes_spa, $mes_eng, $mes_dias) = @{$mes};
  30.  
  31.     my $ref  = ReadData("$ruta/$mes_spa/Inf-Ph-WS-$mes_eng$year.xls");
  32.     my $HOJA = $ref->[1]->{cell};
  33.  
  34.     for my $fila   ( 10 .. 57 ) {               # para todas las filas
  35.         my @fila;
  36.  
  37.         for my $columna ( 1 .. $mes_dias ) {    # para todas las columnas
  38.  
  39.             my $dato = $HOJA->[$columna]->[$fila];
  40.  
  41.             $dato = 'NaN' if not isdigit($dato);
  42.  
  43.             push @fila, $dato;
  44.         }
  45.  
  46.         print $OUT "@fila\n";
  47.     }
  48. }
  49.  
  50. close $OUT;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Detalles:
  • marzo tiene 31 días :)
  • tenías puesto el close del archivo dentro de los bucles, así que se cerraba después del primer mes
  • los datos están puestos en forma de array, así que mantienen un orden. Y cada uno de sus valores es un array, que reúne los tres datos que queremos por cada mes
  • el número de año se utiliza en más de un sitio. Poniéndolo como constante aparte, hacemos el código más fácil de mantener
  • usamos el módulo autodie para que mate el proceso en caso de problemas con la lectura/escritura de archivos
  • usamos el módulo POSIX para importar la función isdigit() y comprobar que el $dato es numérico
  • usando la variable de array @fila, metemos (push) ahí todos los datos de la fila, para luego sacarlos con un simple print, que con la ayuda de las comillas dobles, salen separados con espacios, y además evitamos la salida de un espacio en blanco extra al final de la línea, como estaba antes
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: Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-16 09:11 @424

Hola, explorer, te cuento que ejecuté el código y el archivo que guarda la información final (datos.txt) contiene los siguiente (es solo el ejemplo de una línea de 24 y todas son iguales):
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 0 NaN
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

en el cual a todos los números con decimales les pone NaN. Revisando el código cambio la siguiente línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $dato = 'NaN' if not isdigit($dato);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
por
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $dato = 'NaN' if isdigit($dato);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

el cual arroja como resultado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1.59 3.39 8.45 NaN 6.66 1.18 3.44 3.15 2.44 2.74 4.58 3.37 6.45 4.95 3.64 3.37 5.12 3.64 2.49 1.67 2.7 1.84 4.05 2.95 3.71 0.89 1.96 NaN NaN 1.28 2.34
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

donde respeta los números con decimales, pero los sin decimales los reemplaza por 'NaN'.

Y gracias por el detalle de los días de marzo :D
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

Siguiente

Volver a Básico

¿Quién está conectado?

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

cron