• Publicidad

Cálculo letra DNI

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

Cálculo letra DNI

Notapor gonzalos » 2011-06-01 06:31 @313

Buenas tardes a todos.

Después de mucho tiempo si usar Perl, estoy intentando resolver un problema. Tengo un archivo con unos dos mil DNI sin letra. Y estoy intentando hacer un script en Perl, que me lea el archivo y a cada número le asigne la letra correspondiente. Todavía estoy decidiendo si la salida la escribiré en otro archivo o en la siguiente columna del original, todo dependerá de lo que me cueste hacer una cosa u otra.

Estoy intentado realizar el script, y cuando tenga algo que se pueda colgar lo subiré al foro, ya que como comenté hace tiempo que no uso Perl, y ya he olvidado hasta cómo se lee un archivo.

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Publicidad

Re: Cálculo letra DNI

Notapor explorer » 2011-06-01 06:42 @321

Aquí estaremos para ayudarte, Gonzalo.

De momento, para el cálculo de la letra: http://es.wikibooks.org/wiki/Algoritmo_ ... l_NIF#Perl
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: Cálculo letra DNI

Notapor gonzalos » 2011-06-01 06:52 @328

Hola, explorer

Muchas gracias por la información. Ahora que lo voy meditando, también debo añadir alguna condición a la expresión regular, ya que existen algunos NIE dentro de la lista. Por lo que al pasarles a éstos la fórmula, me daría un error de lectura en el bucle.

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Cálculo letra DNI

Notapor explorer » 2011-06-01 06:57 @331

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: Cálculo letra DNI

Notapor gonzalos » 2011-06-02 03:39 @194

Buenos días a todos

Después de darle vueltas al asunto he pensado en ir haciendo poco a poco el script (incrementando su "complejidad"). Una vez me vaya funcionando las cosas que le vaya añadiendo. Dicho esto, aquí dejo el inicio del código, para que le echéis un vistazo. Lo primero que quiero hacer es que me lea el archivo y me calcule la letra. Más adelante, le añadiré las variables de contorno, para que me restrinja el formato de los datos.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my @archivo_dni;
  6. my $dni;
  7. my $modulo;
  8. my @letra;
  9. open(FILE,"dni.txt");
  10. @archivo_dni=<FILE>;
  11. chomp(@archivo_dni);
  12.  
  13. while ($dni=<@archivo_dni>) {
  14.         $modulo=$dni%23;
  15.         @letra= substr( 'TRWAGMYFPDXBNJZSQVHLCKE',$modulo);
  16.        
  17.         print @letra;
  18. }
  19. close (FILE);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Según he estado probando lo que me hace el programa es simplemente mostrar por pantalla parte del código de letras
Sintáxis: [ Descargar ] [ Ocultar ]
  1. 'TRWAGMYFPDXBNJZSQVHLCKE', 


Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Cálculo letra DNI

Notapor explorer » 2011-06-02 03:49 @200

Te falta un '1' en el substr(). Revisa el enlace que te pasé.

¿Realmente funciona esta línea?

while ($dni=<@archivo_dni>)

Es un poco... mezclar cosas...
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: Cálculo letra DNI

Notapor gonzalos » 2011-06-02 04:47 @241

Hola Explorer

Gracias, pensaba que el

1

definía el cierre de la subrutina. Y como pensaba hacerlo sin usar subrutinas, lo eliminé.

Pues la verdad es que sí, lo primero que hice fue comprobar que el bucle me leía el archivo. Y me presentaba en pantalla el listado de prueba que había creado.

Bien, entonces modificaré el bucle para no liarme más de lo debido, a ver si me voy desoxidando poco a poco.

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Cálculo letra DNI

Notapor explorer » 2011-06-02 05:18 @262

Te ofrezco un sugus si eres capaz de explicar por qué funciona la línea

while ($dni=<@archivo_dni>)

(A mí me ha costado diez minutos encontrar la explicación.)
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: Cálculo letra DNI

Notapor gonzalos » 2011-06-03 03:49 @201

Buenos días

Un sugus... ¡buf, qué recuerdos! Si a ti te ha costado 10 minutos dar con la solución, estando todo el día manejando código, imagínate cuánto podré tardar yo.

A ver, hasta donde entiendo, es una asignación. Al array @archivo_dni, se le asigna el valor del archivo de texto, y a su vez dentro del bucle a la variable escalar se le asigna el valor del array. Por lo que al final la variable escalar tendría el valor del archivo.

while($dni=<File>)

Un saludo
Gonzalo

Pd: que conste que soy oceanógrafo, o sea que de informática nada de nada.
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Cálculo letra DNI

Notapor explorer » 2011-06-03 06:49 @326

gonzalos escribiste:A ver, hasta donde entiendo, es una asignación.
Sí, hay un '='.
gonzalos escribiste:Al array @archivo_dni, se le asigna el valor del archivo de texto, y a su vez dentro del bucle a la variable escalar se le asigna el valor del array.
No exactamente... tienes metido un array dentro del operador '<>'. El array sigue siendo un contenedor de una lista de valores, y se los pasas a '<>', que es un operador de Entrada/Salida de ficheros.
gonzalos escribiste:Por lo que al final la variable escalar tendría el valor del archivo.
Cierto, pero... no por lo que has deducido antes... Perl lo hace por otra razón.
gonzalos escribiste:Pd: que conste que soy oceanógrafo, o sea que de informática nada de nada.
Esto no es cosa de informática, sino de un detalle de Perl... que está explicado en solo una línea en toda la enorme documentación de Perl (que es bastante).

El operador '<>' tiene dos comportamientos bien claros. El primero es el más común: leer el contenido del fichero asociado al gestor de archivo que ponemos entre los ángulos. Ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $fh, '<', 'fichero_a_leer.txt';   # abrimos el fichero_a_leer y lo asignamos al gestor $fh
  2. while (my $linea = <$fh>) {               # leemos una línea cada vez, hasta que lleguemos al fin de fichero
  3.     print $linea, "\n";                   # la línea leída fue asignada a $linea, y ahora la sacamos a pantalla
  4. }
  5. close $fh;                                # cerramos el acceso al fichero
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero hay un segundo comportamiento.

Dentro de perlop, dice:
«Si lo que está dentro de los ángulos no es ni un gestor de archivo ni una variable escalar simple que contenga un nombre de gestor de archivo, typeglob, o referencia a typeglob, se interpreta como un patrón de nombre de archivo para ser expandido, y será devuelta la lista de nombres de archivo o el siguiente nombre de archivo de la lista, dependiendo del contexto.»


Un ejemplo, para verlo mejor:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (my $fichero = <*.txt>) {
  2.     print "El fichero $fichero tiene ", -s $fichero, " bytes\n";
  3. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En este modo de uso, no estamos abriendo ficheros, sino que estamos manejando los nombres de los ficheros. En el ejemplo, estamos buscando todos los ficheros que tengan 'txt' como extensión de su nombre. Pero no miramos su contenido, solo su nombre.

Bueno, pues es justo lo que está pasando en tu programa: el array no es una variable escalar simple, así que la expresión que hay dentro de los ángulos es interpretada como una lista de nombres de ficheros. Y como la asignación es hacia un escalar ($dni), entonces te devuelve un valor cada vez.

Ahora bien... ¿esto es lo que queremos que haga el programa? No se trata de nombres de ficheros, sino de líneas de texto que ya hemos leído antes (unas líneas de programa antes).

Esto es algo así como si tuviéramos en la mano la foto del sonar, mostrando los cuerpos de 4 cetáceos debajo de nuestro barco, y quisieras sacar una fotocopia de esa foto, para empezar a contar cuántos cetáceos hay en la primera foto... ¿no te vale con contarlos en la foto original? :)

El programa puede quedar así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #usr/bin/perl
  2. use strict;
  3. use warnings;
  4. open(FILE, "<dni.txt");
  5. while (my $dni = <FILE>) {
  6.     my $modulo = $dni % 23;
  7.     my $letra  = substr('TRWAGMYFPDXBNJZSQVHLCKE', $modulo, 1);
  8.     print "$dni : $letra\n";
  9. }
  10. close (FILE);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

No hacemos el chomp(), porque en la operación de $dni con el módulo (%), Perl convierte el contenido de $dni en un número, así que ahí desaparece el carácter de fin de línea que hubiéramos leído.

En esta caso, leemos el fichero dni.txt, línea a línea, y por cada una, calculamos la letra.

Observa también que creamos las variables (las declaramos con my()) a medida de que nos van haciendo falta. Solo hay que recordar que una variable creada con my() dentro de unas llaves '{}' será desconocida (desaparecerá) fuera de esas llaves. En este ejemplo, $dni, $modulo y $letra solo son conocidos dentro del bucle while() (que es el dueño de las llaves).
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

Siguiente

Volver a Básico

¿Quién está conectado?

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