Ключ максимального значения

Beginner

This tutorial is from open-source community. Access the source code

Введение

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

Это Guided Lab, который предоставляет пошаговые инструкции, чтобы помочь вам учиться и практиковаться. Внимательно следуйте инструкциям, чтобы выполнить каждый шаг и получить практический опыт. Исторические данные показывают, что это лабораторная работа уровня начальный с процентом завершения 92%. Он получил 100% положительных отзывов от учащихся.

Создание базовой функции

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

Редактор кода с функцией key_of_max

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()

Объяснение:

  1. import unittest: Импортирует фреймворк для тестирования.
  2. from key_of_max import key_of_max: Импортирует функцию, которую мы хотим протестировать.
  3. class TestKeyOfMax(unittest.TestCase):: Определяет тестовый класс. Тестовые классы группируют связанные тесты.
  4. def test_basic_case(self):: Определяет тестовый метод. Каждый тестовый метод проверяет определенный аспект нашей функции. Имена тестовых методов должны начинаться с test_.
  5. self.assertEqual(...): Это утверждение (assertion). Оно проверяет, равны ли два значения. Если они не равны, тест не проходит. В данном случае мы проверяем, возвращает ли key_of_max({'a': 4, 'b': 0, 'c': 13}) 'c', как и должно быть.
  6. def test_another_case(self):: Добавлен еще один тестовый случай для проверки ключа максимального значения, которое может не быть уникальным.
  7. 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, охватывающие базовые случаи, пустые словари и словари со всеми отрицательными значениями. Это сочетание функционального кода и всестороннего тестирования демонстрирует хорошие практики разработки программного обеспечения.