Внимание! Это задание - черновик.
На основе результатов предыдущих заданий нужно разработать сервис-калькулятор с поддержкой хранимых переменных и пользовательских функций. Сервисная часть должна быть выполнена в виде REST API. Нужно поддержать аутентификацию в этом API с логированием запросов для дальнейшего аудита. ААА - данные нужно сохранять в реляционной базе данных.
Вводится две новые сущности - переменная и функция
Переменная - это именованное число. При определении переменной вычисляется её значение. В дальнейшем, при упоминании переменной в выражении при его вычислении на место переменной подставляется её значение. Пример определения и использования переменной:
pi = 3.1415926
10 + 2 * pi -> 10 + 2 * 3.1415926
a = 10
b = 20
h = 10
area = 0.5 * (a + b) * h + a * b -> 0.5 * (10 + 20) * 10 -> 150
2 * area + a * b -> 2 * 150 + 10 * 20 -> 500
Функция - это символьный синоним выражения, в котором присутствуют неопределенные переменные. Значения этих переменных передаются в функцию в качестве аргументов. Аргументы функции пишутся в скобках после её имени. Пример определения и использования функции:
square_area(a) = a * a
square_area(2) -> 2 * 2
pi = 3.1415926
circle_area_from_diameter(d) = pi * d * d * 0.25
circle_area_from_diameter(10) -> 3.1415926 * 10 * 10 * 0.25
Вводится набор предопределенных базовых функций:
sin(a)
cos(a)
tg(a)
sqrt(a)
pow(m, e)
abs(a)
sign(a)
log(a, n)
log2(a)
rnd()
max(a, b)
min(a, b)
Допустимые имена переменных и функций могут состоять из латинских букв, цифр и знака подчеркивания. Цифра не может быть первым символом в имени.
Очевидно, может случаться конфликт имен между предопределенными функциями, переменными и пользовательскими функциями. Его нужно разруливать по праву перводродства - если такая сущность уже есть, её тип изменить нельзя. Но можно перезаписать или удалить, если это не предопределенная функция.
Нужно предоставить REST API для выполнения запросов к сервису. Ниже перечислены необходимые методы:
GET /variable/${variableName}
Получить выражение, обозначенное переменной с указанным именем.
PUT /variable/${variableName}
variable value
Присвоить переменной новое выражение.
DELETE /variable/${variableName}
Удалить переменную с заданным именем.
GET /variable/
Получить список имен всех переменных в сервисе.
GET /function/${functionName}
Получить выражение, обозначенное функцией с указанным именем. Также возвращает список аргументов функции. Нельзя получить выражение для предопределенных функций.
PUT /function/${functionName}?args=${argumentsList}
function expression
Присвоить функции с заданным именем следующее выражение и список аргументов. Предопределенные функции нельзя изменить.
DELETE /function/${functionName}
Удалить функцию с заданным именем. Предопределенные функции нельзя удалить.
GET /function/
Получить список имен всех пользовательских функций в сервисе
POST /eval/
expression
Рассчитать значение выражения.
Для всех методов REST API необходимо реализовать проверку пользователя через HTTP Basic Auth. Каждое изменяющее действие необходимо логировать в базу для последующего аудита. TODO подробнее про аудит.