Как я создал Web-App калькулятор в PuzzleBot ://

В сентябре разработчики PuzzleBot выпустили конструктор мини-приложений для Telegram ботов.
На рынке много конструкторов, но они либо шаблонные и негибкие, либо сложные. Я решил проверить гибкость конструктора и создать калькулятор. Казалось бы, просто бери и используй математические формулы и числа, подумал я, и решил собрать за один вечер. Как же я ошибался!
В итоге у меня получилось, но за неделю продумывания логики, тестов и исправления ошибок. Об этом я и расскажу в этой статье.

Я создал полноценный калькулятор, который имеет все основные математические операции с целыми и дробными числами. 
Я создал полноценный калькулятор, который имеет все основные математические операции с целыми и дробными числами. 
  • Приложение-калькулятор можете протестировать по ссылке: @MadeinPuzzleBot

1. Логика работы калькулятора

Чтобы создать калькулятор, нужно понять его внутреннюю логику. Проанализировав калькуляторы на iOS и Windows, я понял, что для последовательных вычислений нужны только 2 числа и оператор между ними.
Например, для выражения N1*N2+N3-N4 нам нужно всего 2 числа в каждой операции.

Как я создал Web-App калькулятор в PuzzleBot ://

2. Создание переменных

Я создал две переменные: {{number_1}} и {{number_2}} с форматом "Число"

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

А для операций «+», «-», «×», «÷» между этими числами создал 4 переменных, формат - "Формула"

{{sum}} = {{number_1}} + {{number_2}} {{diff}} = {{number_1}} - {{number_2}} {{product}} = {{number_1}} × {{number_2}} {{quotieent}} = {{number_1}} ÷ {{number_2}}
Переменные создаются в разделе Переменные бокового меню - Создать переменную - указать название, формат, значение.
Переменные создаются в разделе Переменные бокового меню - Создать переменную - указать название, формат, значение.

Логика работы калькулятора следующая:

  1. При вводе операции N1*N2 значения сохраняются в переменные {{number_1}} и {{number_2}}.
  2. При вводе следующего оператора «+» результат умножения N1*N2 из формулы произведения {{product}} записывается в {{number_1}}, а в {{number_2}} сохраняется новое число N3.
  3. Далее при вводе оператора «-» происходит сложение {{number_1}} (N1*N2) и {{number_2}} (N3).
  4. Все последующие операции выполняются аналогично: ответ записывается в {{number_1}}, а {{number_2}} перезаписывается следующим числом.
  5. Знак «=» выводит итог последней операции N3-N4, что равно итоговому результату всего выражения N1*N2+N3-N4.

Далее я создал еще 4 переменных:

1. {{display_text}} - для сохранения и отображения всей цепочки операций до знака "="
Как я создал Web-App калькулятор в PuzzleBot ://
2. {{BIG_display_text}} - для приема конкретного веденного числа и отображения итогового ответа
Это текстовая переменная и запись в нее будет происходить в фоновом режиме после каждой нажатой цифры по формуле: 
Это текстовая переменная и запись в нее будет происходить в фоновом режиме после каждой нажатой цифры по формуле: 
{{BIG_display_text}}= {{BIG_display_text}}+"N" Где N - это нажатая цифра

Запись всей операции в переменную {{display_text}} со всеми операторами происходит по такому же принципу

3. {{conver_number_1}} - переменная для передачи числа из текстовой переменной {{BIG_display_text}} в числовую {{number_2}}
Как я создал Web-App калькулятор в PuzzleBot ://

Для чего, объясняю.
После ввода числа, оно записывается в текстовую переменную {{BIG_display_text}}, далее для вычислений нам нужно это число передать в числовую переменную {{number_2}} , но числовая переменная не может напрямую принять значение из текстовой переменной, поэтому я сделал транзитную переменную-формулу, она как бы универсальная, и она всегда равна значению переменной {{BIG_display_text}}

4. {{operator}} - это переменная для записи в нее оператора «+», «-», «×», «÷» По этой переменной бот будет понимать какую из этих формул применять {{sum}} = {{number_1}} + {{number_2}} {{diff}} = {{number_1}} - {{number_2}} {{product}} = {{number_1}} × {{number_2}} {{quotieent}} = {{number_1}} ÷ {{number_2}}

3. Настройка кнопок калькулятора

Сначала создаем web-app приложение, как это сделать описано в Базе знаний PuzzleBot

Для отображения кнопок я использовал блок "Карточки"

Как я создал Web-App калькулятор в PuzzleBot ://

Для каждой карточки я загрузил изображение кнопки калькулятора. Сделал скриншот iOS калькулятора и вырезал все кнопки в фотошопе. Выбрал тип карточки "Прямоугольный", так как можно указать ширину в процентах от экрана.

В моем калькуляторе 4 кнопки в ряду, каждая занимает 25% ширины экрана. Это позволяет адаптировать кнопки для любых устройств.

Как я создал Web-App калькулятор в PuzzleBot ://

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

Первые 2 примера - прямоугольные карточки с процентной фиксацией и адаптируются к ширине. Выглядят они круглыми, так как я их такими вырезал, на самом деле они квадратные) 
Первые 2 примера - прямоугольные карточки с процентной фиксацией и адаптируются к ширине. Выглядят они круглыми, так как я их такими вырезал, на самом деле они квадратные) 

В действиях карточек нужно указать - отправку команды или условия. Но на текущий момент мы их еще не создали. Поэтому в действии указываем действие - "Без действия". В дальнейшем заменим на команды - условия.

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

Таким образом создаем все остальные кнопки.
Один ряд из 4 кнопок - это один блок "Карточки"
Для каждой строки из кнопок нужно создать новый блок "Карточки"

Как я создал Web-App калькулятор в PuzzleBot ://

4. Создание дисплея для отображения операций

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

В качестве дисплея выступают текстовые блоки "Заголовок" и "Описание"

  • "Заголовок" - крупный текст, для отображения ввода, и итогового ответа
  • "Описание" - мелкий текст, для отображения истории ввода после ответа
Первый "дисплей" отображается сразу, как только открыли калькулятор и во время ввода операции, в нем есть только одна переменная <b>{{display_text}}</b> со значение "0" по умолчанию. Поле выше пустое, но имеет пустой символ, чтобы интерфейс не съезжал.
Первый "дисплей" отображается сразу, как только открыли калькулятор и во время ввода операции, в нем есть только одна переменная {{display_text}} со значение "0" по умолчанию. Поле выше пустое, но имеет пустой символ, чтобы интерфейс не съезжал.
Второй "дисплей" нужен для отображения ответа после нажатия "=". В нем переменная <b>{{display_text}}</b> с историей ввода операции перемещается в верхнее поле <b>"Описание"</b>, а в поле <b>Заголовок</b> находится переменная <b>{{BIG_display_text}}</b>, в которую бот запишет ответ.
Второй "дисплей" нужен для отображения ответа после нажатия "=". В нем переменная {{display_text}} с историей ввода операции перемещается в верхнее поле "Описание", а в поле Заголовок находится переменная {{BIG_display_text}}, в которую бот запишет ответ.

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

Далее объединим "дисплей" и ранее созданные кнопки калькулятора.
Для этого используем новый блок "Подстановка"

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

5. Создание условий и действий для каждой кнопки

В этой части статьи я раскрою выполняемые действия для каждого из видов кнопок:

  • Цифры (от 1 до 9)
  • Цифра 0.
  • Точка дроби.
  • Знаки операторов «+», «-», «×», «÷»
  • Знак «=»
  • Очистка "АС"

5.1 Начнем с цифр от 1 до 9, действия в них аналогичные, поэтому опишу работу одной цифры.

Например цифра 5.
Для нее создаем команду-условие. В ней будут производится расчеты.

Конструкция: Приложения ↓ Нажатие кнопки вызывает Условие ↓ Условие делает проверку ↴ Совершает изменения ↓ Обновление приложения
В условии есть три проверки для разных вариантов событий и одно исключающее правило для общего случая. 
В условии есть три проверки для разных вариантов событий и одно исключающее правило для общего случая. 

Какие это события:

5.1.1. - Цифра 5.
Общее событие (исключающее правило):

Добавляет нажатую цифру в дисплее.

{{BIG_display_text}} = {{BIG_display_text}} + "5" {{display_text}} = {{display_text}} + "5"
Если на дисплее было "2", новое значение будет "2"+"5" = "25".
А если "0", то станет "0"+"5" = "05", что недопустимо. Чтобы этого избежать, создаем правило первое 👇
Если на дисплее было "2", новое значение будет "2"+"5" = "25". А если "0", то станет "0"+"5" = "05", что недопустимо. Чтобы этого избежать, создаем правило первое 👇

5.1.2. - Цифра 5.
Правило первое:
Если {{display_text}} и {{BIG_display_text}} равны 0, то 0 должно заменяться на 5, но не складываться.

{{BIG_display_text}} = "5" {{display_text}} = "5"
Как я создал Web-App калькулятор в PuzzleBot ://

5.1.3. - Цифра 5.
Правило второе:
Определяет момент, когда нужно завершить прием первого числа и начать прием второго числа.

  • Переменная {{BIG_display_text}}, принимает значение числа до введения оператора. После ввода оператора значение {{BIG_display_text}} отправляется в {{number_1}}. Новое число, вводимое после оператора, записывается снова в {{BIG_display_text}}, перезаписывая старое значение.
  • Наличие оператора в переменной {{operator}} определяет, когда начать прием второго числа. Я создал дубль переменной {{operator}} - {{operator_double}}, по которой будем выполняем проверку, после чего очищать для избежание повторной проверки при следующем вводе цифры. Значение в {{operator}} нам еще пригодится после "=", поэтому нужен дубль.
  • Пример совершаемых действий:
Введено выражение 23+85: {{display_text}} = "23+85" - текст на дисплее. {{BIG_display_text}} = "23" (передано в {{number_1}}) {{operator_double}} = "+" {{BIG_display_text}} = "85" (передано в {{number_2}}) Далее после оператора "=" будут применяться формулы в зависимости от значения {{operator}} {{sum}} = {{number_1}} + {{number_2}} {{diff}} = {{number_1}} - {{number_2}} {{product}} = {{number_1}} × {{number_2}} {{quotieent}} = {{number_1}} ÷ {{number_2}}

В итоге проверка следующая:
Если переменная {{operator_double}} имеет значение,
Формулы следующие:
Ввод в {{BIG_display_text}} осуществляется через замену старого значения, а в {{display_text}} — через сложение.

{{BIG_display_text}} = "5" {{display_text}} = {{display_text}} + "5"
Как я создал Web-App калькулятор в PuzzleBot ://

5.1.4. - Цифра 5.
Правило третье:

Определяет, что делать с новым вводом числа после завершенного вычисления, когда {{BIG_display_text}} и {{display_text}} не равны "0" и кнопка "АС" не была нажата.

Пример: Завершили вычисление 5+5, нажали "=", получили 10. Далее сразу вводим новую операцию.

Определяющий фактор: наличие знака "=" в переменной {{operator}}.

Если {{operator}} = "=", то применяем действия из первого правила, перезаписывая значения:

{{BIG_display_text}} = "5" {{display_text}} = "5"

Также очищаем переменную {{operator}}

Как я создал Web-App калькулятор в PuzzleBot ://

В конце каждой проверки в действиях так же указываем переход к приложению, в моем случае это приложение "Дисплей 1".
На этом настройки кнопки для цифры "5" завершены, далее нужно продублировать это условие для других цифр от 1 до 9, заменив значения в переменных соответственно.

Тут я указал какие именно значения нужно заменить для каждой из цифр.
Тут я указал какие именно значения нужно заменить для каждой из цифр.

5.2 Теперь рассмотрим настройки условия для цифры 0

5.2.1. - Цифра 0.
Общее событие
(исключающее правило) такое же как и для цифр 1-9:
Добавляет нажатую цифру в дисплее.

{{BIG_display_text}} = {{BIG_display_text}} + "0" {{display_text}} = {{display_text}} + "0"
В конце везде не забываем поставить Переход к мини-приложению.
В конце везде не забываем поставить Переход к мини-приложению.

5.2.2. - Цифра 0.
Правило первое:

Если значение переменной {{BIG_display_text}} равно "0" и не содержит дробной точки, то оставить без действий.
При этом {{display_text}} не должно заканчиваться на знак оператора.

Это правило предотвращает ввод двух нулей ("00") в самом начале, до появления дробной точки или других цифр. Но если выражение будет иметь оператор после 0 ("0+"), то в этом случае разрешать ввод цифры "0".
Это правило предотвращает ввод двух нулей ("00") в самом начале, до появления дробной точки или других цифр. Но если выражение будет иметь оператор после 0 ("0+"), то в этом случае разрешать ввод цифры "0".

5.2.3. - Цифра 0.
Правило второе:

Аналогично как и для цифр 1-9 определяет момент, когда нужно завершить прием первого числа и начать прием второго числа.

Если переменная {{operator_double}} имеет значение,
то ввод в {{BIG_display_text}} осуществляется через замену старого значения на "0", а в {{display_text}} — через сложение со старым.

{{BIG_display_text}} = "0" {{display_text}} = {{display_text}} + "0" {{operator_double}} - очистка
Как я создал Web-App калькулятор в PuzzleBot ://

5.2.4. - Цифра 0.
Правило третье:

Это правило аналогично третьему правилу для цифр - 1-9, и определяет поведение кнопки после знака "="

Если {{operator}} = "=", то обнуляем все предыдущие значения в {{BIG_display_text}} и {{display_text}}, и очищаем {{operator}}

{{BIG_display_text}} = "0" {{display_text}} = "0" {{operator}} - очистка
Как я создал Web-App калькулятор в PuzzleBot ://

5.3 Далее разберем настройки кнопок операторов

Рассмотрим настройки на примере оператора "+", для каждого оператора так же создаем отдельное условие.

5.3.1. - Оператор +
Общее событие (исключающее правило):

Это действие выполняется только для первого оператора в операции в начале ввода (например, "5+").

Добавляем оператор в переменную {{display_text}} путем сложения

Фиксируем первое число, написанное до оператора, в переменную {{number_1}}

Сохраняем оператор в переменные {{operator}} и {{operator_double}}

{{display_text}} = {{BIG_display_text}}+"+" {{number_1}} = {{conver_number_1}} {{operator}} = "+" {{operator_double}} = "+"

Напомню: {{conver_number_1}} равна значению {{BIG_display_text}} и служит для передачи числа.

Как я создал Web-App калькулятор в PuzzleBot ://

5.3.2. - Оператор +
Правило первое:

Если {{display_text}} заканчивается на символ "+", то оставить без действий.
Создано для того, чтобы нельзя было поставить 2 оператора подряд, например ("1++3")

Как я создал Web-App калькулятор в PuzzleBot ://

5.3.3. - Оператор +
Правило второе:

Если {{display_text}} заканчивается на символ "." (точка дроби), то при нажатии "+" перевести на экран с оповещением.

Проверка не дает совершить заведомо не корректную операцию, например 5.+3, формулы конструктора будут делать сложение по правилам сложения текста, а не числа. "5.+3" = "5.3" - что будет не верно.
Проверка не дает совершить заведомо не корректную операцию, например 5.+3, формулы конструктора будут делать сложение по правилам сложения текста, а не числа. "5.+3" = "5.3" - что будет не верно.
Как я создал Web-App калькулятор в PuzzleBot ://
Как я создал Web-App калькулятор в PuzzleBot ://

5.3.4. - Оператор +
Правило третье:

Если {{display_text}} заканчивается на символы "-" , "×" , "÷" , то нажатие знака "+" должно изменить последний оператор.

Например я ввел операцию 12+5 - , после чего нажал на +, и последний оператор "-" должен измениться на "+".

{{display_text}}={{BIG_display_text}}+"+" {{operator}} = "+" {{operator_double}} = "+"

При этом введенная до этого операция будет уже посчитана и выведена с ответом и новым оператором.

12+5- После нажатия + изменится на: 17+
Как я создал Web-App калькулятор в PuzzleBot ://

5.3.5. - Оператор +
Правило четвертое:

Это правило будет делать вычисления для пары чисел в {{number_1}} и {{number_2}} после нажатия второго и последующих операторов.

Например:

15+6+ {{number_1}} = 15 {{number_2}} = 6 После нажатия "+" запишем в {{number_1}} сумму 15+6 {{number_1}} = {{sum}}

В начале мы уже создали формулы для разных операторов:

{{sum}} = {{number_1}} + {{number_2}} {{diff}} = {{number_1}} - {{number_2}} {{product}} = {{number_1}} × {{number_2}} {{quotieent}} = {{number_1}} ÷ {{number_2}}

Итак, в зависимости от оператора будем подставлять одну из формул выше.
Создаем проверку, если {{operator}} = "+", то:

{{display_text}} = {{display_text}}+"+" {{number_2}} = {{conver_number_1}} {{number_1}} = {{sum}} {{BIG_display_text}} = {{number_1}} {{operator}} = "+" {{operator_double}} = "+"

Так мы добавили "+" в дисплее, сохранили второе число в {{number_2}} , Где {{conver_number_1}} равен {{BIG_display_text}}

В переменную {{number_1}} и в {{BIG_display_text}} записали сумму первых двух чисел для дальнейших операций и зафиксировали оператор.

Как я создал Web-App калькулятор в PuzzleBot ://

5.3.6. - Оператор +
Правило пятое, шестое и седьмое:

Эти правила аналогичные с четвертым правилом,
но уже для знаков "-", "÷", "×".
Дублируем правило 4, которое описал выше и корректируем:

1. В проверке ставим "-" , "÷" и "×" для пятой, шестой и седьмой проверки соответственно. Без кавычек.

Как я создал Web-App калькулятор в PuzzleBot ://

2. И там где {{number_1}} = {{sum}} нужно заменить на другую переменную-формулу.
Там где проверка:

  • {{operator}} = "-" , ставим {{number_1}} = {{diff}}
  • {{operator}} = "×" , ставим {{number_1}} = {{product}}
  • {{operator}} = "÷" , ставим {{number_1}} = {{quotieent}}
Как я создал Web-App калькулятор в PuzzleBot ://

Утомились? Я тоже.
Это мы завершили настройки условия только для кнопки оператора "+"
Сохраняем и дублируем это условие, но уже для остальных операторов "-" , "÷" и "×", делаем корректировки.
Ниже я просто размещу скрины, на которых показано, где именно нужно заменить операторы, в остальном эти условия идентичные.
Дублируем и меняем:

Правило 1 - меняем для каждого условия на свой оператор.
Правило 1 - меняем для каждого условия на свой оператор.
Правило 3. В проверке нужно указать те операторы, которые отличаются от того, условие для которого вы создаете. Если условие для оператора "-", то ставим "+" "÷" "×" и тд.
Правило 3. В проверке нужно указать те операторы, которые отличаются от того, условие для которого вы создаете. Если условие для оператора "-", то ставим "+" "÷" "×" и тд.
Правило 4, 5, 6 и 7 меняем только в этих трех действиях.
Правило 4, 5, 6 и 7 меняем только в этих трех действиях.

5.4. Настройки условия для знака "="

Правило первое:
Если все выражение заканчивается на ".", то перекинуть на дисплей с оповещением:
"Введите значение после точки, или начните ввод заново"

Проверка не дает совершить заведомо не корректную операцию, чтобы не получилось так: 5+5. = "55." , бот воспринимает точку в конце как текст и все выражение суммирует по правилам сложения текста.
Проверка не дает совершить заведомо не корректную операцию, чтобы не получилось так: 5+5. = "55." , бот воспринимает точку в конце как текст и все выражение суммирует по правилам сложения текста.

Правило второе:

Это правило тоже предотвращает некорректную операцию, например:
12+7- =

Если после нажатия "-" сразу нажимается "=", то вместо сложения (12+7) выполнится вычитание (12-7), так как наш {{operator}} определяет какая формула будет применена, что даст неверный ответ. Чтобы этого избежать, проверяем {{display_text}} на наличие оператора в конце.

Если {{display_text}} заканчивается оператором, то результат берём из переменной {{number_1}}, а не из формул, так как ответ первых двух чисел уже был сохранён в {{number_1}} после нажатия оператора "-".

Как я создал Web-App калькулятор в PuzzleBot ://

Правило 3-е, 4-е, 5-е и 6-е:

В этих правилах итоговый ответ мы уже берем из формул, в зависимости от последнего оператора в переменной {{operator}}
Ниже слайдером размещены сразу 4 скриншота с настройкой каждого правила, в них единственное отличие только в проверке оператора, и в различии формул из которых записывается итоговый ответ для вывода на дисплей.

В каждом правиле в конце в действиях ставим переход в приложение, в моем примере "Дисплей 2"
На этом настройка условия для кнопки "=" завершена.

5.5. Настройки условия для дробной точки "."
В этом условии 5 правил, кратко опишу их действия.

  • 1. Запрет на две точки подряд:

    Пример: "5..1" недопустимо.

  • 2. Запрет на две точки в одном числе:

    Пример: "5.12.3" недопустимо.

  • 3. Точка нажата сразу после "=":
    Перезаписать значения на "0.":

{{display_text}} = "0." {{BIG_display_text}} = "0." {{operator}} - очистка
  • 4. Точка нажата сразу после оператора "+" "-" "÷" "×":
    Автоматически добавить 0 перед точкой:
{{display_text}} = {{display_text}} + "0." {{BIG_display_text}} = "0." {{operator_double}} - очистка
  • 5. Исключающее правило (точка после цифры):
{{display_text}} = {{display_text}} + "." {{BIG_display_text}} = {{BIG_display_text}} + "."

5.6. Настройки условия для кнопки АС (очистка)

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

Как я создал Web-App калькулятор в PuzzleBot ://

На этом настройка всех кнопок завершена.

6. Привязка условий к кнопкам.

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

Как я создал Web-App калькулятор в PuzzleBot ://

Сохраняем и тестируем.

На этом все. Спасибо, что дочитали до конца!

Многие тонкости не были описаны, статья и так получилась большой, но я готов ответить на вопросы в комментариях или лично в Telegram

  • Приложение-калькулятор можете протестировать по ссылке: @MadeinPuzzleBot
  • Подписывайтесь на мой канал, посвященный разработке в PuzzleBot :// @MadeinPuzzle
3
1
1
4 комментария

Алексей, это реально космическая работа! Такое ощущение, что ты собрал не калькулятор, а целую обучающую станцию для разработчиков. Читаешь и понимаешь, сколько сил ушло на детали.

Я бы с удовольствием посмотрел это в формате видео — видеть шаги и процесс в действии было бы круто. Если решишь сделать видеоруки, обязательно дай знать — буду следить!

2

Спасибо
Да у меня есть один ролик на канале, но он для новичков. Я решил что статьи проще, но оказалось что это тоже сложно)) я неделю эту статью писал. Поэтому есть шанс что ролики тоже будут

1

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

1

Да, пробовал, недвижимость, брони и (возможно) СитиДрайв. Но эти кейсы будут позже

2