Blog Emmanuel Orchanian

astuce bdd bureautique codage culture débat design énigme français hacking html mathématiques méthodologie santé typographie 

 

 [190 vues] 2022-03-29 Emmanuel Orchanian

NOTE : cet article a été affiché dans sa langue originale.

Pour les gens qui ne savent pas ce que c'est

Mon petit schéma pour vos beaux yeux

comment fonctionne une boucle for
Mon schéma de l'appareil digestif d'une boucle "for"

Bon je ne sais pas si mon schéma (pourri) a aidé...
mais si je l'explique avec des mots je ne sais pas si ça va arranger la chose...

Explications textuelle

Une boucle for commence par le mot-clé "for", des parenthèses et des accolades


    for(trois options){
        //instructions à faire en boucle
    }
  1. Dans les parenthèses () nous mettrons les trois "options" de la boucle
  2. Dans les accolades {} nous mettrons les instructions à effectuer en boucle

Comment configurer les options d'une boucle for ?

  • Les 3 options sont écrites dans la paire de parenthèses () après le mot-clé "for"
  • Les 3 options sont séparées par des points-virgule ;
    for (    l'option 1    ;    l'option 2    ;    l'option 3    ) {

    }

Bref, quand on voit un point-virgule ; on sait qu'on passe à l'option suivante

Zoom sur les 3 options

L'option 1

La première option survient qu'une seule fois, avant d'entrer dans la boucle. C'est comme si on avait écrit une ligne avant le for c'est pareil.

    for ( aaaaaaaaaa ;    ;    ) {
        // instructions en boucle
    }

    équivaut à :

    aaaaaaaaaa
    for (    ;    ;    ) {
        // instructions en boucle
    }

L'option 2

C'est la condition pour laquelle on a le droit de faire ou de refaire une boucle.

Personnellement, je me dis que c'est comme c'est équivalent aux parenthèses d'un if

En d'autres terme, c'est une question : j'ai le droit d'entrer dans la boucle ?

    for (     ; bbbbbbbbbb ;    ) {
        // instructions en boucle
    }

    équivaut à :


    if ( bbbbbbbbbb ) {
        // instructions
    }

L'option 3

C'est ce qu'il se passe à chaque fin de boucle réalisée

On peux se dire que c'est ce qui arrive quand on touche l'accolade de fin

    for (     ;     ; cccccccccc ) {
        // instructions en boucle
    }

    équivaut à :

    for (    ;    ;    ) {
        // instructions en boucle
        cccccccccc 
        }
    

Cas école

Ainsi, si je veux faire une boucle qui survient 100 fois, je peux placer un compteur qui commence à 1 et s'arrête à 100, si on dépasse 100, on n'a plus le droit d'entrer dans la boucle, elle est finie.


    for(    $i=1   ;      $i <= 100      ;    $i++     ){
        //instructions à faire en boucle
    }
  1. Je crée $i qui est égal à 0
  2. Est-ce que $i est inférieur ou égal à 100 ? (donc ça saute quand ça touche 101)
  3. $i++ signifie que j'augmente $i de 1 à la fin de la boucle
comment fonctionne une boucle for
Boucle "for"

Optimisation de la boucle for

Ne pas faire plusieurs fois ce qui ne doit arriver qu'une seule fois

Petite histoire

Imaginez vous avez 1548 personnes dans une pièce, vous ne le savez pas, votre patron vous demande de compter le nombre de personne qu'il y a. Vous les comptez, puis votre patron vous redemande de compter alors que le nombre de personne n'a pas changé. C'est bête non ? Imaginez à présent le cas extrême où votre patron vous demande 1548 fois de compter de nouveau ! C'est ce que font la majorité des gens avec les boucle for...

Au lieu de compter 1548 personnes, vous avez comptés 1548 x 1548 = plus de 2 millions de fois...

Cas pratique


    // CODE MÉCHANT 😡
    $liste = ['Matthieu','Marc', etc...] ; // contient 1548 personnes


    for(    $i = 0     ;     $i < compter_longueur($liste)     ;    $i++    ){
        //instructions à faire en boucle
    }

Où est le problème ?

Le problème viens que l'option 2, la condition pour (re)faire une boucle est vérifié à chaque tour de boucle, alors que le nombre de personnes dans la liste ne change pas. Il faut alors faire de telle sorte à ne compter ça qu'une seule fois pour toute et l'enregistrer dans une variable.

Personnellement j'aime appeler ce maximum "imax", en plus ça rappelle le cinéma !


    // CODE GENTIL 🌹🌺🌹🌺🌹🌺🌹🌺
    $liste = ['Matthieu','Marc', etc...] ; // contient 1548 personnes

    $imax = compter_longueur($liste) ;

    for(    $i = 0     ;     $i < $imax     ;    $i++    ){
        //instructions à faire en boucle
    }

Plusieurs instructions par option

En JavaScript et PHP, on a l'habitude de séparer les instructions par des points-virgule ;

Mais pour les 3 options d'une boucle for, vous avez deviné le problème, le signe ; sert déjà à séparer les options, alors comment séparer les instructions ?

Une solution consiste à mettre... *roulement de tambour* une virgule... La virgule sert à séparer différents instructions dans une seule option de boucle for

Pourquoi je vous raconte ça ? Pour éviter d'écrire imax une ligne au dessus du for et utiliser la raison d'être de l'option 1.

Code en JavaScript

En javascipt, comme indiqué dans la documentation, pour déclarer plusieurs variables via des let il ne faut pas écrire deux fois let
let i=0 , let imax=100
mais let i=0, imax=100
les deux variables seront des let.


        let liste = ['Matthieu','Marc', etc...] ; // contient 1548 personnes

        for(    let i = 0  , imax = liste.length       ;    i < imax    ;   i++  ){
            //instructions à faire en boucle
        }
    
        let liste = ['Matthieu','Marc', etc...] ; // contient 1548 personnes

        for(    let i = 0  , imax = liste.length       ;    i < imax    ;   i++  ){
            //instructions à faire en boucle
        }
    

Code en PHP


        $liste = ['Matthieu','Marc', etc...] ; // contient 1548 personnes

        for(    $i = 0  ,  $imax = count($liste)       ;    $i < $imax    ;   ++$i  ){
            //instructions à faire en boucle
        }
    
        $liste = ['Matthieu','Marc', etc...] ; // contient 1548 personnes

        for(    $i = 0  ,  $imax = count($liste)       ;    $i < $imax    ;   ++$i  ){
            //instructions à faire en boucle
        }
    

Remarquez en PHP, il vaut mieux écrire ++$i que $i++ car celui-ci est 1/10ème de fois plus rapide.

Arrêtez le travail une fois que vous avez fini ! (faites un break)

Voici une métaphore : on vous donne un tas avec 1000 papiers, on vous demande d'en chercher un. C'est nul à faire. Une fois que vous avez trouvé ce que cherchiez, est-ce que vous continuez à chercher dans le reste des papiers ? Bien sûr que non ! Et pourtant c'est ce qui est gaspillé quand on cherche quelque chose via une boucle et qu'on ne l'arrête pas quand on a trouvé... faites un break


    foreach ($arr_user as $value) {
        if( trim(mb_strtolower(LOGIN)) == trim(mb_strtolower($value['pseudonyme'])) )  {
            $bool_err_pseudo_existe_deja = true;
            break;
        }
    }

Ce code vérifie si un pseudonyme n'existe pas déjà, si jamais il trouve dans la liste de tous les pseudonymes, alors il break, c'est-à-dire qu'il sort de la boucle.
Si on n'avais pas mis le break cela impliquerai qu'on continuerai à faire tourner la boucle jusqu'à la fin de la liste des pseudonymes. (Note : ce code est inutile si on utilise SQL)

Ce qui peux être fait une fois doit être passé en variable avant la boucle

Je me répète peut-être (pas grave, c'est un tuto sur les boucles 🙃), si on prend le code précédent, la constante LOGIN est nettoyée avec deux fonctions, or ça on aurait pu le faire avant la boucle, en l'insérant dans la variable $login_tmp


    $login_tmp = trim(mb_strtolower(LOGIN));

    foreach ($arr_user as $value) {
        if( $login_tmp == trim(mb_strtolower($value['pseudonyme'])) )  {
            $bool_err_pseudo_existe_deja = true;
            break;
        }
    }
    $login_tmp = trim(mb_strtolower(LOGIN));

    foreach ($arr_user as $value) {
        if( $login_tmp == trim(mb_strtolower($value['pseudonyme'])) )  {
            $bool_err_pseudo_existe_deja = true;
            break;
        }
    }

Au final, tout ça, on s'en fiche...

En effet, ce qui ralentit considérablement le code ce sont les images non-compressées, l'utilisation non-optimisée de grandes base de données et l'importation de bibliothèques en général.

Les optimisations vues dans cette page font plus partie de l'élégance du code selon-moi, dans le sens où on comprends ce qu'il se passe derrière ce qu'on écrit.

Merci d'avoir lu !
Si en général vous avez une question, une curiosité, n'hésitez pas me contacter.