Вопрос

Мне нужно иметь возможность взять формулу, использующую синтаксис формулы OpenDocument, разобрать ее на синтаксис, понятный Python, но без оценки переменных, а затем иметь возможность многократно оценивать формулу с изменением значений для переменных.Формулы могут быть введены пользователем, поэтому pyparsing позволяет мне как эффективно обрабатывать синтаксис формулы, так и очищать пользовательский ввод.Существует ряд хороших примеров pyparsing, но все математические, похоже, предполагают, что все в текущей области немедленно оценивается.

Для контекста я работаю с моделью промышленной экономики (оценка жизненного цикла, или LCA), где эти формулы представляют объем обмена материалами или энергией между процессами.Переменная сумма может быть функцией нескольких параметров, таких как географическое положение.Цепочка ссылок на формулы и переменные хранится в ориентированном ациклическом графе, так что формулы всегда можно просто вычислить.Формулы хранятся в базе данных в виде строк.Мои вопросы таковы:

  1. Возможно ли проанализировать формулу таким образом, чтобы проанализированная оценка также могла быть сохранена в базе данных (в виде строки для оценки или чего-то еще)?
  2. Существуют ли альтернативы такому подходу?Имейте в виду, что идеальное решение - это анализировать / записывать один раз и читать много раз.Например, частично разобрав формулу, а затем используя модуль ast, хотя я не знаю, как это могло бы работать с хранилищем базы данных.
  3. Есть какие-нибудь примеры проекта или библиотеки, похожие на этот, которые я мог бы просмотреть?Я не программист, просто студент, пытающийся закончить свою диссертацию, одновременно создавая модель программного обеспечения LCA с открытым исходным кодом в свободное время.
  4. Не слишком ли медленный этот подход?Я хотел бы иметь возможность выполнять значительные прогоны по методу Монте-Карло, где каждый прогон мог бы включать десятки тысяч вычислений формул (это большая база данных).
Это было полезно?

Решение

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

2) Вы можете выполнить быстрый и неаккуратный проход, просто используя встроенные модули compile и eval, как в следующем интерактивном сеансе:

>>> y = compile("m*x+b","","eval")
>>> m = 100
>>> x = 5
>>> b = 1
>>> eval(y)
501

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

3) Вы можете получить онлайн-пример преобразования выражения в "вычисляемую" структуру данных на странице примеров pyparsing wiki.Проверьте simpleBool.py и evalArith.py особенно.Если вы чувствуете прилив сил, закажите последний выпуск Майский выпуск 2008 года из журнала Python, в котором есть моя статья "Написание простого интерпретатора / компилятора с помощью Pyparsing" с более подробным описанием используемых методов, плюс описание того, как работает обработка и распаковка проанализированных результатов.

4) Медленной частью будет синтаксический анализ, так что вы на правильном пути в сохранении этих результатов в некоторой промежуточной и повторно оцениваемой форме.Часть оценки должна быть довольно быстрой.Вторая медленная часть будет заключаться в извлечении этих обработанных структур из вашей базы данных.Во время вашего запуска MC я бы упаковал единственную функцию, которая принимает параметры выбора для выражения, извлекает данные из базы данных, разгружает и возвращает вычисляемое выражение.Затем, как только у вас это заработает, используйте декоратор memoize для кэширования этих пар запрос-результаты, так что любое заданное выражение нужно извлечь / отменить выбор только один раз.

Удачи с вашей диссертацией!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top