Envoyé par
schmurf
à part les ";" j'aurai pu corriger le reste ..
Ben, il fallait le faire, alors...
Quand tu développes, tu peux éventuellement te permettre de laisser de côté provisoirement un petit bug parce que tu estimes avoir plus urgent à faire.
Mais des erreurs de compilation, non. Il faut les enlever une par une, au fur et à mesure et dans l'ordre. Pas le choix: tu ne peux rien tester ni déboguer tant que le programme ne compile pas. Et les erreurs de compilation, il faut toujours commencer par la première signalée (en n'oubliant pas que l'erreur de codage peut se situer quelques lignes plus haut que la ligne mentionnée par le compilateur), car souvent la première erreur entraîne les autres. Cette après-midi, je développais un programme au boulot. Il compilait correctement (sans erreur) et marchait. A un moment donné, j'ai ajouté un affichage complémentaire dans mon fichier résultat, relancé le programme et me suis retrouvé avec d'un seul coup 15 ou 20 erreurs de compilation, alors que je n'avais ajouté qu'une ou deux ligne(s) de code. J'avais simplement oublié le guillemet fermant de la chaîne de caractère que je voulais imprimer. Du coup, le compilateur était complètement à la ramasse et me trouvait plein d'erreurs dans la suite du programme. J'ai remis ce guillemet manquant, et toutes les erreurs ont disparu comme par enchantement. Si j'avais commencé par n'importe quelle erreur suivante, je n'avais aucune chance de trouver l'origine du problème.
Bon, pour la logique de ton programme, je ne pourrai sans doute pas trop t'aider, n'ayant aucune idée de ce que sont des "des introns ou une fin TAA ou TGA". La dernière fois que j'ai suivi des cours de bio en fac, c'était il y a 40 ans, en 1973-74, et non seulement j'ai beaucoup oublié, mais à l'époque on n'imaginait même pas pouvoir séquencer un jour le génome d'une simple bactérie.
Mais je voudrais aborder quelques questions de codage à la lumière de ton code source (bonnes pratiques et style)
#!C:\strawberry\perl\bin -W
Le '-W" est une syntaxe périmée, inutile et même nuisible dans la mesure où tu as la ligne 'use warnings;' en-dessous. Le pragma 'use warnings;' fait la même chose en mieux, garde-le et supprime '-W'.
Ne mets pas en commentaire cette ligne très importante (et qui te fera gagner un temps fou), mais corrige-la en enlevant le s à la fin de strict:
open HIN, "<C:\\Users\\Maxime\\Desktop\\sequence.txt";
Cette méthode d'ouverture d'un fichier fonctionne encore, mais n'est plus recommandée depuis une vingtaine d'années. Voici une méthode bien meilleure:
1 2
| my $infile = "C:\\Users\\Maxime\\Desktop\\sequence.txt";
open my $HIN, "<", $infile or die "impossible d'ouvrir le fichier $infile $!"; |
Ici, je mets le nom du fichier dans une variable. Je pourrais la réutiliser si besoin (et j'en aurais besoin deux fois ci-dessous).
Puis j'ouvre un file handle lexical ("my $HIN") et non un "mot nu" (bareword) cela présente toutes sortes d'avantages, par exemple si j'ai besoin de transmettre le file handle à une fon ction. Je mets le mode d'ouverture du fichier ("<") séparé du nom, c'est plus clair et préférable dans des cas particuliers. Enfin, la fin de la ligne, 'or die "impossible d'ouvrir le fichier $infile $!"' teste si le programme a pu ouvrir le fichier, et tue le programme si l'ouverture n'a pas fonctionné (ça ne sert à rien de continuer). En cas d'erreur d'ouverture, non seulement le programme merut, mais, avant cela il affiche la raison ("impossible d'ouvrir..."), le nom du fichier qui n'a pas pu être ouvert ($infile) et l'erreur système qui a eu lieu (la variable $! me dira peut-être que le fichier n'existe pas, ou le répertoire n'existe pas, ou je n'ai pas le droits, etc.). Bref, j'ai un maximum d'éléments pour pouvoir corriger.
ou
si j'ai modifié le file handle comme ci-dessus.
Ici, ça marchera avec un fichier petit ou moyen, mais le problème est que tu charges dans un tableau en mémoire l'ensemble de ton fichier. Si ton fichier fait 10 gigaoctets (et ça arrivera sans doute, les fichiers de génétiques sont souvent énormes), ton programme plantera, faute de mémoire, alors qu'il n'y a aucune raison de tout charger en mémoire, tu peux te contenter de lire les lignes une par une. Tu ne consommeras pratiquement pas de mémoire (et ça ira un peu plus vite). Il suffit de remplacer les lignes suivfantes:
1 2 3 4
| my @temp = <$HIN>;
my $a =0;
for (my $j=0 ; $j<=($#temp) ; $j+=1){
my @t = split //, $temp[$j]; |
par:
1 2 3 4
| my $a =0;
while (my $ligne = <$HIN>) {
my @t = split //, $ligne;
# ... |
A supposer que tu aies réellement besoin de charger le fichier en mémoire dans le tableau @temp (ça arrive que l'on doive revenir en arrière, etc.), la syntaxe :
1 2
| for (my $j=0 ; $j<=$#temp ; $j+=1){
my @t = split //, $temp[$j] |
dite syntaxe de style C n'est pas du tout optimale en Perl.
La bonne syntaxe dans ce cas est plutôt:
1 2 3
| for my $ligne (@temp) {
my @t = split //, $ligne;
# ... |
Pas besoin donc de gérer la variable de boucle $j, Perl se débrouille très bien pour te donner les lignes les unes après les autres.
Et si vraiment tu as besoin de la variable de boucle $j parce qu'elle sert aussi à autre chose (c'est assez rare et n'est pas le cas ici), il y a encore une syntaxe plus simple (et meilleure) que la boucle for de style C que tu utilises:
1 2 3
| for my $j (0..$#temp) {
my @t = split //, $ltemp[$j];
# ... |
Bon, si tu utilises la boucle while préconisée ci-dessus pour lire le fichier, tu peux croire ne pas avoir besoin de ces détails sur les boucles for, et, certes tu n'en n'a pas besoin pour la lecture du fichier, mais comme toutes tes autres bouckles sont construites sur le même modèle, tu peux toutes les simplifier.
Bon, je ne vais pas examiner ainsi chacune de tes lignes, j'y passerais la nuit. Juste encore deux points.
Sur l'utilisation de print. Tu écris:
print("exon", "$a",":","@t[$c..$i-1]\n","intron", "$a", ":","@t[$i..$v+1]\n")
La plupart de ces guillemets sont inutiles, Perl gère très bien pour toi.
print("exon$a:@t[$c..$i-1]\n intron$a:@t[$i..$v+1]\n")
devrait marcher aussi bien (bon, pas testé, je n'ai pas les données, mais ça devrait marcher). C'est nettement plus lisible et facile à écrire, non?
Et dernier point: l'indentation de ton code n'a aucun sens et te conduira à des erreurs. L'indentation n'a aucune influence sur le déroulement du programme, mais il a un rôle considérable dans la compréhension que le développeur a de son propre code. Ce n'est que du formatage de code, mais c'est essentiel pour bien travailler. N'hésite pas à demander si tu ne comprends pas ce que je veux dire.
J'ai passé beaucoup de temps à rédiger ce post, j'espère que tu en tiendras compte. Crois-moi, c'est l'expérience qui parle, tu seras gagnant;
OK, sur ce, bonne soirée à toi.
Partager