TP - Chapitre 4 : Les fonctions

N.B. Niveau : Première Générale, enseignement de spécialité NSI (Numérique et Sciences Informatiques)

Chapitre 4 - Les fonctions

Nous avons déjà vu beaucoup de fonctions : print(), type(), len(), input(), range()...
Ce sont des fonctions pré-définies (built-in functions).
Nous avons aussi la possibilité de créer nos propres fonctions !

Intérêt des fonctions

Une fonction est une portion de code que l'on peut appeler au besoin (c'est une sorte de sous-programme).

L'utilisation des fonctions évite des redondances dans le code : on obtient ainsi des programmes plus courts et plus lisibles.

Par exemple, nous avons besoin de convertir à plusieurs reprises des degrés Celsius en degrés Fahrenheit :

>>> print (100.0*9.0/5.0+32.0)
212.0
>>> print (37.0*9.0/5.0+32.0)
98.6
>>> print (233.0*9.0/5.0+32.0)
451.4

La même chose en utilisant une fonction :

>>> def F(DegreCelsius):
print (DegreCelsius*9.0/5.0+32.0)

>>> F(100)
212.0
>>> F(37)
98.6
>>> x = 233
>>> F(x)
451.4

Rien ne vous oblige à définir des fonctions dans vos scripts, mais cela est tellement pratique qu'il serait bête de s'en passer !

L'instruction def

Syntaxe :

def NomDeLaFonction(parametre1,parametre2,parametre3,...):
""" Documentation
qu'on peut écrire
sur plusieurs lignes """
# docstring entouré de 3 guillemets (ou apostrophes)

bloc d'instructions # attention à l'indentation

return resultat # la fonction retourne le contenu de la variable resultat

Exemple n°1

# script Fonction1.py

def MaPremiereFonction(): # cette fonction n'a pas de paramètre
""" Cette fonction affiche 'Bonjour' """
print ('Bonjour')
return # cette fonction ne retourne rien ('None')
# l'instruction return est ici facultative

Une fois la fonction définie, nous pouvons l'appeler :

>>> MaPremiereFonction()	# ne pas oublier les parenthèses ()
Bonjour

L'accès à la documentation se fait avec la fonction pré-définie help() :

>>> help(MaPremiereFonction)	# affichage de la documentation
Help on function MaPremiereFonction in module __main__:

MaPremiereFonction()
Cette fonction affiche 'Bonjour'

Exemple n°2

La fonction suivante simule le comportement d'un dé à 6 faces.
Pour cela, on utilise la fonction randint() du module random.

# script Fonction2.py

def TirageDe():
""" Retourne un nombre entier aléatoire entre 1 et 6 """
import random
valeur = random.randint(1,6)
return valeur
>>> print (TirageDe())
3
>>> print (TirageDe())
6
>>> a = TirageDe()
>>> print (a)
1

Exemple n°3

# script Fonction3.py

# définition des fonctions
def Info():
""" Informations """
print ('Touche q pour quitter')
print ('Touche Enter pour continuer')

def TirageDe():
""" Retourne un nombre entier aléatoire entre 1 et 6 """
import random
valeur = random.randint(1,6)
return valeur

# début du programme
Info()
while True:
choix = input()
if choix == 'q':
break
print ('Tirage :',TirageDe())
>>>
Touche q pour quitter
Touche Enter pour continuer

Tirage : 5

Tirage : 6

q
>>>

Exemple n°4

Une fonction avec deux paramètres :

# script Fonction4.py

# définition de fonction
def TirageDe2(valeurMin,valeurMax):
""" Retourne un nombre entier aléatoire entre valeurMin et valeurMax """
import random
return random.randint(valeurMin,valeurMax)

# début du programme
for i in range(5):
print (TirageDe2(1,10)) # appel de la fonction avec les arguments 1 et 10
>>>
6
7
1
10
2

>>>

Exemple n°5

Une fonction qui retourne une liste :

# script Fonction5.py

# définition de fonction
def TirageMultipleDe(NbTirage):
""" Retourne une liste de nombres entiers aléatoires entre 1 et 6 """
import random
resultat = [random.randint(1,6) for i in range(NbTirage)] # compréhension de listes (Cf. annexe)
return resultat

# début du programme
print (TirageMultipleDe(10))
>>>
[4, 1, 3, 3, 2, 1, 6, 6, 2, 5]
>>> help(TirageMultipleDe)
Help on function TirageMultipleDe in module __main__:

TirageMultipleDe(NbTirage)
Retourne une liste de nombres entiers aléatoires entre 1 et 6

Exemple n°6

Une fonction qui affiche la parité d'un nombre entier.
Il peut y avoir plusieurs instructions return dans une fonction.
L'instruction return provoque le retour immédiat de la fonction.

# script Fonction6.py

# définition de fonction
def Parite(nombre):
""" Affiche la parité d'un nombre entier """
if (nombre % 2) == 1: # L'opérateur % donne le reste d'une division
print (nombre,'est impaire')
return
if (nombre % 2) == 0:
print (nombre,'est paire')
return

# début du programme
Parite(13)
Parite(24)
>>>
13 est impaire
24 est paire

Portée de variables : variables globales et locales

La portée d'une variable est l'endroit du programme où on peut accéder à la variable.

Observons le script suivant :

a = 10		# variable globale au programme

def MaFonction():
a = 20 # variable locale à la fonction
print (a)
return
>>> print (a)		# nous sommmes dans l'espace global du programme
10
>>> MaFonction() # nous sommes dans l'espace local de la fonction
20
>>> print (a) # de retour dans l'espace global
10

La variable a de valeur 20 est créée dans la fonction : c'est une variable locale à la fonction.
Elle est détruite dès que l'on sort de la fonction.

L'instruction global rend une variable globale :

a = 10		# variable globale

def MaFonction():
global a # la variable est maintenant globale
a = 20
print (a)
return
>>> print (a)
10
>>> MaFonction()
20
>>> print (a)
20

Remarque : il est préférable d'éviter l'utilisation de l'instruction global car c'est une source d'erreurs (on peut modifier le contenu d'une variable sans s'en rendre compte, surtout dans les gros programmes).

Exercices

Exercice 4.1 ☆
1) Ecrire une fonction qui retourne la valeur de la fonction mathématique f(x)=27x3 -27x2 -18x +8 :

>>> print f(0),f(1),f(0.5),f(0.25),f(0.375)
8.0 -10.0 -4.375 2.234375 -1.123046875

2) implanter la fonction f(x) dans le programme ci-dessous :

import matplotlib.pyplot as plt

xa=[] #Liste qui contiendra les abscisses des coordonnées de la fonction 2*x
ya=[]
#Liste qui contiendra les abscisses des coordonnées de la fonction 2*x
x=-1
while x<=2:
xa.append(x) # ajouter x dans la liste
ya.append(2*x) # ajouter 2*x dans la liste
x+=0.1

plt.plot(xa,ya,) # Place les points sur le graphique

plt.show() # Affiche le graphique
Exercice 4.2 ★

1) Ecrire une fonction qui retourne la factorielle d'un nombre entier N. La factorielle est la multiplication des nombres entiers de 1 à N : N ! = 1×2×...×N-1×N
Exemple :

>>> print (Factorielle(50))
30414093201713378043612608166064768844377641568960512000000000000

2) Comparez avec le résultat de la fonction factorial() du module math.

Exercice 4.3 ★

La région Grand-Est fournit un fichier csv contenant le nom prénom date de naissance et classe. Vous êtes chargés de générer des mots de passes aléatoires et leur fournir un nouveau fichier csv contenant le Nom;prénom;classe;identifiant;mot de passe (on ne gère pas les doublons).

Le miniprojet se décompose sous formes de fonctions :

    • Enlever les caractères accentués des noms et des prénoms
    • Générer un mot de passe
    • Lire le fichier csv et en ecrire un nouveau contenant les identifiants et mots de passe de la classe.

1. Ecrire une fonction qui retourne la place d'une lettre dans une chaine de caratères

Algorithme :

Déninir la fonction place_de_lettre(lettre,chaine)
place <- -1
i <- 0
pour chaque caractere dans la chaine
si le caratere est égal à la lettre
alors i -> place
incrémenter i
retourne la place

Exemple :

>>> print (place_de_lettre("c","abcdefghijklmnopqrstuvwxyz")
2
>>> print (place_de_lettre("é","abcdefghijklmnopqrstuvwxyz"))
-1

2. Ecrire une fonction qui retourne une chaîne de caratères sans caratères accentués. 

Algorithme :

Déninir la fonction enleve_accents(chaine)
accents <- "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ"
pas_accents <- "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn"
resultat <- ""
pour chaque lettre dans chaine
place = recherche la place de lettre dans accents
Si place >0
ajouter à resultat le caractère de la chaine pas_accents de la même place
sinon
ajouter à resultat la lettre
retourne le resultat
Exemple :
>>> print (enleve_accents("DJARAÏ Zakaryyâ"))
DJARAI Zakaryya

3) A l'aide de la fonction random.randint(valeurMin,valeurMax) du module random, écrire une fonction qui retourne un mot de passe de 8 caractères alphanumériques (Une consonne majuscule, voyelle, consonne,voyelle,consonne,caractère spécial,chiffre).

On donne :

composition = "0123456789BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxzaeiouy%$&@=+()*"

  • les chiffres se trouvent à la position (0,9) de la variable composition,
  • les consonnes majuscules (10,30),
  • les consonnes minuscules (31,50),
  • les voyelles (51,56),
  • les caractères spéciaux (57,65).
Je vous conseille de faire une variable de type liste contenant les uplets des positions de la chaine composition, dans l'ordre du format du mot de passe à générer. Pour chaque uplet se trouvant dans la liste générer un nombre aléatoire dans l'intervale de l'uplet puis créer mot de passe. Retourner le mot de passe généré.

Le format du mot de passe est une consonne majuscule, une voyelle minuscule, une consonne minuscule, une voyelle minuscule, une consonne minuscule, un caractère spécial et un chiffre.

Avant de vous lancer dans le codage, faire l'algorithme du programme.

Résultat attendu :

>>> print (mot_de_passe())
Gikaq$2

Les mots de passe générés seront de sécurité moyenne d'après le site kaspersky


4) Lecture du fichier Eleves.csv

En vous aidant très simplement du code de l'exercice 3.5 du chapitre 3, adapter le programme afin de créer la fonction lecture_fichier(nom_fichier) qui renvoie une liste contenant les noms, prénomset classes.

Résultat attendu :

>>> print (lecture_fichier("Eleves.csv"))
[['Nom', 'Prenom', 'Classe'], ['ABDESSEMED', 'Islem', 'TES2'], ['AGUIAR', 'Andrea', 'TPC1'], ...
5) Créer une fonction eleves_de_la_classe(liste_eleves,classe) qui renvoie la liste des élèves de TES1

Résultat attendu :

>>> print(eleves_de_la_classe(lecture_fichier("Eleves.csv"),'TES1'))
[['Nom', 'Prenom', 'Classe'],['AMARA', 'Sarah', 'TES1'], ['ATLI', 'Engin', 'TES1'], ...
6) Ecrire la fonction Sauvegarde_fichier(liste_eleves,nom_fichier)
Voici le code permettant de sauvegarder des données sur le disque dur :
fichier=open("TES1.csv",'w')  # Ouvre le fichier TES2.csv en ecriture 'w' et le créer s'il n'existe pas
eleves_classe=[['Nom', 'Prenom', 'Classe'],['AMARA', 'Sarah', 'TES1'], ['ATLI', 'Engin', 'TES1']]
lignes = [";".join(ligne) for ligne in eleves_classe] # permet de joindre et séparer les champs par ;
chaine="\n".join(lignes) # permet de joindre toutes les lignes en les séparant par un retour à la ligne
fichier.write(chaine) # Ecrit la chaine dans le fichier
fichier.close() # ferme le fichier
Transformez-le en fonction afin d'obtenir le fichier suivant après avoir ecrit dans la console :
>>> eleves_classe=(eleves_de_la_classe(lecture_fichier("Eleves.csv"),"TES1"))
>>> Sauvegarde_fichier(eleves_classe,"TES1.csv")
on pouvait le faire en une ligne, mais ça devient presque illisible :
>>> Sauvegarde_fichier(eleves_de_la_classe(lecture_fichier("Eleves.csv"),"TES1"),"TES1.csv")

7) Il ne reste qu'à écrire une fonction cree_id_mdp(liste_eleves) qui retourne la liste des élèves avec leur identifiant et mot de passe

Algorithme :

Déninir la fonction cree_id_mdp(liste_eleves)
liste_id_mdp <- []
pour chaque eleve dans la liste_eleves
ligne <- []
if l'élément 0 de la liste eleve ='Nom'
ligne <- ajouter ["Nom","Prénom","Classe","identifiant","mot de passe"]
sinon
ligne <- ajouter le nom de l'élève
ligne <- ajouter le prénom de l'élève
ligne <- ajouter la classe de l'élève
ligne <- ajouter le premier caratère du prénom + nom de l'élève
ligne <- ajouter un mot de passe aléatoire
liste_id_mdp <- ajoute la ligne
retourne liste_id_mdp
A la fin du programme, ajouter le programme principal suivant :

import os
boucle = True
fichier="Eleves.csv"
fichier_mdp="mdp.csv"


print("""1 : Générer les mots de passe
2 : Sauvegarder une une classe
q : quitte le programme""")
liste_complete=[]
while boucle:
choix=input("Entrer votre choix :")
if choix=="1":
reponse="o"
if os.path.exists(fichier_mdp):
reponse=input("êtes-vous sur de régénérer un nouveau fichier ?(o/n)")
if reponse=='o':
liste_complete=cree_id_mdp(lecture_fichier(fichier))
Sauvegarde_fichier(eleves_de_la_classe(liste_complete,"toutes"),fichier_mdp)
elif choix =="2":
if not os.path.exists(fichier_mdp):
print("Merci de générer les mots de passe d'abord")
else:
classe = input("Nom de la classe ?")
Sauvegarde_fichier(eleves_de_la_classe(lecture_fichier(fichier_mdp),classe),classe+".csv")
else:
print("merci d'avoir utilisé ce logiciel")
break