Всем здрасте!
В прошлый раз мы научились работать с переменными, а те кто сделал ДЗ уже знакомы с доступными функциями LUA в прошивке нашего шлюза и собственно дальнейшие уроки ему ни к чему)
Сегодня поговорим о ветвлениях или конструкции ЕСЛИ ТО ИНАЧЕ ВСЁ или If Then Else End и затронем логику.
Ветвления
Помните, в детстве нам родители твердили: "Учись хорошо и будешь успешным и богатым"? Давайте напишем тоже самое на языке программирования
Другими словами: "ЕСЛИ Хорошо учишься, ТО Будешь успешным, ИНАЧЕ Будешь депутатом ВСЁ. Таким образом у нас был выбор кем стать: богатым депутатом или просто богатым.
Так и в программировании: линейное исполнение кода не интересно почти никогда. В нашем шлюзе примером линейного скрипта может быть разве что только скрипт инициализации init.lua, который выполняется каждый раз при загрузке системы и служит для того, чтобы создать объекты, инициализировать таймеры или скажем включить сетевой лог (os.udplogenable(true)) или запустить синхронизацию времени (os.ntp()) - в общем выполнить все те действия, которые не сохраняются при перезагрузке.
В самом простом случае ветвление записывается так
Суть конструкции ветвления в том, что при выполнении заданного условия, должно выполниться одно действие, а при невыполнении - другое. Условие - это логическое выражение, результатом которого должно быть ЛОЖЬ (False) или ИСТИНА (True). Если результатом выражения будет ИСТИНА, то выполнятся инструкции между THEN и END, а если ЛОЖЬ, то инструкции пропускаются. Например:
Что здесь происходит? Оператор ">" сравнивает значения слева и справа и если значение слева БОЛЬШЕ значения справа, то возвращает True, а если это не так - False. Для моделирования выражения, можно выводить их сразу STDOUT:
Также имеются и другие операторы сравнения:
">=" - больше либо равно
"<" - меньше
"<=" - меньше либо равно
"~=" - не равно
"==" - равно.
Не путайте операторы "=" и "=="!
"=" используется для присваивания значений переменным
"==" используется для сравнения значений
И, все эти операторы можно использовать в выражениях If.
Вспомните, когда мы определяли жизненный путь, мы четко выбирали кем стать. А можно ведь просто не учиться и будь, что будет
Так вот используя ELSE (Иначе) можно четко определять какие инструкции выполнять в случае истинного выражения, а какие в случае ложного.
Кстати, ту конструкцию можно записать и так:
И, это будет правильно, хотя трушные программисты так не делают.
А как описать, например анекдот:
Гиви!
Будешь учиться на пятерки куплю тебе черную Волгу!
Будешь учится на четверки куплю тебе белую Волгу!
Будешь учиться на тройки куплю тебе зеленную Волгу — езди как дурак!
Нам понадобится дополнительная проверка ELSEIF
Однако, стоит заметить, что такая конструкция не дает однозначных ветвлений. То есть если оценка 5 - "Черная Волга", если 4 - "Белая Волга", а для всех остальных оценок - "Зелёная". Об этом следует помнить. Чтобы не было разночтений, не используется последний блок else.
Следует заметить, что в LUA нет конструкции Switch Case. Она успешно заменяется описанной выше конструкцией. А блок Default конструкции Switch Case заменяется последним блоком ELSE. Например, обработка состояния zigbee кнопки может выглядеть так:
Логика
Помните, в первом уроке, в четвертой задаче, мы определяли попадает ли влажность в заданный интервал? Давайте вспомним. Мы хотим, чтобы увлажнитель работал в диапазоне значений влажности от 40 до 60 процентов. А проверяли мы это конструкцией
if (Event.State.Value < 40) then
-- вкл
elseif (Event.State.Value > 60) then
-- выкл
end
Если влажность меньше 40% - включить, иначе если больше 60% - выключить Тоже самое мы можем записать изящнее:
if (Event.State.Value > 40) and (Event.State.Value < 60) then
-- вкл
else
-- выкл
end
Теперь читается так: Если влажность больше 40% и меньше 60% - включить, а в остальных случаях выключить.
Многие скажут: "А почему бы не записать так:"
if 40 < Event.State.Value < 60 then
Выглядит логично, но работать не будет. Потому что интерпретатор сначала сравнивает переменную с 40 и если получится False и выражение примет вид False < 60. Можете сказать что меньше: шестьдесят или ложь? Нет? Вот и интерпретатор не сможет.
Оператор and работает следующим образом: "берёт" два операнда (два значения: слева и справа) и возвращает true, если оба они истинные, или false, если хотя бы один из них ложный. Оператор and также известен как: "и", конъюнкция, логическое умножение.
true and true -> true
true and false -> false
false and true -> false
false and false -> fals
Также имеются еще два логических оператора or и not.
Оператор or возвращает true, если хотя бы один из операндов истинен: (или левый, или правый, или оба сразу). Также известен как: "или", дизъюнкция, логическое сложение.
true or true -> true
true or false -> true
false or true -> true
false or false -> false
Оператор not принимает только один операнд и инвертирует его также известен как: "не", инверсия.
not true -> false -- ложь - не истина!
not false -> true -- истина - не ложь!
Помните конструкцию:
if study_well ~= true then
print("Будешь депутатом!")
end
Теперь мы можем записать ее так:
if not study_well then
print("Будешь депутатом!")
end
Кстати, true и false - так же как и обычные значения можно присваивать переменным. Переменные, имеющие логическое значение true или false, на трушные программисты часто называются флагами, наподобие флажков на почтовых ящиках. Флажок поднят (true) - почта пришла, флажок опущен (false) - почты нет. Вот и в примере выше мы использовали такой флаг study_well.
Заметьте, что сравнивать flag с true необязательно: его значение уже имеет логический тип. Только не забывайте, что flag должен быть именно логической переменной. Иначе вы будете проверять не истинность флага, а его наличие как переменной.
Теперь поговорим про nil. NIL - штука важная! Очень много ходовых приёмов программирования на Lua основано на махинациях с этим значением.
Во-первых, если не считать одно исключение, в контексте логических операций nil трактуется как false. Таким образом:
Во-вторых, нелогическое значение в условии if трактуется как истинное, если оно не равно nil, и как ложное, если оно равно nil
Помните, я говорил, что nil не равно 0? Следующий код может вызвать недоумение программистов на С, но он совершенно корректен, так как nil не равен 0.
Таким образом вы можете проверить существование переменной.
Домашнее задание
Все тоже: попробовать осилить референс по функциям, поддерживаемых прошивкой SLS. Хотя бы скачать и полистать книгу по LUA, например эту.
Что дальше
На следующем уроке будем проходить циклы и возможно массивы, они же переменные типа table. Так что подписывайтесь, читайте, ставьте лайки и пишите комментарии. Делайте ДЗ. Пока, пока!
----------
Листинги скриптов
Поддержать канал
Заказать обучение
Поболтать, обсудить вопросы по уроку