• Publicidad

Otra tanda de dudas...

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

Otra tanda de dudas...

Notapor Lurky » 2008-12-30 12:30 @563

¡Hola de nuevo! Me han surgido otros problemas (...), que no soy capaz de resolver...


1/ Por línea de comandos, introduzco entre otros, el nombre del archivo que tengo que abrir, que va en la posición 0 y hago lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$archivo = $ARGV[0];
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

y más tarde en una subrutina a la que paso correctamente los datos por valor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
unless ( open(ARCHIVO, $archivo) ) {
                print "File cannot be opened.";
                exit;
        }
       
        my @datos = <ARCHIVO>;
        close ARCHIVO;
       
        return @datos;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No me abre el archivo por línea de comandos, pero si usando eclipse cambio $ARGV[0] por el nombre del archivo entre comillas simples, sí funciona.

¿Alguna idea?

2/Si hago algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        my %datosprimarios;
        my @array = ($escalar1, $escalar2);
        @datosprimarios{$origen} = [@primario];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


con todos los datos inicializados (incluso los que no he especificado), me recomienda que en vez de usar @datos... use un escalar, ¿por qué?


3/En otro archivo, al abrirlo, tengo que extraer diversas secuencias de datos, que comienzan cada una por un cierto carácter y están separadas por un espacio en blanco
El archivo lo tengo guardado en un array, ¿se os ocurre alguna forma de extraer esas secuencias?

Mi idea es usar

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $linea @archivo {

        if ($linea =~ /^caracter/) {
                guardar las siguientes lineas en un array hasta que $linea =~ /^\s*$/
        }
..
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En cuanto a lo que haría luego con el array y cómo me las apañaría para guardar cada secuencia de forma aparte, eso sí sé como hacerlo.

El problema es que no se me ocurre forma alguna de escribir ese pseudocódigo. Quizás estén mal planteados los bucles...


4/ En un array contenedor de otros arrays, querría hacer lo siguiente mediante un bucle. Creo que no es complicado, pero no se me ocurre forma alguna...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@contenedor = (
        (1,1,1),
        (A,B,C),
        (3,6,9));
...

@operado = (
        (1A3),
        (1B6),
        (1C9));
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡¡Muchas gracias!! ¡Y feliz año nuevo! (o casi)
Lurky
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-12-23 20:53 @912

Publicidad

Notapor creating021 » 2008-12-30 14:49 @659

1/ Por línea de comandos, introduzco entre otros, el nombre del archivo que tengo que abrir, que va en la posición 0

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $archivo = $ARGV[0];
unless ( open(ARCHIVO, $archivo) ) {
    print "File cannot be opened.";
    exit;
}
       
my @datos = <ARCHIVO>;
close ARCHIVO;
       
return @datos;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Cuando haces eso, el programa no te dice que es lo que está pasando... yo haría lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $archivo = $ARGV[0];
open ARCHIVO, $archivo or die "Error con archivo $archivo : $!\n";
my @datos = <ARCHIVO>; #Ten cuidado con esto...
close ARCHIVO;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Así podrás saber cuál es el error.
Ten cuidado con meter todo el contenido del archivo en un array porque puede consumir toda la memoria y te ganas un problema :P
Si realmente necesitas hacer eso con un array usa Tie::File, en el foro hay temas sobre este módulo.
Algo más, cuando sales de un programa con exit el sistema operativo no lo toma como un error.
con todos los datos inicializados (incluso los que no he especificado), me recomienda que en vez de usar @datos... use un escalar, ¿por qué?

No entiendo lo que quieres hacer, pero sea lo que sea... está malo.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@datosprimarios{$origen} = [@primario];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

datosprimarios no es un array... de pronto así lo puedes hacer:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$datosprimarios{$origen} = [@primario];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

O así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
push @{ $datosprimarios{$origen} }, [@primario];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

3/En otro archivo, al abrirlo, tengo que extraer diversas secuencias de datos, que comienzan cada una por un cierto carácter y están separadas por un espacio en blanco
El archivo lo tengo guardado en un array, ¿se os ocurre alguna forma de extraer esas secuencias?

Yo necesito un ejemplo de esos datos para poderte ayudar (así sean falsos).
4/ En un array contenedor de otros arrays, querría hacer lo siguiente mediante un bucle. Creo que no es complicado, pero no se me ocurre forma alguna...

Pues... depende... ¿Cuáles o cómo son los datos?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @array;
for ( my $i = 0; $i < 30; $i += 3; ){
    push @array, [ $i, $i + 1, $i + 2];
}
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Re: Otra tanda de dudas...

Notapor explorer » 2008-12-30 15:46 @698

Lurky escribiste:2/Si hago algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        my %datosprimarios;
        my @array = ($escalar1, $escalar2);
        @datosprimarios{$origen} = [@primario];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


con todos los datos inicializados (incluso los que no he especificado), me recomienda que en vez de usar @datos... use un escalar, ¿por qué?


Por que eso es justo lo que estás intentando hacer: estás guardando UN valor, una array anónimo que contiene los datos de @primario, PERO estás indicando que quieres guardar una LISTA de valores, DEBIDO a la '@' que le has puesto a la variable datosprimarios.

Lo correcto sería:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$datosprimarios{$origen} = [@primario];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Recuerda: el "sigil" indica el TIPO de dato de acceso a la variable. Ya sé que esto es muy distinto de otros lenguajes, pero Perl funciona de esa manera. Esto es una de las cosas más difíciles de entender a los que aprenden Perl, aunque se entiende luego porque aporta más significado a lo que escribimos.

Curiosamente, en Perl 6 SÍ que funciona de forma contraria: las variables mantienen su sigil en todo momento.

Lurky escribiste:3/En otro archivo, al abrirlo, tengo que extraer diversas secuencias de datos, que comienzan cada una por un cierto carácter y están separadas por un espacio en blanco
El archivo lo tengo guardado en un array, ¿se os ocurre alguna forma de extraer esas secuencias?

Mi idea es usar

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $linea @archivo {

        if ($linea =~ /^carácter/) {
                guardar las siguientes lineas en un array hasta que $linea =~ /^\s*$/
        }
..
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En cuanto a lo que haría luego con el array y cómo me las apañaría para guardar cada secuencia de forma aparte, eso sí sé cómo hacerlo.

El problema es que no se me ocurre forma alguna de escribir ese pseudocódigo. Quizás estén mal planteados los bucles...

Puedes usar un sistema de banderas... (no probado)

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @parrafo;
my $en_parrafo = 0;

for my $linea (@archivo) {
    if (!$en_parrafo and $linea =~ /^C/) {
        $en_parrafo = 1;                   # Hemos encontrado un párrafo a guardar
    }

    if ($en_parrafo) {
        if ($linea =~ /^\s*$/) {           # Final del párrafo. Lo procesamos
            $en_parrafo = 0;
            # hacer algo con @parrafo
        }
        else {
            push @parrafo, $linea;         # Todavía no es el final. Seguimos almacenando
        }
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


O también... (no probado)
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
for (@archivo) {
    if (/^C/ .. /^\s*$/) {
        push @parrafo, $_;
    }
    else {
        # Procesar @parrafo, si hay algo
        if (@parrafo) {
            # procesar...
            @parrafo = ();
        }
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Lurky escribiste:4/ En un array contenedor de otros arrays, querría hacer lo siguiente mediante un bucle. Creo que no es complicado, pero no se me ocurre forma alguna...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@contenedor = (
        (1,1,1),
        (A,B,C),
        (3,6,9));
...

@operado = (
        (1A3),
        (1B6),
        (1C9));
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Creo que no es correcto lo que escribes. Mira:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;

my @contenedor = (
    (1,1,1),
    ('A','B','C'),
    (3,6,9),
);

use Data::Dumper;
print Dumper \@contenedor;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sale:
Código: Seleccionar todo
$VAR1 = [
          1,
          1,
          1,
          'A',
          'B',
          'C',
          3,
          6,
          9
        ];
Es decir, los paréntesis "despliegan" su contenido, pero no "separan" unos array unos de otros.
Debería ser así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;

my @contenedor = (
      [ 1,  1,  1 ],
      ['A','B','C'],
      [ 3,  6,  9 ],
);

use Data::Dumper;
print Dumper \@contenedor;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Sale:
Código: Seleccionar todo
$VAR1 = [
          [
            1,
            1,
            1
          ],
          [
            'A',
            'B',
            'C'
          ],
          [
            3,
            6,
            9
          ]
        ];
Ahora sí que es un array de arrays.

Recuerda: Data::Dumper es tu amigo.
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 explorer » 2008-12-30 15:54 @704

creating021 escribiste:No entiendo lo que quieres hacer, pero sea lo que sea... está malo.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@datosprimarios{$origen} = [@primario];
Coloreado en 0.010 segundos, usando GeSHi 1.0.8.4

datosprimarios no es un array... de pronto así lo puedes hacer:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$datosprimarios{$origen} = [@primario];
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

O así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
push @{ $datosprimarios{$origen} }, [@primario];
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

%datosprimarios es un hash, claro, pero que ponga un '@' no significa que lo tratemos como un array, sino que le estamos asignando una lista de valores. No es exactamente lo mismo.

Y tampoco es lo mismo
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$datosprimarios{$origen} = [@primario];
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
que esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
push @{ $datosprimarios{$origen} }, [@primario];
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Fíjate:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

use Data::Dumper;

my %dp;
my @pr = (1 .. 3);

$dp{clave} = [ @pr ];

print Dumper \%dp;

%dp = ();

push @{ $dp{clave} }, [ @pr ];

print Dumper \%dp;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Sale:
Código: Seleccionar todo
$VAR1 = {
          'clave' => [
                       1,
                       2,
                       3
                     ]
        };
$VAR1 = {
          'clave' => [
                       [
                         1,
                         2,
                         3
                       ]
                     ]
        };
Hay que tener cuidado con los ejemplos que se ponen... sería recomendable probarlos antes... o decir que no los has probado y lo pones de memoria :)
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 creating021 » 2008-12-30 19:39 @860

Cierto, eso es muy diferente :lol:

Buen, pero si pongo problema, al igual que warnings.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
use warnings;
use diagnostics;
my %datosprimarios;
my @primario = (0, 1, 2 );
@datosprimarios{"aeiou"} = [@primario];
print ( join "\n", @{$datosprimarios{"aeiou"}});
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Scalar value @datosprimarios{"aeiou"} better written as
$datosprimarios{"aeiou"} at test.pl line 6 (#1)
(W syntax) You've used a hash slice (indicated by @) to select a single
element of a hash. Generally it's better to ask for a scalar value
(indicated by $). The difference is that $foo{&bar} always behaves
like a scalar, both when assigning to it and when evaluating its
argument, while @foo{&bar} behaves like a list when you assign to it,
and provides a list context to its subscript, which can do weird things
if you're expecting only one subscript.

On the other hand, if you were actually hoping to treat the hash element
as a list, you need to look into how references work, because Perl will
not magically convert between scalars and lists for you. See
perlref.
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Notapor Lurky » 2009-01-01 18:07 @796

Muchas gracias a los dos y feliz año.


En cuanto al problema de abrir el archivo, creo que logré solucionarlo

En cuanto al @hash{} ya los he cambiado por escalares.

En lo respectivo al problema 3, ahora probaré las ideas que me has dado, explorer.

En lo que se refiere al problema 4, voy a explicarlo un poco más.

Voy a guardar en un array contenedor varios arrays que contienen una sola letra en cada $array[X]. Lo que quiero es modificar ese array contenedor para que ocurra algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@A = ([A,B,C,D] , [E,F,G,H]);

...

@A = ( [A,E], [B,F], (C,G], [D,H])
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



El problema es que no puedo concretar el caso más, o sea, que el array contenedor puede contener x arrays de n elementos cada uno (pero siempre tienen el mismo número de elementos).

¿Alguna idea?

Ah, un quinto problema.
¿Por qué me dice "Odd number of elemets in anonymous hash"? Este sería un ejemplo resumido del código que me da error.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $origen = 0;
my $b=1;

do {
    $hash{$b} = $origen;
    $origen++;
    $das++;
} until {$b == 10};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y si esto está tan mal hecho... ¿De qué otra forma podré ir añadiendo progresivamente diversos valores a un hash y variando las keys en un bucle?

Muchas gracias.
Lurky
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-12-23 20:53 @912

Notapor explorer » 2009-01-01 20:45 @906

Lurky escribiste:Voy a guardar en un array contenedor varios arrays que contienen una sola letra en cada $array[X]. Lo que quiero es modificar ese array contenedor para que ocurra algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@A = ([A,B,C,D] , [E,F,G,H]);
...
@A = ( [A,E], [B,F], (C,G], [D,H])
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El problema es que no puedo concretar el caso más, o sea, que el array contenedor puede contener x arrays de n elementos cada uno (pero siempre tienen el mismo número de elementos).
¿Y cuál es el problema? ¿Qué código estás probando y no te funciona?

Lurky escribiste:¿Por qué me dice "Odd number of elemets in anonymous hash"? Este sería un ejemplo resumido del código que me da error.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $origen = 0;
my $b=1;

do {
    $hash{$b} = $origen;
    $origen++;
    $das++;
} until {$b == 10};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y si esto está tan mal hecho... ¿De qué otra forma podré ir añadiendo progresivamente diversos valores a un hash y variando las keys en un bucle?

Ese trozo de código tiene dos problemas:
1. La condición del until() debe ir entre paréntesis, no llaves. De ahí el mensaje de error. Y
2. $b nunca se modifica en el bucle, por lo que la condición nunca se cumple, por lo que nunca termina.
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 Lurky » 2009-01-03 14:32 @647

Puf, veo que ni siquiera escribí lo que tenía que poner... Lo siento, es que estaba agotado.

Lurky escribió:
Voy a guardar en un array contenedor varios arrays que contienen una sola letra en cada $array[X]. Lo que quiero es modificar ese array contenedor para que ocurra algo así:

Perl:
@A = ([A,B,C,D] , [E,F,G,H]);
...
@A = ( [A,E], [B,F], (C,G], [D,H])


El problema es que no puedo concretar el caso más, o sea, que el array contenedor puede contener x arrays de n elementos cada uno (pero siempre tienen el mismo número de elementos).
¿Y cuál es el problema? ¿Qué código estás probando y no te funciona?


Ya repasé el código, y me funciona perfectamente. Lo típico, dos tonterías que ni use warnings pudo decirme. Pero con el depurador y algo de paciencia, logré encontrar el error.


Lurky escribió:
¿Por qué me dice "Odd number of elemets in anonymous hash"? Este sería un ejemplo resumido del código que me da error.

Perl:
my $origen = 0;
my $b=1;

do {
$hash{$b} = $origen;
$origen++;
$das++;
} until {$b == 10};


Y si esto está tan mal hecho... ¿De qué otra forma podré ir añadiendo progresivamente diversos valores a un hash y variando las keys en un bucle?

Ese trozo de código tiene dos problemas:
1. La condición del until() debe ir entre paréntesis, no llaves. De ahí el mensaje de error. Y
2. $b nunca se modifica en el bucle, por lo que la condición nunca se cumple, por lo que nunca termina.



De acuerdo, el error venía de los paréntesis (qué cabeza la mía..). ¿Pero eso qué tenía que ver con el hash?

Un par de cosas más (lo siento xD), tengo que introducir ciertos parámetros por línea de comando que influyen en todo el programa, y salvo modificando el código, no se me ocurre cómo podría usar el depurador de forma global en el programa, porque si no introduzco esos parámetros, no funcionaría el programa, y me interesa saber qué tal funciona si los introduzco por línea de comandos.


Y en una serie de escalares que almacenan cada uno n valores numéricos, ¿cómo encontrar el más alto? Se me ocurren algunos códigos, pero tremendamente largos. Yo quería preguntar si hay alguna manera medianamente breve de hallarlo.


De nuevo, muchas gracias.
Lurky
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-12-23 20:53 @912

Notapor explorer » 2009-01-03 15:29 @686

Lo de qué tiene que ver {$b == 10} con un hash es porque en Perl, un hash anónimo se define de esa manera: con llaves. Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $hash_ref = { $b => 10 };
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Estamos definiendo una referencia a un hash que contiene una clave y su valor.

En cambio, en tu código aparece solo un valor en el interior de las llaves: la condición lógica '==' reduce la expresión a un valor. Por eso sale el error, que quiere decir que ha encontrado la definición de un hash con un número impar de valores.

No creo que tengas problemas para ejecutar un programa con argumentos, con el depurador. Solo tienes que colocarles detrás del nombre del programa para que entren como argumentos. O leyéndolos desde la entrada estándar: el depurador esperará la ejecución de la línea antes de tomar el control.

Y para encontrar el valor más alto de una lista de valores puedes usar el módulo List::Util:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use List::Util qw(max);

my $array_ref = [ qw(1 2 3 5 8 234455 3 -3) ];

print max @$array_ref;
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: 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: No hay usuarios registrados visitando el Foro y 21 invitados

cron