что значит деление по модулю

Mod и остаток — не одно и то же

Приготовьтесь, вас ждёт крайне педантичная статья, которая вполне может спасти вас на собеседовании или сэкономить несколько часов при вылавливании бага в продакшне!

Я сейчас активно работаю над вторым сезоном «Руководства для самозванца» и пишу о шифре RSA для SSH, который, очевидно, является самым загружаемым фрагментом кода в истории IT.

Хочется полностью разобраться в этой истории. Кто придумал этот шифр, как он работает, почему работает и будет ли работать в будущем. Сейчас я раскопал одну чертовски интересную историю. Я не криптоманьяк и вижу, как других буквально засасывает в эту область. Но мне это тоже интересно, потому что повсюду есть маленькие норки, а меня как сороку привлекают блестящие штучки в глубоких норках. Я также очень хорош в метафорах.

В любом случае: на прошлой неделе я узнал что-то странное и хочу поделиться: оказывается, mod и остаток от деления — не одно и то же. Действительно забавно то, что некоторые читатели при этих словах выпрыгивают со своих кресел и орут: «А ведь именно это я всегда пытался сказать вам и всем остальным!»

Позовите ребят из секты «mod не остаток»! Это для вас.

Что такое mod?

Я должен был изучить это, как и в прошлый раз, когда всплыла такая тема. Это одна из тех вещей, которые ты знаешь, но не запоминаешь. Когда вы применяете mod, то делите одно число на другое и берёте остаток. Итак: 5 mod 2 будет 1, потому что 5/2=2 с остатком 1.

Вот где мы попадаем в странную серую область.

Математика циферблата

Криптографам нравится эта идея, потому что они могут использовать деление с остатком с гигантскими простыми числами для генерации криптографических ключей. Это совсем другая история: если хотите прочитать об этом, то можете купить книгу или, ещё лучше, поддержать мои усилия написать её.

Впрочем, не будем отклоняться от темы.

Остатки и математика циферблата

Теперь переходим к сути: modulo и простой остаток одинаковы, когда числа положительны, но отличаются в случае отрицательных чисел.

Рассмотрим такую задачу:

JavaScript с этим согласен:

Google согласен с первым утверждением, но не согласен со вторым:

Ruby согласен с Google:

Во имя Дейкстры, что здесь происходит?

Вращение часов назад

Чтобы ответить на вопрос, следует понять разницу между остатком и modulo. Программисты объединяют эти операции, но не должны этого делать, потому что они дают одинаковый результат только в случае, если делитель (в нашем случае 12) положителен. Вы можете легко отправить баги в продакшн, если делитель отрицательный.

Но почему существует разница? Рассмотрим положительный делитель 19 mod 12 на часах:

Это известная вещь

Прежде чем назвать меня сумасшедшим и начать гуглить тему: это известный факт. На самом деле MDN (Mozilla Developer Network) даже дошла до того, чтобы назвать % операцией «остатка» (remainder), а не modulo:

Оператор remainder возвращает остаток от деления одного операнда на другой. Он всегда принимает знак делимого.

Вот что Эрик Липперт, один из богов C#, говорит о modulo в C#:

Однако это совсем не то, что оператор % реально делает в C#. Оператор % не является каноническим оператором modulus, это оператор остатка.

А как на вашем языке?

Ну и что?

Могу понять, если вы дочитали досюда, а теперь чешете голову и задаётесь вопросом, стоит ли беспокоиться. Думаю, что стоит по двум причинам:

Источник

«Деление» по модулю

Обычные арифметические операции по модулю выполняются не сильно сложнее — просто нужно брать модули и заботиться о переполнении. Например:

Но вот с делением возникают проблемы — мы не можем просто взять и поделить.

Через бинарное возведение в степень

Этот подход простой и быстрый, однако следует помнить, что он работает только для простых модулей.

Через расширенный алгоритм Евклида

Расширенный алгоритм Евклида можно использовать для решения в целых числах уравнений вида

Преимущества этого метода над возведением в степень:

Но лично автор почти всегда использует возведение в степень.

Упрощенная реализация

Сначала приведем реализацию, а потом поймем, почему она работает:

Докажем по индукции, что функция действительно возвращает обратный элемент.

Во втором случае проверим правильность формулы:

Предподсчет обратных элементов

Чаще всего нам нужно искать обратный элемент в контексте комбинаторики.

Например, особенно часто нужно считать биномиальные коэффициенты, для чего в свою очередь нужно уметь обращать факториалы:

Простой способ — это предпосчитать обычные факториалы и каждый раз вызывать inv один или два раза:

Однако это добавит лишний логарифм в асимптотику в нередком случае, когда какая-то комбинаторная формула лежит внутри горячего цикла. Поэтому имеет смысл предподсчитать и частые обратные элементы.

Обратные факториалы

Все остальные обратные факториалы можно таким же образом итеративно подсчитать из предыдущего.

Источник

Введение в модулярную арифметику

Для любой системы взаимно простых чисел p1, … pn, любое число X из диапазона [0; M), где M = p1*p2*…*pn взаимооднозначно представимо в виде вектора (a1, a2, …, an), где ai = X%pi (здесь и далее «%» — операция взятия остатка от целочисленного деления X на pi).
p1, … pn – модули системы
a1, a2, …, an – остатки (вычеты) числа по заданной системе модулей

Прямое преобразование

Прямое преобразование из позиционной системы счисления (обычно в двоичном виде) в систему счисления в остатках заключается в нахождении остатков от деления по каждому из модулей системы.

Пример: Пусть требуется найти представление числа X = 25 по системе модулей (3, 5, 7). X = (25%3, 25%5, 25%7) = (1, 0, 4).

Реализация нахождения вычета в микроэлектронике по заданному модулю строится на следующих свойствах вычетов:
(a+b) % p = (a%p + b%p)%p
(a*b) % p = (a%p * b%p)%p

Любое число X можно записать в виде X%p = (xn-1*2 n-1 + xn-2*2 n-2 + x0*2 0 )%p = ((xn-1)%p*2 n-1 %p) + ((xn-2)%p*2 n-2 %p) + … + x0%p)%p. Поскольку в данном случае xn-1, … x0 равны 0 или 1, то фактически нам требуется сложить вычеты вида (2 i %p).

Пример: пусть задано число 25 или в двоичной системе счисления 11001 и требуется найти остаток по модулю 7.
25%7 = (1*2 4 + 1*2 3 + 0*2 2 + 0* 1 + 1*2 0 )%7 = (2 4 %7 + 2 3 %7 + 1%7)%7 = (2 + 1 + 1)%7 = 4

Арифметические операции

Пример: пусть задана система модулей (3, 5, 7), то есть мы можем выполнять операции, результат которых не превышает 3*5*7 = 105. Умножим два числа 8 и 10.
8 = (8%3, 8%5, 8%7) = (2, 3, 1)
10 = (10%3, 10%5, 10%7) = (1, 0, 3)
8*10 = ((2*1)%3, (3*0)%5, (1*3)%7) = (2, 0, 3)
Проверяем
80 = (80%3, 80%5, 80%7) = (2, 0, 3)

Обратное преобразование

Способ, основанный на Китайской теореме об остатках, базируется на следующей идее:
X = (x1, x2, … xn) = (x1, 0, …, 0) + (0, x2, …, 0) + … + (0, 0, …., xn) = x1*(1, 0, …, 0) + x2*(0, 1, …, 0) + … + xn*(0, 0, …, 1).
То есть для обратного преобразования требуется найти систему ортогональных базисов B1 = (1, 0, …, 0), B2 = (0, 1, …, 0), …, BN = (0, 0, …, 1). Эти вектора находятся один раз для заданного базиса, а для их поиска требуется решить уравнение вида: (Mi*bi)%pi = 1, где Mi = M/pi, а bi – искомое число. В этом случае позиционное представление Bi = Mi*bi и
X = (x1*(M1*b1) + x2*(M2*b2) + … + xn*(Mn*bn))%M

Пример: пусть задана система модулей (3, 5, 7), найдем значения Mi и bi (0 b1 = 2
(21*b2)%5 = 1 => b2 = 1
(15*b3)%7 = 1 => b3 = 1
Теперь преобразуем какое-нибудь число в системе остаточных классов. Положим
X = (2, 3, 1) = (2*35*2 + 3*21*1 + 1*15*1)%105 = (140 + 63 + 15)%105 = 218%105 = 8

Минус этого метода заключается в том, что для обратного преобразования требуется умножение и сложение больших чисел (M1, …, Mn), а так же операция взятия остатка по модулю большого числа M.

Читайте также:  что значит пневматичный человек

Источник

Деление по модулю в практике Python или как использовать оператор %

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

В этом уроке вы узнаете:

Об операторе деления по модуля иногда забывают. Но хорошее понимание этого оператора даст вам бесценный инструмент в своём арсенале инструментов Python.

В этом уроке:

Деление по модулю в математике ↑

Классический пример модульной арифметики — двенадцать часов. Двенадцатичасовые часы имеют фиксированный набор значений от 1 до 12. При подсчете двенадцатичасовых часов вы считаете до модуля 12, а затем возвращаетесь к 1. Двенадцатичасовые часы можно классифицировать как «modulo 12», иногда сокращается до «mod 12».

Оператор деление по модулю используется, когда вы хотите сравнить число с модулем и получить эквивалентное число, ограниченное диапазоном модуля.

Если подумать, 17 и 5 эквивалентны в контексте mod 12. Если бы вы посмотрели на часовую стрелку в 5:00 и 17:00, она была бы в том же положении. В модульной арифметике есть уравнение, описывающее эту взаимосвязь:

Это уравнение гласит: «a и b равны по модулю n». Это означает, что a и b эквивалентны по модулю n, поскольку они имеют одинаковый остаток при делении на n. В приведенном выше уравнении n — это модуль как для a, так и для b. Используя значения 17 и 5 из предыдущих, уравнение будет выглядеть так:

Это гласит: «17 и 5 равны по модулю 12». 17 и 5 имеют одинаковый остаток 5 при делении на 12. Таким образом, в модуле 12 числа 17 и 5 эквивалентны.

Подтвердить это можно с помощью деления:

Обе операции имеют одинаковый остаток 5, поэтому они эквивалентны по модулю 12.

Основы работы с операторами деления модуля Python ↑

Оператор деления по модулю, как и другие арифметические операторы, может использоваться с числовыми типами int и float. Как вы увидите позже, его также можно использовать с другими типами, такими как math.fmod(), decimal.Decimal и вашими собственными классами.

Оператор деления по модулю с int ↑

В большинстве случаев вы будете использовать оператор деления по модулю с целыми числами. Оператор деления по модулю, когда он используется с двумя положительными целыми числами, вернет остаток от стандартного евклидова деления или деление с остатком એ :

Будь осторожен! Как и в случае с оператором деления ( / ), Python вернет ошибку ZeroDivisionError, если вы попытаетесь использовать оператор по модулю с делителем 0:

Далее вы узнаете, как использовать оператор деления по модулю чисел с плавающей точкой.

Оператор деления по модулю чисел плавающей точкой (float) ↑

Альтернативой использованию числа с плавающей запятой с оператором по модулю является использование math.fmod() для выполнения операций по модулю над значениями с плавающей запятой:

В следующем разделе вы более подробно исследуете использование оператора по модулю с отрицательными операндами.

Как и другие арифметические операторы, оператор по модулю и math.fmod() могут столкнуться с проблемами округления и точности при работе с арифметикой с плавающей запятой:

Если для вашего приложения важно поддерживать точность с плавающей запятой, вы можете использовать оператор по модулю с decimal.Decimal. Вы рассмотрите это позже.

Оператор деления по модулю с отрицательным операндом ↑

Все операции деления по модулю, которые вы видели до этого момента, использовали два положительных операнда и возвращали предсказуемые результаты. Когда вводится отрицательный операнд, все становится сложнее.

Как выясняется из, способ, которым компьютеры определяют результат операции деления по модулю с отрицательным операндом, оставляет неоднозначность относительно того, должен ли остаток принимать знак делимого (число, которое делится) или знак делителя (число, на которое делится делимое). Разные языки программирования обрабатывают это по-разному.

Например, в JavaScript остаток примет знак делимого:

Остаток в этом примере, 2, положительный, поскольку он принимает знак делимого, 8. В Python и других языках вместо этого остаток принимает знак делителя:

Это уравнение состоит из трех переменных:

Здесь вы можете увидеть, как такой язык, как JavaScript, получает остаток 2. Python и другие языки, в которых остаток принимает знак делителя, используют следующее уравнение:

floor() в этом уравнении означает, что он использует разделение этажей. При положительных числах деление этажа вернет тот же результат, что и усеченное деление. Но с отрицательным числом деление по этажам округляет результат в меньшую сторону, в сторону от нуля:

Оператор деления по модулю и divmod() ↑

Python имеет встроенную функцию divmod(), которая внутренне использует оператор по модулю. divmod() принимает два параметра и возвращает кортеж, содержащий результаты деления этажа и по модулю с использованием предоставленных параметров.

Ниже приведен пример использования divmod() с 37 и 5:

Вы можете видеть, что divmod(37, 5) возвращает кортеж (7, 2). 7 — это результат деления полов на 37 и 5. 2 — результат 37 по модулю 5.

Теперь, когда у вас была возможность увидеть оператор деления по модулю, используемый в нескольких сценариях, важно взглянуть на то, как Python определяет приоритет оператора деления по модулю при использовании с другими арифметическими операторами.

Приоритет оператора деления по модулю ↑

Как и другие операторы Python, для оператора деления по модулю существуют определенные правила, которые определяют его приоритет при оценке выражений. Оператор деления по модулю ( % ) имеет тот же уровень приоритета, что и операторы умножения ( * ), деления ( / ) и деления пола ( // ).

Взгляните на пример приоритета оператора деления по модулю ниже:

Операторы умножения и по модулю имеют одинаковый уровень приоритета, поэтому Python будет оценивать их слева направо. Вот шаги для вышеуказанной операции:

Читайте также:  Что лучше кеторол или мелоксикам в уколах при болях в пояснице

Если вы хотите переопределить приоритет других операторов, вы можете заключить в круглые скобки операцию, которую вы хотите выполнить в первую очередь:

В этом примере сначала вычисляется (12 – 9), затем 4 * 10 и, наконец, 40 % 3, что равно 1.

Оператор деления по модулю Python на практике ↑

Теперь, когда вы ознакомились с основами оператора Python деления по модулю, вы рассмотрите несколько примеров его использования для решения реальных задач программирования. Иногда бывает сложно определить, когда использовать в коде оператор деления по модулю. Приведенные ниже примеры дадут вам представление о многих способах его использования.

Как проверить, четное или нечетное число ↑

В этом разделе вы увидите, как с помощью оператора по модулю определить, четное или нечетное число. Используя оператор по модулю с модулем 2, вы можете проверить любое число, чтобы узнать, делится ли оно без остатка на 2. Если оно делится без остатка, то это четное число.

Здесь num % 2 будет равно 0, если num четное, и 1, если num нечетное. Проверка против 0 вернет логическое значение True или False в зависимости от того, является ли число четным или нет.

Проверка на нечетные числа очень похожа. Чтобы проверить нечетное число, вы инвертируете проверку равенства:

Ответ на этот вопрос — да и нет. Технически эта функция будет работать так же, как Python вычисляет по модулю с целыми числами. Тем не менее, вам следует избегать сравнения результата операции деления по модулю с 1, поскольку не все операции деления по модулю в Python будут возвращать один и тот же остаток.

Вы можете понять, почему, в следующих примерах:

Если вы будете сравнивать операцию Python по модулю с 0, у вас не должно возникнуть проблем с проверкой четных и нечетных чисел или любых других кратных чисел в вашем коде.

В следующем разделе вы узнаете, как можно использовать оператор по модулю с циклами для управления потоком вашей программы.

Как запускать код с определенными интервалами в цикле ↑

С помощью оператора Python деления по модулю вы можете запускать код через определенные промежутки времени внутри цикла. Это делается путем выполнения операции деления по модулю с текущим индексом цикла и модулем. Номер модуля определяет, как часто код, зависящий от интервала, будет выполняться в цикле.

Прежде чем разбирать функцию более подробно, взгляните на нее в действии:

Как видите, список имен разделен на три строки, максимум по три имени в каждой строке. по умолчанию модуль равен 3, но вы можете указать любое число:

Не вдаваясь в подробности, синтаксис: — ^ 15 предписывает print () выполнять следующие действия:

Теперь, когда имя напечатано в строке, взгляните на основную часть split_names_into_rows() :

Этот код берет текущий индекс итерации и, используя оператор по модулю, сравнивает его с модулем. Если результат равен 0, то он может запускать код, зависящий от интервала. В этом случае функция вызывает print() для добавления новой строки, которая начинает новую строку.

Приведенный выше код — это только один пример. Использование шаблона index % modulus == 0 позволяет запускать другой код через определенные промежутки времени в ваших циклах. В следующем разделе вы немного углубитесь в эту концепцию и рассмотрите циклическую итерацию.

Как создать циклическую итерацию ↑

Циклическая итерация описывает тип итерации, которая сбрасывается при достижении определенной точки. Как правило, этот тип итерации используется для ограничения индекса итерации определенным диапазоном.

Вы можете использовать оператор деления по модулю для создания циклической итерации. Взгляните на пример использования библиотеки turtle для рисования формы:

В приведенном выше коде используется бесконечный цикл для рисования повторяющейся формы звезды. После каждых шести итераций он меняет цвет пера. Размер пера увеличивается с каждой итерацией, пока i не сбрасывается обратно в 0. Если вы запустите код, вы должны получить что-то похожее на это:

Важные части этого кода выделены ниже:

Вы можете увидеть шаги итерации ниже для более подробного пояснения:

Как конвертировать единицы измерения ↑

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

В этом первом примере преобразуем дюймы в футы. Оператор деления по модулю используется для получения оставшихся дюймов, которые неравномерно не делятся на футы. Оператор деления без остатка ( // ) используется для округления общего количества футов в меньшую сторону:

Вот пример используемой функции:

Разбив это, вы можете увидеть, что функция выполняет следующее:

Вы можете увидеть, как это работает, ниже:

Хотя в приведенных выше примерах рассматривается только преобразование дюймов в футы и минут в дни, вы можете использовать любые типы единиц с оператором по модулю, чтобы преобразовать меньшую единицу в большую единицу.

Ниже операторы деления без остатка и по модулю были заменены на divmod() :

Как видите, divmod(total_inches, 12) возвращает кортеж, который распакован в футы и дюймы.

Если вы попробуете эту обновленную функцию, то получите те же результаты, что и раньше:

Вы получите тот же результат, но теперь код более лаконичен. Вы также можете обновить convert_minutes_to_days() :

Использование divmod() необязательно для всех ситуаций, но здесь имеет смысл, поскольку при расчетах преобразования единиц используется как деление этажа, так и модуль.

Теперь, когда вы узнали, как использовать оператор по модулю для преобразования единиц, в следующем разделе вы узнаете, как можно использовать оператор по модулю для проверки простых чисел.

Как определить, является ли число простым числом ↑

В следующем примере вы увидите, как можно использовать оператор Python по модулю, чтобы проверить, является ли число простым. Простое число — это любое число, которое содержит только два делителя: 1 и само себя. Некоторые примеры простых чисел: 2, 3, 5, 7, 23, 29, 59, 83 и 97.

Приведенный ниже код представляет собой реализацию для определения простоты числа с помощью оператора по модулю:

Прежде чем вы более внимательно посмотрите на функцию, вот результаты с использованием некоторых других чисел:

Углубившись в код, вы увидите, что он начинается с проверки, меньше ли num 2. Простые числа могут быть только больше или равны 2. Если num меньше 2, то выполнение функции не требуется. Он просто напечатает сообщение и сделает возврат:

Если num больше 2, функция проверяет, является ли num простым числом. Чтобы проверить это, функция выполняет итерацию по всем числам от 2 до квадратного корня из числа, чтобы увидеть, делятся ли они на число поровну. Если одно из чисел делится равномерно, значит, был найден множитель, и число не может быть простым числом.

Читайте также:  Что лечит препарат омник

Вот основная часть функции:

Здесь есть что распаковать, так что давайте рассмотрим это шаг за шагом.

Внутри цикла while оператор по модулю проверяет, делится ли num без остатка на i :

После завершения цикла while код проверяет, не были ли найдены какие-либо дополнительные факторы:

Если в списке factors существует более одного кортежа, то num не может быть простым числом. Для непростых чисел коэффициенты распечатываются. Для простых чисел функция печатает сообщение о том, что num является простым числом.

Как реализовать шифрование ↑

Оператор деления по модулю в Python может использоваться для создания шифров. Шифр એ — это тип алгоритма для выполнения шифрования и дешифрования входных данных, обычно текста. В этом разделе вы познакомитесь с двумя шифрами: шифр Цезаря и шифр Виженера.

Шифр Цезаря

Шифр Цезаря работает, взяв зашифровываемую букву и сдвинув ее на определенное количество позиций влево или вправо в алфавите. Какая бы буква ни была в этой позиции, используется как зашифрованный символ. Это же значение сдвига применяется ко всем символам в строке.

Например, если смена была 5, затем A сдвинется на пять букв вверх, чтобы стать F, B станет G и так далее. Ниже вы можете увидеть процесс шифрования текста REALPYTHON со сдвигом 5:

В результате получается шифр WJFQUDYMTS.

Расшифровка шифра выполняется изменением сдвига в обратном направлении. Процессы шифрования и дешифрования можно описать следующими выражениями, где char_index — это индекс символа в алфавите:

Этот шифр использует оператор по модулю, чтобы гарантировать, что при сдвиге буквы индекс будет перебираться, если будет достигнут конец алфавита. Теперь, когда вы знаете, как работает этот шифр, взгляните на его реализацию:

decrypt включена, так что одна функция может использоваться для обработки как шифрования, так и дешифрования. Эта реализация может обрабатывать только буквенные символы, поэтому функция сначала проверяет, является ли текст буквенным символом в кодировке ASCII:

Затем функция определяет три переменные для хранения символов ASCII нижнего регистра, символов ASCII верхнего регистра и результатов шифрования или дешифрования:

Наконец, caesar_cipher() перебирает отдельные символы в тексте и выполняет следующие действия для каждого символа:

После завершения цикла перебора текстового значения возвращается результат:

Вот еще раз полный код:

Теперь запустите код в Python REPL, используя текст meetMeAtOurHideOutAtTwo со сдвигом 10 :

С шифром Цезаря интересно поиграть, чтобы познакомиться с криптографией. Хотя шифр Цезаря редко используется сам по себе, он является основой для более сложных подстановочных шифров. В следующем разделе вы познакомитесь с одним из потомков шифра Цезаря, шифром Виженера.

Шифр Виженера

Шифр Виженера એ — это полиалфавитный шифр подстановки. Для шифрования он использует разные шифры Цезаря для каждой буквы входящего текста. Шифр Виженера использует ключевое слово, чтобы определить, какой шифр Цезаря следует использовать для поиска буквы шифра.

Вы можете увидеть пример процесса шифрования на следующем изображении. В этом примере вводимый текст REALPYTHON зашифрован с использованием ключевого слова MODULO:

Для каждой буквы входящего текста REALPYTHON используется буква ключевого слова MODULO, чтобы определить, какой столбец шифра Цезаря следует выбрать. Если ключевое слово короче вводимого текста, как в случае с MODULO, то буквы ключевого слова повторяются до тех пор, пока все буквы вводимого текста не будут зашифрованы.

Ниже представлена ​​реализация шифра Виженера. Как вы увидите, оператор деления по модулю используется в функции дважды:

Вы могли заметить, что подпись для vigenere_cipher() очень похожа на caesar_cipher() из предыдущего раздела:

В приведенном выше коде вы можете увидеть, как функция впервые использует оператор деления по модулю:

Для каждой буквы входящего текста несколько шагов определяют, как ее зашифровать или расшифровать:

Взгляните на эти шаги в приведенном ниже коде:

Вы можете видеть, что индексы для расшифровки и шифрования рассчитываются по-разному. Поэтому в этой функции используется расшифровка. Таким образом, вы можете использовать эту функцию как для шифрования, так и для дешифрования.

После определения индекса вы обнаружите, что функция использует оператор по модулю во второй раз:

index % 26 гарантирует, что индекс символа не превышает 25, таким образом гарантируя, что он остается внутри алфавита. С помощью этого индекса зашифрованный или дешифрованный символ выбирается из верхнего регистра и добавляется к результатам.

Вот еще раз полный код шифра Виженера:

Теперь запустите его в Python REPL:

Хорошо! Теперь у вас есть рабочий шифр Виженера для шифрования текстовых строк.

Расширенные возможности оператора деления по модулю Python ↑

Использование оператора деления по модулю Python с decimal.Decimal ↑

Вот несколько примеров использования целых чисел с decimal.Decimal и оператором по модулю:

Вот некоторые числа с плавающей запятой, используемые с decimal.Decimal и оператором деления по модулю:

Как видно из приведенных выше примеров, работа с decimal.Decimal и оператором деления по модулю аналогична работе с другими числовыми типами. Вам просто нужно иметь в виду, как он определяет знак результата при работе с отрицательным операндом.

В следующем разделе вы увидите, как можно переопределить оператор по модулю в своих классах, чтобы настроить его поведение.

Использование оператора деления по модулю Python с настраиваемыми классами ↑

Сейчас, если вы помните из приведенного выше раздела о преобразовании единиц, convert_minutes_to_day() использовал оператор Python деления по модулю для преобразования total_mins в дни, часы и минуты. Теперь вы реализуете модифицированную версию этого метода, чтобы увидеть, как можно использовать свой собственный класс с оператором деления по модулю:

Если вы загрузите этот модуль в Python REPL, вы можете использовать его следующим образом:

Вот полный код после изменений:

Теперь, вызвав код в Python REPL, вы увидите, что он намного лаконичнее:

Заключение ↑

На первый взгляд, оператор деления по модулю Python может не привлечь вашего внимание. Тем не менее, как вы видели, в этом скромном операторе есть так много всего. Вы увидели множество различных применений оператора деления по модулю, от проверки чётности чисел до шифрования текста.

В этом уроке вы узнали, как:

Благодаря знаниям, полученным в этом уроке, теперь вы сможете с большим успехом начать использовать оператор деления по модулю в своем собственном коде. Удачного питонинга!

Опубликовано Вадим В. Костерин

ст. преп. кафедры ЦЭиИТ. Автор более 130 научных и учебно-методических работ. Лауреат ВДНХ (серебряная медаль). Посмотреть больше записей

Источник

Библиотека с советами