Введение
В Python словари (dictionaries) - это полезная структура данных, которая позволяет хранить пары ключ-значение. Иногда вам может понадобиться найти ключ максимального значения в словаре. В этом задании вы напишете функцию, которая принимает словарь в качестве аргумента и возвращает ключ максимального значения в этом словаре.
Создание базовой функции
Начнем с создания ядра нашей функции. Мы будем разрабатывать ее пошагово. Сначала создайте файл с именем key_of_max.py. Вы можете использовать встроенный редактор кода LabEx или терминал-based редактор, такой как nano или vim. Внутри файла key_of_max.py добавьте следующий код:

def key_of_max(d):
"""
Возвращает ключ, связанный с максимальным значением в словаре 'd'.
Если несколько ключей имеют максимальное значение, может быть возвращен любой из них.
"""
return max(d, key=d.get)
Вот разбор кода:
def key_of_max(d):: Это определяет функцию с именемkey_of_max. Она принимает один аргументd, который представляет собой словарь, с которым мы будем работать.return max(d, key=d.get): Это самое важное в функции. Разберем его по частям:max(d,...): Встроенная функцияmax()находит наибольший элемент. По умолчанию, если передатьmax()словарь, она найдет наибольший ключ (в алфавитном порядке). Мы этого не хотим; нам нужен ключ, связанный с наибольшим значением.key=d.get: Это ключевой момент. Аргументkeyсообщаетmax(), как сравнивать элементы.d.get- это метод словарей. Когда вы вызываетеd.get(some_key), он возвращает значение, связанное сsome_key. Установивkey=d.get, мы говоримmax(): "Сравнивайте элементы в словареdпо их значениям, а не по ключам." Функцияmax()затем возвращает ключ, соответствующий максимальному значению.
Обработка случая пустого словаря
Наша текущая функция имеет проблему: она сломается, если входной словарь d пуст. Исправим это. Измените файл key_of_max.py так, чтобы он выглядел следующим образом:
def key_of_max(d):
"""
Возвращает ключ, связанный с максимальным значением в словаре 'd'.
Если несколько ключей имеют максимальное значение, может быть возвращен любой из них.
"""
if not d: ## Check if the dictionary is empty
return None
return max(d, key=d.get)
Добавленные строки выполняют следующие действия:
if not d:: В Python пустой словарь считается "ложным" (falsy). Этоif-выражение проверяет, пуст ли словарьd.return None: Если словарь пуст, то нет максимального значения, поэтому мы возвращаемNone. Это стандартный способ указать на отсутствие значения в Python. Это предотвращает возникновение ошибки в функцииmax().
Это важный шаг при написании надежного кода: всегда учитывайте крайние случаи!
Создание модульных тестов: базовые тесты
Теперь напишем несколько тестов, чтобы убедиться, что наша функция работает правильно. Мы будем использовать модуль unittest Python. Создайте новый файл с именем test_key_of_max.py и добавьте следующий код:
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()
Объяснение:
import unittest: Импортирует фреймворк для тестирования.from key_of_max import key_of_max: Импортирует функцию, которую мы хотим протестировать.class TestKeyOfMax(unittest.TestCase):: Определяет тестовый класс. Тестовые классы группируют связанные тесты.def test_basic_case(self):: Определяет тестовый метод. Каждый тестовый метод проверяет определенный аспект нашей функции. Имена тестовых методов должны начинаться сtest_.self.assertEqual(...): Это утверждение (assertion). Оно проверяет, равны ли два значения. Если они не равны, тест не проходит. В данном случае мы проверяем, возвращает лиkey_of_max({'a': 4, 'b': 0, 'c': 13})'c', как и должно быть.def test_another_case(self):: Добавлен еще один тестовый случай для проверки ключа максимального значения, которое может не быть уникальным.if __name__ == '__main__': unittest.main(): Этот стандартный идиом Python запускает тесты, когда вы выполняете скрипт напрямую (например,python3 test_key_of_max.py).
Запустите тесты из терминала: python3 test_key_of_max.py. Вы должны увидеть вывод, показывающий, что оба теста прошли успешно.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Тестирование пустого словаря (крайний случай)
Давайте добавим тест специально для случая пустого словаря. Добавьте этот метод в класс TestKeyOfMax в файле test_key_of_max.py:
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
self.assertIsNone(...): Это утверждение (assertion) проверяет, является ли значение именноNone. Это важно, потому чтоself.assertEqual(..., None)может пройти для значений, которые вычисляются вNone, но на самом деле не являютсяNone.assertIsNoneболее строгий.
Запустите тесты еще раз (python3 test_key_of_max.py). Теперь все три теста (два базовых теста и тест для пустого словаря) должны пройти успешно.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Тестирование со всеми отрицательными значениями
В качестве последнего теста давайте рассмотрим случай, когда все значения в словаре отрицательны. Добавьте этот метод в класс TestKeyOfMax:
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
Этот тест гарантирует, что наша функция правильно определяет наименее отрицательное значение (которое в данном случае является максимальным) и возвращает соответствующий ключ.
Запустите тесты последний раз (python3 test_key_of_max.py). Все четыре теста должны пройти успешно. Это дает нам большую уверенность в том, что наша функция работает правильно.
Ваш полный файл test_key_of_max.py должен теперь выглядеть так:
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()
Запустите тесты еще раз (python3 test_key_of_max.py). Все четыре теста должны пройти успешно. Это дает нам большую уверенность в том, что наша функция работает правильно.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
Резюме
В этом практическом занятии (лабораторной работе) вы создали функцию Python key_of_max для нахождения ключа, связанного с наибольшим значением в словаре. Вы узнали, как использовать функцию max() с пользовательским аргументом key, и обработали важный крайний случай - пустой словарь. Вы также написали комплексные модульные тесты с использованием модуля unittest, охватывающие базовые случаи, пустые словари и словари со всеми отрицательными значениями. Это сочетание функционального кода и всестороннего тестирования демонстрирует хорошие практики разработки программного обеспечения.