Les Fonctions
Des blocs de code réutilisables. Comme des recettes de cuisine.
La machine à fonction
Une fonction prend une entrée (l'argument), la transforme, et renvoie une sortie. Change x et lance le calcul de f(x) = 2x + 1.
C'est quoi une fonction ?
On dit aussi "méthode" quand la fonction appartient à un objet/classe. C'est la meme chose : un bloc de code reutilisable !
Une fonction c'est comme une recette de cuisine :
Tu donnes des parametres (entrees), la fonction execute des instructions, et te renvoie un resultat.
Testeur de fonctions
Fonction : additionner(a, b) → renvoie a + b
Voir le code Python
def additionner(a, b): return a + b
Definir une fonction
Creer une fonction reutilisable
# Definition def saluer(nom): return f"Bonjour {nom} !" # Appel message = saluer("Alice") print(message) # "Bonjour Alice !"
// Definition function saluer(nom) { return `Bonjour ${nom} !`; } // Appel const message = saluer("Alice"); console.log(message); // "Bonjour Alice !"
// Definition (dans une classe) public static String saluer(String nom) { return "Bonjour " + nom + " !"; } // Appel String message = saluer("Alice"); System.out.println(message); // "Bonjour Alice !"
// Definition static string Saluer(string nom) { return $"Bonjour {nom} !"; } // Appel string message = Saluer("Alice"); Console.WriteLine(message); // "Bonjour Alice !"
// Definition std::string saluer(std::string nom) { return "Bonjour " + nom + " !"; } // Appel std::string message = saluer("Alice"); std::cout << message << std::endl; // "Bonjour Alice !"
# Definition avec function() saluer <- function(nom) { paste("Bonjour", nom, "!") } # Appel message <- saluer("Alice") print(message) # "Bonjour Alice !" # R retourne la derniere expression auto ! carre <- function(x) x^2 # Une ligne
Parametres & Return
Les valeurs qu'on donne a la fonction
calculer(prix, taxe)
La valeur que la fonction renvoie
return prix * taxe
# Plusieurs parametres def calculer_prix(prix, quantite, remise): total = prix * quantite reduction = total * remise return total - reduction # Utilisation final = calculer_prix(100, 3, 0.1) print(final) # 270.0
// Plusieurs parametres function calculerPrix(prix, quantite, remise) { const total = prix * quantite; const reduction = total * remise; return total - reduction; } // Utilisation const final = calculerPrix(100, 3, 0.1); console.log(final); // 270
// Plusieurs parametres static double calculerPrix(double prix, int quantite, double remise) { double total = prix * quantite; double reduction = total * remise; return total - reduction; } // Utilisation double finalPrice = calculerPrix(100, 3, 0.1); System.out.println(finalPrice); // 270.0
Parametres par defaut
Valeurs utilisees si aucun argument n'est fourni
🎮 Testeur interactif
def commander_pizza(taille="medium", extra_fromage=False): prix = {"small": 8, "medium": 12, "large": 16} total = prix[taille] if extra_fromage: total += 2 return total
# Parametres par defaut = valeur si non fourni def saluer(nom, langue="fr", formel=False): if langue == "fr": salut = "Bonjour" if formel else "Salut" else: salut = "Good day" if formel else "Hi" return f"{salut} {nom} !" # Differentes facons d'appeler : saluer("Alice") # Salut Alice ! (defauts: fr, informel) saluer("Bob", "en") # Hi Bob ! (anglais, informel) saluer("Marie", "fr", True) # Bonjour Marie ! (francais, formel) saluer("John", formel=True) # Bonjour John ! (argument nomme)
// Parametres par defaut avec = function saluer(nom, langue = "fr", formel = false) { let salut; if (langue === "fr") { salut = formel ? "Bonjour" : "Salut"; } else { salut = formel ? "Good day" : "Hi"; } return `${salut} ${nom} !`; } // Differentes facons d'appeler : saluer("Alice"); // Salut Alice ! saluer("Bob", "en"); // Hi Bob ! saluer("Marie", "fr", true); // Bonjour Marie !
// Java n'a PAS de parametres par defaut ! // On utilise la SURCHARGE (overloading) : static String saluer(String nom) { return saluer(nom, "fr", false); // Appelle la version complete } static String saluer(String nom, String langue) { return saluer(nom, langue, false); } static String saluer(String nom, String langue, boolean formel) { String salut = langue.equals("fr") ? (formel ? "Bonjour" : "Salut") : (formel ? "Good day" : "Hi"); return salut + " " + nom + " !"; } // Java choisit automatiquement la bonne version ! saluer("Alice"); // → version 1 param saluer("Bob", "en"); // → version 2 params saluer("Marie", "fr", true); // → version 3 params
💡 Regle : Les parametres avec defaut doivent etre a la fin !
def fn(a, b=1, c=2) ✅ OK
def fn(a=1, b, c) ❌ Erreur !
Surcharge de fonctions
Plusieurs versions d'une meme fonction avec des parametres differents
🎯 Comment ca marche ?
🧮 Calculateur d'aire interactif
# Python : parametres optionnels + logique def aire(a, b=None, forme="rect"): if b is None: return a * a # Carre elif forme == "tri": return (a * b) / 2 # Triangle else: return a * b # Rectangle # Utilisation : aire(5) # 25 (carre 5x5) aire(4, 6) # 24 (rectangle 4x6) aire(4, 6, "tri") # 12 (triangle base=4, h=6)
// JavaScript : parametres par defaut function aire(a, b = null, forme = "rect") { if (b === null) { return a * a; // Carre } else if (forme === "tri") { return (a * b) / 2; // Triangle } else { return a * b; // Rectangle } } // Utilisation : aire(5); // 25 (carre) aire(4, 6); // 24 (rectangle) aire(4, 6, "tri"); // 12 (triangle)
// Java : VRAIE surcharge (plusieurs methodes) static double aire(double cote) { return cote * cote; // Carre } static double aire(double longueur, double largeur) { return longueur * largeur; // Rectangle } static double aire(double base, double hauteur, String type) { if (type.equals("triangle")) { return (base * hauteur) / 2; } return base * hauteur; } // Java choisit la bonne methode selon les arguments ! aire(5); // → version 1 param aire(4, 6); // → version 2 params aire(4, 6, "triangle"); // → version 3 params
⚠️ Attention : Python et JavaScript n'ont pas de vraie surcharge. On simule avec des parametres optionnels. Seuls Java, C#, C++ ont une vraie surcharge.
La portee (Scope)
Ou une variable est accessible - concept TRES important !
🏠 Analogie : La maison
Visible par tout le monde, de partout dans la maison.
nom_app = "Mukbang"
Visible seulement quand tu es DANS la chambre.
secret = "mon mot de passe"
🎮 Visualiseur de scope
app = "Mukbang" # Variable GLOBALE def fonction1(): x = 10 # Variable LOCALE print(app) # ✓ OK : app est global print(x) # ✓ OK : x est local ici def fonction2(): y = 20 print(app) # ✓ OK : app est global print(x) # ✗ ERREUR : x n'existe pas ici ! fonction1() print(app) # ✓ OK print(x) # ✗ ERREUR : x est morte avec fonction1
const app = "Mukbang"; // Variable GLOBALE function fonction1() { let x = 10; // Variable LOCALE console.log(app); // ✓ OK : app est global console.log(x); // ✓ OK : x est local ici } function fonction2() { let y = 20; console.log(app); // ✓ OK : app est global console.log(x); // ✗ ERREUR : x n'existe pas ici ! } fonction1(); console.log(app); // ✓ OK console.log(x); // ✗ ERREUR : x est morte avec fonction1
👤 Shadowing (meme nom, differentes variables)
Si une variable locale a le meme nom qu'une globale, la locale "cache" la globale !
x = 100 # Variable globale def test(): x = 5 # Nouvelle variable LOCALE (shadow) print(x) # Affiche 5 (la locale) test() print(x) # Affiche 100 (la globale intacte !)
⚠️ Modifier une variable globale (a eviter !)
- 🐛 Bugs difficiles : N'importe quelle fonction peut modifier la variable → impossible de savoir QUI l'a changee
- 🔄 Effets de bord : La fonction fait des choses "en cachette" en plus de sa tache principale
- 🧪 Tests impossibles : Tu ne peux pas tester la fonction isolement, elle depend d'un etat externe
- 👥 Travail en equipe : Quelqu'un modifie la globale ailleurs → ton code casse mysterieusement
globalcompteur = 0 def incrementer(): global compteur compteur += 1 incrementer() print(compteur) # 1
def incrementer(n): return n + 1 compteur = 0 compteur = incrementer(compteur) print(compteur) # 1
📦 Block Scope (JavaScript seulement)
En JS, let et const sont limites au bloc {},
mais var ignore les blocs !
if (true) { let a = 1; // Scope = ce bloc var b = 2; // Scope = fonction entiere ! const c = 3; // Scope = ce bloc } console.log(a); // ✗ ERREUR : a n'existe plus console.log(b); // ✓ OK : b existe encore (var) console.log(c); // ✗ ERREUR : c n'existe plus
let et const
✗ Evite var
Fonctions flechees / Lambda
Syntaxe courte pour des fonctions simples
# Fonction classique def doubler(x): return x * 2 # Lambda equivalente doubler = lambda x: x * 2 print(doubler(5)) # 10 # Utile avec map, filter... nombres = [1, 2, 3, 4] doubles = list(map(lambda x: x * 2, nombres)) # [2, 4, 6, 8]
// Fonction classique function doubler(x) { return x * 2; } // Arrow function equivalente const doubler = (x) => x * 2; console.log(doubler(5)); // 10 // Utile avec map, filter... const nombres = [1, 2, 3, 4]; const doubles = nombres.map(x => x * 2); // [2, 4, 6, 8]
// Java 8+ avec lambdas List<Integer> nombres = Arrays.asList(1, 2, 3, 4); // Lambda avec Stream API List<Integer> doubles = nombres.stream() .map(x -> x * 2) // Lambda .collect(Collectors.toList()); // [2, 4, 6, 8] // Interface fonctionnelle Function<Integer, Integer> doubler = x -> x * 2; doubler.apply(5); // 10
// C# avec lambdas var nombres = new List<int> { 1, 2, 3, 4 }; // Lambda avec LINQ var doubles = nombres.Select(x => x * 2).ToList(); // [2, 4, 6, 8] // Func delegate Func<int, int> doubler = x => x * 2; doubler(5); // 10
Fonctions sans return
Parfois on veut juste executer des actions sans renvoyer de valeur
calculer_moyenne(notes)
convertir_euros(chf)
est_majeur(age)
trouver_max(liste)
resultat = ma_fonction(x)
afficher_menu()
enregistrer_score(pts)
envoyer_email(dest)
deplacer_joueur(x, y)
ma_fonction(x) (pas de =)
prix = calculer_prix(qte)if est_valide(email):max = trouver_max(liste)afficher_menu()sauvegarder(data)jouer_son("ding")x = fonction() → besoin du resultat → returnfonction() tout seul → juste l'action → pas de returndef afficher_menu(): print("=== MENU ===") print("1. Jouer") print("2. Options") print("3. Quitter") # Pas de return afficher_menu() # Affiche le menu
function afficherMenu() { console.log("=== MENU ==="); console.log("1. Jouer"); console.log("2. Options"); console.log("3. Quitter"); // Pas de return (retourne undefined) } afficherMenu(); // Affiche le menu
// void = pas de retour static void afficherMenu() { System.out.println("=== MENU ==="); System.out.println("1. Jouer"); System.out.println("2. Options"); System.out.println("3. Quitter"); } afficherMenu(); // Affiche le menu
Exemple pratique : Calculatrice
def additionner(a, b): return a + b def soustraire(a, b): return a - b def multiplier(a, b): return a * b def diviser(a, b): if b == 0: return "Erreur: division par zero" return a / b def calculer(a, op, b): if op == "+": return additionner(a, b) elif op == "-": return soustraire(a, b) elif op == "*": return multiplier(a, b) elif op == "/": return diviser(a, b) print(calculer(10, "+", 5)) # 15 print(calculer(10, "/", 3)) # 3.333...
const additionner = (a, b) => a + b; const soustraire = (a, b) => a - b; const multiplier = (a, b) => a * b; const diviser = (a, b) => b === 0 ? "Erreur" : a / b; function calculer(a, op, b) { const operations = { "+": additionner, "-": soustraire, "*": multiplier, "/": diviser }; return operations[op]?.(a, b) ?? "Operation inconnue"; } console.log(calculer(10, "+", 5)); // 15 console.log(calculer(10, "/", 3)); // 3.333...
🪆 Récursivité : Une fonction qui s'appelle elle-même
Une fonction récursive est une fonction qui s'appelle elle-même pour résoudre un problème. C'est comme des poupées russes 🪆 : chaque poupée contient une version plus petite d'elle-même !
🪞 Analogie : Les miroirs infinis
Deux miroirs face à face créent des reflets infinis...
...mais il faut un cas de base pour s'arrêter !
📐 Structure d'une fonction récursive
La condition qui STOPPE la récursion. Sans ça = boucle infinie !
La fonction s'appelle elle-même avec un problème PLUS PETIT.
🧮 Exemple : Factorielle (n!)
5! = 5 × 4 × 3 × 2 × 1 = 120
Mais aussi : 5! = 5 × 4! (récursif !)
def factorielle(n): # 🛑 Cas de base if n <= 1: return 1 # 🔄 Cas récursif return n * factorielle(n - 1) print(factorielle(5)) # 120
function factorielle(n) { // 🛑 Cas de base if (n <= 1) { return 1; } // 🔄 Cas récursif return n * factorielle(n - 1); } console.log(factorielle(5)); // 120
📚 Visualisation : La pile d'appels
Quand tu appelles factorielle(4), voici ce qui se passe :
🎮 Essaie toi-même
⚠️ Attention : Sans cas de base ou si le problème ne "rétrécit" pas,
tu obtiens une récursion infinie → Stack Overflow (dépassement de pile) !
💡 Quand utiliser la récursivité ?
• Structures arborescentes (dossiers, DOM, JSON)
• Algorithmes de tri (quicksort, mergesort)
• Problèmes "diviser pour régner"
• Parcours de graphes
📋 Recapitulatif
Quiz Mode Survie
1 erreur = Game OverLes Fonctions
10 questions aleatoires - Mode Survie