Definir funciones por teclado -y código en general- como argumento de funciones en Python.

Siempre se aprende algo nuevo cuando se lee código de otros, en este caso a los alumnos del grado de matemáticas de la Universidad de Alicante les han pedido un ejercicio en Python -sí, se enseña en lugar de matlab entre otros- el ejercicio en sí no entraña dificultad, pero siempre se le puede dar una vuelta más de tuerca.

“Implementar el método de integración de Simpson para integrar una función en un intervalo”.

Suena sencillo. El “problema” es que cada vez que queremos integrar una función debemos abrir el script por donde está definida esa función y modificarla manualmente, no es nada del otro mundo, pero se puede hacer algo diferente. Vamos a ello.

Primero necesitamos el módulo sys, que nos abre muchas puertas del sistema, entre las cuales se encuentra el tomar datos por teclado.
Seguro que a alguno le suena esta declaración de función si ha visto algo de C:

int main(int argc, const char *argv[])
{
    /* code */
}

Pues bien, el primer parámetro es un entero que contiene el número de elementos que le hemos pasado a la función main y el segundo es un puntero a una lista de esos elementos. En Python no existe la función main como tal, pero podemos usar también los parámetros argv.

Vamos a hacer una prueba, llamemos a nuestro fichero test.py

import sys
print "Argumentos a la funcion %s" %sys.argv[1:]

Ejecutemos el programa por teclado de la siguiente manera:

$python test.py cosas coches 3 gatos

Nuestro programa va a dar esta salida

Args ['cosas', 'coches', '3', 'gatos']

Podemos ver que se trata de una lista y cada uno de los elementos es un string, esto es importante. Otro dato a tener en cuenta es que el argumento 0 es el nombre del script con extensión .py (en algunos casos puede incluir también la ruta completa al fichero). Bien, se os ocurren millones de cosas para hacer ¿verdad? pues vamos a ver un poco más…

Este será nuestro nuevo programa:

import sys
def f(x):
   return 2*x

print "Multiplico tu argumento por dos, prueba!"
print f(float (sys.argv[1]))
#como he dicho antes, todos los argumentos son strings, por lo que tenemos que prestar
#atencion y convertirlos al tipo adecuado.

<<python test.py 2
>>4

Ok, una vuelta más de tuerca, mirad esto:

code = """def f(x):
	      return """ + sys.argv[1]

¿Qué pasa si nuestro argumento 1 es x*x? Pues que code será:

def f(x):
    return x*x

Ahora tenemos un as más guardado, a ver si lo encuentras:

import sys
from math import*

print "Args %s" %sys.argv[1:]#podeis borrar esto, es didactico.

def simpson(a, b):
    f1 = (b-a)/6.0 
    f2 = f(a)+(4*f((a+b)/2.0))+f(b)
    return f1*f2



code = """def f(x):
			return """ + sys.argv[1]
exec code

print 'Resultado de la integracion: ' ,simpson(float(sys.argv[2]), float(sys.argv[3]))

Lo que hace la función exec es convertir nuestro string en código del programa, por lo que a efectos de ejecución es como si hubiésemos implementado nuestra función f(x) sobre el script. Ahora ya tenéis una calculadora de integrales🙂. Hagamos unas pruebas, llamemos kepler.py al programa anterior.

Prueba 1.

<< $python kepler.py x*x 0 2
>> Args ['x*x', '0', '2']
>> Resultado de la integracion:  2.66666666667

Prueba 2. Si tenemos que pasar funciones complejas podemos hacerlo encerrándolas con ” como cadenas:

<< $python kepler.py 'sqrt(x)' 0 2
>> Args ['sqrt(x)', '0', '2']
>> Resultado de la integracion:  1.80473785412

NOTA: El algoritmo de integración es lo de menos, he usado la regla de Kepler en lugar de la de Simpson 1/3 u otras por simplicidad, para que se preste atención a lo que importa, no al algoritmo.

Esta entrada fue publicada en python y etiquetada , , , . Guarda el enlace permanente.

Una respuesta a Definir funciones por teclado -y código en general- como argumento de funciones en Python.

  1. magnificent points altogether, you simply received a emblem new reader. What might you suggest about your post that you made some days ago? Any sure?

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s