Programmer en Python en 2nde

Boucle conditionnelle : exercices

Crédits

Toute la structure html/css/js et une partie du contenu ont été réalisés par Nicolas Buyle-Bodin professeur au lycée Lacassagne, avec l'aide de Jean-Manuel Mény, professeur au lycée de la plaine de l'Ain. Ils ont travaillé pendant plusieurs centaines d'heures pour créer un site de formation à destination des enseignants du secondaire de l'académie de Lyon d'une grande qualité visible sur le portail Mathématiques du site académique. Ils ont eu la gentillesse de placer leur code source sous licence Creative Commons BY-NC-SA Respect de la Paternité - Pas d'utilisation commerciale - Partage des conditions initiales à l'identique..

Nous les en remercions chaleureusement.

Un algorithme de seuil

algorigramme while

Dans un pays connaissant une forte inflation, le taux d’inflation mensuel est de 8 %. Un article coûte 500 euros le 1er janvier 2017.

  1. Calculer au centime près le prix de cet article au 1er février 2017 puis au 1er mars 2017.
  2. L’algorithme de seuil ci-contre détermine le nombre de mois au bout duquel le prix de l’article sera strictement supérieur à 1000 euros. Pourquoi le test de boucle est-il $P \leqslant 1000$ et non pas $P > 1 000$ ?
  3. Recopier et compléter le tableau d’évolution des variables ci-dessous pour dérouler complètement l’algorithme. Les valeurs des variables sont prises juste avant le premier test d’entrée dans la boucle pour l’initialisation puis à la fin de chaque itération (sauf la condition mesurée en entrée de boucle).
  4. algorigramme while
  5. Écrire en Python une fonction nombre_mois(prix) qui retourne le nombre de mois au bout duquel le prix sera supérieur à 1000 euros, en fonction du prix initial.
  6. Généralisons : écrire en Python une fonction nombre_mois2(prix, seuil, taux) qui retourne le nombre de mois au bout duquel le prix sera supérieur à seuil euros, en fonction du prix initial, avec un taux d'inflation donné (un taux de 8 % sera noté $0,08$).

					
					
  • Solution Question 4
  • Solution Question 5

def nombre_mois(prix):
    p = prix
    n = 0
    while p <= 1000:
        p = p * 1.08
        n = n + 1
    return n

print(nombre_mois(500))
        

et le test pour un prix initial de 500 euros :

10

def nombre_mois2(prix, seuil, taux):
    p = prix
    n = 0
    while p <= seuil:
        p = p * (1 + taux)
        n = n + 1
    return n

print(nombre_mois2(500, 1000, 0.08))
        

Temps d'attente

On lance un dé équilibré à six faces numérotées de 1 à 6.

  1. Le code Python ci-dessous permet d'afficher la face supérieure du dé lors de dix lancers successifs d'un dé à 6 faces. On commence par importer la fonction randint du module random. Cette fonction prend deux paramètres : par exemple randint(1, 6) retourne un entier aléatoire compris entre 1 et 6, les bornes sont incluses.
    
    from random import randint
    for k in range(10):
        print(randint(1, 6))
    
    5
    4
    3
    2
    6
    3
    5
    6
    6
    2    
            
    Écrire une fonction moyenneDe(n) qui retourne la valeur moyenne des faces obtenues sur un échantillon de n lancers.
  2. Écrire une fonction premier6() qui retourne le rang du premier 6 obtenu lorsqu'on lance successivement le dé.
  3. Écrire un script qui utilise cette fonction \(10 000\) fois et calcule le temps d'attente moyen du 6 pour cet échantillon de taille \(10 000\).

					
					
  • Valeur moyenne d'un dé
  • Temps d'attente du 6
  • Temps moyen d'attente

On importe la fonction randint du module random afin de générer un entier aléatoire compris entre 1 et 6.


from random import randint

def moyenneDe(n):
	s = 0
    for k in range(n):
    	s = s + randint(1, 6)
    return s / n

On importe la fonction randint du module random afin de générer un entier aléatoire compris entre 1 et 6.


from random import randint

def premier6() :
    de = randint(1,6)
    compteur = 1
    while de != 6 :
        de = randint(1,6)
        compteur = compteur + 1
    return compteur
	
	
print("Nombre de lancers pour obtenir 6 : ", premier6() )

from random import randint

def premier6() :
    de = randint(1,6)
    compteur = 1
    while de != 6 :
        de = randint(1,6)
        compteur = compteur + 1
    return compteur
	
	
s = 0
for k in range(10000) :
    s = s + premier6()
	
print("Temps d'attente moyen sur nos 10 000 essais : ", s/10000)

Racine carrée entière

Dans cet exercice on n'utilisera ni la fonction int de conversion en entier, ni la fonction sqrt du module math.

  1. Écrire une fonction intSquareFloor(n) qui retourne le plus petit entier $p$ tel que $p^2 > n$.
  2. Écrire une fonction intSquareFloor2(n) qui retourne le plus grand entier $p$ tel que $p^2 \leqslant n$.

					
					
  • Solution question 1
  • Solution question 2

def intSquareFloor(n):
    p = 0
    while p ** 2 <= n:
        p = p + 1
    return p

print(intSquareFloor(5))

def intSquareFloor2(n):
    p = 0
    while p ** 2 <= n:
        p = p + 1
    return p - 1

print(intSquareFloor2(5))

Mercato

C’est le mercato et un attaquant est convoité par deux clubs F et G qui lui proposent le même salaire mensuel mais des systèmes différents pour les primes par but marqué :

  • Le club F lui propose une prime de 8 000 euros par but marqué pour les dix premiers buts marqués puis de 11 300 euros par but marqué à partir du onzième but.
  • Le club G lui propose une prime de 10 000 euros par but marqué quel que soit le nombre de buts inscrits.
  1. Si l’attaquant inscrit 12 buts lors de la prochaine saison, dans quel club touchera-t-il la prime la plus importante ? Justifier la réponse.
  2. Écrire des fonctions F(n) et G(n) qui retournent respectivement les montants des primes offertes par les clubs F et G en fonction du nombre n de buts marqués.
  3. Écrire un script qui détermine le nombre de buts que doit marquer l’attaquant pour que le montant de la prime offerte par le club F soit la plus intéressante.

					
					
  • Solution questions 1 et 2
  • Solution question 3

def F(n):
    if n <= 10:
        return 8000 * n
    else:
        return 80000 + 11300 *(n  - 10)
    
def G(n):
    return 10000 * n

print(F(12), G(12))

Pour 12 buts marqués, le club G est plus intéressant :

(102600, 120000)
    

def F(n):
    if n <= 10:
        return 8000 * n
    else:
        return 80000 + 11300 *(n  - 10)

def G(n):
    return 10000 * n

n = 0
while F(n) <= G(n):
	n = n + 1
print(n)

Le club F sera plus intéressant à partir du 26èmebut :

26
    

Somme des entiers consécutifs

  1. Écrire une fonction seuil_somme(p) qui retourne le plus petit entier $n$ tel que $1 + 2 + 3 + \ldots n \geqslant p$.
  2. Le code Python ci-dessous permet d'afficher une ligne constituée de 2 caractères 'A' suivis de 8 caractères 'B'.
    
    print('A' * 2 + 'B' * 8)
    
    AABBBBBBBB        
            
    Écrire une fonction ligne(n, m) qui affiche une ligne constituée de n caractères 'A' suivis de m caractères 'B'.
  3. Écrire une fonction carre(m) tel que l'appel carre(10) donne l'affichage ci-dessous.
    ABBBBBBBBB
    AABBBBBBBB
    AAABBBBBBB
    AAAABBBBBB
    AAAAABBBBB
    AAAAAABBBB
    AAAAAAABBB
    AAAAAAAABB
    AAAAAAAAAB
    AAAAAAAAAA       
            
  4. On note $S_{10}=1+2+ \ldots + 10$ et $S_{9}= 1+2+ \ldots + 9$.
    • Que peut-on dire de $S_{10} + S_{9}$ ?
    • En déduire des formules permettant de calculer $S_{9}$ et $S_{10}$ sous forme de produit.
  5. Peut-on généraliser les formules précédentes pour calculer $S_{n}=1+2+ \ldots + n$, sous la forme d'un produit, pour tout entier naturel $n$ ?

					
					
  • Solution question 1
  • Solution question 2
  • Solution question 3
  • Solution question 4
  • Solution question 5

def seuil_somme(p):
    n = 1
    s = n
    while s < p:
        n = n + 1
        s = s + n
    return n

print(seuil_somme(100))

def ligne(n, m):
    print('A' * n + 'B' * (m - n))

ligne(2, 10)

def ligne(n, m):
    print('A' * n + 'B' * (m - n))

def carre(m):
    for n in range(1, m + 1):
        ligne(n, m)
        
carre(10)
  • $S_{10} + S_{9} = 10^{2}$.
  • De plus on a $S_{10} = S_{9} + 10$, en résolvant un système de deux équations à deux inconnues, on obtient que $S_{10}=\frac{10(10+1)}{2}$ et $S_{9}=\frac{9(9+1)}{2}$ .

En remplaçant $10$ par $n$ et $9$ par $n-1$, on obtient que $S_{n}+S_{n-1}=n^2$. Or $S_{n}=S_{n-1}+n$, et en résolvant un système de deux équations à deux inconnues, on obtient que $S_{n}=\frac{n(n+1)}{2}$ et $S_{n-1}=\frac{(n-1)n}{2}$.

PGCD par l'algorithme d'Euclide

Voici comment déterminer le quotient puis le reste de la division euclidienne du dividende 233 par le diviseur 5 en Python :


print(233 // 5)  #affichage du quotient de la division euclidienne de 233 par 5
print(233 % 5) #affichage du reste de la division euclidienne de 233 par 5
46
3
  1. Appliquer à la main l'algorithme d'Euclide à 420 et 330 pour déterminer leur PGCD.
  2. Écrire une fonction pgcd(n, m) qui retourne le PGCD des entiers n et m.

					
					
  • Solution

def pgcd(n, m):
    while m != 0:
        n, m = m, n % m
    return n

print(pgcd(420, 330))

Le PGCD de 420 et 330 est 30 :

30
    

def intSquareFloor2(n):
    p = 0
    while p ** 2 <= n:
        p = p + 1
    return p - 1

print(intSquareFloor2(5))