• Publicidad

Novato con un par 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.

Novato con un par de dudas...

Notapor Lurky » 2008-12-26 08:04 @377

Bien, tengo que hacer un proyecto para la uni y me están surgiendo dudas tontas.

1/ En un bucle que estoy haciendo, la idea es que pare cuando no exista un valor asociado a una key. ¿Cómo se escribe ese "no exista"?

2/ ¿Qué consume más o a cuál le cuesta menos al ordenador acceder, un array que sea una lista de unos 600 elementos o un hash que contenga esos 600 elementos?

Muchísimas gracias. Un saludo y felices fiestas.

PD: es probable (casi seguro :lol: ) que me sigan surgiendo dudas. Las iré posteando aquí según surjan. ¡Gracias de nuevo!

EDITO: pues sí, me siguen surgiendo dudas xD.
3/ Intento hacer un if similar a éste, pero me da error. Lo que quiero es que si esos escalares almacenan variables que sean letras, me dé error:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ( ($A|$B|$C) =~ /[a..zA..Z]/) {
       
                print "ERROR'
                exit;
        }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


¿Cuál es el fallo?
Lurky
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-12-23 20:53 @912

Publicidad

Notapor creating021 » 2008-12-26 09:52 @453

1/ En un bucle que estoy haciendo, la idea es que pare cuando no exista un valor asociado a una key. ¿Cómo se escribe ese "no exista"?

En este tutorial está todo lo que necesitas saber sobre hashes y como hacer el bucle.
Para saber si existe, con un simple if y la función exists lo puedes hacer.
2/ Qué consume más o a cuál le cuesta menos al ordenador acceder, un array que sea una lista de unos 600 elementos o un hash que contenga esos 600 elementos?

http://ismedia.org/content/perl/advprog/ch08_01.htm
Lee "8.1 Efficient Attribute Storage"
EDITO: pues sí, me siguen surgiendo dudas xD. ¿Alguien me explica cómo se hace correctamente el paso por valor en una subrutina? Es que, a pesar de usar @_ y el return, no me importa ese valor fuera de la subrutina...

http://perlenespanol.com/tutoriales/fun ... iones.html
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 creating021 » 2008-12-26 10:10 @465

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ( ($A|$B|$C) =~ /[a..zA..Z]/) {

print "ERROR'
exit;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Lo que pasa es que en $A | $B, | (pipe) es un operador matemático (retorna 1 si los bits son complementarios).
Si lo que quieres es evaluar si alguna de esas variables son letras...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ( ($A.$B.$C) =~ /^a-zA-Z/ ) {
    die "Error\n";
}
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

Notapor explorer » 2008-12-26 10:40 @486

Hay un error en la expresión regular. Es
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ( ($A.$B.$C) =~ /[a-z]/i ) {
    die "Error\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Lo que hace es una concatenación (.) del contenido de todas las variables. Y luego se busca en ese nuevo contenido alguna letra ([a-z]), independiente de las mayúsculas o minúsculas (/i).

Los corchetes son necesarios, para indicar una "clase" de caracteres a buscar. Sin ellos, estamos buscando literales.

Otra forma de escribirlo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
die "Error\n" if ($A.$B.$C) =~ /[a-z]/i;
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

Notapor Lurky » 2008-12-26 13:38 @610

Muchas gracias a los dos, de verdad.

Intento acabar este proyecto cuanto antes, y me están surgiendo varias buenas ideas, pero estoy algo limitado para llevarlas a cabo por mi conocimiento de Perl...


creating, ahora mismo echo un vistazo a esos enlaces.
Tenía que haber mirado los tutoriales de aquí antes de preguntar... Mea culpa >.<

Intentaré poner las dos últimas tonterías que se me ocurren:

1/Cuando yo me refería a que tenía un bucle que quería parar cuando el valor de un hash no existiese pensaba más bien en:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
do {
            ....
            $valor++;
} until (%hash{$valor} no exista}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Cómo expresaría ese no exista? ¿O es preferible usar el if y exists en un bucle?


2/Visto ya el tutorial de array, lo que me gustaría saber es si hay alguna forma de operar con ellos sumándolos, multiplicándolos...

Estoy pensando en una serie de n array con varios valores, por ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@Tal = ( 5, 6, 1);
@talcual = ( 1, 3, 5);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


De tal forma que tengo que sacar el promedio

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@C = (@A + @B)/2;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Sé que ésto no se puede, y que sí se podría hacer empleando $A[], $B[] y $C[]; pero cuando se trata de muchos array con muchos valores, es algo engorroso y casi imposible.

¿Se os ocurre alguna forma de hacer esto para muchos array?
Lurky
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-12-23 20:53 @912

Notapor explorer » 2008-12-26 14:07 @630

1/
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while ( exists $hash{$valor} ) {
    # ...
    $valor++;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
do {
    # ...
    $valor++;
} while(exists $hash{$valor} );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

De todas formas, si $valor es numérico, es mejor que uses un array.

2/
Si quieres controlar a muchos array, puedes hacerlo con otro array o con un hash.

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

my @letras = (
    [ 1, 3, 5],
    [ 5, 6, 1],
    [ 3, 4, 9],
);

## Sumamos los elementos
my @suma;
for my $array (@letras) {
#   for my $i (0 .. $#$array) {
    for (my $i = 0; $i < @{$array}; $i++) {
        $suma[$i] += $array->[$i];
    }
}

## Calculamos la media
for my $x (@suma) {
    $x = $x / @letras;
}

print "@suma";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


P.D. La notación
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@C = (@A + @B)/2;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
no es posible en Perl 5. En Perl 6 sí que hay una forma de hacerlo.

En PDL se haría con escalares:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$C = ($A + $B)/2;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
siendo cada escalar un "piddle".

Actualización: Ya es auténtica casualidad que, precisamente hoy mismo, se ha tratado este tema en PerlMonks.
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 » 2008-12-26 15:30 @687

De verdad, muchísimas gracias.

Es que estoy intentando guardar ciertos datos en muchos arrays, guardados a su vez en un hash.

Más tarde accedería a esos arrays mediante un bucle y usando las keys del hash. Y promediaría la suma de ciertas combinaciones de esos arrays en otros arrays hasta que se incumplan ciertas condiciones.
Los arrays que sí cumpliesen esas condiciones irían a parar al mismo hash, pero sobreescrito. Tras lo cual, yo trabajaría con esos datos.

¿Me he complicado mucho la vida? ¿Esto sería muy costoso en términos de memoria?

¡Ah!, ya las tres últimas preguntas, palabra xD.

1/ En el código que acabas de enseñarme, $array->[$i] qué quiere decir exactamente?

2/Para operar con esos arrays, los introduciré en un array que los englobe, como me dijiste antes. Para extraerlos del hash en el que están, lo único que se me ocurre es esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my (@secundario) = ( [%hash {$tal}], .., [%hash {$cuall}]);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Me falla, entre otras cosas, creo que el ".." está mal usado.

3/ En un bucle, mi idea es usar esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%datossecundarios = (%datossecundarios, $ventanaorigen, @secundario);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Funcionará? (probablemente no, conociéndome) ¿O cuál sería la alternativa correcta?


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

Notapor explorer » 2008-12-26 16:16 @719

Lurky escribiste:estoy intentando guardar ciertos datos en muchos arrays, guardados a su vez en un hash.

Más tarde accedería a esos arrays mediante un bucle y usando las keys del hash. Y promediaría la suma de ciertas combinaciones de esos arrays en otros arrays hasta que se incumplan ciertas condiciones.
Los arrays que sí cumpliesen esas condiciones irían a parar al mismo hash, pero sobreescrito. Tras lo cual, yo trabajaría con esos datos.

¿Me he complicado mucho la vida? ¿Esto sería muy costoso en términos de memoria?


No creo que te la hayas complicado... las estructuras en Perl, de hash de arrays, son muy comunes.

Lo interesante es saber si es la más óptima o no. Pero eso lo dicta la experiencia.

En cuanto a la memoria, sería costoso si tuvieras que ir a la tienda a comprar más memoria. Mientras uses la que tienes, todo perfecto.

Mejor dicho sería: ¿Sería óptimo el almacenamiento en memoria? Y la respuesta sería que depende del resto de programas del sistema: si les desplazas a la memoria de intercambio, entonces sí que sería costoso en términos de consumo de recursos.

Pero bueno, estamos hablando de varios centenares de millones de datos...

Lurky escribiste:1/ En el código que acabas de enseñarme, $array->[$i] qué quiere decir exactamente?

$array es una variable escalar que almacena una referencia. Una referencia a otra cosa. En este caso, vemos unos corchetes, así que está referenciando a un array. Con el signo '->' lo desreferenciamos (igual que hacemos en lenguaje C) y accedemos al array del que nos quedamos el elemento $i-eximo.

Una referencia en Perl es como un puntero en otros lenguajes, pero... más "virtual".

Lurky escribiste:2/Para operar con esos arrays, los introduciré en un array que los englobe, como me dijiste antes. Para extraerlos del hash en el que están, lo único que se me ocurre es esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my (@secundario) = ( [%hash {$tal}], .., [%hash {$cual}]);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Me falla, entre otras cosas, creo que el ".." está mal usado.

Aunque Perl es muy liberal, eso no quiere decir que podamos programar con el método de "ensayo y error". Hay que seguir las normas del lenguaje.

1. Has escrito %hash{$tal}, cuando, seguramente, quieres decir $hash{$tal}. El "sigil" o carácter que precede a las variables indica el tipo de dato que vamos a obtener de ellas. Si, de un hash (%hash) queremos obtener uno de sus valores (el correspondiente a la clave $tal) entonces es que vamos a recuperar un escalar (un valor), así que por eso ponemos un $ delante de la variable.

2. El operador '..' se usa para rangos de números o como operador de condiciones, pero para nada más... Perl no es tan listo como para saber qué quieres decir, o qué valores van del $tal al $cual. Si quieres sacar todos los valores de un hash, te vale con usar la función values():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @secundario = values %hash;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Si no son todos los valores, entonces hay que trabajar algo más. Si, por ejemplo, quieres los valores dentro de un rango numérico, entonces puedes usar un slice:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @secundario = @hash{$tal .. $cual};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
. Y si, finalmente, son valores no consecutivos, entonces hay que indicarles todos, en el slice:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @secundario = @hash{$tal, $cual, $fulano, $mengano, $zutano};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Observa como, ahora, en estos dos últimos ejemplos, he puesto una @ delante de la variable: es porque voy a recuperar más de un elemento. O dicho de otra manera: voy a recuperar una "lista" de valores.

Lurky escribiste:3/ En un bucle, mi idea es usar esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%datossecundarios = (%datossecundarios, $ventanaorigen, @secundario);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Funcionará? (probablemente no, conociéndome) ¿O cuál sería la alternativa correcta?


No, no funcionará. No sé lo que quieres hacer, pero viendo lo escrito la respuesta es no.

Recuerda: use warnings; 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 Lurky » 2008-12-27 09:05 @420

explorer escribiste:
Lurky escribiste:3/ En un bucle, mi idea es usar esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%datossecundarios = (%datossecundarios, $ventanaorigen, @secundario);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Funcionará? (probablemente no, conociéndome) ¿O cuál sería la alternativa correcta?


No, no funcionará. No sé lo que quieres hacer, pero viendo lo escrito la respuesta es no.

Recuerda: use warnings; es tu amigo.


Muchas gracias. Veo que tengo demasiados fallos de base >.< Repasaré apuntes y miraré en perldoc y demás. Además de los tutoriales de aquí, que ya he mirado grosso modo los que me atañen, ¿me recomiendas alguna web?

Ah, lo que intentaba hacer es añadir una key y un value en cada iteración a un hash. Con los arrays lo hago así, pero me imaginaba que con un hash era distinto.

Un saludo y felices fiestas.

EDITO: uso use warnings, aunque no se note ^^, lo que pasa es que si hay un error gordo delante, deja de avisarme sobre lo que hay detrás.
Lurky
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2008-12-23 20:53 @912

Notapor explorer » 2008-12-27 11:09 @506

Para añadir un nuevo valor a un hash, te vale con asignar un nuevo valor a una nueva clave:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$datossecundarios{$ventanaorigen} = [ @secundario ];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Aunque, también, si tienes un array con pares de valores claves/valores, entonces también puedes pasarlos a un hash:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%datossecundarios = (%datossecundarios, @secundario);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Ejemplo:
Código: Seleccionar todo
explorer@casa:~> perl -le '%x = ( a=>1, b=>2); @y=qw(c 3 d 4); %x = (%x,@y); print map { "$_ => $x{$_}\n" } keys %x'
c => 3
a => 1
b => 2
d => 4

Y en cuento a otra web... no se me ocurre otra mejor que ésta... o quizás, PerlMonks.org
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 0 invitados