Fonctions - Applications
De nombreuses applications des notions Python que vous avec vues : variables, chaînes de caractères, conditions, boucles, fonctions.
Certaines applications sont à compléter, d'autres à écrire de A à Z ! Auparavant, lisez bien le paragraphe qui suit.
Docstring d'une fonction
Il est d'usage de préciser toutes les informations nécessaires à l'utilisation de la fonction dans la docstring ( = "documentation string" ) de la fonction : il s'agit de commentaires placés au début de la définition de la fonction et qui constituent sa documentation.
Voici un exemple pour une fonction vue dans le cours :
def division(n1, n2):
"""
Fonction pour calculer le quotient et le reste de la division de deux nombres.
Entrée :
deux nombres entiers n1, n2 (int)
Sortie :
deux entiers dans l'ordre : quotient, reste de la division de n1 par n2 (int)
"""
quotient = n1 // n2
reste = n1 % n2
return quotient, reste
Ces commentaires sont placés entre deux groupes de triples guillemets ( """ ).
La dostring est un "mode d'emploi" succinct de la fonction.
On y précise ainsi quelles sont les spécifications en entrée et en sortie de la fonction, c'est à dire :
- la nature et le type du (ou des) paramètre(s) de la fonction ( = entrée )
- la nature et le type du (ou des) résultat(s) qu'elle renvoie ( = sortie )
De plus, cette docstring est alors accessible depuis l'interpréteur Python grâce à la fonction help()
( ceci est d'ailleurs valable pour toute fonction ! ) :
>>> help(division)
Help on function division in module __main__:
division(n1 : int, n2 : int) -> int, int:
Fonction pour calculer le quotient et le reste de la division de deux nombres.
Entrée :
deux nombres n1, n2
Sortie :
deux entiers dans l'ordre : quotient, reste de la division de n1 par n2
>>>
Dorénavant, à chaque fonction que vous écrirez, vous penserez impérativement à écrire une docstring succincte de votre fonction.
Minutes
- Compléter la fonction
minutes()suivante pour qu'elle renvoie le nombre de minutes correspondant au nombre d'heures h et de minutes m passées en paramètres. - Effectuer des appels de fonctions pour calculer et afficher le nombre de minutes correspondant à :
- exemple 1 : 5 heures et 27 minutes
- exemple 2 : 13 heures et 4 minutes
- exemple 3 : 0 heure et 59 minutes
Œufs en boîte
On décide de ranger des œufs dans des boîtes de six.
- Programmer la fonction
nb_boites()qui prend en paramètre un entier n correspondant à un nombre d’œufs et renvoie le nombre de boîtes nécessaires pour ranger les œufs. - Vérifier que votre fonction satisfait le jeu de tests suivant :
nb_boites(8) == 2nb_boites(3) == 1nb_boites(6) == 1nb_boites(38) == 7nb_boites(600) == 100nb_boites(601) == 101nb_boites(0) == 0
- En utilisant votre fonction, déterminer combien de boîtes d'oeufs sont nécessaires pour ranger 45190 oeufs.
Nombre premier ( plusieurs return dans une même fonction )
On dit qu'un nombre entier positif est premier s'il admet exactement deux diviseurs (1 et lui même). Ainsi :
- 0 n'est pas premier : 0 est divisible par n'importe quel entier,
- 1 n'est pas premier : 1 admet uniquement 1 comme diviseur,
- 2 est premier : 2 admet 1 et 2 comme diviseurs,
- 3 est premier : 3 admet 1 et 3 comme diviseurs,
- 4 n'est pas premier : 4 admet 1, 2 et 4 comme diviseurs,
- 5 est premier : 5 admet 1 et 5 comme diviseurs,
- 6 n'est pas premier : 6 admet 1, 2, 3 et 6 comme diviseurs etc.
Mis à part pour 0 et 1 qui sont particuliers (et ne sont pas premiers), pour tester si un nombre n est premier il suffit de tester un par un tous les nombres compris entre
2 et n-1 : si l'un d'eux divise n, alors n n'est pas premier.
Par exemple pour tester si 323 est premier, il suffit de tester tous les nombres entre 2 et 322 : si l'un d'eux divise 323 alors 323 n'est pas premier ( en l'occurrence, on trouve que 17 divise 323, donc 323 n'est pas premier).
Remarque : Pour tester si n est divisible par k, on peut utiliser l'opérateur modulo % qui donne le reste dans la division euclidienne de n
par k.
- Compléter la fonction
est_premier()ci-dessous qui prend en paramètre un nombre n entier positif ou nul et renvoie un booléen indiquant si le nombre est premier (True) ou pas (False). - Effectuer le jeu de tests suivants :
est_premier(0) == Falseest_premier(1) == Falseest_premier(4) == Falseest_premier(6) == Falseest_premier(48) == Falseest_premier(57) == Falseest_premier(77) == Falseest_premier(2) == Trueest_premier(3) == Trueest_premier(5) == Trueest_premier(7) == Trueest_premier(11) == Trueest_premier(13) == Trueest_premier(89) == Trueest_premier(241) == True
Mot doublé
- Compléter le code de la fonction
mot_double()ci-dessous pour qu'elle double chaque caractère de la chaîne ch passée en argument, quelle que soit sa longueur. - Effectuer le jeu de tests suivants :
mot_double('MAC') == 'MMAACC'mot_double('Z') == 'ZZ'mot_double('Lovelace') == 'LLoovveellaaccee'mot_double('Turing') == 'TTuurriinngg'
Texte enrhumé
On dit qu'un texte est «enrhumé» lorsque certains caractères ont été remplacés par d'autres caractères correspondant à une prononciation «enrhumée».
Voici un exemple :
Quelle poisse d’être enrhume, une tisane s'il te plaît !
Guelle boizze d'êdre enrhube, une dizane z'il de plaid !
On utilise donc la table de correspondance ci-dessous :
- Compléter la fonction
enrhuber_chaine()suivante pour qu'elle renvoie la version "enrhumée" de la chaîne passée en argument. - Effectuer le jeu de tests suivants :
enrhuber_chaine("place") == 'blage'enrhuber_chaine("chant") == 'ghand'enrhuber_chaine("arret") == 'arred'enrhuber_chaine("ourse") == 'ourze'enrhuber_chaine("stylo") == 'zdylo'
Le javanais
Le javanais ou langue de feu, apparu en France dans la dernière moitié du XIXe siècle, est un procédé de codage argotique [basé sur] l'insertion d'une syllabe supplémentaire entre voyelles
et consonnes, dans le but de rendre ce texte moins compréhensible aux non initiés.
Cette syllabe comporte un son lié au nom de la variante : « ja » ou « av » dans la variante « javanaise » et une syllabe comportant « f » dans la variante « langue de feu ».( Source : Wikipedia )
Exemples :
- train → travain.
- bonjour → bavonjavour.
- gros → gravos.
- bon → bavon.
- champion → chavampavion.
- plans → plavans.
- supermarché → savupavermavarchavé.
- poirier → pavoiravier.
Règles :
- "av" est ajouté après chaque consonne (ou groupe de consonnes comme ch, cl, ph, tr,…) d’un mot, autrement dit avant chaque voyelle.
- si le mot commence par une voyelle, "av" est ajouté devant cette voyelle.
- "av" n'est pas ajouté entre deux voyelles successives.
- Écrire une fonction
javanais()qui prend en paramètre une chaîne de caractères, et renvoie la chaîne "traduite" en javanais - tester la fonction avec les mots ci-dessus, voire avec une phrase complète ( les espaces entre les mots doivent être préservés ).
Réussir à l'examen
Dans tout ce qui suit les notes sont sur 20 points.
Voici un exemple de calcul de moyenne avec des coefficients :
- DS : 13 coefficient 2
- E valuation : 18 coefficient 1
- TP : 16 coefficient 0.5
- La moyenne est obtenue en faisant (2*13 + 1*18 + 0.5*16)/(2+1+0.5)
Un examen comporte 6 épreuves :
- Français coefficient 4,
- Anglais coefficient 3,
- Philosophie coefficient 1,
- Mathématiques coefficient 4,
- Physique coefficient 2,
- Informatique coefficient 6.
Un·e étudiant·e peut être admis·e de deux façons :
- si sa moyenne littéraire est supérieure ou égale à 11 et sa moyenne scientifique est supérieure ou égale à 11,
- ou bien si sa moyenne scientifique est supérieure ou égale à 16.
- Programmer la fonction
reussir_examen()qui prend les six notes des épreuves comme paramètres (fra, ang, phi, mat, phy et inf) et qui renvoieTrueouFalseselon que l'étudiant·e est admis·e ou pas. - Vérifier que votre fonction satisfait le jeu de tests suivant :
reussir_examen(10, 13, 11, 15, 6, 12) == Truereussir_examen(8, 13, 11, 15, 6, 12) == Falsereussir_examen(10, 13, 11, 11, 6, 12) == Falsereussir_examen(6, 3, 11, 15, 16, 20) == True
- En utilisant votre fonction déterminer si un·e étudiant·e ayant eu les notes suivantes (dans l'ordre des matières ci-dessus) : 8, 11, 14, 13, 9, 11 est admis·e ou pas.
Casino
Dans un casino, les machines à sous comportent trois roues ou trois cylindres mécaniques portant chacun les chiffres de 1 à 9.
En faisant tourner ces roues ou cylindres, on peut tirer au hasard un nombre entre 111 et 999 (ne comportant pas de chiffre zéro).
Le joueur mise un euro et récupère un gain qui dépend du résultat :
- si les trois chiffres sont égaux à sept, le joueur récupère une somme de 333 euros,
- sinon, si les trois chiffres sont égaux, le joueur récupère une somme de 33 euros,
- sinon, si le chiffre des centaines est égal au chiffre des unités, le joueur récupère une somme de 1 euro,
- sinon, si les trois chiffres sont consécutifs dans l'ordre croissant (par exemple 567), le joueur récupère une somme de 15 euros,
- sinon il ne récupère rien.
- Compléter la fonction
gain_tirage()qui prend en paramètre trois chiffres c, d et u correspondant aux chiffres des centaines, des dizaines et des unités et qui renvoie la somme récupérée correspondant à ce tirage. - Vérifier que votre fonction satisfait le jeu de tests suivant :
gain_tirage(1, 7, 4) == 0gain_tirage(4, 5, 6) == 15gain_tirage(5, 7, 5) == 1gain_tirage(4, 4, 4) == 33gain_tirage(7, 7, 7) == 333
- En utilisant votre fonction, déterminer le gain associé au tirage (5, 6, 5). En utilisant la fonction
gain_tirage(), compléter la fonction machine_a_sous() afin qu'elle renvoie trois chiffres tirés au hasard ainsi que la somme récupérée correspondante.
Meilleur tarif
On considère les tarifs proposés par deux entreprises de location de véhicules pour la location d’un même modèle automobile :
- Entreprise A : 15 € par jour puis 27 centimes par kilomètre parcouru
- Entreprise B : 26 € par jour puis 19 centimes par kilomètre parcouru
- Programmer une fonction
meilleur_tarif()qui :- prend en arguments : un entier km correspondant au nombre de kilomètres à parcourir, et un entier j correspondant au nombre de jours de location;
- renvoie : l'entreprise qui propose le tarif le plus économique, ainsi que le tarif avec cette entreprise.
- Vérifier que votre fonction satisfait le jeu de tests suivant :
meilleur_tarif(45, 1) == ('A', 27.15)meilleur_tarif(75, 1) == ('A', 35.25)meilleur_tarif(150, 1) == ('B', 54.5)meilleur_tarif(150, 2) == ('A', 70.5)meilleur_tarif(350, 2) == ('B', 118.5)
- En utilisant votre fonction, déterminer quel est le meilleur tarif pour parcourir 1250 kilomètres pendant 7 jours.
Super-Avare
Depuis ses huit ans, Super-avare économise des klipoks (monnaie locale).
- Le jour de ses huit ans il avait 8**3 = 512 klipoks dans sa tirelire.
- Le jour de ses neuf ans il avait 512 + 9**3 = 1241 klipoks dans sa tirelire.
- Le jour de ses dix ans il avait 1241 + 10**3 = 2241 klipoks dans sa tirelire.
- Le jour de ses onze ans il avait 2241 + 11**3 = 3572 klipoks dans sa tirelire.
- Compléter la fonction
calculer_tirelire()qui prend en paramètre un entier n supérieur ou égal à 8 et renvoie le nombre entier correspondant au nombre de klipocks que Super-avare a dans sa tirelire le jour de son n-ième anniversaire. - Effectuer le jeu de tests suivants :
calculer_tirelire(8) == 512calculer_tirelire(9) == 1241calculer_tirelire(10) == 2241calculer_tirelire(11) == 3572
- Compléter la fonction
age_millionnaire()qui utilise la fonction précédente pour renvoyer l'âge à partir duquel Super-avare devient millionnaire
Conversion binaire → base 10
Rappel de l'algorithme
on regarde successivement chaque bit du nombre binaire ( en commençant par le premier ou le dernier ) :
si le bit courant est égal à 1 :
alors on ajoute à la somme totale la puissance de 2 correspondant à la position du bit courant
si le bit courant est égal à 0:
on n'ajoute rien
Travail à faire
Écrire une fonction bin_vers_dec() qui :
- prend comme paramètre une chaîne de caractère formée d'une succession de '0' et de '1' et représentant un nombre binaire.
- renvoie son équivalent en base 10
Il faut coder l'algorithme que vous avez utilisé pour passer du binaire à la base 10.
Indication
Contrairement à ce que vous aviez ( peut-être ) fait lors des conversions "à la main", il est plus facile de coder cet algorithme en commençant par le bit de poids le plus grand ( le MSB ) : Python dispose en effet d'une fonction pour parcourir une chaîne de caractères depuis la gauche, cela peut servir ici...
Faites par contre bien attention au fait que, dans ce cas, on commence par la puissance de 2 la plus grande (27 pour un nombre à 8 bits par exemple ).
Cependant, les nombres binaires à convertir n'auront pas forcément 8 bits : il faut donc que la fonction s'adapte à un nombre quelconque n de bits.
Ce n'est pas très compliqué :
- le nombre de bits n est le nombre de caractères qu'il y a dans la chaîne représentant le nombre binaire.
- Souvenez-vous alors qu'avec n bits, on code 2n valeurs différentes : le MSB correspond donc toujours à la puissance 2n-1
Conversion base 10 → binaire
Attention un peu plus délicat...
Contentez-vous pour ce script d'une conversion sur 8 bits ( donc des valeurs en base 10 comprises entre 0 et 255 ).
Rappel de l'algorithme
tant que le nombre en base 10 n'est pas nul:
on compare le nombre en base 10 à la plus grande puissance de 2 (2^7 pour un nombre sur 8 bits )
si le nombre est supérieur ou égal à la puissance :
alors on ajoute un bit '1' à la chaîne représentant le nombre binaire
on soustrait la puissance au nombre en base 10
sinon on ajoute un bit à '0' à la chaîne
on passe à la puissance de 2 inférieure
Travail à faire
Écrire une fonction dec_vers_bin() qui:
- prend comme paramètre un entier en base 10
- renvoie une chaîne de caractères représentant la conversion de cet entier en binaire
Conversion base 10 → binaire ( bis )
Il existe un autre algorithme pour la conversion décimal → binaire :
Un autre algorithme
tant que quotient n'est pas nul :
quotient ← division entière du nombre en base 10 par 2
reste ← reste de la division entière du nombre en base 10 par 2
binaire ← "reste" + binaire
nombre en base 10 ← quotient
Travail à faire
Réarranger les instructions de la fonction dec_vers_bin_v2() ci-dessous qui utilise l'algorithme précédent; ne pas oublier l'indentation !
Vous pourrez vérifier le bon fonctionnement de votre solution dans l'éditeur ci-dessous :
Somme des chiffres d'un nombre
On souhaite écrire une fonction qui calcule la somme des chiffres d'un nombre.
Par exemple, la somme des chiffres du nombre 32768 est égale à : 3 + 2 + 7 + 6 + 8 = 26
Le problème est donc de "séparer" les chiffres d'un nombre pour les "isoler" et en faire la somme; pour cela, on va se servir du fait que :
- le chiffre le plus à droite est toujours égal au reste de la division du nombre par 10.
- le reste du nombre ( les chiffres restants à gauche ) est toujours égal au quotient entier du nombre par 10.
Par exemple : 32768 = 32760 + 8 = 3276*10 + 8 donc : 32768//10 = 3276, et 32768%10 = 8.
Écrire une fonction somme_chiffres qui prend en paramètre un nombre entier positif, et renvoie la somme de ses chiffres.
Tester la fonction sur plusieurs exemples.
Rendre fiable une pièce truquée...
Dans le script ci-dessous, on trouve une fonction piece_truquee qui simule le lancer d'une pièce truquée, qui renvoie donc "Pile" dans 60% des lancers, et "Face" dans 40% des lancers.
On montre que pour rendre "fiable" le lancer de cette pièce truquée, c'est à dire qu'elle donne aussi bien "Pile" que "Face" dans 50% des lancers, il faut en fait faire deux lancers successifs de la pièce truquée, ce qui donne alors 4 possibilités, qui n'ont pas la même probabilité d'apparaître :
- "Pile" + "Pile" apparaît dans 0,6*0,6 = 0,36 soit 36% des lancers,
- "Face" + "Face" dans 0,4*0,4 = 0,16 soit 16% des lancers,
- "Pile" + "Face" ou "Face" + "Pile" apparaissent tous les deux avec la même probabilité de 0,6*0,4 = 0,24 soit 24% des lancers
On ne considère alors que les situations pour laquelle la probabilité est la même, et on assigne à chacune le résultat "Pile" ou "Face", par exemple :
- deux lancers successifs "Pile" + "Face" correspondront à un unique lancer "Pile",
- deux lancers successifs "Face" + "Pile" correspondront à un unique lancer "Face".
- écrire une fonction
test, qui prend en paramètre un entier n, et qui renvoie le résultat de n lancers successifs d'une pièce ( truquée ou pas...).
Cette fonction appellera une fonction de lancer (piece_truqueeoupiece_fiable, il suffira de changer le nom de la fonction appelée ), et renverra le nombre de lancers "Pile" et le nombre de lancers "Face" obtenus sur les n lancers.
- Utiliser la fonction
testavec la fonctionpiece_truqueepour montrer le déséquilibre en terme de résultats de lancers ( ce déséquilibre est vraiment notable pour de grandes valeurs de n ) - écrire ensuite une fonction
piece_fiable, qui applique le principe de "fiabilisation" décrit ci-dessus, et qui devra renvoyer (normalement...) "Pile" ou "Face" dans 50% des lancers chacune.
Cette fonction devra faire deux appels à la fonctionpiece_truquee; elle ne devra pas tenir compte des deux situations "Pile" + "Pile" ou "Face" + "Face" qui ne nous intéressent pas ( pour cela, on peut par exemple répéter les deux tirages tant que l'on n'a pas obtenu un couple "valide" de tirages...). - utiliser alors cette nouvelle fonction avec la fonction de test, et constater que le "déséquilibre " a bien disparu !