Модуль игрек равен икс: Функция y = |x| — урок. Алгебра, 8 класс.

Урок №2 — Программирование движения робота

Содержание урока

Введение:

2.1. Палитры программирования и программные блоки

2.2. Зеленая палитра – блоки действия

2.3. Прямолинейное движение, повороты, разворот на месте остановка

2.4. Экран, звук, индикатор состояния модуля 

Введение:

На втором занятии мы детальнее познакомимся со средой программирования и подробно изучим команды, задающие движение нашему роботу-тележке, собранному на первом занятии. Итак, давайте запустим среду программирования Lego mindstorms EV3, загрузим наш проект lessons.ev3, созданный ранее и добавим в проект новую программу — lesson-2-1. Программу можно добавить двумя способами:

  • Выбрать команду «Файл»-«Добавить программу» (Ctrl+N).
  • Нажать «+» на вкладке программ.

Рис. 1

2.1. Палитры программирования и программные блоки

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

Зеленая палитра называется: «Действие»:

Рис. 2

На данной палитре расположены программные блоки управления моторами, блок вывода на экран, блок управления индикатором состояния модуля. Сейчас мы начнем изучение этих программных блоков.

2.2. Зеленая палитра – блоки действия

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

Рис. 3

Для правильной настройки блока управления большим мотором мы должны:

  1. Выбрать порт, к которому подключен мотор
    (A, B, C или D) (Рис. 3 поз. 1)
  2. Выбрать режим работы мотора (Рис. 3 поз. 2)
  3. Настроить параметры выбранного режима (Рис. 3 поз. 3)

Чем же отличаются режимы? Режим: «Включить» включает мотор с заданным параметром «Мощность» и после этого управление передается следующему программному блоку программы. Мотор будет продолжать вращаться, пока не будет остановлен следующим блоком «Большой мотор» с режимом «Выключить» или следующий блок «Большой мотор» не будет содержать другие параметры выполнения. Режим «Включить на количество секунд» включает большой мотор с установленной мощностью на указанное количество секунд, и только по завершению времени мотор остановится, а управление в программе перейдет к следующему программному блоку. Аналогично поведет мотор себя в режимах

«Включить на количество градусов» и «Включить на количество оборотов»: только после выполнения установленного вращения мотора, он остановится и управление в программе перейдет к следующему блоку.  

Параметр мощность (на Рис. 3 мощность установлена в 75) может принимать значения от -100 до 100. Положительные значения мощности задают вращение мотора по часовой стрелке, отрицательные — против часовой. При значении мощности равном 0 мотор вращаться не будет, чем «выше» значение мощности, тем быстрее вращается мотор.

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

Отдельно следует сказать о параметре

«Тормозить в конце». Данный параметр, если установлен в значение «Тормозить» заставляет мотор тормозить после выполнения команды, а если установлен в значение «Двигаться накатом», то мотор будет вращаться по инерции, пока сам не остановится.

Следующие два программных блока «Рулевое управление» и «Независимое управление моторами» реализуют управление парой больших моторов. По умолчанию левый большой мотор подключается к порту «В», а правый — к порту «С». Но вы можете в настройках блока поменять порты подключения в соответствии с требованиями вашей конструкции (Рис. 4 поз. 1).

Рис. 4

Параметр «Рулевое управление» (Рис. 4 поз. 2) может принимать значения от -100 до 100. Отрицательные значения параметра заставляют робота поворачивать налево, при значении равном 0 робот движется прямо, а положительные значения заставляют робота поворачивать направо. Стрелка над числовым параметром меняет свою ориентацию в зависимости от значения, подсказывая тем самым направление движения робота (

Рис. 5).

Рис. 5

Программный блок «Независимое управление моторами» похож на программный блок «Рулевое управление». Он также управляет двумя большими моторами, только вместо параметра «Рулевое управление» появляется возможность независимого управления мощностью каждого мотора. При равном значении параметра «Мощность» для левого и правого мотора робот будет двигаться прямолинейно. Если на один мотор подать отрицательное значение мощности (например -50), а на второй — положительное значение (например 50), то робот будет разворачиваться на месте (

Рис. 6).

Рис. 6

Режимы работы этих блоков аналогичны режимам блока управления одним мотором, поэтому дополнительного описания не требуют…

2.3. Прямолинейное движение, повороты, разворот на месте остановка

Итак, теперь мы можем написать программу движения робота по какому-либо маршруту.

Задача 1: Проехать прямолинейно вперед на 4 оборота двигателя. Развернуться. Проехать на 720 градусов.

Решение (Рис. 7):

  1. Используя программный блок «Рулевое управление» проехать вперед на 4 оборота.
  2. Используя программный блок «Независимое управление моторами» развернуться на месте (значение градусов придется подобрать экспериментально).
  3. Используя программный блок «Рулевое управление» проехать вперед на 720 градусов.

Примечание: Почему при развороте пришлось подбирать значение градусов в блоке 2?. Разве не 360 градусов — искомая величина? Нет, если мы зададим значение параметра «Градусы» равным 360, то тем самым заставим на искомую величину провернуться валы левого и правого моторов нашего робота. На какой угол провернется робот вокруг своей оси — зависит от размера (диаметра) колес и расстояния между ними. На Рис. 7 значение параметра «Градусы» равно 385. Данное значение позволяет роботу, собранному по инструкции small-robot 45544 развернуться вокруг своей оси. Если у вас другой робот, то вам придется подобрать другое значение. Можно ли это значение найти математически? Можно, но об этом мы поговорим позднее. 

Рис. 7

Задача 2: Установите на ровной поверхности какое-либо препятствие (банку, кубик, небольшую коробку), отметьте место старта вашего робота.

Создайте в проекте новую программу: lesson-2-2, позволяющую роботу объехать вокруг препятствия и вернуться к месту старта.

Сколько программных блоков вы использовали? Поделитесь своим успехом в комментарии к уроку…

2.4. Экран, звук, индикатор состояния модуля 

Программный блок «Экран» позволяет выводить текстовую или графическую информацию на жидкокристаллический экран блока EV3. Какое это может иметь практическое применение? Во-первых, на этапе программирования и отладки программы можно выводить на экран текущие показания датчиков во время работы робота. Во-вторых, можно выводить на экран название промежуточных этапов выполнения программы. Ну а в-третьих, с помощью графических изображений можно «оживить» экран робота, например с помощью мультипликации. 

Рис. 8

Программный блок

«Экран» имеет четыре режима работы: режим «Текст» позволяет выводить текстовую строку на экран, режим «Фигуры» позволяет отображать на экране одну из четырех геометрических фигур (прямая, круг, прямоугольник, точка), режим «Изображение» может вывести на экран одно изображение. Изображение можно выбрать из богатой коллекции изображений или нарисовать свое, используя редактор изображений. Режим «Окно сброса настроек» сбрасывает экран модуля EV3 к стандартному информационному экрану, показываемому во время работы программы.

Рис. 9

Рассмотрим параметры программного блока «Экран» в режиме «Текст» (Рис. 9 поз.1). Строка, предназначенная для вывода на экран, вводится в специальное поле (Рис. 9 поз. 2). К сожалению, в поле ввода текста можно вводить только буквы латинского алфавита, цифры и знаки препинания. Если режим

«Очистить экран» установлен в значение «Истина», то экран перед выводом информации будет очищен. Поэтому, если вам требуется объединить текущий вывод с информацией уже находящейся на экране, то установите этот режим в значение «Ложь». Режимы «X» и «Y» определяют точку на экране, с которой начинается вывод информации. Экран блока EV3 имеет 178 пикселей (точек) в ширину и 128 пикселей в высоту. Режим «X» может принимать значения от 0 до 177, режим «Y» может принимать значения от 0 до 127. Верхняя левая точка имеет координаты (0, 0), правая нижняя (177, 127)

Рис. 10

Во время настройки программного блока «Экран» можно включить режим предварительного просмотра

(Рис. 9 поз. 3) и визуально оценить результат настроек вывода информации.

В режиме «Фигуры» (Рис. 11 поз. 1) настройки программного блока меняются в зависимости от типа фигуры. Так при отображении круга необходимо будет задать координаты «X» и «Y» центра окружности, а также значение «Радиуса». Параметр «Заполнить» (Рис. 11 поз. 2) отвечает за то, что будет отображен либо контур фигуры, либо внутренняя область фигуры будет заполнена цветом, заданным в параметре «Цвет» (Рис. 11 поз. 3).

Рис. 11

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

Рис. 12

Чтобы отобразить прямоугольник следует задать координаты

«X» и «Y» левого верхнего угла прямоугольника, а также его «Ширину» и «Высоту».

Рис. 13

Отобразить точку проще всего! Укажите лишь её координаты «X» и «Y».

Режим «Изображение», наверное, самый интересный и самый используемый режим. Он позволяет выводить на экран изображения. Среда программирования содержит огромную библиотеку изображений, отсортированную по категориям. В дополнение к имеющимся изображениям вы всегда можете создать свой рисунок и, вставив его в проект, вывести на экран. («Главное меню среды программирования» — «Инструменты» — «Редактор изображения»). Создавая своё изображение, вы можете также вывести на экран символы русского алфавита.

Рис. 14

Как вы видите — отображению информации на экране главного модуля EV3 среда программирования придает огромное значение. Давайте рассмотрим следующий важный программный блок «Звук». С помощью этого блока мы можем выводить на встроенный динамик блока EV3 звуковые файлы, тона произвольной длительности и частоты, а также музыкальные ноты. Давайте рассмотрим настройки программного блока в режиме «Воспроизвести тон» (Рис. 15). В этом режиме необходимо задать «Частоту» тона (Рис. 15 поз. 1), «Продолжительность» звучания в секундах (Рис. 15 поз. 2), а также громкость звучания (Рис. 15 поз. 3).

Рис. 15

В режиме «Воспроизвести ноту» вам вместо частоты тона необходимо выбрать ноту на виртуальной клавиатуре, а также установить длительность звучания и громкость (Рис. 16)

Рис. 16

В режиме «Воспроизвести файл» вы можете выбрать один из звуковых файлов из библиотеки (Рис. 17 поз. 1), либо, подключив к компьютеру микрофон, с помощью Редактора звука («Главное меню среды программирования» — «Инструменты» — «Редактор звука») записать собственный звуковой файл и включить его в проект.

Рис. 17

Давайте отдельно рассмотрим параметр «Тип воспроизведения» (Рис. 17 поз. 2), общий для всех режимов программного блока «Звук». Если данный параметр установлен в значение «Ожидать завершения», то управление следующему программному блоку будет передано  только после полного воспроизведения звука или звукового файла. В случае установки одного из двух следующих значений начнется воспроизведение звука и управление в программе перейдет к следующему программному блоку, только звук или звуковой файл будет воспроизведен один раз или будет повторяться, пока не его не остановит другой программный блок «Звук».

Нам осталось познакомиться с последним программным блоком зеленой палитры — блоком «Индикатор состояния модуля». Вокруг кнопок управления модулем EV3 смонтирована цветовая индикация, которая может светиться одним из трех цветов: зеленым, оранжевым или красным. За включение — выключение цветовой индикации отвечает соответствующий режим (Рис. 18 поз. 1). Параметр «Цвет» задает цветовое оформление индикации (Рис. 18 поз. 2). Параметр «Импульсный» отвечает за включение — отключение режима мерцания цветовой индикации (Рис. 18 поз. 3). Как можно использовать цветовую индикацию? Например, можно во время различных режимов работы робота использовать различные цветовые сигналы. Это поможет понять: так ли выполняется программа, как мы запланировали.

Рис. 18

 Давайте используем полученные знания на практике и немного «раскрасим» нашу программу из Задачи 1.  

Задача 3: 

  1. Воспроизвести сигнал «Start»
  2. Включить зеленую немигающую цветовую индикацию
  3. Отобразить на экране изображение «Forward»
  4. Проехать прямолинейно вперед на 4 оборота двигателя.
  5. Включить оранжевую мигающую цветовую индикацию
  6. Развернуться
  7. Включить зеленую мигающую цветовую индикацию
  8. Отобразить на экране изображение «Backward»
  9. Проехать на 720 градусов
  10. Воспроизвести сигнал «Stop»

Попробуйте решить задачу 3 самостоятельно, не подглядывая в решение! Удачи!

Решение задачи 3

Оператор

— Стандартные операторы как функции — Документация по Python 3.11.2

Исходный код: Lib/operator.py


Модуль оператора экспортирует набор эффективных функций, соответствующих внутренние операторы Python. Например, operator.add(x, y) — это эквивалентно выражению x+y . Многие имена функций используются для специальные методы, без двойных подчеркиваний. Для обратной совместимости, многие из них имеют вариант с сохранением двойного подчеркивания. Варианты без двойных подчеркиваний предпочтительнее для ясности.

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

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

operator.lt( a , b )
operator.le( a , b )
operator.eq( a , b )
оператор.ne( а , б )
operator.ge( a , b )
operator.gt( a , b )
оператор.__lt__( a , b )
оператор. __le__( a , b )
оператор.__eq__( a , b )
оператор.__ne__( a , b )
оператор.__ge__( a , b )
оператор.__gt__( а , б )

Выполнение «расширенных сравнений» между a и b . В частности, lt(a, b) является эквивалентно a < b , le(a, b) эквивалентно a <= b , eq(a, б) эквивалентно a == b , ne(a, b) эквивалентно a != b , gt(a, b) эквивалентно a > b и ge(a, b) эквивалентно а >= б . Обратите внимание, что эти функции могут возвращать любое значение, которое может или не может интерпретироваться как логическое значение. Видеть Сравнения для получения дополнительной информации о расширенных сравнениях.

Логические операции также обычно применимы ко всем объектам и поддерживают проверки истинности, проверки подлинности и логические операции:

оператор. не_( объект )
оператор.__не__( объект )

Вернуть результат не объект . (Обратите внимание, что нет __not__() метод для экземпляров объекта; только ядро ​​интерпретатора определяет эта операция. На результат влияют __bool__() и __len__() методов.)

оператор.правда( obj )

Возврат True , если obj истинен, и False в противном случае. Это эквивалентно использованию конструктора bool .

operator.is_( a , b )

Возврат a is b . Проверяет идентичность объекта.

operator.is_not( a , b )

Возврат a не b . Проверяет идентичность объекта.

Наиболее многочисленны математические и побитовые операции:

operator. abs( obj )
оператор.__abs__( объект )

Вернуть абсолютное значение obj .

оператор. добавить ( a , b )
оператор.__добавить__( a , b )

Возврат a + b , для номеров a и b .

оператор.и_( a , b )
оператор.__и__( a , b )

Возвращает побитовое и из а и б .

оператор.floordiv( a , b )
оператор.__floordiv__( a , b )

Возврат а // б .

оператор.индекс( a )
оператор.__index__( a )

Возвращает a , преобразованное в целое число. Эквивалентно a.__index__() .

Изменено в версии 3.10: Результат всегда имеет точный тип интервал . Ранее результат мог быть экземпляром подкласса int .

оператор.inv( obj )
оператор.инвертировать( объект )
оператор.__inv__( объект )
оператор.__invert__( объект )

Возвращает побитовое обратное число obj . Это эквивалентно ~obj .

оператор.lshift( а , б )
оператор.__lshift__( a , b )

Возврат a сдвиг влево на b .

оператор.mod( a , b )
оператор.__mod__( a , b )

Возврат а % б .

оператор.mul( a , b )
оператор.__mul__( a , б )

Возврат a * b , для номеров a и b .

оператор. matmul( a , b )
оператор.__matmul__( a , b )

Возврат a @ b .

Новое в версии 3.5.

operator.neg( obj )
оператор.__отрицательный__( объект )

Возврат obj инвертируется ( -obj ).

оператор.or_( a , b )
оператор.__или__( a , b )

Возвращает побитовое или a и b .

оператор.pos( obj )
оператор.__pos__( объект )

Возврат объект положительный ( + объект ).

оператор.pow( a , b )
оператор.__pow__( a , b )

Возврат a ** b , для номеров a и b .

оператор. rshift( a , b )
оператор.__rshift__( a , b )

Возврат a сдвинут вправо на b .

оператор.sub( а , б )
оператор.__sub__( a , b )

Возврат а - б .

оператор.truediv( a , b )
оператор.__truediv__( a , b )

Возврат a / b , где 2/3 равно 0,66, а не 0. Это также известно как «истинное» деление.

оператор.xor( a , b )
оператор.__xor__( a , b )

Возвращает побитовое исключающее или a и b .

Операции, которые работают с последовательностями (некоторые из них также с отображениями), включают:

оператор.concat( a , b )
оператор. __concat__( a , b )

Возврат a + b для последовательностей a и b .

оператор.содержит( a , b )
оператор.__содержит__( a , b )

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

operator.countOf( a , b )

Возвращает количество вхождений b в a .

operator.delitem( a , б )
оператор.__delitem__( a , b )

Удалить значение a в индексе b .

оператор.getitem( a , b )
оператор.__getitem__( a , b )

Вернуть значение a по индексу b .

operator.indexOf( a , b )

Возвращает индекс первого вхождения b в a .

оператор.setitem( a , b , c )
оператор.__setitem__( a , b , c )

Установить значение a в индексе b на c .

operator.length_hint( объект , по умолчанию=0 )

Возвращает расчетную длину объекта o . Сначала попробуйте вернуть его фактическая длина, затем оценка с использованием object.__length_hint__() и наконец, вернуть значение по умолчанию.

Новое в версии 3.4.

Следующая операция работает с вызываемыми объектами:

operator.call( obj , /, *args , **kwargs )
оператор.__вызов__( объект , /, *args , **kwargs )

Возврат obj(*args, **kwargs) .

Новое в версии 3.11.

Модуль оператора также определяет инструменты для обобщенного атрибута и элемента поиск. Они полезны для создания быстрых экстракторов полей в качестве аргументов для map() , sorted() , itertools.groupby() или другие функции, которые ожидать аргумент функции.

operator.attrgetter( атр )
operator.attrgetter( *attrs )

Возвращает вызываемый объект, который извлекает attr из своего операнда. Если запрашивается более одного атрибута, возвращает кортеж атрибутов. Имена атрибутов также могут содержать точки. Например:

  • После f = attrgetter('name') вызов f(b) возвращает b.name .

  • После f = attrgetter('имя', 'дата') , вызов f(b) возвращается (имя рождения, дата рождения) .

  • После f = attrgetter('name.first', 'name.last') , вызов f(b) возвращает (b.name.first, b.name.last) .

Эквивалент:

 def attrgetter(*items):
    если есть (не isinstance (item, str) для элемента в элементах):
        поднять TypeError('имя атрибута должно быть строкой')
    если len(items) == 1:
        атрибут = элементы [0]
        определение г (объект):
            вернуть resolve_attr (obj, attr)
    еще:
        определение г (объект):
            вернуть кортеж (resolve_attr (obj, attr) для attr в элементах)
    вернуть г
def resolve_attr (obj, attr):
    для имени в attr.split("."):
        obj = getattr(obj, имя)
    вернуть объект
 
operator.itemgetter( пункт )
operator.itemgetter( *items )

Вернуть вызываемый объект, который извлекает элемент из своего операнда, используя метод операнда __getitem__() . Если указано несколько элементов, возвращает кортеж поисковых значений. Например:

  • После f = itemgetter(2) вызов f(r) возвращает r[2] .

  • После g = itemgetter(2, 5, 3) вызов g(r) возвращает значение (г[2], г[5], г[3]) .

Эквивалент:

 дефгеттер(*items):
    если len(items) == 1:
        предмет = предметы[0]
        определение г (объект):
            вернуть объект[предмет]
    еще:
        определение г (объект):
            возвращаемый кортеж (obj[item] для элемента в элементах)
    вернуть г
 

Элементы могут быть любого типа, допустимого операндом __getitem__() метод. Словари принимают любое хешируемое значение. Списки, кортежи и строки принимают индекс или срез:

 >>> пункт получения(1)('ABCDEFG')
'Б'
>>> элементгеттер(1, 3, 5)('ABCDEFG')
(«Б», «Д», «Ф»)
>>> itemgetter(slice(2, None))('ABCDEFG')
'CDEFG'
>>> солдат = dict(rank='капитан', name='dotterbart')
>>> itemgetter('ранг')(солдат)
'капитан'
 

Пример использования itemgetter() для извлечения определенных полей из запись кортежа:

 >>> inventory = [('яблоко', 3), ('банан', 2), ('груша', 5), ('апельсин', 1)]
>>> getcount = элементполучатель(1)
>>> список(карта(getcount, инвентарь))
[3, 2, 5, 1]
>>> отсортировано(инвентарь, ключ=getcount)
[('апельсин', 1), ('банан', 2), ('яблоко', 3), ('груша', 5)]
 
operator. methodcaller( имя , /, *args , **kwargs )

Вернуть вызываемый объект, который вызывает метод с именем для своего операнда. Если даны дополнительные аргументы и/или аргументы ключевого слова, они будут переданы к методу тоже. Например:

  • После f = methodcaller('name') вызов f(b) возвращает b.name() .

  • После f = methodcaller('name', 'foo', bar=1) , вызов f(b) возвращает b.name('foo', bar=1) .

Эквивалент:

 def methodcaller(name, /, *args, **kwargs):
    вызывающий абонент (obj):
        вернуть getattr(obj, name)(*args, **kwargs)
    перезвонить
 

Преобразование операторов в функции

В этой таблице показано, как абстрактные операции соответствуют символам операторов в Синтаксис Python и функции в оператор модуль.

Эксплуатация

Синтаксис

Функция

Дополнение

а + б

добавить(а, б)

Объединение

последовательность 1 + последовательность 2

concat(seq1, seq2)

Проверка сдерживания

объект в последовательности

содержит (seq, obj)

Отдел

а/б

truediv(a, b)

Отдел

а // б

полдив(а, б)

909б

xor(a, b)

Побитовая инверсия

~

инвертированный(а)

Побитовый или

а | б

или_(а, б)

Возведение в степень

а ** б

мощность(а, б)

Идентификация

а есть б

ис_(а, б)

Идентификация

а не б

is_not(a, b)

Индексированное назначение

обж[к] = v

setitem(obj, k, v)

Индексированное удаление

объект [к]

разделитель(объект, к)

Индексация

обж[к]

getitem(obj, k)

Сдвиг влево

а << б

lshift(a, b)

Модуль

а % б

мод(а, б)

Умножение

а * б

мул(а, б)

Умножение матриц

а @ б

матмуль(а, б)

Отрицание (арифметическое)

-

отрицательный(а)

Отрицание (логическое)

не

не_(а)

Положительный

+

поз(а)

Правый сдвиг

а >> б

rshift(a, b)

Назначение среза

seq[i:j] = значения

setitem(seq, slice(i, j), values)

Удаление фрагмента

последовательность [i:j]

разделитель (последовательность, срез (i, j))

Нарезка

сл[и:к]

getitem(seq, slice(i, j))

Форматирование строк

с % обж

мод(ы, объект)

Вычитание

а - б

под(а, б)

Проверка правды

объект

истина(объект)

Заказ

а < б

л(а, б)

Заказ

а <= б

ле(а, б)

Равенство

а == б

экв(а, б)

Разница

а != б

пе(а, б)

Заказ

а >= б

гэ(а, б)

Заказ

а > б

гт(а, б)

Операторы на месте

Многие операции имеют версию «на месте». Ниже перечислены функции предоставление более примитивного доступа к операторам на месте, чем обычный синтаксис делает; например, оператор x += y эквивалентен х = оператор.iadd(x, y) . Другой способ выразить это - сказать, что z = operator.iadd(x, y) эквивалентно составному оператору г = х; г += у .

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

Для неизменяемых целей, таких как строки, числа и кортежи, обновленный значение вычисляется, но не присваивается входной переменной:

 >>> а = 'привет'
>>> iadd(a, 'мир')
'Привет, мир'
>>> а
'привет'
 

Для изменяемых целей, таких как списки и словари, метод на месте выполнит обновление, поэтому последующее присвоение не требуется:

 >>> s = ['h', 'e', ​​'l', 'l', 'o']
>>> iadd(s, [' ', 'ж', 'о', 'р', 'л', 'д'])
['Привет, мир']
>>> с
['Привет, мир']
 
оператор. iadd( a , b )
оператор.__iadd__( a , b )

a = iadd(a, b) эквивалентно a += b .

оператор.iand( a , b )
оператор.__iand__( a , b )

a = iand(a, b) эквивалентно a &= b .

operator.iconcat( а , б )
оператор.__iconcat__( a , b )

a = iconcat(a, b) эквивалентно a += b для последовательностей a и b .

оператор.ifloordiv( a , b )
оператор.__ifloordiv__( a , b )

a = ifloordiv(a, b) эквивалентно a //= b .

оператор.ilshift( a , b )
оператор.__ilshift__( a , b )

a = ilshift(a, b) эквивалентно a <<= b .

оператор.imod( a , b )
оператор.__imod__( a , b )

a = imod(a, b) эквивалентно a %= b .

operator.imul( a , b )
оператор.__imul__( a , b )

a = imul(a, b) эквивалентно a *= b .

оператор.imatmul( a , b )
оператор.__imatmul__( a , b )

a = imatmul(a, b) эквивалентно a @= b .

Новое в версии 3.5.

operator.ior( a , b )
оператор.__ior__( a , b )

a = ior(a, b) эквивалентно a |= b .

оператор.ipow( a , b )
оператор.__ipow__( a , b )

a = ipow(a, b) эквивалентно a **= b .

operator.irshift( a , b )
оператор.__irshift__( a , b )

a = irshift(a, b) эквивалентно a >>= b .

оператор.isub( a , b )
оператор.__isub__( a , b )

a = isub(a, b) эквивалентно a -= b .

оператор.itruediv( 9= б .

Модули - F# | Microsoft Learn

  • Статья
  • 6 минут на чтение

В контексте F# модуль — это группа кода F#, например значений, типов и значений функций, в программе F#. Группировка кода в модулях помогает объединить связанный код и помогает избежать конфликтов имен в вашей программе.

Синтаксис

 // Объявление модуля верхнего уровня.
модуль [модификатор доступа] [полное пространство имен.]имя модуля
декларации
// Объявление локального модуля.
модуль [модификатор доступности] имя-модуля =
    декларации
 

Модуль F# — это группа конструкций кода F#, таких как типы, значения, значения функций и код в привязках do . Он реализован как класс общеязыковой среды выполнения (CLR), который имеет только статические члены. Существует два типа объявлений модулей, в зависимости от того, включен ли в модуль весь файл: объявление модуля верхнего уровня и объявление локального модуля. Объявление модуля верхнего уровня включает в себя весь файл в модуле. Объявление модуля верхнего уровня может появиться только как первое объявление в файле.

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

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

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

 // В файле program.fs.
пусть х = 40
 

Этот файл будет скомпилирован так, как если бы он был написан следующим образом:

 Модуль Программа
пусть х = 40
 

Если у вас есть несколько модулей в файле, вы должны использовать локальное объявление модуля для каждого модуля. Если объявлено объемлющее пространство имен, эти модули являются частью объемлющего пространства имен. Если окружающее пространство имен не объявлено, модули становятся частью неявно созданного модуля верхнего уровня. В следующем примере кода показан файл кода, содержащий несколько модулей. Компилятор неявно создает модуль верхнего уровня с именем Multiplemodules 9.0009 и MyModule1 и MyModule2 вложены в этот модуль верхнего уровня.

 // В файлеmultimodules.fs.
// МойМодуль1
модуль МойМодуль1 =
    // Все программные элементы внутри модулей, которые объявлены со знаком равенства, имеют отступ.
    пусть module1Value = 100
    пусть module1Function x =
        х + 10
// МойМодуль2
модуль МойМодуль2 =
    пусть module2Value = 121
    // Используйте полное имя для доступа к функции.
    // из MyModule1.
    пусть module2Function x =
        x * (МойМодуль1.модуль1Функциональный модуль2Значение)
 

Если у вас есть несколько файлов в проекте или в одной компиляции, или если вы создаете библиотеку, вы должны включить объявление пространства имен или объявление модуля в начало файла. Компилятор F# неявно определяет имя модуля только в том случае, если в проекте или командной строке компиляции есть только один файл, и вы создаете приложение.

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

Ссылка на код в модулях

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

Пространство имен1.Пространство имен2.Имя модуля.Идентификатор

Вы можете открыть модуль или одно или несколько пространств имен, чтобы упростить код. Дополнительные сведения об открытии пространств имен и модулей см. в разделе Объявления импорта: ключевое слово open .

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

 модуль Арифметика
добавим х у =
    х + у
пусть суб х у =
    х - у
 

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

 // Полное определение имени функции.
пусть результат1 = Арифметика.добавить 5 9
// Открываем модуль.
открытая арифметика
пусть результат2 = добавить 5 9
 

Вложенные модули

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

 модуль Y =
    пусть х = 1
    модуль Z =
        пусть г = 5
 

Но модуль Z является родственником модуля Y в следующем коде.

 модуль Y =
    пусть х = 1
модуль Z =
    пусть г = 5
 

Модуль Z также является родственным модулем в следующем коде, потому что он не имеет отступа по сравнению с другими объявлениями в модуле Y .

 модуль Y =
        пусть х = 1
    модуль Z =
        пусть г = 5
 

Наконец, если внешний модуль не имеет объявлений и сразу за ним следует объявление другого модуля, предполагается, что объявление нового модуля является внутренним модулем, но компилятор предупредит вас, если отступ определения второго модуля не превышает отступ первого .

 // Этот код выдает предупреждение, но рассматривает Z как внутренний модуль.
модуль Y =
модуль Z =
    пусть г = 5
 

Чтобы убрать предупреждение, сделайте углубление на внутреннем модуле.

 модуль Y =
    модуль Z =
        пусть г = 5
 

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

 // Объявление модуля верхнего уровня можно опустить, если файл называется
// TopLevel.fs или topLevel.fs, и это единственный файл в
// приложение.
модуль верхнего уровня
пусть topLevelX = 5
модуль Внутренний1 =
    пусть внутренний1X = 1
модуль Внутренний2 =
    пусть внутренний2X = 5
 

Рекурсивные модули

В F# 4.1 введено понятие модулей, которые позволяют всему содержащемуся коду быть взаимно рекурсивным. Это делается через модуль rec . Использование модуля rec может облегчить некоторые проблемы, связанные с невозможностью написания взаимоссылаемого кода между типами и модулями. Вот пример этого:

 запись модуля RecursiveModule =
    тип Ориентация = Вверх | Вниз
    тип PeelState = Очищенный | Неочищенный
    // Это исключение зависит от типа ниже.
    исключение DontSqueezeTheBananaИсключение банана
    тип Банан (ориентация: ориентация) =
        член val IsPeeled = false с get, set
        member val Orientation = ориентация с помощью get, set
        член val Стороны: список PeelState = [ Unpeeled; неочищенный; неочищенный; Неочищенный] с get, set
        member self. Peel() = BananaHelpers.peel self // Обратите внимание на зависимость от модуля BananaHelpers.
        член self.SqueezeJuiceOut() = поднять (DontSqueezeTheBananaException self) // Этот член зависит от исключения выше.
    модуль BananaHelpers =
        пусть очистит (б: Банан) =
            пусть флип (банан: банан) =
                соответствовать банану. Ориентация с
                | Вверх ->
                    банан.Ориентация <- Вниз
                    банан
                | Вниз -> банан
            пусть очищают стороны (банан: банан) =
                банан.Бока
                |> List.map (функция
                             | Неочищенный -> Очищенный
                             | Очищенный -> Очищенный)
            соответствие b.Ориентация с
            | Вверх -> b |> перевернуть |> очистить стороны
            | Вниз -> b |> очистить стороны
 

Обратите внимание, что исключение DontSqueezeTheBananaException и класс Banana ссылаются друг на друга.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *