Introduction
En Python, les dictionnaires sont une structure de données utile qui vous permet de stocker des paires clé-valeur. Parfois, vous devrez peut-être trouver la clé de la valeur maximale dans un dictionnaire. Dans ce défi, vous allez écrire une fonction qui prend un dictionnaire en argument et renvoie la clé de la valeur maximale dans le dictionnaire.
Création de la fonction de base
Commençons par créer le noyau de notre fonction. Nous allons la construire étape par étape. Tout d'abord, créez un fichier nommé key_of_max.py. Vous pouvez utiliser l'éditeur de code intégré de LabEx ou un éditeur basé sur le terminal comme nano ou vim. À l'intérieur de key_of_max.py, ajoutez le code suivant :

def key_of_max(d):
"""
Renvoie la clé associée à la valeur maximale dans le dictionnaire 'd'.
Si plusieurs clés partagent la valeur maximale, l'une d'entre elles peut être renvoyée.
"""
return max(d, key=d.get)
Voici une analyse détaillée :
def key_of_max(d):: Cela définit une fonction nomméekey_of_max. Elle prend un argument,d, qui représente le dictionnaire avec lequel nous allons travailler.return max(d, key=d.get): C'est le cœur de la fonction. Analysons-le morceau par morceau :max(d,...): La fonction intégréemax()trouve l'élément le plus grand. Par défaut, si vous donnez un dictionnaire àmax(), elle trouvera la plus grande clé (par ordre alphabétique). Nous ne voulons pas cela ; nous voulons la clé associée à la plus grande valeur.key=d.get: C'est la partie cruciale. L'argumentkeyindique àmax()comment comparer les éléments.d.getest une méthode des dictionnaires. Lorsque vous appelezd.get(some_key), elle renvoie la valeur associée àsome_key. En définissantkey=d.get, nous disons àmax(): "Comparez les éléments du dictionnaireden utilisant leurs valeurs, pas leurs clés." La fonctionmax()renvoie alors la clé correspondant à cette valeur maximale.
Gestion du cas du dictionnaire vide
Notre fonction actuelle a un problème : elle plantera si le dictionnaire d'entrée d est vide. Corrigeons cela. Modifiez key_of_max.py pour qu'il ressemble à ceci :
def key_of_max(d):
"""
Renvoie la clé associée à la valeur maximale dans le dictionnaire 'd'.
Si plusieurs clés partagent la valeur maximale, l'une d'entre elles peut être renvoyée.
"""
if not d: ## Check if the dictionary is empty
return None
return max(d, key=d.get)
Les lignes ajoutées font ce qui suit :
if not d:: En Python, un dictionnaire vide est considéré comme "faux" (falsy). Cette instructionifvérifie si le dictionnairedest vide.return None: Si le dictionnaire est vide, il n'y a pas de valeur maximale, donc nous renvoyonsNone. C'est une façon standard d'indiquer l'absence d'une valeur en Python. Cela empêche la fonctionmax()de lever une erreur.
Ceci est une étape cruciale dans l'écriture de code robuste : pensez toujours aux cas limites (edge cases)!
Création de tests unitaires : tests de base
Maintenant, écrivons quelques tests pour nous assurer que notre fonction fonctionne correctement. Nous allons utiliser le module unittest de Python. Créez un nouveau fichier nommé test_key_of_max.py et ajoutez le code suivant :
import unittest
from key_of_max import key_of_max ## Import our function
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
if __name__ == '__main__':
unittest.main()
Explication :
import unittest: Importe le framework de test.from key_of_max import key_of_max: Importe la fonction que nous voulons tester.class TestKeyOfMax(unittest.TestCase):: Définit une classe de test. Les classes de test regroupent des tests liés.def test_basic_case(self):: Définit une méthode de test. Chaque méthode de test vérifie un aspect spécifique de notre fonction. Les noms des méthodes de test doivent commencer partest_.self.assertEqual(...): C'est une assertion. Elle vérifie si deux valeurs sont égales. Si elles ne sont pas égales, le test échoue. Dans ce cas, nous vérifions sikey_of_max({'a': 4, 'b': 0, 'c': 13})renvoie'c', ce qu'il devrait faire.def test_another_case(self):: Ajout d'un autre cas de test pour vérifier la clé de la valeur maximale qui peut ne pas être unique.if __name__ == '__main__': unittest.main(): Ce code Python standard exécute les tests lorsque vous exécutez le script directement (par exemple,python3 test_key_of_max.py).
Exécutez les tests depuis votre terminal : python3 test_key_of_max.py. Vous devriez voir un résultat indiquant que les deux tests ont réussi.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Test du dictionnaire vide (cas limite)
Ajoutons un test spécifiquement pour le cas du dictionnaire vide. Ajoutez cette méthode à votre classe TestKeyOfMax dans test_key_of_max.py :
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
self.assertIsNone(...): Cette assertion vérifie si la valeur est spécifiquementNone. Cela est important carself.assertEqual(..., None)pourrait réussir pour des éléments qui s'évaluent àNone, mais qui ne sont pas réellementNone.assertIsNoneest plus strict.
Exécutez les tests à nouveau (python3 test_key_of_max.py). Les trois tests (les deux tests de base et le test du dictionnaire vide) devraient maintenant réussir.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Test avec des valeurs toutes négatives
En tant que dernier test, gérons un cas où toutes les valeurs du dictionnaire sont négatives. Ajoutez cette méthode à TestKeyOfMax :
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
Ce test garantit que notre fonction identifie correctement la valeur la moins négative (qui est la valeur maximale dans ce cas) et renvoie la clé associée.
Exécutez vos tests une dernière fois (python3 test_key_of_max.py). Les quatre tests devraient réussir. Cela nous donne une forte confiance que notre fonction fonctionne correctement.
Votre fichier test_key_of_max.py complet devrait maintenant ressembler à ceci :
import unittest
from key_of_max import key_of_max
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
if __name__ == '__main__':
unittest.main()
Exécutez les tests à nouveau (python3 test_key_of_max.py). Les quatre tests devraient réussir. Cela nous donne une forte confiance que notre fonction fonctionne correctement.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
Résumé
Dans ce laboratoire, vous avez créé une fonction Python, key_of_max, pour trouver la clé associée à la plus grande valeur dans un dictionnaire. Vous avez appris à utiliser la fonction max() avec un argument key personnalisé, et vous avez géré le cas limite important d'un dictionnaire vide. Vous avez également écrit des tests unitaires complets en utilisant le module unittest, couvrant les cas de base, les dictionnaires vides et les dictionnaires avec des valeurs toutes négatives. Cette combinaison de code fonctionnel et de tests complets démontre de bonnes pratiques de développement logiciel.