Análisis de ecuaciones en Python


¿Cómo puedo (fácilmente) tomar una cadena como "sin(x)*x^2" que podría ser introducida por un usuario en tiempo de ejecución y producir una función Python que podría ser evaluada para cualquier valor de x?

Author: bummi, 2009-02-27

7 answers

El propio compilador interno de Python puede analizar esto, si usa notación Python.

Si cambia ligeramente la notación, será más feliz.

import compiler
eq= "sin(x)*x**2"
ast= compiler.parse( eq )

Se obtiene un árbol de sintaxis abstracta con el que se puede trabajar.

 46
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 11:12:34

Puedes usar Python parser:

import parser
formula = "sin(x)*x**2"
code = parser.expr(formula).compile()

from math import sin
x = 10
print eval(code)

Funciona mejor que pure eval y, por supuesto, evita la inyección de código!

 26
Author: Don,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-26 18:11:43
 f = parser.parse('sin(x)*x^2').to_pyfunc()

Donde parser podría definirse usando PLY, pyparsing, builtin tokenizer, parser, ast.

No utilice eval en la entrada del usuario.

 13
Author: jfs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 10:51:37

Pyparsing podría hacer lo que quieres ( http://pyparsing.wikispaces.com / ) especialmente si las cadenas son de una fuente no confiable.

Véase también http://pyparsing.wikispaces.com/file/view/fourFn.py para una calculadora bastante completa construida con él.

 7
Author: cryo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-29 12:11:39

Para enfatizar el consejo de J. F. Sebastian, las soluciones 'eval' e incluso las 'compiladoras' pueden estar abiertas a sutiles agujeros de seguridad. Que tan confiable es la entrada? Con 'compiler' puedes al menos filtrar cosas como las búsquedas de getattr desde el AST, pero he encontrado que es más fácil usar CAPAS o pyparsing para este tipo de cosas que asegurar el resultado de dejar que Python ayude.

Además, 'compiler' es torpe y difícil de usar. Está en desuso y eliminado en 3.0. Debe utilizar el módulo 'ast' (añadido en 2.6, disponible en 2.5 como '_ast').

 2
Author: Andrew Dalke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 11:57:10

De acuerdo con vartec. Yo usaría SymPy-en particular la función lambdify debería hacer exactamente lo que quieres.

Véase: http://showmedo.com/videotutorials/video?name=7200080&fromSeriesID=720

Para una explicación muy agradable de esto.

Mis mejores deseos,

 1
Author: Geddes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-29 11:44:17

Sage está pensado como reemplazo de matlab y en los videos introductorios se demuestra cuán similares son los casos que se manejan. Parecen apoyar una amplia gama de enfoques. Dado que el código es de código abierto, puede navegar y ver por sí mismo cómo los autores manejan estos casos.

 0
Author: SilentGhost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 10:50:39