Как создать конструктор формул на Python?

При разработке очередного проекта, возникла потребность в внесении огромного количества формул в код на Python. Оказалось это весьма не удобным и мало читабельным в процессе реализации программы. По этому решил создать конструктор для введение и работу с формулами на подобие той, что есть в стандартном инструментарии Word, но так, чтобы после написание такой визуальной формулы, программа конвертировала ее в код Python.

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


Ответы (1 шт):

Автор решения: Ben Puls

Я предлагаю попробовать решить такую задачу через паттерн Интерпретатор.

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

Абстрактный класс Expression:

class Expression:
    def to_code(self) -> str:
        pass

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

class Number(Expression):
    def __init__(self, value) -> None:
        self.value = value

    def to_code(self) -> str:
        return str(self.value)


class Add(Expression):
    def __init__(self, *args) -> None:
        self.args = args

    def to_code(self) -> str:
        return f"({" + ".join((str(i.to_code()) for i in self.args))})"


class Sin(Expression):
    def __init__(self, expression) -> None:
        self.expression = expression

    def to_code(self) -> str:
        return f"math.sin({self.expression.to_code()})"


class Cos(Expression):
    def __init__(self, expression) -> None:
        self.expression = expression

    def to_code(self) -> str:
        return f"math.cos({self.expression.to_code()})"


class Sqrt(Expression):
    def __init__(self, expression) -> None:
        self.expression = expression

    def to_code(self) -> str:
        return f"math.sqrt({self.expression.to_code()})"

По сути можно создать любую математическую функцию или константу и записать её. В моём случае результат можно будет вычислить при помощи стандартного модуля math.

Далее создадим для примера какое-нибудь выражение:

expression = Add(Sin(Number(0)), Sqrt(Number(16)), Cos(Number(0)))
code = expression.to_code()

В результате мы получаем следующее выражение:

(math.sin(0) + math.sqrt(16) + math.cos(0))

Соответственно, без проблем вычислить его можно, импортировав модуль math. Помещаем выражение в код и получаем 5.0.

Затем, можно использовать это, написав небольшую реализацию по аналогии с калькулятором, например, на Tkinter.

→ Ссылка