• Publicidad

Error módulo Lingua::ES::Numeros

Aquí encontrarás todo lo que sea específicamente acerca de módulos de Perl. Ya sea que estás compartiendo tu módulo, un manual o simplemente tienes una duda acerca de alguno.

Error módulo Lingua::ES::Numeros

Notapor Lor » 2010-01-04 09:15 @427

Explorer, he detectado un error en el módulo Lingua::ES::Numeros;

Dado el número 62.482,50

my $letras = Lingua::ES::Numeros->new('MAYUSCULAS' => 1);
$letras->real(62.482,50);

Da como resultado: SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 05 CTMS

¿Cómo se notifica el mismo para corrección?
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Publicidad

Re: Error módulo Lingua::ES::Numeros

Notapor explorer » 2010-01-04 10:52 @494

Lo normal es escribir un correo a la dirección de correo que figura al final del módulo (la dirección de cpan.org).

Si al cabo de un par de días no te responde, lo siguiente es enviar un mensaje de error en la página de seguimiento de incidencias del propio módulo.

Y al mismo tiempo, le intentas localizar en Internet. En este caso, tiene página en Twitter y un Blog llamada Perliscopio.

Es un error grave... yo intentaría mandarle un aviso a todos los sitios, a la vez.

Mientras, voy a ver dónde está el problema.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14477
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Error módulo Lingua::ES::Numeros

Notapor explorer » 2010-01-05 22:41 @987

Bueno, después de una breve investigación, he llegado a los siguientes puntos:

* El error se mantiene incluso en la última versión (0.06).

* He conseguido realizar un apaño, que parece que funciona. Explicado más abajo.

* Los más de 70.000 test que pasa el módulo antes de su instalación, no lo detecta (!)

El tema está en la función real(), que sirve para formatear los números a una determinada precisión en los decimales. Para ello, se hace uso del atributo FORMATO que por defecto es 'con %02d ctms.'. Hay dos formas de indicar esa precisión:
1- %Ns: la parte fraccionaria se pasa a cardinal con la precisión de decimales indicada con N. Por ejemplo: si es FORMATO => 'con %2s ctms.', saldría algo como 'CINCO DÉCIMOS CTMS.'
2- %Nd: la parte fraccionaria se pasa a número, como en la función sprintf()

Y ahí es donde creo que está el error:

En la función real() aparece:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.              # Numérico, se da formato a los dígitos
  2.              $frc = substr( '0' x $exp . $frc, 0, $1 );
  3.              $frc = sprintf( $self->{'FORMATO'}, $frc );
  4.              last;
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

Observamos que la parte fraccionaria se rellena con ceros por la parte derecha según lo indique el exponente del número. Luego, se extraen tantos dígitos como lo indique la precisión asignada a FORMATO. Pasa luego el número por la función sprintf con el formato indicado, y termina.

El problema es que del número de ejemplo "62482.50", la parte fraccionaria queda en "5", debido a que Perl elimina el '0' final (los ceros a la derecha no tienen "valor"). Esto es así porque estamos pasando un número a una función, y Perl hace el "redondeo" numérico antes de agregarlo como argumento a la función. Más tarde, las rutinas de parseo del módulo lo siguen manteniendo así, hasta que llega a la parte de formateo de la expresión indicada antes.

La solución que he encontrado es "agregar" los ceros eliminados a la derecha, tantos como los indicados en la expresión de formato (al menos). Para ello, modifiqué la línea 331 de la siguiente manera:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.              # Numérico, se da formato a los dígitos
  2.              $frc = substr( '0' x $exp . $frc . '0' x $1, 0, $1 );
  3.              $frc = sprintf( $self->{'FORMATO'}, $frc );
  4.              last;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y ya sale la respuesta correcta:
SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 50 CTMS.

Haciendo una prueba con otro formato,
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use utf8;
  7. use open IO  => ':locale';
  8.  
  9. use Lingua::ES::Numeros;
  10.  
  11. my $letras = Lingua::ES::Numeros->new('MAYUSCULAS' => 1, FORMATO => 'con %3d milésimas');
  12.  
  13. print $letras->real(62482.50), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 500 MILÉSIMAS
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Y vemos que funciona: la parte fraccionaria es "rellenada" con ceros a la derecha.

No sé si es la solución correcta, pero al menos, parece que funciona.

Ahora bien... alguien podría pensar que hay una solución más sencilla... en vez de
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print $letras->real(62482.50), "\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
podríamos indicarlo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print $letras->real("62482.50"), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 50 CTM.
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
y de esa manera, el '0' final no es descartado al no haber una conversión a número, sino que estamos pasando una cadena de caracteres. Y es cierto, la salida sale bien. Pero... tenemos que modificar el programa para acordarnos de que siempre deben aparecer dos dígitos en la parte fraccionaria, porque sino,
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print $letras->real("62482.5"), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON  5 CTM.
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
fallará.

Ahora intento comunicarme con el autor para decírselo.

Actualización
El ejemplo completo que pone Lor es 62.482,50.

Aquí tenemos otro problema: la notación que por defecto está esperando Perl es la anglosajona (el punto como separador decimal). Así que lo que tenemos que hacer es decirle al objeto del módulo cómo son los números que queremos procesar:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. use utf8;
  7. use open IO  => ':locale';
  8.  
  9. use Lingua::ES::Numeros;
  10.  
  11. my $letras = Lingua::ES::Numeros->new(
  12.     MAYUSCULAS =>   1,
  13.     DECIMAL     => ',',
  14.     SEPARADORES => '.',
  15. );
  16.  
  17. print $letras->real("62.482,50"), "\n"; # SESENTA Y DOS MIL CUATROCIENTOS OCHENTA Y DOS CON 50 CTMS.
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sólo hemos agregado DECIMAL y SEPARADORES, y ahora ya obtenemos la salida esperada.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14477
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Error módulo Lingua::ES::Numeros

Notapor Lor » 2010-01-06 05:37 @276

¡¡¡¡¡Grande Explorer!!!!!

He enviado un email a José Rey pero no he tenido respuesta.

He reportado el error enviando un email a [email protected]

¡¡¡Gracias!!! :D
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Error módulo Lingua::ES::Numeros

Notapor Lor » 2010-01-06 05:55 @288

Por lo que veo ya se hizo la corrección. Ahora tenemos la versión v0.07

Explorer, ¡¡¡Gracias por todo!!!
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282

Re: Error módulo Lingua::ES::Numeros

Notapor explorer » 2010-01-06 14:38 @651

José me ha respondido por correo. En dos horas preparó el arreglo y lo subió a CPAN.

Voy a bajar esa versión y ver qué es lo que ha tocado (por insaciable curiosidad, claro).

Actualización:
Estas son las diferencias que ha puesto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
casa:/usr/lib/perl5/site_perl/5.8.8/Lingua/ES # diff Numeros.pm*
42c42
< our $VERSION = '0.07';
---
> our $VERSION = '0.06';
331c331
<             $frc = substr( '0' x $exp . $frc . '0' x $1, 0, $1 );
---
>             $frc = substr( '0' x $exp . $frc, 0, $1 );
691,698d690
<
<     # Translate the lower 6 digits for female numbers
<     if ($gen eq FEMALE) {
<         $n =~ s/(.{1,6})$//x;
<         $fmag->( $1, \@group, $mag++ );
<         s/cientos$/cientas/g for @group;
<     }
<
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Vemos que ha admitido mi solución, y ha agregado un formateo para los números menores de un millón, en femenino.

¡Vaya!
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Revision history for Perl extension Lingua::ES::Numeros.

0.07  Wed Jan  6 00:14:36 VET 2010
    - Corrected fractional formating bug in real() thanks to Joaquin Ferrero
    - Corrected female hundreths under one million
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Un bonito regalo de Rey(es) :D
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14477
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Error módulo Lingua::ES::Numeros

Notapor Lor » 2010-01-06 15:11 @674

!!!!FELICITACIONES!!!!!
Lor
Perlero nuevo
Perlero nuevo
 
Mensajes: 187
Registrado: 2005-04-28 05:47 @282


Volver a Módulos

¿Quién está conectado?

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

cron