Калькулятор полезен, когда пользователь вводит параметры, понимает формулу и получает воспроизводимый результат. Генеративная модель не должна определять итог по текстовому описанию на каждом нажатии: для калькулятора правило должно быть явной детерминированной формулой, которую можно проверить обычной арифметикой.
Учебный пример: оценка поездки
Пусть учебный калькулятор оценивает стоимость поездки по трём входам: базовая цена 350 ₽, расстояние в километрах и время поездки в минутах. Правило для демонстрации: итог = 350 ₽ + 25,50 ₽ × километры + 2,40 ₽ × минуты. Минимум расстояния — больше нуля, длительность от нуля; отрицательные значения запрещены. Это условная формула, она ничего не говорит о реальных тарифах такси.
Для расстояния 12,4 км и времени 18 мин расчёт такой:
- расстояние:
12,4 × 25,50 ₽/км = 316,20 ₽; - время:
18 × 2,40 ₽/мин = 43,20 ₽; - сумма:
350 + 316,20 + 43,20 = 709,40 ₽.
Результат сохраняет две десятичные цифры в валюте с копейками. Определи округление явно: например, ввод допускает до двух десятичных для расстояния, время целое, итог округляется до копеек один раз после сложения. Если округлять каждый компонент отдельно, на большом числе позиций может возникнуть отличие. В этом примере промежуточные суммы уже заканчиваются на копейку, поэтому итог 709,40 ₽.
Запиши контракт для каждого поля
Для расстояния укажи единицу, минимальное и максимальное значение, шаг ввода и допустимый разделитель десятичной дроби. Для времени — целое число минут или дробное значение, но не неопределённое «время». Для цены — валюту и точность. Покажи формулу рядом с результатом, а не только в техническом разделе.
Попроси ИИ сформулировать тесты до генерации кода:
Реализуй учебный калькулятор поездки. Формула: 350 RUB + 25,50 RUB/km × distanceKm + 2,40 RUB/min × durationMinutes. Distance > 0 и не более 100 km; minutes целое от 0 до 600. Дистанция допускает максимум 2 знака после запятой; итог округляется до 2 десятичных один раз после сложения. Не меняй формулу и не вызывай модель во время расчёта. Сначала составь таблицу тестов, затем добавь форму и покажи, где можно проверить результат.
Это пример промпта, не запущенный код. Независимо пересчитай числа вручную.
Таблица тестов, включая границы
| Расстояние | Время | Ожидаемое поведение |
|---|---|---|
| пусто | 18 мин | запросить расстояние; не показывать 0 ₽ как готовый итог |
| 0 км | 18 мин | отказ: расстояние должно быть больше нуля |
| −1 км | 18 мин | отказ: отрицательная длина недопустима |
| 12,4 км | 18 мин | 709,40 ₽ по формуле выше |
| 100 км | 600 мин | верхняя граница допустима: 350 + 2550 + 1440 = 4340 ₽ |
| 100,01 км | 600 мин | отказ: выше установленного максимума |
| 12,4 км | 600,5 мин | отказ: минуты должны быть целым числом |
abc |
18 мин | ошибка формата, не NaN на экране |
Арифметика верхней границы: 25,50 × 100 = 2550 ₽; 2,40 × 600 = 1440 ₽; вместе с базовыми 350 ₽ получается 4340 ₽. Проверяй и обычный случай, и каждую границу диапазона; формула может правильно считать допустимые числа, но неверно принимать единицы или ввод.
Для работы с табличными исходниками и объяснимыми агрегациями смотри также дашборд из CSV.
Числовое представление и форматирование
JavaScript Number хранит значения как двоичную floating-point величину; некоторые десятичные дроби не имеют точного двоичного представления. MDN описывает Number как формат double-precision IEEE 754 и показывает его ограничения точности (MDN Number). Для серьёзных денежных расчётов выбери осознанное представление: хранить суммы в целых копейках, использовать проверенную decimal arithmetic библиотеку или рассчитывать на сервере с точной decimal-моделью. Нельзя просто прикрепить toFixed(2) к любому результату и считать, что расчёт верен.
Форматирование отдели от вычисления. Intl.NumberFormat форматирует числа согласно локали и валюте, например меняет порядок знака и разделители (MDN Intl.NumberFormat). Сначала вычисли и проверь числовое значение, затем отобрази 709,40 ₽ для выбранной локали. Не удаляй введённые разделители молча: покажи, как пользователь может ввести десятичную дробь.
Границы применения
Подпиши, что калькулятор оценивает результат по условной формуле и какие доплаты не учитывает. Если формула меняется по региону, дате, профилю или правилам тарификации, нужно показывать соответствующую версию/условия и покрыть каждый вариант тестами. Генератор интерфейса может изменить логику незаметно, поэтому зафиксируй тест-векторы и прогоняй их после изменений. Калькулятор готов к демонстрации, когда ввод валидируется, формула видна, пример совпадает с ручным расчётом, а крайние значения дают заранее определённый ответ.
