• 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.

Re: Imprimir en orden claves hash de segundo nivel

Notapor explorer » 2013-12-16 14:54 @663

Sí, hemos metido la pata.

isdigit() solo devuelve verdadero si el argumento es un entero. Mejor dicho: solo devuelve verdadero si el argumento es un carácter entre '0' y '9', incluidos (más información en man 3 isdigit).


Entonces... lo podemos resolver de otra manera, por medio de una expresión regular.

Eliminamos la línea 2 y cambiamos la 41 por
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.             $dato = 'NaN' if $dato !~ /^[\d.,+-e]+$/i;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Así, miramos a ver que $dato coincida con ese patrón (dígitos, '.', ',', '-', '+', y 'e' -exponente-). Si no es así, lo marcamos como NaN.

Si te falla porque hay algunas celdas con espacios en blanco, se puede hacer un $dato += 0; para pasarlo a número, antes de lo del NaN.

O de otra manera: si sospechamos que la celda puede tener espacios en blanco o caracteres extraños aparte de los números, se pueden extraer con un expresión regular, y comprobarlo después:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.             my($dato) = $HOJA->[$columna]->[$fila] =~ /^([\d.,+-e]+)$/i;
  2.  
  3.             $dato = 'NaN' if not $dato;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Publicidad

Re: Imprimir en orden claves hash de segundo nivel

Notapor lis » 2013-12-17 16:01 @709

¡Hola, explorer! Como dije antes, dentro de la planilla Excel hay casillas que contienen dos tipos de información:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1,13
Dat[-]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

y yo quiero que estos dos datos sean reemplazados por el carácter 'NaN', y este código me arroja como resultado:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1.13
NaN
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Por más que trato de arreglarlo con las expresiones regulares no saco nada en limpio :(
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-17 16:11 @716

Quita la coma, del patrón de la expresión regular.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
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-19 10:37 @484

Hola, explorer. Intenté quitando la coma, y nada.

También hice esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  $dato = 'NaN' if $dato =~ /^[(\d+.) \r (\w+)]$/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

pero obtengo el mismo resultado:
    1,13
    NaN
en vez de
    NaN
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-19 11:22 @515

Pues es extraño, porque a mi sí que me funciona. Prueba esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. my $celda = '1,13';
  3.  
  4. my($dato) = $celda =~ /^([\d.+e-]+)$/;
  5.  
  6. $dato = 'NaN' if not defined $dato;
  7.  
  8. print "$dato\n";    # NaN
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

O quizás no he entendido el problema. Vamos a ver, cuando pones
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1,13
Dat-
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
te refieres a que ese es el contenido que puede aparecer en una celda, y que lo quieres cambiar a 'NaN'. Bueno, pues el caso es que también me funciona, cambiando la línea 2 por
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $celda = "1,13\nDat-";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
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-19 13:15 @593

Lamento no haberme explicado bien.

Efectivamente, en el archivo Excel existen casillas que contienen más de un dato (como el ejemplo anterior) y otras celdas que tienen uno solo. En las casillas que existen dos datos (tanto números, letras y/o símbolos) reemplazarlos por el carácter NaN (un solo carácter) cosa que todas las celdas de la hoja o planilla Excel contengan un dato.
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-19 13:42 @612

Bueno, pues entonces son varias las condiciones:

1- Si la celda no tiene nada, no hacer nada
2- Si la celda contiene un número, quedarse con él
3- En los demás casos, cambiarlo por 'NaN'

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.10;                                               # necesario para el operador '//'
  3.  
  4. my $celda = $HOJA->[$columna]->[$fila] // '';            # leemos la celda. Si no contiene un valor definido, se lo ponemos a ''
  5. my $dato  = $celda;                                      # el $dato, será, de principio, igual a la $celda
  6.  
  7. if ($celda) {                                            # si la celda contiene algo
  8.     ($dato) = $celda =~ /^([\d.+e-]+)$/i;                # comprobamos que la $celda contiene un dato numérico
  9.     $dato = 'NaN' if not defined $dato;                  # si no hemos encontrado un $dato numérico, le asignamos 'NaN'
  10. }
  11.  
  12. print "$dato\n";                                         # nuevo valor de la celda
  13.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
¡Ojo! los paréntesis que rodean a $dato, son importantes ;)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
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-19 16:00 @708

Lo que hace el código es identificar los caracteres que no sean números y los reemplaza por NaN. Lo que pido es que si encuentra una celda que contenga números y letras juntos que los reemplace por un solo NaN. Disculpa si molesto mucho :oops:
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-19 18:45 @823

Perdona, pero mi código sí que hace eso: cuando $celda contiene letras y números, los cambia por 'NaN'.

Por favor, prueba mi código con diferentes valores de $celda. Si encuentras un valor de $celda que no funcione, publícalo aquí.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
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-27 08:55 @413

Hola perleros, espero que hayan pasado unas lindas fiestas junto a sus seres queridos :D

explorer, aún no soluciono mi problema por lo que adjunto un archivo Excel muy parecido al que debo ocupar donde en la parte inferior indica qué significa cada marca. En resumen, las celdas que contengan números, letras y un signo negativo juntos, se deben reemplazar por el carácter 'NaN'. En cambio, si las celdas contienen números, letras y un signo positivo juntos se debe dejar el solo número, pero este código no lo hace, al menos a mí no me funciona :(

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use Spreadsheet::Read;
  5. use v5.10;
  6.  
  7. ## Constantes
  8. my $year  = 2013;
  9. my $ruta  = "/home/modelacion/Escritorio/excel_perl";
  10. my @meses = (
  11.           [ 'Enero', 'January', 31 ],
  12.     #     [ 'Febrero',         'February',     29 ],
  13.     #     [ 'Marzo',           'March',        31 ],
  14.     #     [ 'Abril',           'April',        30 ],
  15.     #     [ 'Mayo',            'May',          31 ],
  16.     #     [ 'Junio',           'June',         30 ],
  17.     #     [ 'Julio',           'July',         31 ],
  18.     #     [ 'Agosto',          'August',       31 ],
  19.     #     [ 'Septiembre',      'September',    30 ],
  20.     #     [ 'Octubre',         'October',      31 ],
  21.     #     [ 'Noviembre',       'November',     30 ],
  22.     #     [ 'Diciembre',       'December',     31 ],
  23. );
  24.  
  25. ## Proceso
  26. open my $OUT, '>', 'datos.txt';
  27.  
  28. for my $mes (@meses) {                                     # para todos los meses
  29.  
  30.     my ( $mes_spa, $mes_eng, $mes_dias ) = @{$mes};
  31.  
  32.     my $ref  = ReadData("$ruta/Inf-WS-$mes_eng$year.xls");
  33.     my $HOJA = $ref->[1]->{cell};
  34.  
  35.     for my $fila ( 1 .. 48 ) {                             # para todas las filas
  36.         my @fila;
  37.  
  38.         for my $columna ( 1 .. $mes_dias ) {               # para todas las columnas
  39.  
  40.             my $celda = $HOJA->[$columna]->[$fila] // '';  # leemos la celda. Si no contiene un valor definido, se lo ponemos a ''
  41.             my $dato = $celda;                             # el $dato, será, de principio, igual a la $celda
  42.  
  43.             if ($celda) {                                  # si la celda contiene algo
  44.  
  45.                 ($dato) = $celda =~ /^([\d.+e-]+)$/i;      # comprobamos que la $celda contiene un dato numérico
  46.                 $dato = 'NaN' if not defined $dato;        # si no hemos encontrado un $dato numérico, le asignamos 'NaN'
  47.             }
  48.  
  49.             push @fila, $dato;
  50.         }
  51.         print $OUT "@fila\n";
  52.     }
  53. }
  54. close $OUT;
  55.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Muchas gracias.
Adjuntos
Inf-WS-January2013.xls
(24.5 KiB) 80 veces
Última edición por explorer el 2013-12-27 18:17 @804, editado 2 veces en total
Razón: Formateado de código con Perltidy
lis
Perlero nuevo
Perlero nuevo
 
Mensajes: 106
Registrado: 2008-05-27 21:43 @946

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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

cron