Página 1 de 3

Procesamiento básico de textos

NotaPublicado: 2012-04-23 08:10 @382
por locurainformatica
Buenas, este es el ejercicio que nos han mandado:

Previamente es necesario estudiar los temas de "Entrada y salida en archivos" y "procesamiento básico de textos".
Posteriormente hay que copiar los cuatro archivos que están en: http://bip.weizmann.ac.il/course/prog/a ... 4_sources/ y que corresponden a la descripción textual de un gen, presentes en la base de datos UniGene.

El objetivo de la práctica es:
Escribir un programa que reciba el nombre del gen, abra el archivo correspondiente, extraiga el listado de los tejidos en los que el gen aparece ("se expresa") y lo guarde en un archivo cuyo nombre será el nombre del gen y la extensión "express".

El formato del archivo de salida será el siguiente (ejemplo para el gen TGM1):

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
TGM1

1. Esophagus
2. Germ Cell
3. Larynx
4. Pancreas
5. Uterus
6. colon
7. head_neck
8. uterus
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


El programa tendrá que ejecutarse cuatro veces, una por gen ('ADH2', 'CEACAM4', 'TGM1', 'GLDC'), de forma que al final obtengamos cuatro archivos de salida con extensión "express".

Tened en cuenta que:
1) La lista de tejidos aparece después de la palabra clave 'EXPRESS'.
2) Numerar los tejidos a partir del 1 y que no hay asignaciones vacías en la lista de tejidos.
3) Utilizar las funciones "substring" y "split".

El problema que tengo, es que no sé por dónde empezar, y tengo que entregarlo mañana.
¡Espero que alguien pueda ayudarme!
Un saludo, y gracias por antelación!

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-23 13:28 @603
por explorer
Bienvenido a los foros de Perl en Español, locurainformatica.

Tranquilo, es muy fácil.

Lees el nombre del gen desde el array @ARGV. Abres los archivos con open(). Con readline() o con el operador diamante (<>) lees línea a línea el archivo. Por cada línea, usas split() para quedarte con las dos partes. Si la primera parte es igual a 'EXPRESS', entonces: coges la segunda parte y vuelves a usar split() para partirla por ';'. Luego, abres al archivo para la salida. Haces un bucle por el array obtenido con el split(), y con una variable de contador, vas sacando los números y los contenidos. Cierras el archivo de salida, y terminas.

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-23 17:10 @757
por locurainformatica
A ver el ejercicio lo hice de la siguiente manera:

use warnings;
use strict;

my $gen;
my $nuevo;
my $ext;

print "\nIntroduzca el nombre del fichero\n\n";
$gen=<STDIN>;

print "\nHa escogido usted el gen $gen\n";
print "\nLo seleccionado será escrito en un archivo. Indique la extensión\n\n";

$ext=<STDIN>;

my $letras;

print "\nAhora diga las dos primeras letras que desee buscar por el archivo\n\n";


open (MANEJ,"$gen") || die "no se puede abrir el archivo: $!";
open (RESULT,">organos-$gen.$ext") || die "no se puede abrir el archivo: $!";

$letras=<STDIN>;
chomp ($letras);

my @tex_gen = <MANEJ>;

my $linea;
my @tejidos;
my $dos;
my $tejidos;

foreach $linea (@tex_gen) {
chomp ($linea);

$dos = substr ($linea,0,2);

if ($dos eq $letras) {
push (@tejidos, $linea);
@tejidos = split(/ /, $linea);
}
}

my $sobra;
my $tejido;

$sobra = shift (@tejidos);

my $opcion;
my $contador1;

$contador1 = 0;

print RESULT "\nEstos son los tejidos en los que se expresa el gen $gen:\n";

foreach $tejido (@tejidos) {
$contador1++;

print RESULT "\t organo $contador1:$tejido\n";
}

close (MANEJ);
close (RESULT);

Pero debe de haber algún error, porque al ejecutarlo me da que existe un error.

Luego, pues lo volví a hacer y pensé que esta vez saldría, y tampoco se ejecuta. El programa es el siguiente:

use strict;
use warnings;

my ($gen, $resultado, $line, $exp);

$gen = "adh2.txt";
$resultado = "express.txt";

open (SOURCE, $gen) || die "cannot open \"$gen\": $!";
open (RESULT, ">$resultado") || die "cannot open \"$resultado\": $!";

while ($line = <SOURCE>) {
my $variable = substr ($line, 0, 2);
my $value = substr ($line, 5);

if($variable eq "EXP") {
$exp = $value;
}
}

$string = "adh2.txt"
@genes = split (/::/, $string);

my $i;
foreach $i (0 .. $#genes) {
print "$i. $genes[$i]\n";
}

close (SOURCE);
close (RESULT);

Y, bueno, repetir esto las siguientes tres veces restantes en el mismo programa, pero si no es capaz de ejecutarse uno, pues para qué iba a seguir.

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-23 18:02 @793
por explorer
Varias cosas...
* No hace falta preguntar por la extensión del archivo porque ya nos dicen que tiene que ser 'express'.

* Recuerda que cada vez que lees algo del usuario por su teclado, o de un archivo de texto, por líneas, cada línea va terminada por el carácter o caracteres de fin de línea, y si no los vas a necesitar, es mejor quitarlos inmediatamente con el chomp()

* En el segundo código usas split(/::/), pero juraría que el separador de los tejidos es el carácter ';'

* En el último foreach(), estás haciendo, correctamente, un bucle desde 0 al último índice del array de los tejidos, pero lo imprimes, incorrectamente, directamente en pantalla. Debes hacer que salga con un valor más del que tiene (nos piden que empiece la lista de tejidos en 1) y además, debes enviar la salida hacia el archivo RESULT.

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-24 12:00 @541
por alexclipse
Intentando hacer este ejercicio "a mi manera" :)

He llegado a un punto muerto. No sé muy bien cómo utilizar la función split() ni como quitar los ';' que separan los tejidos.

Sé que para reconocer la palabra express debo usar =~ pero no cómo cortar e imprimir.

Tengo esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use warnings;
  2. use diagnostics;
  3. my $a  = "ADH2.txt";                   #Archivo de entrada del primer gen
  4. my $a1 = "ADH2.express";               #Archivo de salida del primer gen
  5. my $a2 = "prueba.txt";                 #compruebo que se escriben los datos en un txt
  6. my $b  = "CEACAM4.txt";                #Archivo de entrada del segundo gen
  7. my $b1 = "CEACAM4.express";            #Archivo de salida del segundo gen
  8. my $b2 = "prueba2.txt";
  9. my $c  = "GLDC.txt";                   #Archivo de entrada del tercer gen
  10. my $c1 = "GLDC.express";               #Archivo de salida del tercer gen
  11. my $c2 = "prueba3.txt";
  12. my $d  = "TGM1.txt";                   #Archivo de entrada del cuarto gen
  13. my $d1 = "TGM1.express";               #Archivo de salida del cuarto gen
  14. my $d2 = "prueba4.txt";
  15. print "Introduzca el nombre del gen:";
  16. my $gen = <STDIN>;
  17. chomp($gen);
  18.  
  19. if ( $gen eq "adh2" ) {
  20.     open( ADH2,    $a )     || die "No se pudo abrir el archivo \"$infile\": $!";    #Este proceso lo repito
  21.     open( FINADH2, ">$a1" ) || die "No se pudo abrir el archivo \"$infile\": $!";    #con los otros 3 genes
  22.     open( PRUEBA,  ">$a2" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  23.     while ( $a = <ADH2> ) {
  24.         print FINADH2 "$a";
  25.         print PRUEBA "$a";
  26.     }
  27.     close(ADH2);
  28.     close(FINADH2);
  29. }
  30. elsif ( $gen eq "ceacam4" ) {
  31.     open( CEACAM4,    $b )     || die "No se pudo abrir el archivo \"$infile\": $!";
  32.     open( FINCEACAM4, ">$b1" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  33.     open( PRUEBA2,    ">$b2" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  34.     while ( $b = <CEACAM4> ) {
  35.         print FINCEACAM4 "$b";
  36.         print PRUEBA2 "$b";
  37.     }
  38.     close(CEACAM4);
  39.     close(FINCEACAM4);
  40. }
  41. elsif ( $gen eq "gldc" ) {
  42.     open( GLDC,    $c )     || die "No se pudo abrir el archivo \"$infile\": $!";
  43.     open( FINGLDC, ">$c1" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  44.     open( PRUEBA3, ">$c2" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  45.     while ( $c = <GLDC> ) {
  46.         print FINGLDC "$c";
  47.         print PRUEBA3 "$c";
  48.     }
  49.     close(GLDC);
  50.     close(FINGLDC);
  51. }
  52. elsif ( $gen eq "tgm1" ) {
  53.     open( TGM1,    $d )     || die "No se pudo abrir el archivo \"$infile\": $!";
  54.     open( FINTGM1, ">$d1" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  55.     open( PRUEBA4, ">$d2" ) || die "No se pudo abrir el archivo \"$infile\": $!";
  56.     while ( $d = <TGM1> ) {
  57.         print FINTGM1 "$d";
  58.         print PRUEBA4 "$d";
  59.     }
  60.     close(TGM1);
  61.     close(FINTGM1);
  62. }
  63. else {                                 #si no introduzco el nombre de ninguno de los 3 genes haz...
  64.     print "Gen incorrecto\n";
  65. }
  66.  
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-24 12:11 @549
por explorer
Parece que estás repitiendo lo mismo, cuatro veces :)

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-24 12:14 @551
por alexclipse
Claro que he repetido lo mismo 4 veces, pero cada una de las veces es para un gen. Hasta aquí bien, todo funciona, lo que no sé es cómo seguir.

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-24 12:29 @562
por explorer
Pues eso digo... que no es necesario, ¿no?

Lo que queda es sacar la información del fichero, solo las líneas EXPRESS, y dentro de ella, los tejidos.
Y con split(), se puede hacer.

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-24 12:32 @564
por alexclipse
¿Cómo hago para no repetirlo varias veces?

Re: Procesamiento básico de textos

NotaPublicado: 2012-04-24 17:09 @756
por explorer
Recapitulemos: la práctica dice:
«Escribir un programa que reciba el nombre del gen, abra el archivo correspondiente, extraiga el listado de los tejidos en los que el gen aparece ("se expresa") y lo guarde en un archivo cuyo nombre será el nombre del gen y la extensión "express"».

Así que lo primero es leer el nombre del gen (print, readline, chomp).
Luego hay que abrir el archivo correspondiente (open).
Extraer el listado de los tejidos. Esto hay que resolverlo con un bucle que vaya leyendo el archivo por líneas, haga un split(" ") para obtener las dos columnas (etiqueta y datos), y si la etiqueta es igual (eq) a 'EXPRESS', procesamos los datos, que sabemos que son los tejidos, separados con ';'. Entonces hay que hacerles otro split(/;/) y meter los valores resultantes en un array.
Queda abrir el archivo de salida con nombre "$gen.express", hacer un bucle por los tejidos, y sacarlos en el formato que nos dicen.

La práctica no dice nada de leer los cuatro genes. Sí que dice que el programa se ejecutará cuatro veces, con un gen distinto cada vez. Pero para eso le preguntamos al usuario, al principio, qué gen quiere que procesemos.

Humm... ahora que lo veo. Dice la práctica que hay que usar en algún momento, también, substr(), pero creo que no es necesario. Con split() es suficiente :)