• Publicidad

Contar duplicados y mostrar número

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

Re: Contar duplicados y mostrar número

Notapor explorer » 2009-12-02 17:38 @776

Analicemos el código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open(DATOS,"entrada.txt");    # Abrimos el fichero "entrada.txt"
@registro=<DATOS>;            # Leemos todo el fichero,
                              # cada línea en un elemento del arreglo
while ( $registro[$x]<2 )     # Mientras la línea $x-ésima contenga un
                              # valor numérico menor que 2,
{
        print $registro [$x]; # pintamos la línea $x-ésima
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Hummm... se ven los problemas enseguida, ¿no?
* ¿Cuánto vale $x? ¿Dónde se inicializa? ¿Para qué sirve su valor? ¿Dónde cambia?

* ¿Es seguro que en las líneas hay valores numéricos? ¿No decías que contenían nombres?

* Si quieres imprimir los nombres, ¿por qué hay un bucle con una condición?

Esta es una forma de mostrar en pantalla los nombres almacenados en el fichero:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open(DATOS,'<entrada.txt')       # Abrimos el fichero en lectura
    or die "ERROR: No pude abrir el fichero: $!\n";  # O morimos en el intento
my @registro = <DATOS>;          # Lo leemos entero
for my $nombre (@registro) {     # Para cada $nombre guardado en el @registro
    print $nombre;               # Lo pintamos
}
close(DATOS);                    # Cerramos el fichero
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Naturalmente, queda más corto haciéndolo más directo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open(DATOS,'<entrada.txt')       # Abrimos el fichero en lectura
    or die "ERROR: No pude abrir el fichero: $!\n";  # O morimos en el intento
while (my $nombre = <DATOS>) {   # Leemos un $nombre cada vez, hasta fin de fichero
    print $nombre;               # Lo pintamos
}
close(DATOS);                    # Cerramos el fichero
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Vale, ya tenemos los nombres, uno a uno. Solo queda recordar las veces que sale cada uno de ellos. Por ejemplo, con un hash:

$cuantas_veces_sale{$nombre}++;

Ya solo te queda sacar la información almacenada para saber %cuantas_veces_sale cada $nombre.
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: Contar duplicados y mostrar número

Notapor gonzalos » 2009-12-03 13:48 @617

Hola, explorer

Gracias por la ayuda. Lo hice así porque quería que me mostrara en pantalla, la lista de nombres, sólo uno cada vez, por eso le añadí la condición. Es decir, si había un nombre que se repitiera 3 veces (una suposición), sólo me lo mostrara una vez, por eso ponía que fuera menor que dos, para que sólo lo leyera una vez.

No sé si me estoy explicando bien o me lío demasiado.

Pero ya he entendido que debes leerlos todos para luego contarlos y mostrar la cantidad en la que aparecen.

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

Re: Contar duplicados y mostrar número

Notapor explorer » 2009-12-03 13:59 @624

Para construir una casa con ladrillos caravista, antes debes aprender que existen 6 tipos distintos de ladrillos caravista.

Y los ladrillos esquineros son 3 variantes más.

Solo entonces podrás empezar a amasar el cemento...
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: Contar duplicados y mostrar número

Notapor gonzalos » 2009-12-03 16:09 @714

Ya sé que los cimientos son los que sustentan el edificio. Por eso estoy buscando libros en formato papel sobre Perl, ya que prefiero tenerlos físicamente; así, si me surge una duda podría consultarlos en cualquier momento. He leído en foro que los mejores para empezar son el de la llama y el del camello.

Aquí va el código con el hash.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
open(DATOS,'<entrada.txt')       # Abrimos el fichero en lectura
or die "ERROR: No pude abrir el fichero: $!\n";  # O morimos en el intento
my @registro = <DATOS>;          # Lo leemos entero
for my $nombre (@registro) {     # Para cada $nombre guardado en el @registro
    print $nombre;               # Lo pintamos
}
my (%cuantas_veces_sale);        #Definimos hash
while (<DATOS>){                 #Leemos el archivo

if ($cuantas_veces_sale{$nombre}){ #aplicamos condición
    $cuantas_veces_sale{$nombre} = $cuantas_veces_sale{$nombre}++; #añadimos un contador
} else {}
}
print $cuantas_veces_sale{$nombre};  #Mostramos las veces que aparece
close(DATOS);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


He definido el hash y lo he leído; ahora no sé me ocurre qué condición podría ponérsele, y no sé si para mostrarlo bastaría con imprimirlo o se debería utilizar alguna otra orden.

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

Re: Contar duplicados y mostrar número

Notapor explorer » 2009-12-03 17:30 @771

En lenguajes de programación, los ladrillos son la sintaxis, las funciones incorporadas o primitivas y el paradigma de programación (y más cosas).

Si no los conoces, estás programando al estilo intento y error. Mientras que es cierto que Perl es muy liberal en lo que puede admitir, igual que cualquier otro lenguaje informático, tiene sus limitaciones: no es lenguaje natural (pero casi).

Eso quiere decir que Perl no hará lo que queremos si se lo expresamos mal. Por eso hay que saber la sintaxis.

En Internet tienes muchos recursos para aprender. También hay libros, desde luego, y los puedes tener también físicamente (tanto en papel como en PDF).

En concreto, para el problema planteado, te vale con entender lo que significa y para qué sirven los hash. O saber distinguir los distintos escenarios que se deben plantear a la hora de elegir un hash o un array para resolver un problema. Una vez me encontré con unas personas que habían sido recicladas para programar Perl, en muy poco tiempo. Y eso es muy peligroso, porque cuando yo llegué, ellos no sabían muy bien la diferencia entre los dos. Mejor dicho, no sabían cuándo aplicar uno u otro. Y eso que llevaban programando con Perl durante más de un año.

Esos conceptos son fáciles de ver en los libros que mencionas (a propósito, no es un camello, es un dromedario -camello arábigo-). El contenido del libro del dromedario es un volcado casi literal del contenido de la ayuda de Perl. Es decir, que puedes empezar a leer el libro mirando antes la ayuda en Perl. perlsyn, perldata, etc.

En este sitio hay tutoriales, aunque, claro, van al grano y no tocan elementos más básicos. Si no sabes por dónde empezar, por aquí te pongo una lista de recursos en Español para que empieces a leer.

Y, naturalmente, por aquí te seguiremos echando una mano.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while (<DATOS>){                 # Leemos el archivo
if ($cuantas_veces_sale{$nombre}){ #aplicamos condición
    $cuantas_veces_sale{$nombre} = $cuantas_veces_sale{$nombre}++; #añadimos un contador
} else {}
}
print $cuantas_veces_sale{$nombre};  #Mostramos las veces que aparece
close(DATOS);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Aquí tienes el problema de la condición if(). Dices que "aplicas la condición", pero esa condición es verdadera si y solo si $cuantas_veces_sale{$nombre} es positivo (un valor mayor que cero, por ejemplo). Pero... al principio... el hash %cuantas_veces_sale está siempre vacío. Por lo tanto, nunca entra en el if(), y por lo tanto, nunca es incrementado.

A ver así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %cuantas_veces_sale;                                # Definimos memoria

open(DATOS,'<entrada.txt')                             # Abrimos el fichero en lectura
    or die "ERROR: No pude abrir el fichero: $!\n";    #     o morimos en el intento

while (my $nombre = <DATOS>) {                         # Lo leemos línea a línea
    chomp $nombre;                                     # quitamos el carácter de fin de línea
    $cuantas_veces_sale{$nombre}++;                    # estamos viendo a ese $nombre una vez más
}

close(DATOS);                                          # Cerramos

# salida del resultado
for my $nombre (keys %cuantas_veces_sale) {            # Para todos los nombres leídos
    if ($cuantas_veces_sale{$nombre} > 2) {            # Si sale más de dos veces
        print "$nombre : $cuantas_veces_sale{$nombre}\n";   # mostramos las veces que aparece
    }
}
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: Contar duplicados y mostrar número

Notapor gonzalos » 2009-12-05 17:14 @759

Hola a todos.

Estuve corriendo el programa y en un principio no me imprimía la salida. Estuve leyendo el código detenidamente y me dí cuenta que sólo imprimiría aquellos nombres que se repitieran más de dos veces, por lo que eliminé el último condicional y ahora funciona perfectamente.

Para rizar el rizo y como estaba aburrido decidí que además de la salida en pantalla quería que me lo imprimiera en un archivo. Por lo que después de ojear un poco por la red encontré que se podía usar el módulo Storable.

Aquí os dejo el código con la parte añadida del módulo Storable. Declaré su uso al inicio del código y añadí el comando al final del programa.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %cuantas_veces_sale;                                 # Definimos memoria

open(DATOS,'<entrada.txt')                              # Abrimos el fichero en lectura
    or die "ERROR: No pude abrir el fichero: $!\n";     #     o morimos en el intento

while (my $nombre = <DATOS>) {                          # Lo leemos línea a línea
    chomp $nombre;                                      # quitamos el carácter de fin de línea
    $cuantas_veces_sale{$nombre}++;                     # estamos viendo a ese $nombre una vez más
}
close(DATOS);                                           # Cerramos

# salida del resultado
for my $nombre (sort keys %cuantas_veces_sale) {            # Para todos los nombres leídos y ordenados
        print "$nombre = $cuantas_veces_sale{$nombre}\n";   # mostramos las veces que aparece
    }
store \%cuantas_veces_sale, 'salida.txt';                   # Guarda el arreglo asociativo en un fichero
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Por último quería agradecer la ayuda y la paciencia mostradas por todos. Y las explicaciones y consejos que me han servido de gran ayuda. Seguiremos leyendo por el foro para continuar el aprendizaje.

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

Re: Contar duplicados y mostrar número

Notapor explorer » 2009-12-05 17:26 @768

Solo aclarar que Storable sirve para guardar estructuras de datos Perl a ficheros, para luego recuperarlos. Es lo que se llama persistencia de los datos de un programa.

Pero lo que no hace es guardarlo en formato texto, como indica gonzalos al poner '.txt' como extensión del fichero de salida.
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: Contar duplicados y mostrar número

Notapor gonzalos » 2009-12-09 12:52 @578

Hola, explorer.

Ya he averiguado cómo copiar la salida del hash a un fichero. Si quieres modifico el código y elimino la referencia al módulo Storable, para evitar la confusión.

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

Re: Contar duplicados y mostrar número

Notapor explorer » 2009-12-09 13:09 @590

Es que todo depende de la forma en la que quieres guardar la información.

Ya has mostrado cómo se hace con Storable, así que si pones la otra opción, mejor, más variedad.
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: Contar duplicados y mostrar número

Notapor gonzalos » 2009-12-09 14:05 @629

Bueno pues aquí va otra versión de cómo guardarlo usando el manejador de archivos.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
# salida del resultado
for my $nombre (sort keys %cuantas_veces_sale) {            # Para todos los nombres leídos y ordenados

        print "$nombre = $cuantas_veces_sale{$nombre}\n";   # Mostramos las veces que aparece
        }  
       
open (SALIDA,'>salida.txt')                                     #Abrimos un fichero de salida
    or die "ERROR: No se pudo abrir el fichero: $!\n";        
      for $nombre (sort keys %cuantas_veces_sale) {             # Para todos los nombres leidos y ordenados
        print SALIDA "$nombre=$cuantas_veces_sale{$nombre}\n";  # Imprimimos la salida
   }
close (SALIDA);                                                 # Cerramos el fichero
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Bueno, con esto y si no hay ningún comentario más podemos dar por resuelta la cuestión.

Lo dicho: muchas gracias por la ayuda y seguiremos por aquí indagando y resolviendo dudas.

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

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron