---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
kernelspec:
  display_name: Python 3 (ipykernel)
  language: python
  name: python3
learning:
  objectives:
    understand: [boucle for, compteur, accumulateur, initialisation, "incr\xE9mentation",
      retour]
    apply: [boucle for, compteur, accumulateur, fonction, affectation, expression,
      "param\xE8tre"]
  prerequisites:
    apply: [expression, affectation, print, boucle for]
---

+++ {"nbgrader": {"grade": false, "grade_id": "cell-6b385bea40435793", "locked": true, "schema_version": 3, "solution": false}}

# Compteurs et accumulateurs

+++ {"nbgrader": {"grade": false, "grade_id": "cell-c245b204365d1c55", "locked": true, "schema_version": 3, "solution": false, "task": false}}

On souhaite calculer la factorielle de $7$ : $7!=1 \cdot 2 \cdot 3 \cdots 7$

Cela peut s'écrire de la façon suivante :

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-251754e333e9c277
  locked: true
  schema_version: 3
  solution: false
  task: false
---
résultat = 1

résultat = résultat * 2
résultat = résultat * 3
résultat = résultat * 4
résultat = résultat * 5
résultat = résultat * 6
résultat = résultat * 7

résultat
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-c501f2a945f48f7f", "locked": true, "schema_version": 3, "solution": false, "task": false}}

La variable `résultat` sert d'accumulateur : on y accumule les entiers $1, 2, 3, ...$ par
produit et elle vaut successivement :

- $1$
- $1\cdot2$
- $1\cdot2\cdot3$
- ...
- $1\cdot2\cdot3\cdot4\cdot5\cdot6\cdot7$

+++ {"nbgrader": {"grade": false, "grade_id": "cell-6580f55c39ba3632", "locked": true, "schema_version": 3, "solution": false, "task": false}}

**Problèmes :**

- Ce code [sent mauvais](https://fr.wikipedia.org/wiki/Code_smell) : il y a beaucoup de
  répétitions!

- Et si on veut calculer $10!$ ou $100!$ ?

+++ {"nbgrader": {"grade": false, "grade_id": "cell-4c91d5ac951a67a4", "locked": true, "schema_version": 3, "solution": false, "task": false}}

Des instructions répétées ? Cela suggère une boucle. On compte de 1 à 7 ? C'est une
mission pour la boucle `for`!

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-88cbdfc007705f0d
  locked: true
  schema_version: 3
  solution: false
  task: false
---
n = 10
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-4cdf95f28a68f2cd
  locked: true
  schema_version: 3
  solution: false
  task: false
---
résultat = 1;
for i in range(2, n+1):
    résultat = résultat * i

résultat
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-339a4551984debfa", "locked": true, "schema_version": 3, "solution": false, "task": false}}

Nous avons donc vu deux techniques classiques de boucles :

- L'utilisation d'un {definiendum}`compteur` : `i` qui parcours les valeurs de ... à ...
  par pas de ...

- L'utilisation d'un {definiendum}`accumulateur` : `résultat` qui accumule
  progressivement des valeurs par produit, somme, ...

+++ {"nbgrader": {"grade": false, "grade_id": "cell-780b0efc6101c8d0", "locked": true, "schema_version": 3, "solution": false, "task": false}}

## Exercices

+++ {"nbgrader": {"grade": false, "grade_id": "cell-560788172824cc61", "locked": true, "schema_version": 3, "solution": false, "task": false}}

- Observez les deux cellules suivantes et devinez la valeur finale de la variable `c`;
  puis exécutez les pour vérifier.

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-fda4a5905295a758
  locked: true
  schema_version: 3
  solution: false
  task: false
---
c = 0
for i in range(6):
    c = i + c
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-f75c84eb6d116fc4
  locked: true
  schema_version: 3
  solution: false
  task: false
---
c
```

+++ {"nbgrader": {"schema_version": 3, "solution": true, "grade": true, "locked": false, "task": false, "grade_id": "cell-b87dd082a29be4b9", "points": 0}}

Entre `c` et `i` quelle variable sert de compteur? d'accumulateur?

BEGIN SOLUTION

- `i` sert de compteur
- `c` sert d'accumulateur

END SOLUTION

+++ {"nbgrader": {"grade": false, "grade_id": "cell-742f622bc7056e10", "locked": true, "schema_version": 3, "solution": false, "task": false}}

- Recopiez la boucle ci-dessous puis modifiez la condition d'arrêt pour que la variable
  `c` soit égale à $36$ après l'exécution :

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-9c0385060494fe0c
  locked: false
  schema_version: 3
  solution: true
  task: false
---
c = 0;
### BEGIN SOLUTION
for i in range(9):
### END SOLUTION
    c = c + i
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-27c0da7d14f62d91
  locked: true
  schema_version: 3
  solution: false
  task: false
---
c   # doit valoir 36
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-a92593ec6373f39d", "locked": true, "schema_version": 3, "solution": false, "task": false}}

La cellule suivante contient des tests automatisés ; nous reviendrons dessus plus en
détails par la suite; pour le moment, vous pouvez juste exécuter la cellule et vérifier
qu'il n'y a pas de message d'erreur.

```{code-cell} ipython3
---
nbgrader:
  grade: true
  grade_id: cell-bf26103d9c19d6f5
  locked: true
  points: 1
  schema_version: 3
  solution: false
  task: false
---
assert( c == 36 )
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-4e242b4c7dd64021", "locked": true, "schema_version": 3, "solution": false, "task": false}}

- En vous inspirant des exemples ci-dessus, écrivez ci-dessous un programme qui calcule
  la valeur de la somme des entiers de 1 à n : 1 + 2 + ... + n, en utilisant une variable
  `s` comme accumulateur :

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-b3947d8539dfc764
  locked: true
  schema_version: 3
  solution: false
  task: false
---
n = 5
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-c0739002bc408396
  locked: false
  schema_version: 3
  solution: true
  task: false
---
### BEGIN SOLUTION
s = 0
for i in range(n+1):
    s = s + i;
### END SOLUTION
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-a7fa6c68f7a8f078
  locked: true
  schema_version: 3
  solution: false
  task: false
---
s # 15 pour n = 5
```

```{code-cell} ipython3
---
nbgrader:
  grade: true
  grade_id: cell-70156efdecd752af
  locked: true
  points: 2
  schema_version: 3
  solution: false
  task: false
---
assert( s == 15 )
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-262927f9eba5a9ae", "locked": true, "schema_version": 3, "solution": false, "task": false}}

- Reprendre votre programme pour le mettre sous la forme d'une *fonction* qui calcule la
  somme des entiers de 1 à $n$ :

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-59d27e7e46c6be00
  locked: false
  schema_version: 3
  solution: true
---
def somme(n):
    ### BEGIN SOLUTION
    s = 0
    for i in range(n+1):
        s = s + i;
    ### END SOLUTION
    return s
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-bbc3a5eababe0ebd", "locked": true, "schema_version": 3, "solution": false, "task": false}}

L'appel suivant à votre fonction devrait renvoyer 120 :

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-20fcc91fff7098df
  locked: true
  schema_version: 3
  solution: false
  task: false
---
somme(5)
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-57835c5482344135", "locked": true, "schema_version": 3, "solution": false, "task": false}}

Vérifiez votre fonction grâce aux tests suivants (ils doivent tous afficher `true`) :

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-e8bde338e8e91293
  locked: true
  schema_version: 3
  solution: false
  task: false
---
somme(5) == 15
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-0f480f455c001cb4
  locked: true
  schema_version: 3
  solution: false
  task: false
---
somme(63) == 2016
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-c0e7b253d4de674e
  locked: true
  schema_version: 3
  solution: false
  task: false
---
somme(100) == 5050
```

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-1ee3df1dc7a458a7
  locked: true
  schema_version: 3
  solution: false
  task: false
---
somme(1) == 1
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-a49ebc122273ee08", "locked": true, "schema_version": 3, "solution": false, "task": false}}

Tests automatisés :

```{code-cell} ipython3
---
nbgrader:
  grade: true
  grade_id: cell-a5be78a5a5a25142
  locked: true
  points: 2
  schema_version: 3
  solution: false
  task: false
---
assert( somme(0) ==   0 )
assert( somme(1) ==   1 )
assert( somme(2) ==   3 )
assert( somme(3) ==   6 )
assert( somme(4) ==  10 )
assert( somme(5) == 15 )
### BEGIN HIDDEN TESTS
assert( somme(100) == 5050)
### END HIDDEN TESTS
```

+++ {"nbgrader": {"grade": false, "grade_id": "cell-5ad82ee0d38b1f83", "locked": true, "schema_version": 3, "solution": false, "task": false}}

### Exercices supplémentaires

+++ {"nbgrader": {"grade": false, "grade_id": "cell-da67b1b12f55eda6", "locked": true, "schema_version": 3, "solution": false, "task": false}}

Pour vous entraîner aux boucles `for`, aux compteurs et aux accumulateurs, sélectionnez
le thème "07 - Boucles For".

```{code-cell} ipython3
---
nbgrader:
  grade: false
  grade_id: cell-7fd920957613c7d3
  locked: true
  schema_version: 3
  solution: false
  task: false
tags: [skip-execution]
---
import sys
sys.path.append('..')
from Exercices.entraîneur import entraîneur
entraîneur
```
