• Publicidad

Búsqueda especial

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

Notapor explorer » 2007-10-06 03:50 @201

Entonces, si partimos de un texto en que las secciones ya tienen divididas a las palabras, solo hay que leer las secciones y procesarlas por separado. Ni siquiera hay que saber el número total de palabras.

Eso al menos he entendido cuando has escrito "tendrán". ¿O te refieres a que tenemos que transformar las 1000 palabras en cinco secciones de igual tamaño? En ese caso, no es necesario leer el texto como secciones separadas por las marcas '<s>'. Bastaría con leer todo el texto palabra a palabra, como tienes en la primera lectura, y luego procesarlas en cinco bloques de igual tamaño.

Quizás si pones un ejemplo quede más claro. Siento ser tan específico, pero no es lo mismo según cómo sea la entrada que nos den y la salida que nos piden.

En cuanto a la parte que no entiendes, olvídala, al menos de momento.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Publicidad

Notapor jorcaes » 2007-10-07 17:01 @751

Hola Explorer, lo has entendido bien, pero creo que yo no me he explicado con claridad, allá va un pequeño ejemplo:

Teniendo el siguiente texto:

Código: Seleccionar todo
Alonso acaba segundo y se jugará el título en Brasil
AGENCIAS. Shanghai · Así vivimos el Gran Premio de China con Alonso

¿Quién dice que los milagros no existen? Kimi Raikkonen y Fernando Alonso acabaron primero y segundo en el Gran Premio de China, penúltima prueba del Mundial de Fórmula 1, lo que sumado al abandono de Lewis Hamilton hará que el título se decida el próximo 21 de octubre en Brasil. El piloto inglés sigue líder, con 107 puntos, por los 103 del español y los 100 del finlandés. Son los únicos pilotos con opciones.

La salida de la carrera, como ya sucedió hace una semana en Japón, tuvo al agua como protagonista. Así, los coqueteos con la  lluvia surgieron nada más ponerse verdes los semáforos, aunque, eso sí,  el pavimiento nunca se puso tan difícil como en tierras niponas. En esas condiciones, Alonso buscó el lado exterior izquierdo de  la calzada para rebasar a los Ferrari. Lo logró con Massa a la salida de la primera curva, pero el  brasileño le devolvió la moneda poco después.


El texto tiene 178 palabras, las cuales hay que dividir en 5 secciones. (178/5=35.6) Por lo que se deberán formar 4 secciones de 35 palabras y una última sección de 38 palabras (el resto). Un vez tenemos las palabras en cada una de las $secciones, tenemos que buscar en cada sección las diferentes KEYWORDS de la parte __DATA__

Código: Seleccionar todo
Sección 1 (35 palabras)
Alonso acaba segundo y se jugará el título en Brasil
AGENCIAS. Shanghai · Así vivimos el Gran Premio de China con Alonso
¿Quién dice que los milagros no existen? Kimi Raikkonen y Fernando Alonso acabaron

Sección 2 (35 palabras)
primero y segundo en el Gran Premio de China, penúltima prueba del Mundial de Fórmula 1, lo que sumado al abandono de Lewis Hamilton hará que el título se decida el próximo 21 de octubre

Sección 3 (35 palabras)
en Brasil. El piloto inglés sigue líder, con 107 puntos, por los 103 del español y los 100 del finlandés. Son los únicos pilotos con opciones.
La salida de la carrera, como ya sucedió hace

Sección 4 (35 palabras)
una semana en Japón, tuvo al agua como protagonista. Así, los coqueteos con la  lluvia surgieron nada más ponerse verdes los semáforos, aunque, eso sí,  el pavimiento nunca se puso tan difícil como en tierras

Sección 5 (38 palabras)
niponas. En esas condiciones, Alonso buscó el lado exterior izquierdo de  la calzada para rebasar a los Ferrari. Lo logró con Massa a la salida de la primera curva, pero el  brasileño le devolvió la moneda poco después.


Siguiendo con el ejemplo anterior:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
__DATA__
alonso
título
...
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


La salida del programa debería ser:

Código: Seleccionar todo
Alonso - sección 1: 3 ocurrencias
Alonso - sección 4: 1 ocurrencia

título - sección 1: 1 ocurrencia
título - sección 2: 1 ocurrencia


Creo que ahora puede haber quedado más claro, y una vez tenga esa salida, lo almacenaré en una matriz de la siguiente forma:

Imagen

Acumulando los resultados de varios ficheros en la misma matriz.

Espero que puedas ayudarme en este problema que se me ha planteado.

¡Un saludo y muchísimas gracias por la ayuda prestada!
jorcaes
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2006-07-12 02:35 @149

Notapor explorer » 2007-10-07 18:17 @803

A ver si este hilo te puede dar alguna pista más.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2007-10-07 22:07 @963

Esta es otra solución: se basa en contar las apariciones de las palabras en cada sección, antes de buscarlas.

Es una forma de contar elementos sin tener que usar expresiones regulares.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        1 #!/usr/bin/perl
        2 use strict;     # somos estrictos,
        3 use warnings;   # precavidos,
        4 use integer;    # enteros,
        5 use locale;     # y lugareños.
        6
        7 # lectura ###################################################################
        8
        9 # leemos todo el texto
       10 my $fichero = do{ local $/ = undef; open FICHERO, '<kk.txt'; <FICHERO> };
       11
       12 # sacamos las palabras
       13 my @palabras = $fichero =~ m/ (\w+) /mogsix;
       14 #print 'Hay ', scalar @palabras, " palabras en el texto,\n";
       15
       16 # tamaño de las secciones
       17 my $largo_de_seccion = @palabras / 5;
       18 #print "Con $largo_de_seccion palabras por sección.\n";
       19
       20 # vamos guardando las @palabras, en bloques del tamaño del $largo_de_seccion,
       21 # para las cinco secciones
       22 my @secciones;
       23 for ( 0 .. 4 ) {
       24
       25     # extraemos la sección
       26     my @seccion_palabras = splice @palabras, 0, $largo_de_seccion;
       27
       28     # contamos las veces que sale cada palabra
       29     my %seccion_palabras;
       30     foreach my $palabra ( @seccion_palabras ) { $seccion_palabras{ $palabra }++ }
       31
       32     # la estadística la guardamos en el array de @secciones
       33     # como un hash en que las palabras son las claves y el valor, las veces que aparece
       34     push @secciones, { %seccion_palabras };
       35 }
       36
       37 # la última sección debe contener el resto de @palabras por colocar
       38 $secciones[ -1 ]{ $_ }++ foreach @palabras;
       39
       40 # el resultado es de la forma:
       41 # @secciones = [
       42 #          {
       43 #            'existen' => 1,
       44 #            'segundo' => 1,
       45 #            'primero' => 1,
       46 #            'jugará' => 1,
       47 #            'no' => 1,
       48 #            'Shanghai' => 1,
       49 #            'Fernando' => 1,
       50 #            'y' => 2,
       51 #            'Alonso' => 3,
       52 #            ...
       53 #          },
       54 #          {
       55 #            ...
       56 #
       57 # No nos importa el orden de las palabras.
       58 # Solo saber que existen, en qué sección están y cuantas veces aparecen
       59
       60 # ahora, leemos las keywords, quitándoles los finales de línea
       61 chomp (my @keywords = <DATA>);
       62
       63 # estadísticas ###############################################################
       64 foreach my $keyword ( @keywords ) {
       65
       66     my $ocurrencias;
       67
       68     foreach my $seccion ( 0 .. 4 ) {
       69
       70         # si existe en la sección el keyword
       71         if ( exists $secciones[ $seccion ] { $keyword } ) {
       72
       73             # vamos las veces que aparece
       74             $ocurrencias = $secciones[ $seccion ] { $keyword };
       75
       76             print "$keyword - sección ", $seccion+1, ': ';
       77             print $ocurrencias, ' ocurrencia';
       78
       79             if ( $ocurrencias != 1 ) { print 's' }
       80
       81             print "\n";
       82         }
       83     }
       84
       85     print "\n" if $ocurrencias;
       86 }
       87
       88 __DATA__
       89 Alonso
       90 título
       91 Pedro
Coloreado en 0.002 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: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor jorcaes » 2007-10-08 02:52 @161

Hola Explorer, ahora ya lo tengo muchísimo más claro. Tu ejemplo me ha ayudado muchísimo, es más, ahora tan sólo debo completar tu desarrollo para que se realice sobre un directorio lleno de textos y almacenarlo todo en un fichero Excel.

Revisando tu código tengo una pregunta. ¿Cómo debo leer la sección DATA y las palabras en las secciones para que también considere ocurrencia aunque esté en mayúsculas y minúsculas? Es decir:

Alonso == alonso == ALONSO

Debe ser con lc en la siguiente línea, no?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
 61 chomp (my @keywords = lc(<DATA>));
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero no sé si debo de ajustar alguna otra línea del código...

Otra cosa, he estado modificando el código para almacenar la salida en una matriz en formato Excel y no me funciona. Yo creo que está correcto, pero por más vueltas que le doy, no consigo localizar el error.

Os dejo el trozo de código que empleo para guardar en Excel:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $seccion ( 0 .. 4 ) {

          # si existe en la sección el keyword
                if ( exists $secciones[ $seccion ] { $keyword } ) {

                  # vemos las veces que aparece
                $ocurrencias = $secciones[ $seccion ] { $keyword };
                                                       
                                                        $sheet->Cells(1,2)->{Value}="Sección 1";
                                                        $sheet->Cells(1,3)->{Value}="Sección 2";
                                                        $sheet->Cells(1,4)->{Value}="Sección 3";
                                                        $sheet->Cells(1,5)->{Value}="Sección 4";
                                                        $sheet->Cells(1,6)->{Value}="Sección 5";
                                                       
                                                        if (! $fila { $keyword } ) {
                                                        $fila {$keyword}=$fila;
                                                        $sheet->Cells($fila,1)->{Value} = "$keyword";
                                                        $fila++;
                                                        }
                                                       
                                                        $sheet->Cells($fila{$keyword},$columna{$seccion+1})->{Value} += "$ocurrencias";
                                                       
                print "$keyword - sección ", $seccion+1, ': ';
                print $ocurrencias, ' ocurrencia';

                if ( $ocurrencias != 1 ) { print 's' }

                print "\n";
                }
        }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y en éste enlace podeis ver TODO el código, no lo pongo aquí porque sino se queda muy largo del post.

http://rafb.net/p/3WnX5F82.html


Saludos y muchas gracias!
jorcaes
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2006-07-12 02:35 @149

Notapor explorer » 2007-10-08 06:02 @293

Sí, una buena medida es pasar todas las palabras a minúsculas o mayúsculas. Pero no te vale lo que has escrito con la función lc(). Tendrás que hacer un bucle por cada keyword o usar un map() (no probado):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
chomp( my @keywords = map { lc } <DATA> );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y también habrá que hacerlo en el array de las palabras leídas desde el $fichero. Notar que tampoco se hace un control de los posibles espacios en blanco en los keywords, pero supongamos que los hemos escrito bien, sin ellos.

En cuanto a la parte de Excel, como has comentado la línea del strict y del warning, perl no ha podido avisarte de que no tienes definido ni declarado el hash %fila por ningún lado.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor jorcaes » 2007-10-08 11:50 @535

Hola de nuevo, pues he realizado las siguientes modificaciones:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
...

my @palabras = $fichero =~ /(\b[^\W_\d][\w'-]+\b)/g;

...

chomp (my @keywords = map {lc}<DATA>);

...
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



Y tras algunas pruebas NO está del todo correcto, ya que no me considera iguales las palabras en minúsculas y la primera en mayúscula, es decir, esto lo NO lo considera igual Alonso != alonso, y yo quiero que lo interprete como igual.

Por otra parte ya he conseguido redirigir la salida hacia una matriz excel correctamente y más o menos lo realiza correctamente para el primero de los ficheros contenidos en un idrectorio, pero no realiza ninguna acción para el resto de textos y está todo incluido en el bucle principal...

Pego TODO el código en el siguiente enlace...

http://rafb.net/p/XiUegv18.html

Muchísmas gracias por la ayuda, esto parece un foro Online casi, las respuestas son instantáneas.
jorcaes
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2006-07-12 02:35 @149

Notapor explorer » 2007-10-08 12:19 @554

Te falta por pasar a minúsculas también las palabras que lees del $fichero. Te lo he dicho antes.

Al principio del programa, donde declaras las variables, agrega: my %fila;.

Solo se procesa un fichero porque el <DATA> se agota. Debes sacar la línea que lee del __DATA__ y llevarla fuera del bucle, antes de que empiece.

No he mirado mucho la forma de escribir a la hoja de cálculo, pero creo que se puede simplificar bastante, teniendo en cuenta que estamos haciendo un doble bucle por keywords y secciones.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor jorcaes » 2007-10-10 10:30 @479

Correcto Explorer, tienes toda la razón del mundo. Se me había pasado. Por otra parte he modificado la forma de escribir en el Excel y la he simplificado un poco y ahora funciona perfecto, es más, ya lo tengo finalizado.

¡¡¡Muchísimas gracias por la ayuda ofrecida!!!
jorcaes
Perlero nuevo
Perlero nuevo
 
Mensajes: 26
Registrado: 2006-07-12 02:35 @149

Notapor rednet » 2007-11-15 09:36 @441

Hola, ¿sería posible ver el código entero ya que, el link http://rafb.net/p/XiUegv18.html no se encuentra activo y tengo que realizar algo similar y me serviría mucho? Desde ya, muchas gracias.
rednet
Perlero nuevo
Perlero nuevo
 
Mensajes: 14
Registrado: 2007-11-15 09:15 @427

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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