# Résolution de problèmes, fonctions et traitements conditionnels

## But

* Papier crayon à l'honneur pour la résolution de problèmes.
* Représentation de la solution avec pseudo-codes et organigrammes.
* Retour sur les fonctions.
* Traitements conditionnels (if/elif/else).

## Énoncé

On essaie de déterminer la catégorie d’une personne et ce que cette personne peut faire dans la société en raison de son âge selon certains critères.

Les critères sont :

* Droit de vote : avoir au moins 18 ans
* Être à l’école : avoir entre 5 et moins de 50 ans
* Pouvoir conduire : avoir 16 ans et plus
* Avoir un prix spécial pour la STO: avoir moins de 18 ans ou 65 ans et plus
* Avoir sa carte de l’âge d’or: avoir 50 ans ou plus
* Notez qu’il est possible d’avoir une fraction d’âge, c’est-à-dire 13.5 ans!

On considère qu’une personne est un ou une :

* adulte, si son âge dépasse 18 ans,
* adolescent.e, si son âge se situe entre 12 et 18 ans et
* enfant, si son âge ne dépasse pas 11 ans.

Votre programme doit donner la possibilité à l’utilisateur d’entrer le nom, le prénom et l'année de naissance d’une personne et, ensuite, de pouvoir afficher, selon son choix, l’âge et la catégorie de cette personne, ce qu’il peut faire en société, ou les deux (3 choix).

Un affichage propre et aligné sera important pour bien voir les réponses.

Voir [l'annexe ](#annexe)pour un aperçu du résultat d'exécution d'un tel programme.

***

## Résolution

Avant de commencer à écrire un code source, il est primordial de réfléchir et de concevoir une solution par écrit, via des diagrammes (organigramme) ou un pseudo-code.

[Notes de cours sur la résolution de problèmes](https://cours-5.gitbook.io/dalicia-420-1g2-hu-logique-de-programmation/etapes-danalyse-et-de-resolution-de-problemes)  (ne faites pas l’exercice qui est dans ces notes de cours).

* Découpage du problème en sous-problèmes -> Identification des fonctions
  * **Question à se poser :** Quelles sont les parties distinctes du problème qu'on peut traiter, chacune, indépendamment des autres parties ?
  * Chacune des parties correspond à une fonction.
* Quelles sont les entrées sorties pour chaque sous-problème?
* La résolution de chaque sous-problème se fait dans les étapes suivantes.

<details>

<summary><mark style="color:red;">Solution : Découpage en sous-problèmes (fonctions) et entrées sorties</mark></summary>

**Question à se poser :** Quelles sont les parties distinctes du problème qu'on peut traiter, chacune, indépendamment des autres parties ?

* <mark style="color:green;">**Fonctions :**</mark>&#x20;
  * <mark style="color:purple;">Calculer l'âge d'une personne.</mark>
  * <mark style="color:purple;">Trouver la catégorie d'une personne selon son âge.</mark>
  * <mark style="color:purple;">Afficher les droits et privilèges d'une personne selon son âge.</mark>
* <mark style="color:green;">**Programme principal :**</mark>&#x20;
  * <mark style="color:purple;">Lire les entrées de l'utilisateur</mark>
  * <mark style="color:purple;">Traiter les choix.</mark>
  * <mark style="color:purple;">Afficher les résultats selon le choix.</mark>&#x20;

Quelles sont les entrées (paramètres) sorties (valeurs de retours) pour chaque sous-problème?

* <mark style="color:green;">**Calculer l'âge d'une personne :**</mark>&#x20;

  <mark style="color:green;">**Paramètre**</mark> <mark style="color:green;"></mark><mark style="color:green;">:</mark> <mark style="color:purple;">année de naissance.</mark>

  <mark style="color:green;">**Valeur de retour**</mark> <mark style="color:green;"></mark><mark style="color:green;">:</mark> <mark style="color:purple;">âge</mark> <mark style="color:green;">.</mark>

- <mark style="color:green;">**Trouver la catégorie d'une personne selon son âge :**</mark>&#x20;

  <mark style="color:green;">**Paramètre :**</mark> <mark style="color:purple;">âge</mark><mark style="color:green;">.</mark>

  <mark style="color:green;">**Valeur de retour :**</mark> <mark style="color:purple;">catégorie</mark><mark style="color:green;">.</mark>

* <mark style="color:green;">**Afficher les droits et privilèges d'une personne selon son âge :**</mark>&#x20;

  <mark style="color:green;">**Paramètre :**</mark> <mark style="color:purple;">âge</mark><mark style="color:green;">.</mark>

  <mark style="color:green;">**Valeur de retour :**</mark> <mark style="color:purple;">aucun</mark><mark style="color:green;">, la fonction doit afficher elle même les droits et privilèges.</mark>

</details>

***

Une solution **incomplète** d’un sous-problème vous a été fournie à travers un organigramme et un pseudo-code ainsi qu’un programme en python. Voir les notes de cours pour plus de détails sur les méthodes de [présentation d’une solution](https://cours-5.gitbook.io/dalicia-420-1g2-hu-logique-de-programmation/etapes-danalyse-et-de-resolution-de-problemes#presentation-de-la-solution).

<figure><img src="https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2F9YUbHW1ZjcVmr8PpXTmr%2Fimage.png?alt=media&#x26;token=91d381a8-7f01-4f12-b547-3ce8db18e775" alt="" width="375"><figcaption><p>Organigramme pour trouver la catégorie d'une personne selon son âge</p></figcaption></figure>

<pre class="language-python" data-title="Pseudo code pour la fonction qui permet de trouver la catégorie d&#x27;une personne selon l&#x27;âge." data-line-numbers><code class="lang-python"># ************************** Entrées/sorties ****************************
<strong># Entrées (paramètres) : age
</strong># Sorties (retour) : Une chaîne de caractères indiquant la catégorie d'âge de la
#           personne "adulte" ou "adolescent"
# ************************** Début pseudo-code **************************
# Début : fonction qui détermine la catégorie
#     Si l'age est > 18 alors 
#        categorie = "adulte"
#     Sinon, 
#        categorie = "adolescent"
#     retourner la categorie
# Fin
</code></pre>

<pre class="language-python" data-line-numbers><code class="lang-python">def categorie_age():
    """
    Fonction qui retourne une chaîne de caractères indiquant s'il
    s'agit d'un adulte ou non selon l'âge entré en paramètre.
    :param age: l'age de la personne (entier positif)
    :return: Un string indiquant la catégorie de la personne.
            Valeurs attendues : "Adulte" ou "Enfant ou Adolescent"
    """
    if age > 18:
    categorie = "adulte"
    else:
    categorie = "adolescent"

    return categorie

if __name__ == "__main__":
<strong>nom = input("Entrez un prénom : ")
</strong>    prenom = input("Entrez un nom : ")
</code></pre>

***

## À vos marques ...

1. La fonction `categorie_age` ainsi que le programme principal contiennent des erreurs de syntaxe et d'exécution. Vous devez les corriger afin de faire fonctionner votre programme. Voir les notes de cours sur [les traitements conditionnels](https://cours-5.gitbook.io/dalicia-420-1g2-hu-logique-de-programmation/les-differents-types-de-traitement/structures-logiques-conditionnelles-if-else-elif) au besoin.

<details>

<summary><mark style="color:red;">Solution</mark></summary>

<mark style="color:green;">**Erreurs syntaxiques**</mark> <mark style="color:green;"></mark><mark style="color:green;">:</mark> Il y a des indentations manquantes aux lignes 10, 12 ainsi que la ligne 17.

![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2FDI0FPL781BVM8WXiB8Ks%2Fimage.png?alt=media\&token=92d5ceb3-9460-493c-999b-08d74a350e3b)     ->         ![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2FPI4hRIQs5AAGBY1KJVGi%2Fimage.png?alt=media\&token=b768b7bc-d8e8-4dca-b54a-c77f5617bb84)

<mark style="color:green;">**Erreur d'exécution**</mark>**&#x20;:** l'âge doit être un paramètre (une entrée) de la fonction.&#x20;

**Comment le savoir?**

* Mentionné à l'étape de résolution de problèmes. On doit donner l'âge comme entrée à la fonction pour qu'elle puisse trouver la catégorie.
* Mentionné dans la documentation (docstring) de la fonction.

![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2F7CvNdjzteJSBCtXyI6I6%2Fimage.png?alt=media\&token=f18f399f-6c6b-42b7-b9d8-fe319ca73b01) -> ![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2Fq9dtbHOBXNrFKFxndQ37%2Fimage.png?alt=media\&token=510bb4bf-f0e2-430f-a5e4-472707df0423)

</details>

1. Testez votre fonction avec les âges : 30, 15, 8.  Que constatez-vous?

<details>

<summary><mark style="color:red;">Solution</mark></summary>

* Afin de tester la fonction, nous devons d'abord l'appeler dans le programme principal.&#x20;
* Cette fonction a besoin du paramètre `age` pour fonctionner. On doit donc lui passer les valeurs d'âge 30, 15, 8, un à la fois.
* Étant donné que la fonction retourne une valeur, qui est la catégorie, on doit "l'attraper" dans le programme principal et la mettre dans une variable. Cette variable sera appelée `categorie` .&#x20;

On doit donc exécuter le programme avec les valeurs demandées :&#x20;

```python
categorie = categorie_age(30)
```

```python
categorie = categorie_age(15)
```

```python
categorie = categorie_age(8)
```

<img src="https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2FoweVbv3n3z2wCUGE0rtW%2Fimage.png?alt=media&#x26;token=89637239-952b-403f-989d-42c8ae08864b" alt="" data-size="original">

* <mark style="color:red;">Réponse :</mark> Il y a une **erreur de logique**. Lorsqu'on a **8 ans**, on est **enfant** et non pas **adolescent**.

![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2F1wMJB65VL6Dbx9yN3r29%2Fimage.png?alt=media\&token=f0417d6b-0373-4c7f-b010-0d80ec58ac82)

</details>

<table><thead><tr><th width="96">age</th><th width="163">Résultat attendu</th><th>Résultat observé</th></tr></thead><tbody><tr><td>30</td><td><mark style="color:green;">adulte</mark></td><td><mark style="color:green;">adulte</mark></td></tr><tr><td>15</td><td><mark style="color:green;">adolescent</mark></td><td><mark style="color:green;">adolescent</mark></td></tr><tr><td><mark style="color:red;">8</mark></td><td><mark style="color:green;">enfant</mark></td><td><mark style="color:red;"><strong>adolescent</strong></mark></td></tr></tbody></table>

{% hint style="info" %}
**Note** : pour l'instant, vous pouvez tester votre fonction **sans** utiliser l'année de naissance.
{% endhint %}

3. La fonction ne traite pas le cas où l'âge correspond à celui d'un enfant. Il s'agit d'une erreur de logique que vous allez corriger.
   * Avant de corriger l'erreur de logique, vous avez besoin de connaître les [structures décisionnelles multiples](https://cours-5.gitbook.io/dalicia-420-1g2-hu-logique-de-programmation/bases-de-la-logique-de-programmation/les-differents-types-de-traitement/structures-logiques-conditionnelles-if-else-elif#structure-decisionnelle-multiple). Prenez le temps de lire les notes de cours.
   * Complétez l'organigramme et le pseudo-code ci-dessus afin de prendre en compte le cas où l'âge correspond à celui d'un enfant. (utilisez le papier et crayon pour schématiser votre organigramme et écrire votre pseudo-code).
   * Corrigez ensuite votre fonction et testez la. Assurez-vous d'avoir mis à jour la documentation (docstring) de la fonction.

<details>

<summary><mark style="color:red;">Solution</mark></summary>

**Syntaxe structure décisionnelle multiple** `if/elif/else`

```python
if condition1:
    # Bloc de code exécuté si condition1 est vraie
elif condition2:
    # Bloc de code exécuté si condition1 est fausse et condition2 est vraie
else:
    # Bloc de code exécuté si toutes les conditions précédentes sont fausses
```

**Pseudo-code corrigé**

<pre class="language-python"><code class="lang-python"># ************************** Entrées/sorties ****************************
# Entrées (paramètres) : age
# Sorties (retour) : Une chaîne de caractères indiquant la catégorie d'âge de la
#           personne "adulte", "enfant" ou "adolescent"
# ************************** Début pseudo-code **************************
# Début : fonction qui détermine la catégorie
#     Si l'age est >= 18, alors categorie = "adulte"
#     <a data-footnote-ref href="#user-content-fn-1">Sinon si l'age est &#x3C; 12, alors categorie = "enfant" </a>
#     Sinon, categorie = "adolescent"
#     retourner la categorie
# Fin
</code></pre>

**Organigramme corrigé**

![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2Fhixqwep0EGyKBqjQfo9L%2F1000017454.jpg?alt=media\&token=6c860e86-e7f8-4b7e-ab24-bf055ba831f3)

**Fonction corrigée :**&#x20;

* <mark style="color:red;">Notez que la documentation de la fonction (docstring) a également été corrigée!</mark>

```python
def categorie_age(age):
    """
    Fonction qui retourne une chaîne de caractères indiquant s'il
    s'agit d'un adulte, d'un enfant ou d'un adolescent selon l'âge
    entré en paramètre.
    :param age: l'age de la personne (entier positif).
    :return: Un string indiquant la catégorie de la personne.
            Valeurs attendues : "Adulte", "Enfant" ou "Adolescent"
    """
    if age >= 18:
        categorie = "adulte"
    elif age < 12:
        categorie = "enfant"
    else:
        categorie = "adolescent"

    return categorie
```

</details>

4. Maintenant, vous allez compléter la résolution du problème. **Pour chacun des sous-problèmes (fonctions) restant(e)s,**&#x20;
   1. créez un algorithme (pseudo-code ou organigramme (papier crayon)),
   2. traduisez votre algorithme en une fonction Python et
   3. testez votre fonction :
      * Créez un plan de test contenant des valeurs variées.&#x20;
      * Testez votre programme pour confirmer son fonctionnement et relevez les erreurs.&#x20;

<details>

<summary><mark style="color:red;">Solution</mark></summary>

* **Pseudo-code de la fonction `calcul_age`** :&#x20;

{% code title="Pseudo-code calcul\_age" %}

```python
 ************************** Entrées/sorties ****************************
  Entrées (paramètres) : année de naissance
  Sorties (retour) : l'âge
 ************************** Début pseudo-code **************************
 Début : fonction qui retourne l'âge
     age = année en cours - année de naissance
     retourner age
 Fin
 ************************** Fin pseudo-code **************************
```

{% endcode %}

* **Organigramme de la fonction `calcul_age` :**&#x20;

![](https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2FbFBcQCzHm4Bb2YYZLFng%2F1000017455.jpg?alt=media\&token=dd42cd1e-2ee8-4377-9196-bfe4508ec757)

* **Fonction `calcul_age` en python :**&#x20;

```python
def calcul_age(annee_naissance):
    """
    Fonction qui calcule et retourne l'âge.
    :param annee_naissance: année de naissance.
    :return: l'âge.
    """
    annee_courante = 2024
    age = annee_courante - annee_naissance

    return age
```

**Appel de la fonction `calcul_age` dans le programme principal**&#x20;

<mark style="color:red;">Notez que nous avons besoin de l'année de naissance (variable</mark> <mark style="color:red;"></mark><mark style="color:red;">`annee_naisse`</mark><mark style="color:red;">) de la personne afin de calculer son âge.</mark>

```python
if __name__ == "__main__":
    prenom = input("Entrez un prénom : ")
    nom = input("Entrez un nom : ")
    
    # Notez que nous avons besoin de l'année de naissance 
    #    de la personne afin de calculer son age.
    annee_naiss = int(input("Entrez l'année de naissance : "))
    age = calcul_age(annee_naiss)
```

* **Pseudo-code de la fonction `affichage_droits` :**&#x20;

{% code title="Pseudo-code affichage\_droits" %}

```python
 ************************** Entrées/sorties ****************************
 Entrées : age
 Sorties : Les messages affichants les droits de la personne selon son age
 ************************** Début pseudo-code **************************
 Début : fonction d'affichage des droits et privilèges
 Si age >= 18, afficher "x Droit de vote"
 Sinon afficher "- Droit de vote"
 
 Si entre 5 (compris) et 25, afficher "x Être à l'école"
 Sinon, afficher "- Être à l'école"

 Si age >= 16, afficher "x Pouvoir conduire"
 Sinon, afficher "- Pouvoir conduire"

 Si age entre 18 et 65 (compris), afficher "x Prix spécial à la STO"
 Sinon, afficher "- Prix spécial à la STO"

 Si age >= 50, afficher "x Carte de l'âge d'or"
 Sinon, afficher "- Carte de l'âge d'or"
 Fin
 ************************** Fin pseudo-code **************************
```

{% endcode %}

* **Organigramme de la fonction `affichage_droits` : (ça sera trop grand en organigramme, on se contente du pseudo-code** :smile: **)**

- **Fonction `affichage_droits` en python :**  &#x20;

{% code lineNumbers="true" %}

```python
def affichage_droits(age: int):
    """
    Fonction qui affiche les droits et les privilèges 
    d'une personne selon son âge.
    :param age: l'âge de la personne
    :return: (aucun, le résultat est affiché)
    """
    if age >= 18:
        print("x Droit de vote")
    else:
        print("- Droit de vote")

    if 5 <= age < 50:
        print("x Être à l'école")
    else:
        print("- Être à l'école")

    if age >= 16:
        print("x Pouvoir conduire")
    else:
        print("- Pouvoir conduire")

    if age < 18 or age >= 65:
        print("x Prix spécial à la STO")
    else:
        print("- Prix spécial à la STO")

    if age >= 50:
        print("x Carte de l'âge d'or")
    else:
        print("- Carte de l'âge d'or")
```

{% endcode %}

</details>

5. Finalisez le programme principal de façon à permettre de donner à l'utilisateur le choix mentionné dans l'énoncé.

<details>

<summary><mark style="color:red;">Solution</mark></summary>

* **Pseudo-code du programme principal**

<pre class="language-python"><code class="lang-python"><strong>************************** Entrées/sorties ****************************
</strong> Entrées : choix de l'utilisateur (A, B, ou C), prénom, nom, année de naissance
 Sorties : Affichage de l'âge et de la catégorie, des droits de la personne, ou des deux
************************** Début pseudo-code **************************
Début du programme principal

Demander le prénom à l'utilisateur.
Demander le nomà l'utilisateur.
Demander l'année de naissance à l'utilisateur.

Demander (lire) le choix de l'utilisateur (choix) avec le message suivant : 
<strong>         "**************************************************************"
</strong>         "Souhaitez-vous :"
         "  A. Afficher l'âge et la catégorie de la personne."
         "  B. Afficher ce que cette personne peut faire en société."
         "  C. Afficher l'âge, la catégorie et ce que cette personne peut faire en société."
         "**************************************************************"

Si choix == 'A' Alors 
    Calculer l'âge en appelant la fonction calcul_age
    Appeler la fonction categorie_age pour trouver la catégorie
    Afficher résultat au format "prenom nom est un ou une categorie de age ans"
Sinon Si choix == 'B' Alors
    Afficher résultat au format "prenom nom a les droits suivants :"
    Appeler la fonction affichage_droits
Sinon Si choix == 'C' Alors
    Appeler la fonction categorie_age pour trouver la catégorie
    Afficher résultat au format "prenom nom est un ou une categorie de age ans. Il ou elle a les droits suivants :"
    Appeler la fonction affichage_droits
Sinon
    Afficher "Cette option (choix) n'existe pas, veuillez choisir une autre option (A, B ou C)."
Fin Si
Fin
************************** Fin pseudo-code **************************

</code></pre>

* **Programme principal en Python**

<mark style="color:red;">Traduisez le pseudo-code en code Python.</mark>

</details>

## Annexe

Voici un exemple de résultat d'exécuté de la totalité du programme :&#x20;

<figure><img src="https://700524925-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fn5YnWU89G98lz0ROIcGu%2Fuploads%2FJ7QnJr2b2Xp53JL9C6HM%2Fimage.png?alt=media&#x26;token=ae9eefae-293c-40ec-a02b-046a7c1942e9" alt=""><figcaption></figcaption></figure>

[^1]: modification pour ajouter la condition de la catégorie "enfant"
