un petit soucis de boucle

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : un petit soucis de boucle

par Tracker » 22 oct. 2007, 20:08

Salut,

Php c'est sympa, mais ton problème doit pouvoir se résoudre intégralement en SQL:

Code : Tout sélectionner

select tir.id_clients, count(tir_ns.n) as nbNum from (SELECT id_grids, date FROM grids_winning ORDER BY id_grids DESC LIMIT 1,1) win inner join ( select id_grids, substring(grids_1,1,2) as n from grids_winning union all select id_grids, substring(grids_1,3,2) from grids_winning union all select id_grids, substring(grids_1,5,2) from grids_winning union all select id_grids, substring(grids_1,7,2) from grids_winning union all select id_grids, substring(grids_1,9,2) from grids_winning union all select id_grids, substring(grids_1,11,2) from grids_winning ) win_ns on win.id_grids = win_ns.id_grids inner join grids_clients tir on tir.timeplayed between win.date and now() left join ( SELECT id_clients, substring(grids_1,1,2) as n from grids_clients union all SELECT id_clients, substring(grids_1,3,2) from grids_clients union all SELECT id_clients, substring(grids_1,5,2) from grids_clients union all SELECT id_clients, substring(grids_1,7,2) from grids_clients union all SELECT id_clients, substring(grids_1,9,2) from grids_clients union all SELECT id_clients, substring(grids_1,11,2) from grids_clients ) tir_ns on tir_ns.id_clients = tir.id_clients and tir_ns.n = win_ns.n group by tir.id_clients
L'ordre te ramène, pour le dernier tirage, l'id des clients ayant joué aussi que leur nombre de numéros gagnants.

à tester... si tu files un lien pour télécharger les structures + données SQL, je veux bien m'y coller :wink:


Tracker.

par choubix » 22 oct. 2007, 18:39

j'ai juste du rajouter un strToarray ici :
$rang=comparegrids(strtoArray($return['grids_1']) , strtoArray($grid));

et ca marche au poil.

je vais demonter le code pour voir comment c'est ecrit.
je comprends la logique qui est derriere mais passer a l'ecriture est difficile... :(

merci a tous

par fgranjon » 22 oct. 2007, 14:14

Re ,

Alors je ne sais si cela répondra à ta problèmatique .

Dans un premier temps à ta place je créerai une fonction qui transforme ma string de 12 en tableau .
A partir de "012345678901" ca te renverra array(0=>"01",1=>"23",2=>"45",3=>"67",4=>"89",5=>"01")
function strToArray($string) {
   $result=array();
   for ($i=0;$i<=12;$i=$i+2) {
      
      $result[]=substr($string,$i,2);
   }
   return $result
}
Ensuite je ferais une function pour comparer deux grilles , j'imagine que le rang est la notion de "nombre" de bon numéro par rapport à la grille d'origine.
Cette fonction retourne le nombre de numero identique
function compareGrids($grid_player,$grid) {
     $nb_wrong=0;
     //attention cette comparaison fonctionne si l'ordre des numéros n a pas d importance.   
     $nb_wrong=count(array_diff($grid_player,$grid));
    
     /*en fait $nb_wrong contient le nombre de mauvais numéro ,c est pour cela que le nombre de bon numéro est égale à 6 moins le nombre de numéro qui diffèrent.   */
     return (6-$nb_wrong);
}
Ensuite il ne reste plus qu'a utiliser ces 2 fonctions.
//select the grids played after last draw only
$query = ("SELECT * FROM grids_clients WHERE timeplayed BETWEEN $dateprevious AND $datecurrent");
$result = mysql_query($query) or die('Invalid query: ' . mysql_error());

//loop: load $data with one field of the array (will be used for comparaison with winning numbers
while ($return = mysql_fetch_assoc($result))
{
          //on reccupere le nombre de bon numéro 
          $rang=compareGrids( strToArray($return['grids_1']) , $grid );

         //on stocke le tout dans un tableau résultat
          $resultat[$return['id_client']]=array("rang"=>$rang,"grid"=>$return['grids_1']);
}
 
//ensuite tu peux parcourir le tableau resultat
while(list($id_player,$val)=each($resultat) ) {
      echo "idplayer:$id_player <br>";
      echo "grille jouée:".$val['grid']."<br>";
      echo "nombre de chiffre bon:".$val['rang']."<br>";
}
Voila en espérant que cela aide.
Nb:Je n'ai pas tester le code

par Ryle » 22 oct. 2007, 12:26

par contre le print_r ($temp); me retourne par exemple:
Array ( [0] => 021319212542 [1] => 122022303142 )
Ce qui est un peu normal puisque tu constitues toi même le tableau $temp en ajoutant chaque valeur prise dans la base. Le soucis vient du fait que tous les nombres sélectionnés sont collés, alors qu'un séparateur du style ";" entre chaque te faciliterait grandement la vie (tu n'aurais qu'à faire un explode() pour obtenir un tableau et faire ton array_diff())

Du coup il te faut parser la chaine pour récupérer chaque nombre (de deux caractères) et reconstituer ta liste de numéros. Tu peux le faire à coup de substring() ou plus joliement avec wordwrap() en insérant un caractère tous les 2 caractères et en faisant un explode() ensuite pour obtenir un tableau :)

par choubix » 22 oct. 2007, 12:13

bonjour fgranjon,

ce que je souhaite c'est trouver les perdants et les gagnants (a tous les rangs) et avoir une action specifique a chacun des rangs. (crediter le compte client avec des points, envoyer un emil etcetc)

sachant que la grille gagnante je peux l'avoir en string ou en array (ce qui est moins sexy qu'en string on est bien d'accord ;) )

par fgranjon » 22 oct. 2007, 12:02

Bonjour ,

Que cherches tu à faire en fait ?
extraire les id clients ayant une grille gagnante ?

par choubix » 22 oct. 2007, 11:45

salut Berzemus.

bon: moi ca n'avance pas d'un poil :(

je vais faire un bref recapitulatif:

dans ma base de donnees j'ai des grilles qui ont etees jouees par les utilisateurs.
ces grilles sont sous la forme (exemple) 011218223437. donc: leur choix a ete ordonne et fait toujours 12 caracteres.
par ailleurs j'ai une grille qui est la grille gagnante.

je souhaite donc comparer les grilles des utilisateurs avec la grille gagnante.

la grille gagnante je l'ai sous cette forme: 051719223547 (string)
mais je peux l'avoir sous cette forme: Array ( [0] => 05 [1] => 17[2] => 19 [3] => 22 [4] => 35 [5] => 47 )


maintenant je veux recuperer les grilles jouees et les comparer: la, rien en va plus...
//select the grids played after last draw only
$query = ("SELECT * FROM grids_clients WHERE timeplayed BETWEEN $dateprevious AND $datecurrent");
$result = mysql_query($query) or die('Invalid query: ' . mysql_error());

//loop: load $data with one field of the array (will be used for comparaison with winning numbers
while ($return = mysql_fetch_assoc($result))
{
$id_clients[] = $return['id_clients'];
$temp[] = $return['grids_1'];
}

print_r($id_clients);
print_r($temp);



la requete sql est bonne: seules les nouvelles grilles sont utilisees dans la boucle
le print_r ($id_clients); me retourne les bonnes valeurs dans un tableau

par contre le print_r ($temp); me retourne par exemple:
Array ( [0] => 021319212542 [1] => 122022303142 )

donc: une chaine de caracteres dans un tableau...

je suis paume: je voulais utiliser array_diff() entre la grille gagnante et les grilles jouees mais ca ne peut pas marcher car c'est comme si je comparais des patates et des carottes... :( (et deja en primaire c'etait pas bien, alors maintenant...)

si je pouvais avoir un avis sur la strategie a prendre ca serait super

merci

par Berzemus » 22 oct. 2007, 10:20

mais un affichage de quoi ?
"print_r($data[$i]); " ?

A voir le code, $data[$i] est un élément d'un tableau, une chaine, et pas un tableau en tant que tel.

Si tu veux afficher le tableau en entier, alors print_r est pratique. Si tu ne veux qu'afficher une seule valeur du tableau, une chaine, tu as meilleurs temps d'utiliser echo.
echo $data[$i];

par choubix » 21 oct. 2007, 23:12

salut Zeus: ok pour la balise. je changerai. et merci de me preter main forte. :)

pour ce qui est de la difference entre ton code et le mien j'en vois deja 2:
ma boucle prenait pas en compte le tableau (mysql_fetch_assoc) mais le nombre d'occurence a traiter ( count() ).

par ailleurs je faisais un affichage au sein de la boucle.

correct??

par zeus » 21 oct. 2007, 22:59

Modération :
Choubix, quand tu postes du code PHP, préfère la balise [php] à [code], merci


Sinon, il est normal que ton tableau contient X fois la même valeur vu que, pour chaque itération de ton for, tu affectes à l'index courante de $data la valeur $return['grids_1']; qui est initialisé en dehors de la boucle, donc qui ne change pas au cours de ton for ;)

Si ton but est de parcourir la liste des résultats de la requête, la manière de faire est fausse.

D'une manière générale, on fait :
// Construction de la requête
$query = "SELECT liste, des, champs FROM matable";
// Exécution de la requête
$result = mysql_query($query) or die('Invalid query: ' . mysql_error());

// Parcours des résultats de la requête
while ( $return = mysql_fetch_assoc($result); )
{
  // On ajoute la valeur de l'enregistrement courant dans un tableau global
  $data[] = $return['list'];
}
Essaye de comparer mon exemple à ton code pour adapter ton code ;)

un petit soucis de boucle

par choubix » 21 oct. 2007, 22:30

je fais une requete dont depend une boucle FOR.
dans cette boucle je veux extraire d'un tableau le contenu du champs "grids_1" en fonction de la requete precedente.

par la suite je voudrais faire un array_diff entre cette valeur et une autre.

pour le moment ce qui me preoccupe est que ma boucle me sort X fois le meme contenu du champs grids_1.

est ce que vous voyez qq chose qui cloche dans cette boucle svp?
$query = ("SELECT date FROM grids_winning ORDER BY id_grids DESC LIMIT 1,1");
$result = mysql_query($query) or die('Invalid query: ' . mysql_error());

//store it into an array
// this will be useful in order to compare ONLY new grids for the current draw and diregards PREVIOUS grids
$dateprev = mysql_fetch_assoc($result);
$dateprevious = implode('',$dateprev);

//current date
$datecurrent = time();

//select the grids played after last draw only
$query = ("SELECT * FROM grids_clients WHERE timeplayed BETWEEN $dateprevious AND $datecurrent");
$result = mysql_query($query) or die('Invalid query: ' . mysql_error());

$counter = mysql_num_rows($result);

//load the variable with the array. fetch the array from query
$return = mysql_fetch_assoc($result);


//loop: load $data with one field of the array (will be used for comparaison with winning numbers)
for ($i = 0; $i < $counter; $i++)
{
$data[$i] = $return['grids_1'];
print_r($data[$i]);
}