Как я создал Web-App калькулятор в PuzzleBot ://
В сентябре разработчики PuzzleBot выпустили конструктор мини-приложений для Telegram ботов.
На рынке много конструкторов, но они либо шаблонные и негибкие, либо сложные. Я решил проверить гибкость конструктора и создать калькулятор. Казалось бы, просто бери и используй математические формулы и числа, подумал я, и решил собрать за один вечер. Как же я ошибался!
В итоге у меня получилось, но за неделю продумывания логики, тестов и исправления ошибок. Об этом я и расскажу в этой статье.
- Приложение-калькулятор можете протестировать по ссылке: @MadeinPuzzleBot
1. Логика работы калькулятора
Чтобы создать калькулятор, нужно понять его внутреннюю логику. Проанализировав калькуляторы на iOS и Windows, я понял, что для последовательных вычислений нужны только 2 числа и оператор между ними.
Например, для выражения N1*N2+N3-N4 нам нужно всего 2 числа в каждой операции.
2. Создание переменных
Я создал две переменные: {{number_1}} и {{number_2}} с форматом "Число"
А для операций «+», «-», «×», «÷» между этими числами создал 4 переменных, формат - "Формула"
Логика работы калькулятора следующая:
- При вводе операции N1*N2 значения сохраняются в переменные {{number_1}} и {{number_2}}.
- При вводе следующего оператора «+» результат умножения N1*N2 из формулы произведения {{product}} записывается в {{number_1}}, а в {{number_2}} сохраняется новое число N3.
- Далее при вводе оператора «-» происходит сложение {{number_1}} (N1*N2) и {{number_2}} (N3).
- Все последующие операции выполняются аналогично: ответ записывается в {{number_1}}, а {{number_2}} перезаписывается следующим числом.
- Знак «=» выводит итог последней операции N3-N4, что равно итоговому результату всего выражения N1*N2+N3-N4.
Далее я создал еще 4 переменных:
Запись всей операции в переменную {{display_text}} со всеми операторами происходит по такому же принципу
Для чего, объясняю.
После ввода числа, оно записывается в текстовую переменную {{BIG_display_text}}, далее для вычислений нам нужно это число передать в числовую переменную {{number_2}} , но числовая переменная не может напрямую принять значение из текстовой переменной, поэтому я сделал транзитную переменную-формулу, она как бы универсальная, и она всегда равна значению переменной {{BIG_display_text}}
3. Настройка кнопок калькулятора
Сначала создаем web-app приложение, как это сделать описано в Базе знаний PuzzleBot
Для отображения кнопок я использовал блок "Карточки"
Для каждой карточки я загрузил изображение кнопки калькулятора. Сделал скриншот iOS калькулятора и вырезал все кнопки в фотошопе. Выбрал тип карточки "Прямоугольный", так как можно указать ширину в процентах от экрана.
В моем калькуляторе 4 кнопки в ряду, каждая занимает 25% ширины экрана. Это позволяет адаптировать кнопки для любых устройств.
Наглядный пример. Третий вариант с типом карточек - Круглый, показывает как будут выглядеть кнопки на других устройствах, которые будут отличаться по ширине от вашего устройства, на который вы ориентировались при создании.
В действиях карточек нужно указать - отправку команды или условия. Но на текущий момент мы их еще не создали. Поэтому в действии указываем действие - "Без действия". В дальнейшем заменим на команды - условия.
Таким образом создаем все остальные кнопки.
Один ряд из 4 кнопок - это один блок "Карточки"
Для каждой строки из кнопок нужно создать новый блок "Карточки"
4. Создание дисплея для отображения операций
Для дисплея я создал 2 отдельных мини приложения, они идентичные, но отличаются местоположением отображаемого числа.
В качестве дисплея выступают текстовые блоки "Заголовок" и "Описание"
- "Заголовок" - крупный текст, для отображения ввода, и итогового ответа
- "Описание" - мелкий текст, для отображения истории ввода после ответа
Конечно можно было сделать проще с одним дисплеем, но с меняющимися переменными, но изначально я не имел представления как я буду делать, и конце я уже не решился все переделывать, главное это работает.
Далее объединим "дисплей" и ранее созданные кнопки калькулятора.
Для этого используем новый блок "Подстановка"
5. Создание условий и действий для каждой кнопки
В этой части статьи я раскрою выполняемые действия для каждого из видов кнопок:
- Цифры (от 1 до 9)
- Цифра 0.
- Точка дроби.
- Знаки операторов «+», «-», «×», «÷»
- Знак «=»
- Очистка "АС"
5.1 Начнем с цифр от 1 до 9, действия в них аналогичные, поэтому опишу работу одной цифры.
Например цифра 5.
Для нее создаем команду-условие. В ней будут производится расчеты.
Какие это события:
5.1.1. - Цифра 5.
Общее событие (исключающее правило):
Добавляет нажатую цифру в дисплее.
5.1.2. - Цифра 5.
Правило первое:
Если {{display_text}} и {{BIG_display_text}} равны 0, то 0 должно заменяться на 5, но не складываться.
5.1.3. - Цифра 5.
Правило второе:
Определяет момент, когда нужно завершить прием первого числа и начать прием второго числа.
- Переменная {{BIG_display_text}}, принимает значение числа до введения оператора. После ввода оператора значение {{BIG_display_text}} отправляется в {{number_1}}. Новое число, вводимое после оператора, записывается снова в {{BIG_display_text}}, перезаписывая старое значение.
- Наличие оператора в переменной {{operator}} определяет, когда начать прием второго числа. Я создал дубль переменной {{operator}} - {{operator_double}}, по которой будем выполняем проверку, после чего очищать для избежание повторной проверки при следующем вводе цифры. Значение в {{operator}} нам еще пригодится после "=", поэтому нужен дубль.
- Пример совершаемых действий:
В итоге проверка следующая:
Если переменная {{operator_double}} имеет значение,
Формулы следующие:
Ввод в {{BIG_display_text}} осуществляется через замену старого значения, а в {{display_text}} — через сложение.
5.1.4. - Цифра 5.
Правило третье:
Определяет, что делать с новым вводом числа после завершенного вычисления, когда {{BIG_display_text}} и {{display_text}} не равны "0" и кнопка "АС" не была нажата.
Пример: Завершили вычисление 5+5, нажали "=", получили 10. Далее сразу вводим новую операцию.
Определяющий фактор: наличие знака "=" в переменной {{operator}}.
Если {{operator}} = "=", то применяем действия из первого правила, перезаписывая значения:
Также очищаем переменную {{operator}}
В конце каждой проверки в действиях так же указываем переход к приложению, в моем случае это приложение "Дисплей 1".
На этом настройки кнопки для цифры "5" завершены, далее нужно продублировать это условие для других цифр от 1 до 9, заменив значения в переменных соответственно.
5.2 Теперь рассмотрим настройки условия для цифры 0
5.2.1. - Цифра 0.
Общее событие (исключающее правило) такое же как и для цифр 1-9:
Добавляет нажатую цифру в дисплее.
5.2.2. - Цифра 0.
Правило первое:
Если значение переменной {{BIG_display_text}} равно "0" и не содержит дробной точки, то оставить без действий.
При этом {{display_text}} не должно заканчиваться на знак оператора.
5.2.3. - Цифра 0.
Правило второе:
Аналогично как и для цифр 1-9 определяет момент, когда нужно завершить прием первого числа и начать прием второго числа.
Если переменная {{operator_double}} имеет значение,
то ввод в {{BIG_display_text}} осуществляется через замену старого значения на "0", а в {{display_text}} — через сложение со старым.
5.2.4. - Цифра 0.
Правило третье:
Это правило аналогично третьему правилу для цифр - 1-9, и определяет поведение кнопки после знака "="
Если {{operator}} = "=", то обнуляем все предыдущие значения в {{BIG_display_text}} и {{display_text}}, и очищаем {{operator}}
5.3 Далее разберем настройки кнопок операторов
Рассмотрим настройки на примере оператора "+", для каждого оператора так же создаем отдельное условие.
5.3.1. - Оператор +
Общее событие (исключающее правило):
Это действие выполняется только для первого оператора в операции в начале ввода (например, "5+").
Добавляем оператор в переменную {{display_text}} путем сложения
Фиксируем первое число, написанное до оператора, в переменную {{number_1}}
Сохраняем оператор в переменные {{operator}} и {{operator_double}}
Напомню: {{conver_number_1}} равна значению {{BIG_display_text}} и служит для передачи числа.
5.3.2. - Оператор +
Правило первое:
Если {{display_text}} заканчивается на символ "+", то оставить без действий.
Создано для того, чтобы нельзя было поставить 2 оператора подряд, например ("1++3")
5.3.3. - Оператор +
Правило второе:
Если {{display_text}} заканчивается на символ "." (точка дроби), то при нажатии "+" перевести на экран с оповещением.
5.3.4. - Оператор +
Правило третье:
Если {{display_text}} заканчивается на символы "-" , "×" , "÷" , то нажатие знака "+" должно изменить последний оператор.
Например я ввел операцию 12+5 - , после чего нажал на +, и последний оператор "-" должен измениться на "+".
При этом введенная до этого операция будет уже посчитана и выведена с ответом и новым оператором.
5.3.5. - Оператор +
Правило четвертое:
Это правило будет делать вычисления для пары чисел в {{number_1}} и {{number_2}} после нажатия второго и последующих операторов.
Например:
В начале мы уже создали формулы для разных операторов:
Итак, в зависимости от оператора будем подставлять одну из формул выше.
Создаем проверку, если {{operator}} = "+", то:
Так мы добавили "+" в дисплее, сохранили второе число в {{number_2}} , Где {{conver_number_1}} равен {{BIG_display_text}}
В переменную {{number_1}} и в {{BIG_display_text}} записали сумму первых двух чисел для дальнейших операций и зафиксировали оператор.
5.3.6. - Оператор +
Правило пятое, шестое и седьмое:
Эти правила аналогичные с четвертым правилом,
но уже для знаков "-", "÷", "×".
Дублируем правило 4, которое описал выше и корректируем:
1. В проверке ставим "-" , "÷" и "×" для пятой, шестой и седьмой проверки соответственно. Без кавычек.
2. И там где {{number_1}} = {{sum}} нужно заменить на другую переменную-формулу.
Там где проверка:
- {{operator}} = "-" , ставим {{number_1}} = {{diff}}
- {{operator}} = "×" , ставим {{number_1}} = {{product}}
- {{operator}} = "÷" , ставим {{number_1}} = {{quotieent}}
Утомились? Я тоже.
Это мы завершили настройки условия только для кнопки оператора "+"
Сохраняем и дублируем это условие, но уже для остальных операторов "-" , "÷" и "×", делаем корректировки.
Ниже я просто размещу скрины, на которых показано, где именно нужно заменить операторы, в остальном эти условия идентичные.
Дублируем и меняем:
5.4. Настройки условия для знака "="
Правило первое:
Если все выражение заканчивается на ".", то перекинуть на дисплей с оповещением:
"Введите значение после точки, или начните ввод заново"
Правило второе:
Это правило тоже предотвращает некорректную операцию, например:
12+7- =
Если после нажатия "-" сразу нажимается "=", то вместо сложения (12+7) выполнится вычитание (12-7), так как наш {{operator}} определяет какая формула будет применена, что даст неверный ответ. Чтобы этого избежать, проверяем {{display_text}} на наличие оператора в конце.
Если {{display_text}} заканчивается оператором, то результат берём из переменной {{number_1}}, а не из формул, так как ответ первых двух чисел уже был сохранён в {{number_1}} после нажатия оператора "-".
Правило 3-е, 4-е, 5-е и 6-е:
В этих правилах итоговый ответ мы уже берем из формул, в зависимости от последнего оператора в переменной {{operator}}
Ниже слайдером размещены сразу 4 скриншота с настройкой каждого правила, в них единственное отличие только в проверке оператора, и в различии формул из которых записывается итоговый ответ для вывода на дисплей.
В каждом правиле в конце в действиях ставим переход в приложение, в моем примере "Дисплей 2"
На этом настройка условия для кнопки "=" завершена.
5.5. Настройки условия для дробной точки "."
В этом условии 5 правил, кратко опишу их действия.
- 1. Запрет на две точки подряд:
Пример: "5..1" недопустимо.
2. Запрет на две точки в одном числе:
Пример: "5.12.3" недопустимо.
3. Точка нажата сразу после "=":
Перезаписать значения на "0.":
- 4. Точка нажата сразу после оператора "+" "-" "÷" "×":
Автоматически добавить 0 перед точкой:
- 5. Исключающее правило (точка после цифры):
5.6. Настройки условия для кнопки АС (очистка)
В этом условии без проверки, в действиях обнуляем и очищаем все переменные и возвращаем на приложение.
На этом настройка всех кнопок завершена.
6. Привязка условий к кнопкам.
Далее снова открываем приложение Калькулятор, в котором создавали кнопки из Карточек, и в каждой кнопке заменяем действие.
Указываем переход к команде или условию и указываем для каждой кнопки свое условие.
Сохраняем и тестируем.
На этом все. Спасибо, что дочитали до конца!
Многие тонкости не были описаны, статья и так получилась большой, но я готов ответить на вопросы в комментариях или лично в Telegram
- Приложение-калькулятор можете протестировать по ссылке: @MadeinPuzzleBot
- Подписывайтесь на мой канал, посвященный разработке в PuzzleBot :// @MadeinPuzzle
Алексей, это реально космическая работа! Такое ощущение, что ты собрал не калькулятор, а целую обучающую станцию для разработчиков. Читаешь и понимаешь, сколько сил ушло на детали.
Я бы с удовольствием посмотрел это в формате видео — видеть шаги и процесс в действии было бы круто. Если решишь сделать видеоруки, обязательно дай знать — буду следить!
Спасибо
Да у меня есть один ролик на канале, но он для новичков. Я решил что статьи проще, но оказалось что это тоже сложно)) я неделю эту статью писал. Поэтому есть шанс что ролики тоже будут
чел, ты крейзи... А помимо развлечения уже использовал мини-приложения для реальных кейсов?
Да, пробовал, недвижимость, брони и (возможно) СитиДрайв. Но эти кейсы будут позже