Newsgroup: it.comp.lang.perl
Titolo: trattare singoli caratteri

Ciao a tutti, sono un principiante e mi sto scontrando con un
problemino. Vorrei essere in grado di leggere e trattare ogni singolo
carattere di una linea di testo, come una variabile indipendente.
Esempio: 	$1= 1,2,3,..10;
		$text= pqrst  abcdefghil;
Io vorrei leggere la linea $text e leggere i singoli caratteri perche'
vorrei associare $texta{$a}=$1, $textb{$b}=$2,ecc..
In pratica voglio mantenere l'informazione 1a, 2b,... ed ignorare la
prima parte della stringa. Ho provato a fare qualcosa con getc ma non lo
trovo particolarmente facile da usare, oltre che abbastanza lento, e mi
piacerebbe sapere se esiste qualcosa di meglio che riesce a svolgere
questo compito.
Grazie in anticipo a chi mi dara' una mano
		Giulio

 cerchero' un'altra donna dentro ai sogni di Tarzan...

 carattere di una linea di testo, come una variabile indipendente.
@testo = split //, 'pqrst  abcdefghil';
%posizione = ();
$cont = 0;
foreach $carattere (@testo) {
        $posizione{$carattere} = ++$cont;
}
In questo caso, per es. $posizione{'a'} restituisce 8.
Non mi č chiaro se ti interessa tener conto dei caratteri
ripetuti.
Se č cosě, si potrebbe usare:
...
foreach $carattere (@testo) {
        if (not defined($posizione{$carattere})) {
                $posizione{$carattere} = \@$carattere;
        }
        push @{$posizione{$carattere}}, ++$cont;
}
Adesso, @{$posizione{' '}} restituisce la lista (6, 7).
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

@testo = split //, 'pqrst  abcdefghil';
E ora te lo senti tu il Munafo', per aver fatto uno split non
strettamente necessario ;o)))))


 
Grazie per il suggerimento, mi potresti dire anche gli altri modi che ti
vengono in mente? Oppure dimmi quali sono i comandi da usare, per
esempio non conoscevo il substr che mi sembra molto interessante. 
Di nuovo grazie
Ciao
	Giulio

esempio non conoscevo il substr che mi sembra molto interessante. 
Al tuo posto darei un'occhiata a perlfunc... c'e' tutto.


 strettamente necessario ;o)))))
Ops 8)
Il fatto è che l'avevo scritto in un altro modo (giusto per farti
inorridire ti dirò che avevo usato 'map' ;) e lo split serviva...
così l'ho dimenticato quando ho 'semplificato' il tutto.
Inginocchiato sui ceci, chiedo venia.


 strettamente necessario ;o)))))
Perche' mai? A parte il fatto che non si puo' rispondere seriamente alla
richiesta originaria perche' il problema era veramente mal posto e non si
capisce (o almeno io, limitato quanto sono, non capisco) che cosa si debba 
fare, mi sembra che split() sia la prima soluzione
che dovrebbe venire in mente se mai dovessero veramente servire i caratteri
uno alla volta. substr() mi sembra la seconda scelta.
Comunque, di solito, se ti servono i caratteri uno alla volta e' perche' non
sai esattamente quello che vuoi e quello che stai facendo.
Soddisfatto? :)
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)

Soddisfatto? :)
Diciamo che non mi hai deluso :-)))


 sai esattamente quello che vuoi e quello che stai facendo.
O probabilmente non sai come farlo!!!
	Giulio

NQQSSQ  (assenze in una sola sequenza)
Ehh???
Puoi spiegare meglio il criterio di match/nonmatch?


 Puoi spiegare meglio il criterio di match/nonmatch?
Considerando semper le due linee di allineamento nella stessa posizione
devo eliminare i punti se presenti su entrambi le linee (falso
allineamento) ma non se presenti su una sola linea.
Qui voglio eliminare (SI) 
LKCNKL...I PIASKTCPAG KNLCYKMF.. ..MMS.DLTI PVKRGCIDVC
LECHNQQSSQ 
PPTTKTC.SG
 ETNCYKKW.. ..WSD.HRGT IIERGCG..C
      -no-                    --SI-
Prima era un problema di formattazione che ha fatto andare a capo
Ciao
		Giulio

Prima era un problema di formattazione che ha fatto andare a capo
Metti tutte le righe in file distinti, poi quali righe di quali file
confronti? Quante righe confronti? Che output vuoi? E dove lo vuoi?


> nel file lcrf
sub appendfile
	{
	...
	}	
...
while(<>) {
	/^([^ ]+) +/ && appendfile($1, $');
}
...
---
"Ci sono tre tipi di persone al mondo: quelle che sanno contare, 
e quelle che non ne sono capaci."

 
La cosa diventa abbastanza complicata. Ogni file ha un numero di righe
variabile ma ho risolto il problema con un loop ed il riconoscimento del
nome ad inizio riga, deve essere sempre presente la prima sequenza (in
tutta la sua lunghezza, ciioe' diverse linee da 50 chr) allineata con le
altre volta per volta:
file INPUT
nome1		seq1
nome2		seq2
nome3		seq3
..
file OUTPUT1
nome1 seq1
nome2 se2
file OUTPUT2
nome1 	seq1
nome3		seq3
..
Il formato deve essere identico all'originale, 50chr e spazio ogni 10chr.
Il tutto viene da un database ed andra' a fare un altro database.
In pratica tutto il programma intorno e' pronto, manca "solo" questo
"piccolo" particolare della scomposizione e riconoscimento.
Forse inizio a vedere la luce in fondo al tunnel

nome3		seq3
scusa ma allora mi sfugge qualcosa:
perche' seq1 e seq3 vanno in output2?
perche' seq1 e seq2 vanno in output1?
Oha


Forse inizio a vedere la luce in fondo al tunnel
Spegnila e torna a terra: IMO sei al buio (altrimenti vuol dire che
sei proprio negato per spiegare ;o))


Ricominciamo:
Ho un file con stringhe.Ogni stringa e' un pezzo di sequenza da 50 caratteri.
Una sequenza in genere e' lunga piu' di 50 char-->avro' per ogni
sequenza diverse stringhe.
FILE INPUT
nome1		seq1 (1..50)
nome2		seq2 (1..50)
nome3		seq3 (1..50)
nome4 	seq4 (1..50)
1                                                   50
LKCNKL...I PIASKTCPAG KNLCYKMF.. ..MMS.DLTI PVKRGCIDVC
LECHNQQSSQ 
PPTTKTC.SG
 ETNCYKKW.. ..WSD.HRGT IIERGCG..C
LKCNKL...I PIASKTCPAG KNLCYKMF.. ..MMS.DLTI PVKRGCIDVC
LECHNQQSSQ 
PPTTKTC.SG
 ETNCYKKW.. ..WSD.HRGT IIERGCG..C
nome1		seq1 (50..100)
nome2		seq2 (50..100)
nome3		seq3 (50..100)
nome4 	seq4 (50..100)
ecc....
Considerando questo un file "riassuntivo" a me SERVE e DEVO avere un
singolo file per ogni singola coppia di sequenze avendo come riferimento
fisso la sequenza "madre" numero1.
Percio':
OUT1
nome1 seq1 (1..)
nome2 seq2 (1..)
OUT2
nome1 seq1
nome2 seq2
OUT3
nome1 seq1
nome3 seq3
ecc...tanti file output quante sono le sequenze nell'input
Il carattere "." significa che NON c'e' un carattere. Devo eliminarlo se
presente in tutte e due le seq
MF.. ..M                       MFM
KW.. ..W     dovrebbe essere   KWW
ma lo devo tenere se e' presente solo su una delle due sequenze
CIDVC
CG..C     Rimane cosi', per me e' una informazione importante
                 PRIMA
1                                                   50
LKCNKL...I PIASKTCPAG KNLCYKMF.. ..MMS.DLTI PVKRGCIDVC
LECHNQQSSQ 
PPTTKTC.SG
 ETNCYKKW.. ..WSD.HRGT IIERGCG..C
                 DOPO
1                                                   50
LKCNKL...I PIASKTCPAG KNLCYKMFMM SDLTIPVKRG CIDVC
LECHNQQSSQ 
PPTTKTC.SG
 ETNCYKKWWS DHRGTIIERG CG..C
Chi ha spento la luce?

CG..C     Rimane cosi', per me e' una informazione importante
Da quello che hai detto, invece, la C finale dovrebbe scomparire... e
invece no. Ricapitolo il discorso per quello che ho capito e basandomi
su singoli file composti di due paragrafi:
- le sequenze sono separate da spazi
- le sequenze vanno saltate del tutto se identiche
- se non identiche vanno riportate del tutto, ma prive dei
  punti se nelle stesse posizioni.
- il risultato sono due paragrafi che sostituiscono
  quelli originali.
ok?


 
Ok!

 
-- 
"Time flies like an arrow; fruit flies like a banana."

stesse posizioni
Quindi in realta' a noi che ci siano 5 sequenze da 10 caratteri non ce
ne frega niente, e possiamo trattare il tutto come righe.
Quella che segue e' la funzione confronta('nomedelfile') che effettua
il confronto e modifica il file.
Non e' "elegante", ho volutamente utilizzato strumenti che molto
probabilmente conosci per permetterti, eventualmente, di rimaneggiarla
(ad esempio generalizzandola per confrontare n sequenze).
sub confronta { $cosa = shift;
  my(@in, @out, $i, $c1, $c2);
  local *ORIG;
  open(ORIG,"<$cosa");
  @in = <ORIG>;
  close(ORIG);
  for ($i=0; $i < length($in[0]); $i++) {
    $c1 = substr($in[0],$i,1);
    $c2 = substr($in[1],$i,1);
    do {
      $out[0] .= $c1;
      $out[1] .= $c2;
      } unless ($c1 eq '.') && ($c2 eq '.');
    }
  open(ORIG,">$cosa");
  print ORIG join '',@out;
  close(COSA);
  }
Continuo a pensare che, se la quantita' di dati del file originale non
e' sropositata, si potrebbe tranquillamente processare direttamente il
file di origine.


fisso la sequenza "madre" numero1.
un file per ogni _possibile_ coppia oppure un file per
ogni coppia adiacente?
btw: 
### tutte le coppie possibili, l'ordine non interessa
@seqs=<INPUT>;
my($s1);
while ($s1=shift @seqs) {
	my($i)=0;
	while($i<$#seqs) {
		writeuniquefile($s1,$seqs[$i++]);
	}
### solo le adiacenti
my($old)=<INPUT>;
while(<INPUT>)
	{
	writeuniquefile($old,$_);
	$old=$_;
	}
###
Oha
ps: il codice serve da riferimento.


  close(COSA);
	close(ORIG);
solo una piccola correzione banale.
Oha


Grazie a tutti per l'aiuto e per la disponibilita'. 
In particolare, ma senza assolutamente sminuire gli altri, vorrei
ringraziare Marco (ma che ti ha fatto tarzan?)con cui praticamente ho
avuto un filo diretto.Mi dispiace per la spiegazione ma io ragiono
(seeeee!!che parolone!!) da biologo e non da programmatore, quindi la
mia tendenza era di dare importanza a certe caratteristiche invece di
trattare tutto per quello che e' veramente:una semplice stringa di
caratteri. Vabbe' la prossima volta andra' meglio.
Ciao
		Giulio