Частичная оценка с pyparsing - PullRequest
3 голосов
/ 17 декабря 2009

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

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

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

1 Ответ

4 голосов
/ 17 декабря 2009

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

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

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

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

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

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

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

...