Замена магического числа символьной константой
В коде используется число, которое несёт какой-то определённый смысл.
Решение
Замените это число константой с человеко-читаемым названием, объясняющим смысл этого числа.
double potentialEnergy(double mass, double height)
static final double GRAVITATIONAL_CONSTANT = 9.81; double potentialEnergy(double mass, double height)
double PotentialEnergy(double mass, double height)
const double GRAVITATIONAL_CONSTANT = 9.81; double PotentialEnergy(double mass, double height)
function potentialEnergy($mass, $height)
define(«GRAVITATIONAL_CONSTANT», 9.81); function potentialEnergy($mass, $height)
def potentialEnergy(mass, height): return mass * height * 9.81
GRAVITATIONAL_CONSTANT = 9.81 def potentialEnergy(mass, height): return mass * height * GRAVITATIONAL_CONSTANT
potentialEnergy(mass: number, height: number): number
static const GRAVITATIONAL_CONSTANT = 9.81; potentialEnergy(mass: number, height: number): number
Причины рефакторинга
Магические числа — это числовые значения, встречающиеся в коде, но при этом неочевидно, что они означают. Данный антипаттерн затрудняет понимание программы и усложняет её рефакторинг.
Дополнительные сложности возникают, когда нужно поменять определённое магическое число. Это нельзя сделать автозаменой, так как одно и то же число может использоваться для разных целей, а значит, вам нужно будет проверять каждый участок кода, где используется это число.
Достоинства
- Символьная константа может служить живой документацией смысла значения, которое в ней хранится.
- Значение константы намного проще заменить, чем искать нужное число по всему коду, при этом рискуя заменить такое же число, которое в данном конкретном случае использовалось для других целей.
- Убирает дублирование использования числа или строки по всему коду. Это особенно актуально, если значение является сложным и длинным (например, -14159 , 0xCAFEBABE ).
Полезные факты
Не все числа являются магическими.
Если предназначения чисел очевидны, их не надо заменять константами, классический пример:
for (i = 0; i
Альтернативы
- Иногда, магическое число можно заменить вызовом метода. Например, если у вас есть магическое число, обозначающее количество элементов коллекции, вам не обязательно использовать его для проверок последнего элемента коллекции. Вместо этого можно использовать встроенный метод получения длины коллекции.
- Магические числа могут быть использованы для реализации кодирования типа. Например, у вас есть два типа пользователей, и чтобы обозначить их, у вас есть числовое поле в классе, в котором для администраторов хранится число 1 , а для простых пользователей — число 2 . В этом случае имеет смысл использовать один из рефакторингов избавления от кодирования типа:
- замена кодирования типа классом
- замена кодирования типа подклассами
- замена кодирования типа состоянием/стратегией
Порядок рефакторинга
- Объявите константу и присвойте ей значение магического числа.
- Найдите все упоминания магического числа.
- Для всех найденных чисел проверьте, согласуется ли это магическое число с предназначением константы. Если да, замените его вашей константой. Эта проверка важна, так как одно и тоже число может означать совершенно разные вещи (в этом случае, они должны быть заменены разными константами).
Устали читать?
Сбегайте за подушкой, у нас тут контента на 7 часов чтения.
Или попробуйте наш интерактивный курс. Он гораздо более интересный, чем банальный текст.

Скидки!
Этот рефакторинг — малая часть интерактивного онлайн курса по рефакторингу.

- Премиум контент
- Книга о паттернах
- Курс по рефакторингу
- Введение в рефакторинг
- Чистый код
- Технический долг
- Когда рефакторить
- Как рефакторить
- Раздувальщики
- Длинный метод
- Большой класс
- Одержимость элементарными типами
- Длинный список параметров
- Группы данных
- Операторы switch
- Временное поле
- Отказ от наследства
- Альтернативные классы с разными интерфейсами
- Расходящиеся модификации
- Стрельба дробью
- Параллельные иерархии наследования
- Комментарии
- Дублирование кода
- Ленивый класс
- Класс данных
- Мёртвый код
- Теоретическая общность
- Завистливые функции
- Неуместная близость
- Цепочка вызовов
- Посредник
- Неполнота библиотечного класса
- Составление методов
- Извлечение метода
- Встраивание метода
- Извлечение переменной
- Встраивание переменной
- Замена переменной вызовом метода
- Расщепление переменной
- Удаление присваиваний параметрам
- Замена метода объектом методов
- Замена алгоритма
- Перемещение метода
- Перемещение поля
- Извлечение класса
- Встраивание класса
- Сокрытие делегирования
- Удаление посредника
- Введение внешнего метода
- Введение локального расширения
- Самоинкапсуляция поля
- Замена простого поля объектом
- Замена значения ссылкой
- Замена ссылки значением
- Замена поля-массива объектом
- Дублирование видимых данных
- Замена однонаправленной связи двунаправленной
- Замена двунаправленной связи однонаправленной
- Замена магического числа символьной константой
- Инкапсуляция поля
- Инкапсуляция коллекции
- Замена кодирования типа классом
- Замена кодирования типа подклассами
- Замена кодирования типа состоянием/стратегией
- Замена подкласса полями
- Разбиение условного оператора
- Объединение условных операторов
- Объединение дублирующихся фрагментов в условных операторах
- Удаление управляющего флага
- Замена вложенных условных операторов граничным оператором
- Замена условного оператора полиморфизмом
- Введение Null-объекта
- Введение проверки утверждения
- Переименование метода
- Добавление параметра
- Удаление параметра
- Разделение запроса и модификатора
- Параметризация метода
- Замена параметра набором специализированных методов
- Передача всего объекта
- Замена параметра вызовом метода
- Замена параметров объектом
- Удаление сеттера
- Сокрытие метода
- Замена конструктора фабричным методом
- Замена кода ошибки исключением
- Замена исключения проверкой условия
- Подъём поля
- Подъём метода
- Подъём тела конструктора
- Спуск метода
- Спуск поля
- Извлечение подкласса
- Извлечение суперкласса
- Извлечение интерфейса
- Свёртывание иерархии
- Создание шаблонного метода
- Замена наследования делегированием
- Замена делегирования наследованием
- Введение в паттерны
- Что такое Паттерн?
- История паттернов
- Зачем знать паттерны?
- Критика паттернов
- Классификация паттернов
- Фабричный метод
- Абстрактная фабрика
- Строитель
- Прототип
- Одиночка
- Адаптер
- Мост
- Компоновщик
- Декоратор
- Фасад
- Легковес
- Заместитель
- Цепочка обязанностей
- Команда
- Итератор
- Посредник
- Снимок
- Наблюдатель
- Состояние
- Стратегия
- Шаблонный метод
- Посетитель
- C#
- C++
- Go
- Java
- PHP
- Python
- Ruby
- Rust
- Swift
- TypeScript
Found magic number python что это



Скачай курс
в приложенииПерейти в приложение
Открыть мобильную версию сайта© 2013 — 2023. Stepik
Наши условия использования и конфиденциальности

Public user contributions licensed under cc-wiki license with attribution required
Python: Магические числа
Возьмем пример программы, которая считает курс валют:
euros_count = 1000 dollars_count = euros_count * 1.25 # 1250.0 rubles_count = dollars_count * 60 # 75000.0 print(rubles_count)С точки зрения профессиональной разработки, такой код не соответствует «лучшим практикам» — best practices.
В этом примере сложно понять, что значат числа 60 и 1.25 . Представьте, что вам придется разбираться в этом коде через месяц или через год — это будет сложно. Также сложно будет программисту, который не видел код ранее.
В нашем примере контекст легко восстановить, потому что переменные названы грамотно. Но в реальных проектах код значительно сложнее, поэтому догадаться до смысла чисел зачастую невозможно.
Проблема кроется в «магических числах» — magic numbers. Это числа, происхождение которых невозможно понять с первого взгляда — приходится глубоко вникать в то, что происходит в коде.
Чтобы предотвратить проблему, нужно создавать переменные с правильными именами. Так все встанет на свои места:
dollars_per_euro = 1.25 rubles_per_dollar = 60 euros_count = 1000 dollars_count = euros_count * dollars_per_euro # 1250.0 rubles_count = dollars_count * rubles_per_dollar # 75000.0 print(rubles_count)В этой программе:
- Используется именование snake_case
- Две новые переменные отделяются от последующих вычислений пустой строчкой. Эти переменные имеют смысл и без вычислений, поэтому такое отделение уместно, потому что повышает читаемость
- Получился хорошо именованный и структурированный код, но он длиннее прошлой версии. Так часто бывает — это нормально, ведь код должен быть читабельным
Магические числа и непонятные именования переменных не ломают код, но делают его менее читабельным.
Нужно понимать, что компьютер в любом случае выполнит заданное вычисление. Однако другой программист будет читать код и ничего не поймет — это усложнит работу. Правильное именование переменных — половина успеха анализа кода.
Задание
Вы столкнулись с таким кодом, который выводит на экран общее количество комнат во владении нынешнего короля:
king = "Rooms in King Balon's Castle:" print(king) print(6 * 17)Как видите, это магические числа: непонятно, что такое 6 и что такое 17. Можно догадаться, если знать историю королевской семьи: каждый новый король получает в наследство все замки от предков и строит новый замок — точную копию родительского.
Эта странная династия просто плодит одинаковые замки…
Избавьтесь от магических чисел, создав новые переменные, а затем выведите текст на экран.
Rooms in King Balon's Castle: 102
Названия переменных должны передавать смысл чисел, но должны при этом оставаться достаточно короткими и ёмкими для комфортного чтения.
Помните: код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность.
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Полезное
Что такое магические числа в программировании и как снять это заклятие

Магические числа — пример плохих практик в программировании. Из этой статьи вы узнаете, почему от них надо избавляться и как это делать.
- Что такое магические числа
- Как избавиться от магических чисел
Что такое магические числа
В программировании магическими называют числа в коде, смысл которых сложно понять. Взгляните на пример.
// показываем пользователю окончательную цену товара const showBruttoPrice = (nettoPrice) => const bruttoPrice = nettoPrice * 1.20; return bruttoPrice; >;Это пример магического числа, потому что невозможно однозначно ответить на вопрос, почему для вычисления bruttoPrice нужно умножить nettoPrice на 1.20 . Смысл числа 1.20 приходится восстанавливать по контексту. Но при работе с большими приложениями в реальной разработке это не всегда возможно.
Магические числа не ломают код. В примере выше пользователь увидит окончательную цену, то есть программа отработает. В чём же проблема?
Код с магическими числами сложно понять без контекста. Это может стать проблемой для разработчиков, которые впервые видят приложение. Да и автор кода может забыть, почему использовал именно это число.
Как избавиться от магических чисел
Это можно сделать с помощью константы с понятным названием. То есть название константы должно передавать смысл числа.
// указываем ставку НДС const vatRate = 1.20; const showBruttoPrice = (nettoPrice) => const bruttoPrice = nettoPrice * vatRate; return bruttoPrice; >;Очевидное указание ставки НДС делает код более понятным.
Код с магическими числами сложно поддерживать и расширять. Например, если магазин продаёт товары людям из разных стран, магические числа приводят к дублированию:
// в разных странах разные ставки НДС const showBruttoPrice = (nettoPrice, country) => let bruttoPrice; if (country === 'Russia') bruttoPrice = nettoPrice * 1.20; > if (country === 'Germany') bruttoPrice = nettoPrice * 1.19; > // стран может быть 5, 20 или 50 // для каждой придётся использовать // своё магическое число // . return bruttoPrice; >;Проблему решает избавление от магических чисел:
const getVatRate = (country) => // получаем ставку НДС для конкретной страны из // базы данных или из внешнего источника >; const showBruttoPrice = (nettoPrice, country) => // определяем ставку НДС вместо того, // чтобы указывать её с помощью магических чисел const vatRate = getVatRate(country); // определяем окончательную цену const bruttoPrice = nettoPrice * vatRate; return bruttoPrice; >;- Магические числа — плохая практика в программировании
- Обычно магические числа не ломают код, а делают его менее понятным
- Чтобы избавиться от магических чисел, достаточно использовать константы или переменные с понятными названиями