difficulter pour coder.... - Perl - Programmation
Marsh Posté le 19-03-2007 à 12:17:52
steve419 a écrit : je dois coder un petit bout de perl, et comme je suis débutant avec ce langage je ne sais pas trop comment coder mon "algo". |
Bon c'est vraiment pas bien compliqué, alors biensur on pourrait te l'écrire en trois lignes zou on en parlerait plus, mais cela perdrait de son coté pédagogique ( AMHA)
.
Prenons les choses dans l'ordre, tu dis que ton algo est fini, tu peux nous le montrer?
Ensuite dis-nous étape par étape ce que tu n'arrives pas à implémenter en perl.
Marsh Posté le 19-03-2007 à 12:25:51
il faut commencer par lire ton fichier ligne par ligne, puis récupérer les données contenues dans chaque ligne, en tenant compte du fait que les champs sont séparés par des virgules. Ensuite, tu peux commencer à traiter réellement tes données.
Code :
|
C'est écrit à l'arrache et non testé, mais ça te donne grosso modo une idée du squelette de ton truc.
EDIT: OOPS, désolé anapajari, j'ai détruit une partie de ton travail pédagogique
Marsh Posté le 19-03-2007 à 14:42:11
déjà, merci pour votre aide
@franceso : les lignes sont mélangées,
200703091000 pour cette valeure tu rentres dans la 1ère condition alors que pour moi c'est le dernier 1/4 d'heure
@anapajari : voici ce que je veux coder :
1 - pour toutes les lignes du fichier stoquer chaque élément séparé par une virgule dans une table de hash. le nombre de compteur c... peut-être variable, la partie fixe c'est les champs principaux du header à savoir : le couple (bscid-siteid-btsid-mcc-mnc-lac-ci,time) qui constituent ma clef de hash. (en retregnant le champ 'time' au deux dernier chiffre pour apprès faire la somme)
voila ce que je veux avoir dans mon table de hachage :
hashtab[bscid-siteid-btsid-mcc-mnc-lac-ci,time]=[c1,c2,...cn]
ex : hashtab[3-1-1-603-1-3102-16102,05]=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
hashtab[3-1-1-603-1-3102-16102,10]=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ]
2- faire la somme :
res[i,00][j]=somme des hashtab[i,05][j]+hashtab[i,10][j]+hashtab[i,15][j] pour tous les i (bscid-siteid-btsid-mcc-mnc-lac-ci) de mon tableau pour le 1er 1/4 d'heure et tous les j (c1,c2,...cn)
res[i,15][j]=hashtab[i,20][j]+hashtab[i,25][j]+hashtab[i,30][j] pour le 2nd 1/4 d'heure
res[i,30][j]=somme des hashtab[i,35][j]+hashtab[i,40][j]+hashtab[i,45][j] pour le 3ième 1/4 d'heure
res[i,45][j]=somme des hashtab[i,50][j]+hashtab[i,55][j]+hashtab[i,60][j] pour le 4ième 1/4 d'heure
4- reconstituer le fichier résultat en lisant la table res
3,1,1,200703090900,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090915,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090930,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090945,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
le début de mon code :
my $memoryfile = shift; # Array Reference to each open input file
my($line,$time,$key_hash,@dat,@fields);
%table_hash;
foreach $line (@memoryfile)
{
chomp($line);
if ($line !~ /^bscid/) # la ligne n'est pas la ligne de header
{
# line : bscid,siteid,btsid,time,mcc,mnc,lac,ci,c1,c2,..,c(n)
@fields = split(",",$line);
$time = $fields[4];
$time =~ s/^(\d{10})(\d{2})$/$1/;
$heure = $2;
$key_hash = "$fields[0]-$fields-[1]-$fields[2]-$fields[3]-$fields-[5]-$fields-[6]$fields[7]-$fields[8]";
je ne sais pas comment faire a partir d'ici :
$table_hash{$key_hash,$heure} = <c1,c2,..,c(n)>
}
}
# Update the Input file with the pre-parsed data
foreach $cle (keys (%table_hash))
{
push @dat, $line;
}
push @dat, $line;
@{$memoryfile} = @dat;
return 0;
merci pour votre aide
Marsh Posté le 19-03-2007 à 15:30:11
A mon avis, tu devrais faire une hash de hash ( enfin de référence sur hash), et du coup sur ta ligne en rouge tu aurais quelque chose du style:
Code :
|
A noter que si tes fichiers sont vraiment gros, c'est pas une super bonne idée de se les trimballer dans des tableaux en mémoire...
franceso a écrit : EDIT: OOPS, désolé anapajari, j'ai détruit une partie de ton travail pédagogique |
pas grave
Marsh Posté le 19-03-2007 à 15:46:28
steve419 a écrit : 200703091000 pour cette valeure tu rentres dans la 1ère condition alors que pour moi c'est le dernier 1/4 d'heure |
Au temps pour moi : j'ai mis le -1 au mauvais endroit... Je voulais écrire :
Code :
|
Ceci dit, ta solution à base de /(\d{10})(\d{2})/ est très bien aussi...
+1 pour la hash de hash proposée par anapajari.
Marsh Posté le 19-03-2007 à 15:48:08
a noter qu'en me relisant je constate que j'ai bien insisté sur le fait que c'était une hash de référence de hash mais que dans mon code j'ai merdé
Il manque un $ ou une flèche, au choix.
Marsh Posté le 19-03-2007 à 16:48:21
merci pour votre aide,
si je rajoute le predicat suivant : si heure = 05 , 10 ou 15 alors heure = 0
si heure = 20 , 25 ou 30 alors heure = 15
ou si heure = 35 , 40 ou 45 alors heure = 30
ou si heure = 50 , 55 ou 00 alors heure = 45
je peux directement faire la somme comme je veux avec le code ci dessous de anapajari ( res[i,00][j]=somme des hashtab[i,05][j]+hashtab[i,10][j]+hashtab[i,15][j] pour tous les i (bscid-siteid-btsid-mcc-mnc-lac-ci) de mon tableau pour le 1er 1/4 d'heure et tous les j (c1,c2,...cn) )
Code :
|
est-ce que tu peux m'aider dans le code perl avec ces deux boucles (for par exemple) pour que le nombre de compteur (c...) soient dynamique ?????
par avance merci bcp
Marsh Posté le 19-03-2007 à 16:58:49
bin au lieu de 'c1' tu mets 'c'.$i ou i est l'itérateur de ta boucle
Et pour la valeur pareil tu récupéres celle du tableau resultant du split qui va bien
Marsh Posté le 19-03-2007 à 17:14:11
my $memoryfile = shift; # Array Reference to each open input file (mandatory)
my($line,$time,$key_hash,@dat,@fields);
%table_hash;
foreach $line (@memoryfile)
{
chomp($line);
if ($line !~ /^bscid/)
{
# line : bscid,siteid,btsid,time,mcc,mnc,lac,ci,c1,c2,..,c(n)
@fields = split(",",$line);
$time = $fields[4];
$time =~ s/^(\d{10})(\d{2})$/$1/;
$heure = $2;
if (($heure =~ /05/) || ($heure =~ /10/) || ($heure =~ /15/))
{
$heure = "00";
}
elsif (($heure =~ /20/) || ($heure =~ /25/) || ($heure =~ /30/))
{
$heure = "15";
}
elsif (($heure =~ /35/) || ($heure =~ /40/) || ($heure =~ /45/))
{
$heure = "30";
}
elsif (($heure =~ /50/) || ($heure =~ /55/) || ($heure =~ /00/))
{
$heure = "45";
}
$key_hash = "$fields[0]-$fields-[1]-$fields[2]-$fields[3]-$fields-[5]-$fields-[6]$fields[7]-$fields[8]";
for ($i = 9; $i < 17; $i++) { $table_hash{$key_hash}{$heure}{'c'.$i} += $fields[$i]; }
}
}
exact ???
Marsh Posté le 19-03-2007 à 17:28:15
sauf que du coup tu te retrouves avec C9 - C17 dans ta clé alors que tu cherches C1- C9; ça donne plus:
Code :
|
Attention maintenant tu joues avec un hash (clé $key_hash) de référence de hash ( clé heure) de référence de hash ( clé CN). Il faut que tu mettes des fleches au bon endroit et que tu penses à initialiser tes références si elles n'existe nt pas:
Code :
|
un peu verbeux mais au moins toutes les étapes sont bien décomposées
Marsh Posté le 19-03-2007 à 17:58:03
pour le c9 - c17 ok mais cela ne me gène pas.
Code :
|
lors de la compilation j'ai les messages :
Perl error: Global symbol "%table_hash" requires explicit package name at ********** line 74.
Global symbol "%table_hash" requires explicit package name at ********* line 107.
edit : merci encore pour ton aide, je dois y alelr.
J'espère à demain si j'ai encore des questions...
Marsh Posté le 19-03-2007 à 18:00:25
euh veut bien t'aider mais la c'est de l'erreur ou si tu t'en sors pas autant allez elever des ratons laveurs.
Y'a quoi ligne 74 dans ton truc ( allez, sur ton bout de code ci-dessus, à mon avis ça doit être la ligne 3)? Tu vois pas comme un truc qui manque?
Marsh Posté le 19-03-2007 à 18:01:44
je ne sais pas comment déclarer la table de hash
edit : avec le my ok !!!
il me reste plus qu'a coder la boucle pour reconstituer l'input !!!
Marsh Posté le 19-03-2007 à 18:11:45
# Update the Input file with the pre-parsed data
foreach $cle (keys (%table_hash))
{
$line = $table_hash{$cle} ;
}
push @dat, $cle , $line;
@{$memoryfile} = @dat;
Marsh Posté le 19-03-2007 à 18:40:15
steve419 a écrit : je ne sais pas comment déclarer la table de hash |
cherche feignasse ...
steve419 a écrit : edit : avec le my ok !!! |
tu vois quand tu veux...
steve419 a écrit : il me reste plus qu'a coder la boucle pour reconstituer l'input !!! |
et ouais y'a plus qu'a ...
steve419 a écrit : # Update the Input file with the pre-parsed data |
Nan mais la t'es gentil, tu ressors un vieux bout de code de je sais pas où, sans même avoir essayer de l'adapter à la hash préalablement construite...
Marsh Posté le 19-03-2007 à 21:06:18
ok pour le vieu bout de code...
je vais voir ça demain...
en espérant ne pas avoir perdu de vu mon professeur
encore merci
@ deux mains
Marsh Posté le 20-03-2007 à 16:27:56
merci à anapajari, j'ai terminé, avec en plus des bouts de code pour durcir le traitement (traitement des cas particulier)
@+
Marsh Posté le 19-03-2007 à 12:12:17
bonjour,
je dois coder un petit bout de perl, et comme je suis débutant avec ce langage je ne sais pas trop comment coder mon "algo".
voici le problème :
j'ai un fichier
bscid,siteid,btsid,time,mcc,mnc,lac,ci,c11101,c11102,c11103,c11104,c11105,c11106,c11107,c11108,c11109,c11110,c11111,c11112,c11113,c11114,c11115,c11116
3,1,1,200703090905,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090910,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090915,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090920,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090925,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090930,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090935,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090940,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090945,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090950,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090955,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703091000,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
la première ligne c'est le "header" de description...
je dois faire la somme des compteurs (des c... i.e des c11101, c11102, etc...) suivant 4 1/4 d'heures.
1 -
3,1,1,200703090905,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090910,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090915,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2-
3,1,1,200703090920,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090925,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090930,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3-
3,1,1,200703090935,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090940,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090945,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
4-
3,1,1,200703090950,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090955,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703091000,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
la clef de hash pour faire cette somme c'est bscid,siteid,btsid,time finit par 05,10 ou 15,mcc,mnc,lac,ci dans le premier cas
bscid,siteid,btsid,time finit par 20,25 ou 30,mcc,mnc,lac,ci dans le second
bscid,siteid,btsid,time finit par 35,40 ou 45,mcc,mnc,lac,ci dans le troisième
bscid,siteid,btsid,time finit par 50,55 ou 00,mcc,time mnc,lac,ci dans le 4ième
les champs bscid,siteid,btsid,mcc,time mnc,lac,ci sont variables, ils sont différents dans tous le fichier à traiter.
le résultat est mis dans un tableau agrégé :
3,1,1,200703090900,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090915,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090930,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3,1,1,200703090945,603,1,3102,16102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
quelqu'un peu t'il m'aider à coder cela ??
par avance merci a ceux qui prendront le temps de m'aider