Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Diario de aprendizaje de un perlero desde cero
Ir a página 1, 2, 3, 4, 5  Siguiente
 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Jue Jun 14, 2007 3:40 pm
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Diario de aprendizaje de un perlero desde cero Responder citando

Bueno vamos a la aventura.... me he propuesto aprender Perl, aunque sea poco a poco.... pero lo intentaré.

Lo primero que he hecho fue leer el tutorial de esta web de Perl básico parte I ..... tras leerlo lo entendí bien pero me faltaba algo, la práctica.... demasiadas cosas nuevas como para seguir leyendo sin antes haber practicado un poco.

Para solucionar esto creating021 me propuso una serie de ejercicios.

Los podéis ver aquí:
http://perlenespanol.baboonsoftware.com/foro/viewtopic.php?t=1754

Sin más me pongo a tratar de escribir el primer ejercicio:

"1) Haz un programa que te pregunte tu edad y calcule cuántos años faltan para que cumplas 3000."

Abrimos el Notepad y empezamos...

Perl:
#!/usr/bin/perl -w


print "Cual es tu edad?";

my $edad = <STDIN>;

my $resta;
$resta = 3000 - $edad;

print "Para que cumplas 3000 faltan $resta"


Problemas y dudas:

1) La primera línea del código la cogí de los ejemplos que te instala ActivePerl... vi que todos los ejemplos la tenían y por eso se la puse...

Question ¿Es necesaria? ¿Qué significa? ¿Para qué sirve?


2) No soy capaz de que aparezcan los caracteres "¿" y "ñ" al hacer un print...

Question ¿Hay alguna manera?

3) Un mismo problema tiene varias soluciones, esa es la que se me ocurrió... parece que funciona bien...

Question Alguna observación? alguna forma de hacerlo mejor (ojo, teniendo en cuenta lo poco que se hasta ahora)?

4) ¿Alguna recomendación a la hora de escribir el código, me refiero a que en este caso son 4 o 5 líneas de código y es difícil perderte...

Question ¿Cuál sería el mejor orden para escribir el código...? ¿Declaro todas las variables que vaya a usar al principio? ¿Tabulo de otra manera? No sé... ¿Alguna recomendación sencilla para empezar?
Mensaje Jue Jun 14, 2007 4:05 pm
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

SEGUNDO EJERCICO:

Calcular el número de letras en una palabra tomada del prompt.

Jejeje.... este ejercicio ya me quede estancado... a ver.... me explico.

Primero puse lo siguiente:

Código:
#!/usr/bin/perl -w

print "Escribe una palabra para contar sus caracteres";

my $palabra = <STDIN>;

my $contador;
$contador = ¿?¿?¿?¿?¿?¿?¿?¿?¿?¿;

print "Tu palabra tiene $contador caracteres"



No se como programar ese contador... tengo la palabra que entra por teclado almacenada en la variable $palabra pero como contar sus caracteres??


P.D: lei algo por ahi de chop y length pero ni idea de como usarlo.
Mensaje Jue Jun 14, 2007 4:35 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

1) Es la línea de shebang. En la página Perl de Wikipedia se comenta un poco sobre esto.

Le dice al sistema operativo con cuál y dónde se encuentra el programa necesario para interpretar y ejecutar el código que sigue. En Windows no es necesario (sección non-Unix systems) porque ese sistema se basa en la extensión del fichero para saber dónde está el ejecutable perl.exe. Yo suelo poner #!Perl.

Es también útil porque puedes colocar allí opciones de ejecución (como el -w).

2) Posiblemente porque el Notepad está trabajando en UTF8 y la consola de comandos en Win1252.

3) Falta un ';' al final. No es grave, pero has de tomártelo como costumbre ponerlo siempre.
Pon 'use strict;' al principio del programa. Te obligará a programar de forma estricta. Deberás entonces declarar todas las variables (con my() y our()) y a cambio Perl te avisará cuando te equivoques al escribir alguna variable.
El '-w' lo puedes cambiar por un 'use warnings;'.
Si quieres más ayuda (en inglés) desde el Perl, pon 'use diagnostics;'.
Algunas cosas se pueden abreviar, como
Perl:
my $resta = 3_000 - $edad;
pero eso se 'cura' leyendo código. Adelante. Pero si funciona un programa, es lo importante.

4) Para declarar variables yo sigo este orden y nomenclatura:
Código:
Regla de la declaración:
* Constantes en todo el programa. Al principio de todo.
* Variables globales en todo el programa. Al principio de todo.
* Variables de contexto muy limitado: en el mismo lugar donde se necesitan.

Regla de escritura:
* Constantes, en mayúscula: $DIR_PRINCIPAL = 'C:/temp';
* Variables, en minúscula, separando las palabras con '_': $almacen_de_bichos

Regla de la longitud del nombre:
Cuanto más importante es una variable, más larga es
(el recíproco también es cierto):

foreach my $persona ( @personas_con_discapacidad_con_derecho_a_pension ) {
    my $grupo = $grupos_organizativos{ $persona };
    for $i ( 1 .. 12 ) {
        $cotizacion_anual{$grupo}{$persona} = 234,5 * $i;
    }
}

Dos recomendaciones: lee mucho código y si te es posible, leete el libro "Perl Best Practices", de Damian Comway. No importa si no entiendes algunos conceptos a partir de la mitad del libro, pero aprenderás a tabular, colocar, indentar y nombrar a variables y funciones.

Y en vez del Notepad, puedes bajarte el Komodo EDIT de ActiveState.

En este foro básico hay muchos más consejos sobre cómo empezar.
Mensaje Jue Jun 14, 2007 4:56 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Perl es un lenguaje informático y como tal se compone de una serie de funciones y operadores. Lo que distingue a Perl de otros lenguajes es que es muy 'rico' en ese sentido.

No te queda otra opción que, al menos, leerte la lista de esas funciones y operadores.

Si el problema es el inglés, lo mejor es que empieces por lo que hay en castellano: tutoriales y manuales. No tienes que leerles enteros, sino localizar problemas parecidos a lo que intentas resolver y ver cómo lo hacen.

O este mismo foro.
Mensaje Jue Jun 14, 2007 6:08 pm
creating021
Vive para Perl en Español
Vive para Perl en Español
Registrado: 23 Feb 2006
Mensajes: 481
Ubicación: Frente al monitor
Responder citando

Algo más (sí hay más, aprate de lo que explorer te ha dicho Laughing )
Mira, hay una diferencia muy grande entre carácter[1] y palabra.
Si contamos carácteres sería todo lo que hay en el STDIN, es decie, se contarían consas como los espacios.
______
1. http://es.wikipedia.org/wiki/Carácter_(informática)
Mensaje Jue Jun 14, 2007 6:27 pm
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

Bien gracias por las respuestas veo que tengo que leer unas cosillas básicas para poder ponerme manos a la obra con el segundo código.

Me bajo el Komodo EDIT que parece que me será de ayuda ya que chequea bastantes cosillas automáticamente y te ayuda detectar errores. Smile

Gracias por la ayuda.... sigo leyendo, en unos días pongo mis progresos. Wink
Mensaje Jue Jun 14, 2007 7:34 pm
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

Bueno creo tener la solución al ejercicio número dos. Ahí va.

Perl:
#!/usr/bin/perl -w

use strict;

print "Palabra?\n";

my $palabra = <STDIN>;

chop($palabra);

my $longitud = length($palabra);

print "El numero de caracteres de la palabra es $longitud";


Lo aprendido en este ejercicio fue que si pongo \n me hace un salto de línea y queda mejor a la hora de pedir una entrada por teclado Smile

La función chop , que l oque hace es eliminar los salto de linea, es decir eliminaria los \n

La función length, que cuenta los caracteres de una variable.

quizás no me expliqué con total exactitud pero por el momento es lo que hay... aún queda mucho por leer.

Me paso al siguiente ejercicio.
3) Calcular el número de líneas de un archivo dado.

Para este ejercicio tomaré como archivo dado un txt llamado archivo.txt y con el siguiente contenido:

Código:
Perro
Gato  Morcilla
Morcilla @yup@yup@yup@yup@yup
Sol  1233334  1233334  1233334  sdfsdfsdf@3s/;][W0P-~
1233334
@yup
/////\\\\\
45t3r15c0/////\\\\\**********/////\\\\\
<>::<>
/;][W0P-~kk¿
Mensaje Vie Jun 15, 2007 5:07 am
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

A ver, tengo un problemilla con el tercer ejercicio.

Por el momento tengo escrito el siguiente código.

Perl:
#!/usr/bin/perl -w

use strict;

open (TEXTO,"test.txt");

my @texto=<TEXTO>;

close (TEXTO);


Lo aprendido hasta el momento fue como abrir un archivo y asignarle un nombre lógico. También me di cuenta de que al tratarse de varias líneas el fichero tiene varios elementos, por lo que hay que usar un array @texto.

Ahora el problema. Como tengo que contar el número de líneas que tiene el documento, la forma de contar esas líneas, sería contar el número de saltos de línea que hay, es decir el número de "\n".

Pero no encontré ninguna función que buscará elementos dentro de un array, lo que si encontré fue una expresión regular =~ que me dice si existe algo que yo especifiqué dentro del array... Mmm... no sé, ahora si que me perdí un poco; ¿alguna pista?
Mensaje Vie Jun 15, 2007 5:53 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

Pistas:
Al leer el documento en forma de lista, cada línea del fichero está en cada elemento del array, por lo que el número de líneas del fichero es igual al número de elementos del array.
Mensaje Vie Jun 15, 2007 6:59 am
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

Bueno, este ejercicio está interesante... traigo dos soluciones: una la entiendo y la segunda la entiendo a medias, porque la hice por tanteo. Además me surgieron nuevas dudas.

Perl:
#!/usr/bin/perl -w

use strict;

open (TEXTO,"test.txt");

my @texto=<TEXTO>;

print "El numero de lineas del archivo es ";

print $#texto + 1;

close (TEXTO);


Este código lo entiendo, lo que se me escapa es que puedo meter entre las comillas $#texto y me lo imprime, pero si pongo $#texto + 1, no realiza la operación suma, deduzco porque esas comillas se introducen para que imprima literalmente, sin realizar operaciones con variables, arrays, etc... Además esta algo a tener en cuenta y es que Perl empieza contar desde 0 y no desde uno.... por eso hay que sumar uno al número de elementos del array.

Este otro código, funciona pero.... vamos a verlo:

Perl:
#!/usr/bin/perl -w

use strict;

open (TEXTO,"test.txt");

my @texto=<TEXTO>;

my @lineas = $#texto;

my $final = @lineas+9;

print "El numero de lineas es $final";

close (TEXTO);


Se ve que uso un array nuevo "@lineas" y lo igualo con "$#texto" que me dice el número de elementos del array.

¡Anda!, ahora que lo escribo, veo que para este código he hecho trampa ya que partí de que sabia el número final de líneas (en este caso al tratarse de un txt pequeño lo sé.... pero el objetivo sería partir de que el archivo tiene muchas líneas y que no cuantas tiene a simple vista).

Lo que no pude hacer fue usar un variable escalar, es decir $lineas en lugar de @lineas, eso me daba error, pero no entiendo porque no me deja almacenar en el escalar.... ¿ alguna idea ?

Otra cosa, como sería lógico (para mi)... en la línea "my $final = @lineas+9;" pondría la operación "my $final = @lineas+1;" ya que sumaría los elementos del array que son 9 (empezando a contar desde 0) y le sumo uno, lo que daría 10.... pero no.... para que dé 10 fui tanteando y hay que sumarle 9 ...jeje... ¿por qué?

Vaya, vaya, vaya..... mientras escribía la pregunta se me ocurrió una posible razón de porque hace eso... es simplemente porque digamos que el @lineas es una matriz con 9 elementos y cuando igualo esa matriz a un escalar pasa de tener 9 elementos a tener 1 porque es un escalar.

Pero aun así ¿por qué me muestra en pantalla el siguiente código que el número de líneas es 1 si Perl empieza a contar desde cero y un escalar tiene un elemento lo que para Perl sería un número de elementos igual a 0?

Perl:
#!/usr/bin/perl -w

use strict;

open (TEXTO,"test.txt");

my @texto=<TEXTO>;

my @lineas = $#texto;

my $final= @lineas;

print "El numero de lineas es $final";

close (TEXTO);


Buffff..... no se si me habré explicado bien, sera difícil entenderme.... perdón Embarassed

P.D: cada vez me gusta más esto de aprender Perl, Gracias explorer y creating por ir respondiendo a mis dudas.
Mensaje Vie Jun 15, 2007 7:48 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4092
Ubicación: Valladolid, España
Responder citando

* Las comillas dobles hacen interpolación de variables, pero no de expresiones. $#texto es una variable 'especial' que guarda el índice del último elemento del array @texto. Si @texto tiene nueve elementos, valdrá 8. Así que no es correcto lo que dices al final de la primera solución.

* La variable @lineas es distinta de la variable $lineas, ya que una es un array y la otra un escalar.

* Una cosa es el número de elementos de un array o de una lista. Y otra cosa es cuál es el índice del último elemento del array. Generalmente el índice del último elemento será uno menos que el número de elementos, pero eso se puede cambiar (pero no aconsejable).

* Analizando la segunda solución:

Perl:
#!/usr/bin/perl -w

use strict;

open (TEXTO,"test.txt");

my @texto=<TEXTO>;            # @texto tiene todas las líneas de TEXTO, así que tiene 10 elementos

my @lineas = $#texto;         # Se declara @lineas, y el primer elemento, $lineas[0] lo inicializamos a 9
                              # (porque $#texto es el índice del último elemento)

my $final = @lineas+9;        # Se declara $final y se inicializa al valor de @lineas en escalar, que es
                              # igual al número de sus elementos, 1, y se le suma 9.

print "El numero de lineas es $final"# $final vale 10

close (TEXTO);


* Un array evaluado en contexto escalar devuelve el número de sus elementos (longitud del array).

* Otras posibilidades de solución son:

Perl:
my $final = @texto;
print "El numero de lineas del archivo es ", $final;

Perl:
print "El numero de lineas del archivo es ", scalar @texto;


* Cosas de Perl: lo dicho antes sobre que en las comillas dobles no se pueden interpolar expresiones no es del todo cierto. Lo normal es interpolar valores de variables. Si una de esas variables es un array, saldrán todos los elementos del array. Perl hace aquí una doble interpolación: convierte de variable array a sus elementos y luego los va colocando dentro del string, con un separador. Bueno, pues podemos hacer un truco: convertimos nuestra expresión en un array de un sólo elemento:

Perl:
print "El numero de lineas del archivo es @{[ $#texto + 1 ]}";
pero claro... esto es bastante rebuscado mirando las otras soluciones. Pero está bien acordarse de esto cuando necesitemos meter una expresión dentro de un string, y no tener que hacer
Perl:
print "El numero de lineas del archivo es ", $#texto + 1;
Mensaje Vie Jun 15, 2007 8:17 am
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

Bien, me quedaron unas dudas que no tenia muy claras ya despejadas.

Lo que no llego a entender es por que esta mal la primera solucion...

Perl:
#!/usr/bin/perl -w

use strict;

open (TEXTO,"test.txt");

my @texto=<TEXTO>;

print "El numero de lineas del archivo es ";

print $#texto + 1;

close (TEXTO);


ya que me dices:

"$#texto es una variable 'especial' que guarda el índice del último elemento del array @texto. Si @texto tiene nueve elementos, valdrá 8. Así que no es correcto lo que dices al final de la primera solución."

Vamos aya, mi txt tiene 10 lineas, de ahi que cuando pongo
"my @texto=<TEXTO>;" en el array @texto se almacenan las 10 lineas, pero como perl cuenta desde cero, al decirme el numero del ultimo indice me dira que es el 9.

Por eso debo sumarle uno, para ello pongo
"print $#texto + 1;" con esto corrijo que perl empiece contando desde 0 y me da el numero de lineas, no se por que est mal, porque funcionar funciona, me devuleve el numero correcto de lineas en todas las pruebas que hice.


Y sin mas, me pongo con el siguiente ejercicio.

4) Encontrar áreas de cuadrados y rectángulos.
Mensaje Vie Jun 15, 2007 8:25 am
creating021
Vive para Perl en Español
Vive para Perl en Español
Registrado: 23 Feb 2006
Mensajes: 481
Ubicación: Frente al monitor
Responder citando

¡Hombre, que vas rápido! Very Happy

Bueno, un par de cosas:

Cita:
La función length, que cuenta los caracteres de una variable.

quizás no me expliqué con total exactitud pero por el momento es lo que hay... aún queda mucho por leer.

Lo de length, lo descubriste rápido, que bien, pero en cuanto a chop...
Lo que chop hace es cortar el último carácter, si no hay retorno de carro ("\n") cortará el último carácter dado (podría ser parte del texto).

Tenemos la función chomp. que no quita el último dato (si es que está).
Ese dato es asignado por $/ que es asignada por Perl y suele ser "\r\n" o simplemente "\n";

Bueno, con ejercicio del archivo, hay otra forma de hacerlo (me sorprende que explorer no la haya dicho, siendo que el ya la ha enseñado antes).

Era usando while, en este foro (y en últimos mensajes, hecho por otros) hay algo sobre eso, por si te interesa...

Bueno, pero aún no has hecho lo que decía el ejercicio, a ver si te pone a pensar un poquito (no creo, teniendo en cuenta lo que has hecho).
Cuenta el número de palabras es un string pero teniendo en cuenta que estamos en archivos... cuenta el número de palabras en un archivo. Wink
Mensaje Vie Jun 15, 2007 8:30 am
creating021
Vive para Perl en Español
Vive para Perl en Español
Registrado: 23 Feb 2006
Mensajes: 481
Ubicación: Frente al monitor
Responder citando

Es que es mejor la otra posible solución que te da explorer, la que usa scalar puesto que esta función da una respuesta más rápida que $#array +1 o algo similar.
Mensaje Vie Jun 15, 2007 8:46 am
Zeokat
Perlero Frecuente
Perlero Frecuente
Registrado: 22 Ago 2006
Mensajes: 117
Responder citando

Ok, aclarado entonces lo que decía explorer.

Vamos a ver.... el ejercicio que me propones ahora creating es contar las palabras de un archivo.

Mmmm.... las palabras están separadas por espacios, si cuento el número de espacios y le sumo uno, me da el número de palabras, jejeje es una forma un poco cavernícola de hacerlo, pero puede funcionar.

El problema es que a veces los textos tiene sangrías diferentes, por ejemplo:

Código:
Y entonces dijo:
    "saludos"


Ahí se ve que si cuento el número de espacios ya no funciona el método, por lo que quizás en primer lugar debería de tratar de usar un expresión regular que sustituya x espacios seguidos por un único espacio y luego contar los espacios y sumarle uno.

No sé..... es la única manera que se me ocurre ahora mismo.... aunque supongo que habrá otra más precisa, ya que el método que planteo es un poco simplón y si la primera línea empieza por un espacio o la última termina en un espacio ya no sirve.... quizás agregando esas dos condiciones y compensando esos espacios extra se consiga el número de palabras.

Jejejeje estoy seguro que lo estoy planteando de una forma muy complicada y que seguro que se resuelve de alguna manera más sencilla.... jejeje... sigo pensando a ver qué se me ocurre.

¡Se aceptan pistas! Wink
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Ir a página 1, 2, 3, 4, 5  Siguiente
Página 1 de 5



Powered by phpBB © 2001, 2005 phpBB Group