JeuWeb - Crée ton jeu par navigateur
[PHP] Comparaison entre deux chaines - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [PHP] Comparaison entre deux chaines (/showthread.php?tid=5933)



[PHP] Comparaison entre deux chaines - Ter Rowan - 21-01-2012

coucou,
certaines de mes fonctions produisent des chaines de caractères.
Pour mes tests automatisés, je faisais une simple comparaison entre le résultat et l'attendu, et je me débrouillais pour voir où était la différence.

Sauf que j'ai commencé a avoir des chaines assez longues (genre des logs) et c'est alors assez compliqué d'identifier à partir d'où ça déconne...


l'idée :

j'ai deux chaines $expected et $r
j'affiche les deux côte à côte. Pour comparer je veux quand j'affiche $expected mettre en rouge la partie qui diverge de $r
exemple

$expected = "totototototototototo";
$r = "tototutututi";

devient
$expected = "totototototototototo";
$r = "tototutututi";

J'ai donc cherché sans grand succès une méthode qui me permette d'identifier le premier caractère déconnant.

De fait j'ai pondu mon propre code et j'aimerais juste savoir si ca vous parait bien, si il y avait plus élégant ou si ça existait déjà.


if ( strcmp($expected, $r) )
{
$splitexpected = str_split($expected);
$splitr = str_split($r);

foreach( $splitexpected as $i => $c)
{
if ($c != $splitr[$i])
break;
}

$expected = substr($expected,0,$i).'<span class="rouge">'.substr($expected, $i).'</span>';
}



RE: [PHP] Comparaison entre deux chaines - Sephi-Chan - 21-01-2012

Avant de parler du traitement, j'aimerai en savoir un peu plus sur la cause.
Pourquoi est-ce que tu compares des chaînes dans tes tests ?
Peut-on en voir un échantillon ?



RE: [PHP] Comparaison entre deux chaines - Ter Rowan - 21-01-2012

en ce moment par exemple je développe les méthodes controlant qu un joueur puisse manipuler un objet dans une quantité suffisante

si mon code trouve une anomalie (donc que le joueur soit triche, soit s'est planté, soit n'a plus l'objet parce qu un autre lui a piqué entre deux clics) je dois lui renvoyer un message

Pour le moment, mon controle provoque une alerte en cas de défaut :

if ($reason)
msg::AddMsg($reason, $this->MySystem()->GetId(), $idAction, $idConstraint, $line['idSystem'], $expected);
Je ne sais pas encore ce que fera msg et peut importe d'ailleurs, je ne développe que la couche métier. Simplement je stocke l'ensemble de ces messages sous forme de tableaux

Pour vérifier que mon algo tourne, j'instancie des objets des contraintes, etc.. pour construire une batterie de test. C'est pourquoi on peut voir en dessous "sol_bon8" pour un id d'un objet (qui est au sol, au bon endroit, dont le "type" est 8). Evidemment dans la réalité, les objets auront des id numériques et au lieu d'être instancié par le programme en dur, viendront de la bdd mais là l'objectif est de contrôler les contrôles justement

Donc mes tests se résument à comparer le retour d'une méthode avec la valeur que j'attends. Si c'est bon pas de soucis, si c'est faux je veux pour analyser identifier le delta. Facile si c'est un nombre plus compliqué quand c'est une collection

Typiquement, j'ai pour le cas qui nous concerne une centaine de cas tests (certains indiquant que oui l'objet est utilisable par le joueur, dans d'autres que non) et puis un dernier qui constitue la liste des messages d'erreur (soit pour les logs, soit pour les joueurs)

Je formate côté scripts de tests les résultats pour avoir quelque chose de lisible (var_dump c'est pas toujours sympa à lire) et ça me donne un beau message mais pour identifier d'un coup d oeil que c'est le 17eme message d erreur qui ne convient pas c'est déjà plus dur :[/quote]


Citation :0>NOT_ENOUGH 1>sys_a 2>1 3>2 4>8 5>5
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>5 4>sol_ferme_8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>6 4>sol_mal8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>7 4>sol_mal8f 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>8 4>sol_mal8p 5>8
0>CLASS_REJECT 1>sys_a 2>1 3>9 4>item_a3 5>8
0>PORTER_REJECT 1>sys_a 2>1 3>11 4>item_b8 5>8
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>40
0>NOT_ENOUGH 1>sys_a 2>1 3>2 4>8 5>5
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>5 4>sol_ferme_8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>6 4>sol_mal8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>7 4>sol_mal8f 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>8 4>sol_mal8p 5>8
0>CLASS_REJECT 1>sys_a 2>1 3>9 4>item_a3 5>8
0>PORTER_REJECT 1>sys_a 2>1 3>11 4>item_b8 5>8
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>40
0>NOT_ENOUGH 1>sys_a 2>1 3>2 4>8 5>5
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>5 4>sol_ferme_8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>6 4>sol_mal8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>7 4>sol_mal8f 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>8 4>sol_mal8p 5>8
0>CLASS_REJECT 1>sys_a 2>1 3>9 4>item_a3 5>8
0>KNOWLEDGE_REJECT 1>sys_a 2>1 3>10 4>sol_coffre 5>10
0>PORTER_REJECT 1>sys_a 2>1 3>11 4>item_b8 5>8
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>40
0>NOT_ENOUGH 1>sys_a 2>1 3>2 4>8 5>5
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>5 4>sol_ferme_8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>6 4>sol_mal8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>7 4>sol_mal8f 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>8 4>sol_mal8p 5>8
0>CLASS_REJECT 1>sys_a 2>1 3>9 4>item_a3 5>8
0>PORTER_REJECT 1>sys_a 2>1 3>11 4>item_b8 5>8
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>40
0>NOT_ENOUGH 1>sys_a 2>1 3>2 4>8 5>5
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>5 4>sol_ferme_8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>6 4>sol_mal8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>7 4>sol_mal8f 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>8 4>sol_mal8p 5>8
0>CLASS_REJECT 1>sys_a 2>1 3>9 4>item_a3 5>8
0>PORTER_REJECT 1>sys_a 2>1 3>11 4>item_b8 5>8
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>40
0>NOT_ENOUGH 1>sys_a 2>1 3>2 4>8 5>5
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>5 4>sol_ferme_8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>6 4>sol_mal8 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>7 4>sol_mal8f 5>8
0>WRONG_PLACE 1>sys_a 2>1 3>8 4>sol_mal8p 5>8
0>CLASS_REJECT 1>sys_a 2>1 3>9 4>item_a3 5>8
0>PORTER_REJECT 1>sys_a 2>1 3>11 4>item_b8 5>8
0>QUANTITY_REJECT 1>sys_a 2>1 3>3 4>sol_bon8 5>40



RE: [PHP] Comparaison entre deux chaines - Holy - 21-01-2012

Ca m'a l'air drôlement compliqué pour l'utilité que tu en as. Bête question, mais pourquoi tu n'utilises pas un tableau regroupant toutes les "sous-conditions" ?

Au lieu d'avoir une chaine avec "X" sous conditions à l'intérieur, tu aurais un tableau de "X" sous-conditions. Limite, si tu veux pas trop bidouiller ton script, tu fais un explode sur le ">" (qui semble délimiter les conditions).

Ta dernière citation, c'est un log ?



RE: [PHP] Comparaison entre deux chaines - Maks - 21-01-2012

c'est là que tu serais content d'utiliser un vrai langage objet avec une chaîne issue d'une classe String renvoyant un tableau de char, c'est quand même plus simple pour tester après ^^


RE: [PHP] Comparaison entre deux chaines - Ter Rowan - 21-01-2012

ben je crois surtout que du coup tu focus sur mes tests au lieu d'être sur la question initiale qui était beaucoup plus basique Smile

j'ai essayé d'expliquer le contexte comme Sephi le demandait, mais y a pas tellement de rapport

je cherche a comparer deux chaines et a mettre en rouge la partie des chaines différentes à l'affichage rien de plus.


sinon pour aider quand même a la compréhension du contexte, je viens de mettre une page html (bon j y ai rajouté les styles a l intérieur pour tout voir)

les 78 premiers cas tests sont mes cas unitaires. Fonction d'un ordre du joueur (simulé) le système renvoie des instructions (unitaires) que je traduis pour pouvoir les lire visuellement (dans mes tests)

Dans le cas où il y a refus du système je m'attends à avoir une chaine vide visuellement (dans la réalité la méthode renvoie NULL)

Ensuite le dernier test concerne le "log" de tous les refus. Ce log correspond à tous les messages que le système (un peu comme une levée d'exception) envoie pour chaque refus (explication du refus).

Typiquement, j'ai actuellement deux soucis remonté par ma page de tests(donc des bugs [/code]dans ma prog) :

le système refuse un ordre du joueur alors que je m'attends à une liste d'instruction (premier ko) - même si probablement, le système a raison et c'est moi qui me suis planté dans mon cas test, je creuse -

j'ai un paquet de cagades dans les raisons de refus. C'était beaucoup plus compliqué sans le rouge, va trouver ou ça plante mais maintenant je peux voir clairement où ça commence

le sujet est bien et je le répète :

Est ce que ce code est pertinent (rajouter les balises span a l'endroit où il y a une différence entre deux chaines) ou y a t il plus efficace

if ( strcmp($expected, $r) )
{
$splitexpected = str_split($expected);
$splitr = str_split($r);

foreach( $splitexpected as $i => $c)
{
if ($c != $splitr[$i])
break;
}

$expected = substr($expected,0,$i).'<span class="rouge">'.substr($expected, $i).'</span>';
}