[Python-es] Ayuda con sintaxis de Calculadora en Python usando WXPython

Mariano Reingart reingart en gmail.com
Jue Ene 24 01:16:16 CET 2013


Para analizar el código y evitar en alguna forma el eval lo más fácil
de usar es tokenizer:

http://docs.python.org/2/library/tokenize.html?highlight=tokenizer

import tokenize
from StringIO import StringIO
s = "1 + sqrt(10)"
g = tokenize.generate_tokens(StringIO(s).readline)

Eso te generaría una "lista"  con el analisis de los tokens (elementos
sintácticos), por ej para "1 + sqrt(10)":

(2, '1', (1, 0), (1, 1), '1 + sqrt(10)'),
(51, '+', (1, 2), (1, 3), '1 + sqrt(10)'),
(1, 'sqrt', (1, 4), (1, 8), '1 + sqrt(10)'),
(51, '(', (1, 8), (1, 9), '1 + sqrt(10)'),
(2, '10', (1, 9), (1, 11), '1 + sqrt(10)'),
(51, ')', (1, 11), (1, 12), '1 + sqrt(10)'),
(0, '', (2, 0), (2, 0), '')

El primer valor es el tipo de token:
token.OP = 51
token.NAME = 1
token.NUMBER = 2

El segundo valor es el string, el tercero y cuarto son la posición y
el quinto es la linea de código fuente.
Con el tipo y el string podrias armarte un mini-interprete para evitar
el uso de eval, y sin preocuparte mucho por la sintaxis.

Para temas avanzados, podrías usar los módulos parser y ast (pero es
algo bastante complejo y ya entra en juego la maquina virtual de
python):

http://docs.python.org/2/library/parser.html

http://docs.python.org/2/library/ast.html

Al margen, ¿que materia estas cursando? ¿vas a publicar el código o el trabajo?

Sds

Mariano Reingart
http://www.sistemasagiles.com.ar
http://reingart.blogspot.com


2013/1/23 manuel <manuelcortez00 en gmail.com>:
> Hola a todos,
>
> Para un proyecto de fin de cursos, me planteé crear una pequeña y simple
> calculadora usando Python como lenguaje y WXPython como Widgets gráficos,
> entre otras cosas, porque es multiplataforma, y en Microsoft Windows, que es
> donde la necesito ejecutar, ofrece accesibilidad, cosa necesaria para mí y
> que no ofrece ninguna calculadora gratuita, al menos que yo sepa.
>
> La cosa, es que me gustaría que la calculadora tenga una sintaxis intuitiva,
> y para eso pido su consejo.
>
> Cuando la calculadora solo se encargaba de sumar y restar, lo que hacía era
> pasarle la cadena tomada del campo de texto a eval(), intentando encerrar lo
> más posible la función, por aquello que eval podría ejecutar más código.
> Parecía todo funcionar de una forma aceptable.
>
> El problema llegó cuando, por exigencias de la escuela, teníamos que
> trabajar seguido con raíces cuadradas. Bien, implementé la función, pero eso
> supondría tener que hacer algo como math.sqrt() o sqrt(); no sé la demás
> gente, pero no suena algo bastante simple de realizar, al menos para alguien
> que no tiene idea de Python (este proyecto lo comparto con otro compañero
> ciego que va en la universidad).
>
> La respuesta a esto, fue algo más o menos claro. La idea ahora, es que se
> carga una cadena a una función, y la cadena se encarga de reemplazar
> símbolos por las funciones correspondientes, que toma de un par de
> diccionarios. En pocas palabras, se hace la conversión de algo como "R25" a
> sqrt(25); luego, se pasa a eval, que ya tiene importado todo math. Si la
> cadena llegase a dar una excepción, se maneja mostrando un mensaje en el
> programa, sin más. Cada nueva operación (que se calcula presionando enter o
> el botón = ) carga la cadena, y la función hace su trabajo.
>
> Pero hay dos motivos que me llevan a hacer esta petición a la lista; una, es
> que no estoy seguro, pero quiero preguntar si hay una forma más sencilla de
> hacer que una expresión se vea más común, como el ejemplo anterior; imagino
> que usar eval tiene sus riesgos por todas partes, y quería preguntar si
> alguno conoce un parser que pueda ayudarme de modo que pueda cambiar la
> sintaxis, sería de gran ayuda.
>
> Otra de las cosas que quisiera preguntar, es si se podría conseguir un
> resultado de un porcentaje, pero escrito de la siguiente forma: 25+50%.
>
> En GCalctool, esto se hace, pero no sé leer el código; no entiendo de muy
> buena forma cómo lo hacen; se asume que el 50% debe ser del número 25, pero
> cuando haces 25% se obtiene un 0.25, donde se asume no sé qué, se multiplica
> 25*1/100, y se obtiene el resultado.
>
> Alguien tiene una idea de cómo podría hacer esto en Python? Alguien me
> sugirió hacer una especie de compilador o intérprete, porque se podía
> definir la sintaxis, pero no veo una luz al respecto.
>
> Muchas gracias por su atención; saludos.
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/


Más información sobre la lista de distribución Python-es