Corrigé

Stratégie
Bien que je me base toujours sur le même modèle pour bien préparer le travail, vous pouvez rajouter une ou plusieurs étapes si vous en éprouvez le besoin, et si vous êtes un as, vous pouvez peut-être en sauter.

Si le passage à l'écriture est un endroit critique pour vous, essayez d'utiliser un crayon une gomme et du papier (si, si, ça existe encore et c'est bien pratique, là, je ne plaisante pas).


Réfléchir
Le problème ayant été suffisamment exposé dans la page précédente, je peux le reprendre tel quel:

Pour les trois premiers champs il suffit de tester si il y a un nombre et s'il est compris entre 0 et 255, par contre pour le code, c'est un peu plus compliqué, il faut tester qu'il y ait bien 7 caractères, que le premier soit "#", que les autres soient des chiffres ou des lettres de "A-F" et les passer en majuscules au besoin, rien de compliqué.


Découper
Pour les trois premiers champs qui exécutent déjà une fonction (frouge,fvert,fbleu), j'ai le choix entre faire une seule routine commune ou insérer le test dans chaque fonction déjà existante, mais comme chacune de ces fonctions doit impérativement retourner "true" ou "false" pour valider le champ ou non avec la valeur entrée je ne vais pas trop compliquer les choses et faire ce test à l'intérieur de la fonction, et tant pis pour la triple répétition car le test n'est pas très long, ni compliqué. A vous de voir si vous préférez l'autre solution, bien plus élégante.

Pour le champ code, pas besoin de se casser la tête, il est unique, donc le test se fera à l'intérieur de la fonction, j'ai dit, Ugh !


Chercher
Pour tester si la valeur d'une variable est nulle tout en n'étant pas égale à zéro on utilise la fonction parseInt() qui convertit le texte en nombre et une petite astuce déjà employée dans la validation de formulaire de l'extraordinaire guide du langage Javascript que vous avez l'honneur de lire en ce moment et qui consiste à comparer la valeur du nombre avec le texte, si c'est un nombre Javascript le convertira la chaîne de caractère pour faire le test et ne criera pas parce que "5"==5 (houlà) mais "zorro" ne sera pas égal à zéro "zorro" converti donne (0) et "zorro"!=0.

Pour tester ensuite si le nombre est plus petit que zéro ou plus grand que 255 (pour retourner une erreur) on utilisera tout bêtement les opérateurs "<" et ">", et "||" (OU), c'est plus simple que de tester si il est égal à zéro, puis à un, puis à deux, etc... et de retourner "true" si tous ces cas sont vrais.

Ensuite pour le code, on va réutiliser la méthode .charAt() pour savoir si le "#" est bien en position 1, une propriété pas encore vue (je crois) pour connaître la longueur de la chaîne de caractères .length, puis la solution la plus simple me semble-t-il c'est de faire une boucle pour parcourir et tester les caractères 2 à 7, dans cette boucle (je choisi une boucle for) je vais simplement prendre le caractère avec .charAt et contrôler qu'il soit compris entre 0 et 9 (comme ci-dessus), ou A à F, voire a-f (et le passer en majuscule, mais là ça demande encore réflexion), et voilà.

Comment vais-je donc passer un caractère en majuscule ? Hum, il existe bien une méthode .toUpperCase, mais elle n'aime pas beaucoup les chiffres et on ne peut pas modifier le contenu initial de la variable avec, la seule solution que je vois c'est de reconstruire dans une autre variable, caractère par caractère, le nouveau code en profitant de la boucle de test, en transférant sans modification les nombres et caractères valides et en ne les changeant en majuscule que quand c'est nécessaire.

Bon, je crois que c'est à peu prêt tout ce dont j'ai besoin, je vais donc pouvoir passer à l'étape suivante.


Comptabiliser
Alors nous avons donc: quatre routines déjà existantes qui sont à modifier, trois de la même façon (merci copier/coller) avec une variable x qui contient le nombre, et une autre fonction avec beaucoup plus de tests, plus une variable x, qui contient le code.

Pour les trois premières, je n'ai pas besoin de variable, il faut juste faire les tests, mais pour la dernière, il me faut une variable pour la boucle for (y fera l'affaire), et une autre pour le "nouveau" code, je vais prendre z, comme elles sont déjà déclarées et initialisées pour le reste du programme et que l'on peut les modifier sans rien perturber car elles n'ont qu'un rôle temporaire partout, c'est tout bénef (car j'ai un poil dans la main).

Il faut aussi penser à saupoudrer des quelques fonctions alert() pour indiquer le dépassement des limites et autres erreurs, mais je ne vais pas m'embêter à remettre le champ fautif en état et à le resélectionner, j'ai déjà donné dans la validation de formulaire.


Écrire
Quand faut y aller, faut y aller, mais là au moins on commence par du facile, je prends la fonction existante:

function frouge(x) {rr=x.value; dechexa(rr,vv,bb); rouge=rr; refresh();}

et je la modifie comme ça:

function frouge(x)
{
  if (parseInt(x.value)!=x.value) {return false}   // Pas un nombre
  if (x.value<0 || x.value>255)                    // Erreur si hors limites
  {
    alert('Erreur:\n
           Le nombre doit être compris entre 0 (noir) et 255 (rouge maximum)');
    return false;
  }
  rr=x.value;        // Pas de changement
  dechexa(rr,vv,bb); // Pas de changement
  rouge=rr;          // Pas de changement
  refresh();         // Pas de changement
  return true;                                     // OK on l'accepte
}

On modifie fvert et fbleu de la même façon sans oublier de changer les couleurs.

Et on attaque avec fcode qui s'écrivait précédemment:

function fcode(x) {cd=x.value; hexadec(cd); rr=rouge; vv=vert; bb=bleu; refresh();}

et qui devient:

function fcode(x)
{
  if (x.value.charAt(0)!="#")                 // Manque "#" en premier
  {
    alert('Le premier caractère du code doit être: \"#\"');
    return false;
  }
  if (x.value.length!=7)                      // Pas sept caractères
  {
    alert('Erreur:\n
           Le format du code est: \"#rrvvbb\" rr=rouge, vv=vert, bb=bleu.\n
           La valeur est à donner en hexadécimal (00 à FF).');
    return false;
  }
  z='#';                                      // Initialise le nouveau code
  for (y=1;y<7;y++)                           // Boucle de 1 à 6
  {
    if (parseInt(x.value.charAt(y))==x.value.charAt(y))     // Nombre ?
    {
      z=z+x.value.charAt(y);                  // Oui, on concatène au code
    }else                                     // Pas un nombre
    {
      if (x.value.charAt(y)>='A' && x.value.charAt(y)<='F')  // Lettre A à F ?
      {
        z=z+x.value.charAt(y);                // Oui, on concatène au code
      }else                                   // Pas lettre A-F
      {
        if (x.value.charAt(y)>='a' && x.value.charAt(y)<='f')// Lettre a à f ?
        {
          z=z+hexa.charAt(10+"abcdef".indexOf(x.value.charAt(y))); // voir note
        }else                                 // Alors c'est une erreur
        {
          break;                              // Pas la peine de continuer
        }
      }
    }
  }
  if (y<7)                                    // Boucle pas finie ?
  {
    alert('Erreur:\n
           Le format du code est: \"#rrvvbb\" rr=rouge, vv=vert, bb=bleu.\n
           La valeur est à donner en hexadécimal (00 à FF).');
    return false;
  }
  x.value=z;                                  // Nouveau code dans ancien
  cd=x.value;  // Pas de changement
  hexadec(cd); // Pas de changement
  rr=rouge;    // Pas de changement
  vv=vert;     // Pas de changement
  bb=bleu;     // Pas de changement
  refresh();   // Pas de changement
  return true;                                // Fin normale de la routine
}


Note: Comme j'ai utilisé quelques finesses de pro dans cette routine, je me sens obligé de vous donner encore quelques explications.

Les valeurs de la boucle for: on part du deuxième caractère du code avec y=1 (le premier est en position 0) et on boucle TANT QUE l'on a pas atteint la 8ième position avec y<7 (0 à 7 ça fait 8), pour les détails retournez voir les boucles.

On teste d'abord si c'est un nombre, puis si c'est une majuscule, et enfin si c'est une minuscule, et là, problème, la méthode .toUpperCase() me fait un caca nerveux, impossible de l'utiliser sur trois navigateurs différents. Crotte alors, je m'en passe et je fabrique moi même ma propre fonction miracle qui marche comme ça:

On cherche la position du caractère dans la chaîne "abcdef", puis on prends le caractère correspondant dans la chaîne "hexa", comme celle-ci comprend en outre les dix premiers chiffres, il suffit d'ajouter 10 à la position trouvée...

Et enfin l'astuce, en cas d'erreur la méthode habituelle consiste à mettre dans une variable une indication d'erreur que l'on teste plus loin, ici on casse la baraque avec un break qui sert deux buts, premièrement et surtout arrêter la boucle (qui aurait pu être très longue), et deuxièmenent à limiter la valeur de la variable de comptage, en effet, si la boucle se termine, la variable y contient 7, dans le cas d'une erreur et même sur le dernier caractère, cette valeur sera plus petite que 7 et on utilise cette propriété dans la suite du programme.

Il ne faut pas oublier non plus de remettre le nouveau code en place dans la bonne variable et c'est fini.


Tester
Contrairement à ce que j'ai dit dans la page précédente vous pouvez tester ces routines en essayant de dépasser les valeurs limites ou en mettant n'importe quoi dans les cases, j'ai rajouté ces routines dans la page.

Debuger (ou corriger)
Comme je n'ai eu aucune demande à ce sujet, les personnes qui sont arrivées jusque ici ayant certainement un QI important, je ne donnerais pas d'exemple de debuging.

Bel effort
Si vous êtes venu dans cette page sans avoir essayé de faire l'exercice, je ne vous félicite pas, par contre une tentative, même ratée (surtout pour le code), c'est un bel effort, bravo, et si par miracle vous l'avez réussie (si, c'est possible quand on à déjà programmé dans d'autres langages), vous êtes fin prêt pour la suite, sinon ne désespérez pas, ça viendra avec encore un peu de pratique.

Quand à ceux qui ne sont même pas venus ici, pas la peine que je les engueule, ils ne le sauront de toutes façons pas (regardez le compteur et soyez fier, il n'y a pas beaucoup de courageux comme vous)...




Utilisez le bouton de retour de votre navigateur SVP.
Dernière mise à jour de cette page: 04/09/2001, visiteurs: depuis le 6 avril 2002