<commit_before>.. author::
   <NAME> et <NAME>

La boucle for
=============

Présentation
------------

Jusqu'à présent, nous avons vu la boucle ``while`` (et sa congénère la boucle ``do...while``). Celle-ci permet de réaliser toutes les boucles existantes en pratique, et on pourrait s'en contenter pour la suite. Néanmoins, il existe un autre type principal de boucle, qui est bien plus utilisé en pratique : la boucle ``for``.

Vous l'avez sans doute remarqué, en Java, on doit souvent écrire des boucles dans lesquelles on déclare une ou plusieurs variables avant la boucle, que l'on incrémente ensuite dans la boucle, et dont on vérifie la valeur dans la condition de la boucle. Par exemple,

.. code-block:: Java

        int i = 0;
        while (i <= 5) {
                System.out.println("Coucou " + i + " fois.");
                i = i + 1;
        }

ou encore

.. code-block:: Java

        int i = 10;
        System.out.print("Décollage dans ");
        while (i >= 1) {
                System.out.print(i + " ");
                i = i - 1;
        }
        System.out.println();
        System.out.println("Décollage !");

ou encore

.. code-block:: Java

        System.out.println("Combien de tasse de café me faut-il ?");
        int i = 1;
        while (i < 10) {
                System.out.println(i + " tasses de caffé ?");
                i = i + 1;
        }
        System.out.println("Pfiou, ça fait beaucoup");

Toutes ces boucles comprennent des caractéristiques communes :

* la déclaration et/ou l'initialisation d'une variable avant d'entrer dans la boucle (par exemple, la variable ``i`` dans chacun des exemples ci-dessus) ;
* la condition de boucle utilisant cette variable pour déterminer s'il faut sortir de la boucle ou non, généralement par une comparaison ;
* un certain nombre d'instructions manipulant la variable (par exemple, les différents affichages avec ``System.out.println``) ;
* le changement de la valeur de la variable à la fin de ces instructions, généralement par un incrémentation ou une décrémentation.

Ce type de boucles est tellement fréquente en pratique (elle est omniprésente dans les tableaux par exemple) que les concepteurs du langage ont créé une structure condensée, la boucle for :

.. code-block:: Java

        for (<déclarations et initialisation>; <condition>; <incrémentations>) {
                <code>
        }

Détaillons la manière dont fonctionne cette boucle :

* La boucle commence par effectuer tout ce qui se trouve dans la section ``<déclaration et initialisation>`` : il s'agit d'une seule instruction, qui est généralement une déclaration et/ou initialisation d'une ou plusieurs variables de même type. Cette instruction n'est exécutée qu'une seule fois, avant le début de la boucle proprement dite.
* Ensuite, à chaque tour de boucle :

  * elle vérifie la condition de la section ``<condition>`` : si elle est vérifiée, les instructions suivantes sont exécutées ; sinon, le programme sort de la boucle
  * elle exécute le ou les instruction(s) contenues dans la section ``<code>``.
  * elle exécute enfin le ou les instructions contenues dans la section ``<incrémentation>`` : ces instructions sont généralement une incrémentation ou une décrémentation d'une variable, mais il est possible de mettre plusieurs incrémentations ou décrémentations, ou de mettre des instructions plus complexes (comme des appels de fonctions).

Comme exemples, réécrivons les exemples ci-dessus à l'aide d'une boucle ``for`` :

.. code-block:: Java

        for (int i = 0; i <= 5; i = i + 1) {
                System.out.println("Coucou " + i + " fois.");
        }

.. code-block:: Java

        System.out.print("Décollage dans ");

        for (int i = 10; i >= 1; i = i - 1) {
                System.out.print(i + " ");
        }

        System.out.println();
        System.out.println("Décollage !");

.. code-block:: Java

        System.out.println("Combien de tasse de café me faut-il ?");

        for (int i = 1; i < 10; i = i + 1) {
                System.out.println(i + " tasses de café ?");
        }

        System.out.println("Pfiou, ça fait beaucoup");

.. tache INGInious : quelle est l'avant-dernière ligne affichée par le programme ?

Pour vérifier que vous ayez bien compris, quelle est l'avant-ernière ligne affichée par le programme ci-dessus ?

.. class:: positive

   - "9 tasses de café ?"

.. class:: negative

   - "10 tasses de café ?"

   - "8 tasses de café ?"

           .. class:: comment-feedback

              Est-ce que vous avez compté la ligne de code en dehors de la boucle à la fin ?

Comme vous pouvez le constater, ces boucles sont plus court que les boucles écrites avec un ``while``, et souvent plus lisibles quand on a l'habitude de s'en servir : l'initialisation de la variable de boucle, son incrémentation, et la condition de la boucle sont situées au même endroit, entre les parenthèses du ``for``, au lieu d'être situés à plusieurs endroits de la boucle ; c'est du condensé, en quelque sorte.

Quelques exemples
-----------------

Voyons quelques exemples de boucles construites avec la boucle ``for``.

Afficher l'alphabet
'''''''''''''''''''

Le code suivant affiche l'alphabet, de la lettre ``'A'`` à la lettre ``'Z'``.

.. code-block:: Java

        for (char ch = 'A'; ch <= 'Z'; ch = ch + 1) {
                System.out.println(ch);
        }

Déterminer si un nombre est premier
'''''''''''''''''''''''''''''''''''

Un nombre entier est qualifié de *premier* s'il ne possède que deux diviseurs entiers différents : 1 et lui-même. Les nombres premiers sont 2, 3, 5, 7, 11, 13, et une infinité d'autres. Pour vérifier qu'un nombre est premier, il suffit de compter son nombre de diviseurs, et de comparer à 2. Le programme suivant permet de vérifier si un nombre est premier

.. code-block:: Java

        int nombre = 34;
        int nbreDiviseurs = 0;
        for (int diviseurTest = 1; diviseurTest <= nombre; diviseurTest = diviseurTest + 1) {
                if (nombre % diviseurTest == 0) // si le nombre diviseurTest divise notre nombre
                {
                        nbreDiviseurs = nbreDiviseurs + 1;
                }
        }
        if (nbreDiviseurs == 2) {
                System.out.println("Le nombre " + nombre + " est premier.");
        } else {
                System.out.println("Le nombre " + nombre + " n'est pas premier.");
        }

Exercice : nombres parfaits
...........................

A vous ! Pour votre première boucle ``for``, vous allez écrire un petit programme qui détermine si un nombre est parfait. Un *nombre parfait* est un nombre naturel dont la somme des `diviseurs stricts`_ est égale au nombre lui-même. Le nombre naturel à vérifier est stocké dans la variable ``n``. Le résultat final, un booléen indiquant si le nombre ``n`` est parfait,  doit être stocké dans la variable ``isPerfect`` à la fin de l'exécution de votre boucle. Pour vous aider, le code permettant de vérifier si un nombre est premier est déjà pré-rempli, à l'exception des paramètres de la boucle ``for``. Faites bien attention à la valeur initiale et finale de la variable de boucle !

.. _diviseurs stricts: https://fr.wikipedia.org/wiki/Diviseur_strict

.. inginious:: syllabus-boucles-for-Q1-nbrepft

        int n = 34;
        int nbreDiviseurs = 0;
        for (/*à compléter*/) {
                if (n % /*une variable*/ == 0)
                {
                        nbreDiviseurs = nbreDiviseurs + 1;
                }
        }<commit_msg>Another minor correction<commit_after>.. author::
   <NAME> et <NAME>

La boucle for
=============

Présentation
------------

Jusqu'à présent, nous avons vu la boucle ``while`` (et sa congénère la boucle ``do...while``). Celle-ci permet de réaliser toutes les boucles existantes en pratique, et on pourrait s'en contenter pour la suite. Néanmoins, il existe un autre type principal de boucle, qui est bien plus utilisé en pratique : la boucle ``for``.

Vous l'avez sans doute remarqué, en Java, on doit souvent écrire des boucles dans lesquelles on déclare une ou plusieurs variables avant la boucle, que l'on incrémente ensuite dans la boucle, et dont on vérifie la valeur dans la condition de la boucle. Par exemple,

.. code-block:: Java

        int i = 0;
        while (i <= 5) {
                System.out.println("Coucou " + i + " fois.");
                i = i + 1;
        }

ou encore

.. code-block:: Java

        int i = 10;
        System.out.print("Décollage dans ");
        while (i >= 1) {
                System.out.print(i + " ");
                i = i - 1;
        }
        System.out.println();
        System.out.println("Décollage !");

ou encore

.. code-block:: Java

        System.out.println("Combien de tasse de café me faut-il ?");
        int i = 1;
        while (i < 10) {
                System.out.println(i + " tasses de caffé ?");
                i = i + 1;
        }
        System.out.println("Pfiou, ça fait beaucoup");

Toutes ces boucles comprennent des caractéristiques communes :

* la déclaration et/ou l'initialisation d'une variable avant d'entrer dans la boucle (par exemple, la variable ``i`` dans chacun des exemples ci-dessus) ;
* la condition de boucle utilisant cette variable pour déterminer s'il faut sortir de la boucle ou non, généralement par une comparaison ;
* un certain nombre d'instructions manipulant la variable (par exemple, les différents affichages avec ``System.out.println``) ;
* le changement de la valeur de la variable à la fin de ces instructions, généralement par un incrémentation ou une décrémentation.

Ce type de boucles est tellement fréquente en pratique (elle est omniprésente dans les tableaux par exemple) que les concepteurs du langage ont créé une structure condensée, la boucle for :

.. code-block:: Java

        for (<déclarations et initialisation>; <condition>; <incrémentations>) {
                <code>
        }

Détaillons la manière dont fonctionne cette boucle :

* La boucle commence par effectuer tout ce qui se trouve dans la section ``<déclaration et initialisation>`` : il s'agit d'une seule instruction, qui est généralement une déclaration et/ou initialisation d'une ou plusieurs variables de même type. Cette instruction n'est exécutée qu'une seule fois, avant le début de la boucle proprement dite.
* Ensuite, à chaque tour de boucle :

  * elle vérifie la condition de la section ``<condition>`` : si elle est vérifiée, les instructions suivantes sont exécutées ; sinon, le programme sort de la boucle
  * elle exécute le ou les instruction(s) contenues dans la section ``<code>``.
  * elle exécute enfin le ou les instructions contenues dans la section ``<incrémentation>`` : ces instructions sont généralement une incrémentation ou une décrémentation d'une variable, mais il est possible de mettre plusieurs incrémentations ou décrémentations, ou de mettre des instructions plus complexes (comme des appels de fonctions).

Comme exemples, réécrivons les exemples ci-dessus à l'aide d'une boucle ``for`` :

.. code-block:: Java

        for (int i = 0; i <= 5; i = i + 1) {
                System.out.println("Coucou " + i + " fois.");
        }

.. code-block:: Java

        System.out.print("Décollage dans ");

        for (int i = 10; i >= 1; i = i - 1) {
                System.out.print(i + " ");
        }

        System.out.println();
        System.out.println("Décollage !");

.. code-block:: Java

        System.out.println("Combien de tasse de café me faut-il ?");

        for (int i = 1; i < 10; i = i + 1) {
                System.out.println(i + " tasses de café ?");
        }

        System.out.println("Pfiou, ça fait beaucoup");

.. tache INGInious : quelle est l'avant-dernière ligne affichée par le programme ?

Pour vérifier que vous ayez bien compris, quelle est l'avant-ernière ligne affichée par le programme ci-dessus ?

.. class:: positive

   - "9 tasses de café ?"

.. class:: negative

   - "10 tasses de café ?"

   - "8 tasses de café ?"

           .. class:: comment-feedback

              Est-ce que vous avez compté la ligne de code en dehors de la boucle à la fin ?

Comme vous pouvez le constater, ces boucles sont plus court que les boucles écrites avec un ``while``, et souvent plus lisibles quand on a l'habitude de s'en servir : l'initialisation de la variable de boucle, son incrémentation, et la condition de la boucle sont situées au même endroit, entre les parenthèses du ``for``, au lieu d'être situés à plusieurs endroits de la boucle ; c'est du condensé, en quelque sorte.

Quelques exemples
-----------------

Voyons quelques exemples de boucles construites avec la boucle ``for``.

Afficher l'alphabet
'''''''''''''''''''

Le code suivant affiche l'alphabet, de la lettre ``'A'`` à la lettre ``'Z'``.

.. code-block:: Java

        for (char ch = 'A'; ch <= 'Z'; ch = ch + 1) {
                System.out.println(ch);
        }

Déterminer si un nombre est premier
'''''''''''''''''''''''''''''''''''

Un nombre entier est qualifié de *premier* s'il ne possède que deux diviseurs entiers différents : 1 et lui-même. Les nombres premiers sont 2, 3, 5, 7, 11, 13, et une infinité d'autres. Pour vérifier qu'un nombre est premier, il suffit de compter son nombre de diviseurs, et de comparer à 2. Le programme suivant permet de vérifier si un nombre est premier

.. code-block:: Java

        int nombre = 34;
        int nbreDiviseurs = 0;
        for (int diviseurTest = 1; diviseurTest <= nombre; diviseurTest = diviseurTest + 1) {
                if (nombre % diviseurTest == 0) // si le nombre diviseurTest divise notre nombre
                {
                        nbreDiviseurs = nbreDiviseurs + 1;
                }
        }
        if (nbreDiviseurs == 2) {
                System.out.println("Le nombre " + nombre + " est premier.");
        } else {
                System.out.println("Le nombre " + nombre + " n'est pas premier.");
        }

Exercice : nombres parfaits
...........................

A vous ! Pour votre première boucle ``for``, vous allez écrire un petit programme qui détermine si un nombre est parfait. Un *nombre parfait* est un nombre naturel dont la somme des `diviseurs stricts`_ est égale au nombre lui-même. Le nombre naturel à vérifier est stocké dans la variable ``n``. Le résultat final, un booléen indiquant si le nombre ``n`` est parfait,  doit être stocké dans la variable ``isPerfect`` à la fin de l'exécution de votre boucle. Pour vous aider, le code permettant de vérifier si un nombre est premier est déjà pré-rempli, à l'exception des paramètres de la boucle ``for``. Faites bien attention à la valeur initiale et finale de la variable de boucle !

.. _diviseurs stricts: https://fr.wikipedia.org/wiki/Diviseur_strict

.. inginious:: syllabus-boucles-for-Q1-nbrepft

        // int n = 34; Le nombre naturel à vérifier
        int nbreDiviseurs = 0;
        for (/*à compléter*/) {
                if (n % /*une variable*/ == 0)
                {
                        nbreDiviseurs = nbreDiviseurs + 1;
                }
        }
{'fraction_non_alphanumeric': 0.10555666201951802, 'fraction_numerical': 0.006771559450308703, 'mean_word_length': 2.651878787878788, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 27, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5885424', 'n_tokens_mistral': 4763, 'n_tokens_neox': 4630, 'n_words': 1845}