Problème "simple" (?) de boucle

Problème "simple" (?) de boucle - Perl - Programmation

Marsh Posté le 13-03-2008 à 15:46:34    

Bonjour à tous. :hello:  
 
Je code à l'occasion en perl pour mon "plaisir" et je tente en ce moment de réaliser un petit script ayant pour objectif d'extraire des valeurs d'un fichier texte pour construire un graphique (je vous passe les détails)
 
Voici mon bout de code "problématique" :
 

Code :
  1. $url = 'chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:';
  2. for ($k=1;$k<11;$k++) {
  3. print "iteration premiere boucle for : rang $k\n";
  4. for ($i=1;$i=$rangmax;$i++) {
  5.  print "iteration seconde boucle for : rang $i\n";
  6.  print "avec une valeur de rangmax : $rangmax\n";
  7.  $url = $url."$i,";
  8.  print "url vaut $url\n";
  9. }
  10. #autres instructions .. #
  11. }


 
Je cherche à obtenir une variable ($url) contenant :
chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:1,2,3,4,5,6,7,8,9,10, [...] à laquelle j'ajouterais d'autres éléments durant le reste de la première boucle FOR.
 
Pour l'instant, le code que j'ai pondu me donne un résultat du type :
chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:71,71,71,71,71,71,71,71, [...]
 
la variable $rangmax vaut 71 dans cet exemple.
J'ai rajouter quantité de PRINT pour étudier le comportement de mon script mais je ne comprend toujours pas pourquoi la seconde boucle FOR ne "passe pas" par la valeur 1, puis 2, ....
En sortie, je m'attend à :
 
iteration premiere boucle for : rang 1
iteration seconde boucle for : rang 1
avec une valeur de rangmax : 71
url vaut chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:1,
iteration seconde boucle for : rang 2
avec une valeur de rangmax : 71
url vaut chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:1,2, [et cetera]
 
Avec ce code, j'obtient :
 
iteration premiere boucle for : rang 1
iteration seconde boucle for : rang 71 ( :??: )  
avec une valeur de rangmax : 71
url vaut chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:71,
iteration seconde boucle for : rang 71
avec une valeur de rangmax : 71
url vaut chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:71,71, [et cetera]  :cry:  
 
 
J'ignore totalement ou est ma faute.
Merci de m'avoir lu;
 

Reply

Marsh Posté le 13-03-2008 à 15:46:34   

Reply

Marsh Posté le 13-03-2008 à 15:56:28    

rien compris :o ( en plus je pense que le "autres instructions" est nécessaire pour qu'on comprenne)
Mais bon déjà j'écrirais le début comme ça:

Code :
  1. $url = 'chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:';
  2. for ($k=1;$k<11;$k++) {
  3. print "iteration premiere boucle for : rang $k\n";
  4. $url = $url.(join (1..$rangmax) , ',');
  5. print "url vaut $url\n";
  6. #autres instructions .. #
  7. }


---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Marsh Posté le 13-03-2008 à 16:04:00    

ligne 4     $i=1;i$<=$rangemax
 
le inferieur mec...

Reply

Marsh Posté le 13-03-2008 à 16:45:55    

Merci messieurs ! \o/
Vos 2 réponses fonctionnent tout à fait.
texaff, si ta solution fonctionne, je ne comprend pas pourquoi.
Dans l'instruction : for ($i=1;$i=$rangmax;$i++)  
le $i=$rangmax serait une affectation ?
 
En tout cas je donne le code complet de mon "projet" (en l'état, càd pas tout à fait fonctionnel) pour anapajari. Merci beaucoup à vous.
 
 
Code :

Code :
  1. #!/usr/bin/perl
  2. ##### L'objectif de se programme est d'utilisé l'api charts (graphiques) de google pour créer une courbe décrivant l'évolution du "stack" de chaque joueur dans un tournoi sit&go Everest poker, et cela à partir d'un historique en format texte #####
  3. ##### Le programme va lire ce fichier, en extraire le nom de chaque joueur, puis les valeurs de stack de chacun. le tout sera restitué sous une url directement utilisable pour visualiser le graphique (enfin, c'est le but ...) #####
  4. ##### Determiner le nom des joueurs #####
  5. # ouvre  le fichier d'historique d'everest sous le "nom " (descripteur de fichier) de FILE
  6. open (FILE, 'history.txt') || die "Ouverture du fichier history.txt impossible\n";
  7. # démarre un compteur pour éviter une valeur nulle lier au format des historique
  8. $compteur = -1;
  9. # démarre une boucle pour lire les 12 premières lignes du fichier une à une stocker dans la variable $ligne
  10. while (($ligne=<FILE> ) && ($compteur<12)) {
  11. # enlève l'eventuel caractère de fin de ligne de la lignes
  12. chomp $ligne;
  13. # si la ligne fini par ' est au siège [un chiffre entre 0 et 9] avec' , stocke dans un tableau (@joueurs) ce qui se trouvait avant le masque
  14. if ($ligne =~ /(.*) est au siège [0-9] avec/) {$joueurs[$compteur] = $1;}
  15. # fait avancer le compteur pour que le prochain nom de joueur ($1)  soit stocker dans la prochaine case du tableau
  16. $compteur++;
  17. }
  18. # initialisation du compteur de "rangmax"
  19. $rangmax = 0;
  20. ##### Construction du tableau %table #####
  21. # parcourt le fichier dans son intégralité 1 fois par joueur.  la variable de la boucle for ($i) servira de compteur pour définir le joueur que l'on "suit"
  22. for ($i=1;$i<11;$i++) {
  23. # ouvre de nouveau l'historique (doit être ouvert à chaque itération pour être de nouveau positionné au début du fichier )
  24. open (FILE, 'history.txt') || die "Ouverture du fichier history.txt impossible\n";
  25. # initialisation du compteur de "rang"
  26. $rang = 0;
  27. # démarre une boucle pour lire l'intégralité du fichier ligne par ligne
  28. while ($ligne=<FILE> ) {
  29.  chomp $ligne;
  30. # démarre un compteur pour repérer le début d'une nouvelle main, et ainsi définir la variable de "temps" du graphique ( : cette valeur de stack pour le joueur X est pour la main n°$rang)
  31.  if ($ligne =~ /Commencer une partie [\d*]./) {$rang++}
  32. # stocke la valeur du "stack" du joueur dans la variable perl $1 (comme tout à l'heure, ce qui est entre parenthèse est stocké)
  33.  if ($ligne =~ /$joueurs[$i] est au siège [0-9] avec (.*)./) {
  34. # stocke la valeur dans dans une variable "manipulable"
  35.   $var = $1;
  36. # supprime un éventuel retour chariot
  37.   chomp $var;
  38. # supprime un espace dans le nombre (ie : '1 000' => '1000')
  39.   $var =~ s/\s//;
  40. # le système de charts de google ne permet pas d'utiliser une amplitude de valeur supérieur à 100 => divise par 100 le stack du joueur, conserve seulement la valeur entière
  41.   $var =int($var/100);
  42. # ajoute la valeur au tableau contenant toutes les informations à extraire.
  43.   $table[$rang][$joueurs[$i]] = $var;
  44. # détermine le rang le plus élevé (le nombre total de main joué)
  45.   if ($rangmax < $rang) {$rangmax = $rang}
  46.  }
  47. }
  48. # c'est la fin de la "première" itération de la boucle for. $i va changer de valeur. la regex trouvera alors les stacks du joueur suivants dans le tableau @joueurs, et inscriras de nouvelles valeurs dans le tableau @table
  49. }
  50. # maintenant, c'est la prise de tête pour générer l'url valide avec toutes ces informations.
  51. $url = 'http://chart.apis.google.com/chart?chs=700x300&cht=lxy&chd=t:';
  52. for ($k=1;$k<11;$k++) {
  53. print "iteration premiere boucle for : rang $k\n";
  54. for ($i=1;$i<=$rangmax;$i++) {
  55.  print "iteration seconde boucle for : rang $i\n";
  56.  print "avec une valeur de rangmax : $rangmax\n";
  57.  $url = $url."$i,";
  58.  print "url vaut $url\n";
  59.  sleep (1);
  60. }
  61. print "après boucle pour les rangs, url vaut $url\n";
  62. chop $url;
  63. $url = $url.'|';
  64. for ($i=1;$i<=$rangmax;$i++) {
  65.  if ($table[$joueurs[$k]][$i] eq undef) {$url = $url."0,";}
  66.  else {$url = $url."$table[$joueurs[$k]][$i],";}
  67. }
  68. print "après boucle pour les valeurs, url vaut $url\n";
  69. chop $url;
  70. $url = $url.'|';
  71. }
  72. chop $url;
  73. print "après traitement, url vaut $url\n";
  74. open (DEBUG, '>>debug.txt') || die "Ouverture du fichier debug.txt impossible\n";
  75. print DEBUG $url;


Message édité par Tut_noh le 13-03-2008 à 16:48:57
Reply

Marsh Posté le 13-03-2008 à 16:51:00    

oui tu affecte effectivement   rangemax a $i (d'ou le souci )
 
c'est un peut comme si tu fais if ($i = $rangemax)
 
tu affecte rangemax a $i et le if marche toujours...

Reply

Marsh Posté le 13-03-2008 à 16:54:01    

texaff a écrit :

oui tu affecte effectivement   rangemax a $i (d'ou le souci )
 
c'est un peut comme si tu fais if ($i = $rangemax)
 
tu affecte rangemax a $i et le if marche toujours...


 
Ok merci pour cette précision.  :jap:

Reply

Marsh Posté le 13-03-2008 à 17:44:40    

c'est n'importe quoi :)
tu lis 12 fois ton fichier alors qu'un seule lecture serait suffisante.

 

Et pis ta division par 100 pour s'assurer de l'écart ça marche pas non plus :o
Exemple: Marc a eu 11000 et Jean 100. Divisé par 100 tu te retrouves avec 110 et 1 soit un écart de plus de 100 ;)

 

A l'instinct j'aurais écrit un truc comme ça:

Code :
  1. open (FILE, 'history.txt') || die "Ouverture du fichier history.txt impossible\n";
  2. my %players;
  3. my $currentPlayer;
  4. my $maxStack = 0;
  5. while(<FILE> ){
  6.  next if $_ !~ /(.*) est au siège [0-9] avec/;
  7.  $currentPlayer = $1;
  8.  $players{$currentPlayer} = [] if ! defined $players{$currentPlayer};
  9.  if ($_ =~ /Commencer une partie \d*\./ && $_ =~ /$joueurs[$i] est au siège [0-9] avec (.*?)\./) {
  10.    my $stack =  $1 ;
  11.    $stack =~ s/\s//g;
  12.    push @{$players{$currentPlayer}}, $stack;
  13.    $maxStack = $stack if $stack > $maxStack;
  14.  }
  15. }
  16.  
  17. foreach(keys %players){
  18.  map { $_ = sprintf("%d", ($_ / $maxStack)*100) } @{$players{$_}};
  19. }
 

Après tu devrais te retrouver avec une hash dont la clé est le nom du joueur, et la valeur un tableau qui te présente l'évolution du stack de celui-ci .
note: je dis devrais parce que comme j'ai pas ton fichier, c'est à l'instinct sans rien vérifier
note2: en connaissant mieux la ligne du fichier il doit être possible de simplifier 2/3 trucs aussi


Message édité par anapajari le 13-03-2008 à 17:46:22

---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Marsh Posté le 13-03-2008 à 18:57:54    

Citation :

c'est n'importe quoi :)
tu lis 12 fois ton fichier alors qu'un seule lecture serait suffisante.


Euuuh désolé, mais j'ai construit mon script petit bout par petit bout; Dès lors qu'un code faisait ce que je voulait une fois, j'ai juste chercher à le mettre en boucle ... ça donne ce genre de code déguelasse
 

Citation :

Et pis ta division par 100 pour s'assurer de l'écart ça marche pas non plus :o
Exemple: Marc a eu 11000 et Jean 100. Divisé par 100 tu te retrouves avec 110 et 1 soit un écart de plus de 100 ;)


Les parties de poker que ce code à pour but d'étudier sont à 10 joueurs ayant un stack de départ de 1000. Aucun joueur ne peut atteindre 11000 jetons.
 
Je comprend bien que tu ne puisse faire un code fonctionnel juste avec mes ébauches.
Je te donne un extrait du fichier à titre d'exemple;
Je vais prendre le temps nécessaire pour revoir le script (il m'a fallu 3 jours pour pondre ce que tu à réécris en 10 minutes) ;
Je reviendrais vers HardWare.fr pour me faire "corriger" de nouveau  :D
 
 

Citation :

Commencer une partie 2874842385.
 
Keks82m est au siège 0 avec 895.
denis.balbir est au siège 1 avec 835.
ketum est au siège 4 avec 2 055.
Tuuuuuut_noh est au siège 5 avec 1 105.
tobe666 est au siège 6 avec 1 910.
lambswool est au siège 7 avec 960.
dododu13 est au siège 8 avec 1 225.
Reoquois est au siège 9 avec 1 015.
 
Le donneur est au siège 7.
 
dododu13 mise un blind de 10.
Reoquois mise un blind de 20.
 
(Kc Ks ont été distribuées à Tuuuuuut_noh.)
 
Pré-flop:
Keks82m passe.
denis.balbir suit pour 20.
ketum suit pour 20.
Tuuuuuut_noh relance pour 85.
tobe666 passe.
lambswool suit pour 105.
dododu13 passe.
Reoquois suit pour 85.
denis.balbir passe.
ketum passe.
 
Le flop vient
 Kh 3s 4c.
 
Reoquois dit parole.
Tuuuuuut_noh mise 100.
lambswool suit pour 100.
Reoquois relance pour 100.
Tuuuuuut_noh relance pour 100.
lambswool passe.
Reoquois suit pour 100.
 
Le tournant vient Kd.
 
Reoquois va all-in pour 610.
Tuuuuuut_noh va all-in pour 700.
90 est retourné au Tuuuuuut_noh.
 
Dévoilement des Cartes:
 
Reoquois montre: 10d Ac
 Kh Kd Ac 10d 4c
 Une paire de Rois
 
Tuuuuuut_noh montre: Kc Ks
 Kh Kd Kc Ks 4c
 Carré Rois
 
La rivière vient 10c.
 
Reoquois montre: 10d Ac
 Kh Kd 10c 10d Ac
 Deux Paires Rois et Dix
 
Tuuuuuut_noh montre: Kc Ks
 Kh Kd Kc Ks 10c
 Carré Rois
 
Tuuuuuut_noh gagne le pot de (2 285).
 
 
----------------------------------------

Message cité 1 fois
Message édité par Tut_noh le 13-03-2008 à 18:58:29
Reply

Marsh Posté le 14-03-2008 à 09:29:32    

bon j'étais pas forcément super loin.
Essaye ça et dis moi ce que tu penses du résultat:

Code :
  1. #!/usr/bin/perl
  2.  
  3. open (FILE, 'history.txt') || die "Ouverture du fichier history.txt impossible\n";
  4. my %players;
  5. my $currentPlayer;
  6. my $stack;
  7. my $maxStack = 0;
  8. while(<FILE> ){
  9.  next if $_ !~ /(.*) est au siège [0-9] avec (.*?)\./;
  10.  $currentPlayer = $1;
  11.  $stack = $2;
  12.  $players{$currentPlayer} = [] if ! defined $players{$currentPlayer};
  13.  $stack =~ s/\s//g;
  14.  push @{$players{$currentPlayer}}, $stack;
  15.  $maxStack = $stack if $stack > $maxStack;
  16. }
  17. foreach(keys %players){
  18.  map { $_ = sprintf("%d", ($_ / $maxStack)*100) } @{$players{$_}};
  19. }


 

Tut_noh a écrit :

Les parties de poker que ce code à pour but d'étudier sont à 10 joueurs ayant un stack de départ de 1000. Aucun joueur ne peut atteindre 11000 jetons.


Ok, alors je comprends.
Si cette méthode te convient tu peux virer les 3 dernières lignes du script plus haut.


Message édité par anapajari le 14-03-2008 à 09:31:26

---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed