• Publicidad

Leer archivo, pasarlo a matriz y calcular estadísticos

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

Leer archivo, pasarlo a matriz y calcular estadísticos

Notapor ddcastro » 2009-04-17 21:56 @956

Hola:

Empecé con Perl leyendo el libro "sam teach yourself Perl in 21 days"... bueno... lo de los 21 días no es tan así, al menos para mí. El primer trabajo que me planteé es el siguiente:

Desde un archivo externo (en este caso un txt) obtener estadísticas simples: media, moda, mínimo, máximo, etc.

Me surge un problema:

Quisiera guardar el archivo en una matriz y para eso hago lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/local/bin/perl -w

open (DATOS, 'misdatos.txt');
@archivo = <DATOS>;
close(DATOS);
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


El problema está en que por ejemplo, si deseo llamar al elemento (1,2) de la matriz:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$archivo[0][1];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Solo me muestra la primera fila, como si le dijera
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$archivo[0];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Mi solución es "vaciar" cada fila de @archivo en un nuevo conjunto de arreglos, por ejemplo de la siguiente forma:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@row1="";
@row2="";
@row3="";

foreach $single (@archivo){
$c++;
($row1[$c],$row2[$c],$row3[$c]) = split "\n", $single;
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero lo que logro es que en @row1 coloque todo el arreglo @archivo. Y si hago el cambio
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
($row1[$c],$row2[$c],$row3[$c]) = split " ", $single;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En @row1 coloca toda la primera columna, pero sin ninguna separación entre los datos y lo mismo con @row2 y @row3.

Agradecería me iluminaran un poco... pues una vez que tenga los datos en arreglos, creo que es más fácil hacer lo que me propuse.

Si de alguna forma se pudiera sistematizar aún más el programa, sería lo óptimo.
Me refiero a que el programa no dependa del archivo que tengo, para que así, si quiero hacer lo mismo con otro archivo, no tenga que reescribir las sentencias. (eso de todas maneras es un extra... me quedo feliz con una solución para lo que planteé primero).

Muchas gracias
ddcastro
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2009-04-17 20:57 @914

Publicidad

Notapor explorer » 2009-04-18 11:49 @534

Bienvenido a los foros de Perl en Español, ddcastro.

En el primer ejemplo tuyo estás leyendo el archivo por líneas, almacenando cada una de ellas en cada uno de los elementos del arreglo @archivo. Pero... Perl no sabe qué aspecto tiene cada una de esas líneas. Recuerda: Perl solo hace lo que le estás diciendo, pero nada más. Él no sabe que esas líneas son campos separados por espacios. Aún no se lo has dicho.

Y otro detalle: en Perl no existe el concepto de matriz, así que debe imitarse por medio de otras estructuras más simples. En Perl se hace de la misma que en el lenguaje C: una matriz se puede hacer como una sucesión de valores contiguos en memoria del que sabemos sus dimensiones y sabemos cómo llegar a cada valor -en ese caso no es una matriz sino un simple arreglo-, pero también podemos construir un arreglo para que contenga, cada elemento, una referencia a otro arreglo. Así, podemos pensar en el primer arreglo como las filas, mientras que las segundas son las columnas -o al revés-.

En Perl, a esto se llama hacer un arreglo de un arreglo -abreviado. AoA-.

La forma de leerlo sería así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/local/bin/perl -w

open (DATOS, 'misdatos.txt');
while (<DATOS>) {
    chomp;
    push @archivo, [ split ];
}
close(DATOS);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Mientras (while) tengamos línea que leer, a cada una de ellas le quitamos los finales de línea (chomp), la dividimos partiéndola por los espacios en blanco (split). A todos ellos, como lista de valores que recibimos, los metemos en un arreglo anónimo ([]). Y, finalmente, lo guardamos al final de @archivo.

Si quieres ver el aspecto que tiene, usaremos Data::Dumper:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use Data::Dumper;
print Dumper \@archivo;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y ahora ya sí que podemos referirnos a cada uno de sus elementos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print $archivo[2][1];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
que es la forma corta de escribirlo así: $archivo[2]->[1], que es a su vez la forma corta de escribirlo así: ${$archivo[2]}[1].

Está claro que $archivo[2] se refiere al tercer elemento del arreglo $archivo. Y como lo que contiene es una referencia a un arreglo, lo desreferenciamos (${}) para tener acceso a ese arreglo, del que, finalmente, obtenemos su segundo elemento ([1]).

Más información, en tu ordenador, con perldoc, o en la web, en perldata, perllol y perldsc.
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

Notapor ddcastro » 2009-04-18 12:30 @563

Muchas gracias explorer. En alguno de mis intentos había llegado a algo parecido, así que no estaba tan perdida.
Ahora, cuando deseo imprimir $archivo[2][1] aparece lo siguiente:
"Use of uninitialized value in print"
y cuando imprimo $archivo[2] aparece:
"ARRAY <0x18296e4>".
¿A qué se debe esto?.
ddcastro
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2009-04-17 20:57 @914

Notapor explorer » 2009-04-18 12:40 @569

A que estás intentando imprimir un arreglo completo como si fuera un escalar.

Prueba con @{$archivo[2]}.
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: Bing [Bot] y 17 invitados

cron