Autor: Luis Fernando Apáez Álvarez
-Curso PyM-
Proyecto 1: Instrucciones
Fecha: 27 de Agosto del 2022
Tiempo aproximado: 90 minutos.
Completa según se te vaya indicando. Recuerda que el código completo de tu proyecto debe estar en un sólo script de Python en el IDE en línea Replit.
Asimismo, lo que deberás hacer para resolver y programar este proyecto es, primero, copiar el código de la plantilla (Plantilla_p1) en un script de Python del IDE en línea de la página Replit. Después, conforme se te vaya indicando en esta notebook las instrucciones, deberás ir modificando dicho código de tu proyecto.
Comenzaremos por crear una ventana y, dentro de un menú, colocaremos la opción de graficar
para que el usuario pueda acceder a la calculadora graficadora que programaremos. Para ello
$1.$ Importaciones necesarias:
# Realiza la importacion de las librerias tkinter
# (asi como del modulo ttk), matplotlib.pyplot,
# numpy y sympy:
# .
# .
# .
# Configura el estilo de graficacion ggplot
# .
# .
# .
$2.$ Creación de la ventana principal, así como su configuración.
# Configuracion de la ventana principal
# Crea un objeto ventana denominado _ventana_
# .
# Asignale un titulo
# .
# Configura un tamanio de 500 px por 300 px
# .
# Creamos un menu principal en la ventana antes creada
menu_principal = tk.Menu(ventana)
# Agregamos dicho menu a la ventana principal
ventana.config(menu = menu_principal)
# Creamos un submenu de opciones para el
# menu principal
submenu = tk.Menu(menu_principal, tearoff=False)
Ahora bien, mediante el método tk.Toplevel()
podemos crear una ventana nueva. Así, dada la ventana principal de nuestro programa, crearemos una nueva ventana con la interfaz para la calculadora graficadora. Para tener una mejor organización de código crearemos una función definida por el usuario que tendrá todo el código necesario para que trabaje nuestra calculadora graficadora.
$3.$ Así, lo que haremos será programar un código para poder graficar la función que el usuario ingrese en una caja de texto.
# Completa segun se te indique:
# Configuramos una nueva ventana correspondiente a
# la opcion de calculadora graficadora
def c_graficar():
# Creamos una nueva ventana y la denominamos vc_graficar
# auxiliandonos del metodo Toplevel()
vc_graficar = tk.Toplevel()
# Configura el tamanio de esta nueva ventana en
# 500px por 200px
vc_graficar._ _ _
# ------------------------------------------------------
# Ahora agregaremos una etiqueta de texto a esta
# nueva ventana:
# ventana donde| texto que
# colocaremos | se mostrara
# la etiqueta |
etiqueta_fun = ttk._ _ _ (vc_graficar, text='Ingrese la función: ')
# Posicion de la etiqueta
etiqueta_fun.place(x = 20, y = 20)
# ------------------------------------------------------
# Caja de texto para que el usuario ingrese la funcion.
# La caja de texto se mostrara en esta nueva ventana
caja_fun = ttk._ _ _ (vc_graficar)
# Posicion de la caja de texto y capacidad de caracteres
caja_fun.place(x = 120, y = 20, width = 80)
# ------------------------------------------------------
# Ahora definiremos las funciones que realizaran
# las acciones de nuestros botones.
# Accion del boton graficar.
# (Para graficar funciones polinomiales)
def graficar():
# Rango fijo de graficacion
x = np.arange(-3, 3, 0.1)
# Obtendremos la funcion que el usuario ingreso
# en la caja de texto caja_fun, para lo cual
# utilizaremos el metodo get() como sigue
# Recuperamos la cadena de texto
# que el usuario ingreso.
# Dicha cadena de texto corresponde
# a la funcion a graficar
fun_str = caja_fun.get()
# El siguiente codigo nos permite realizar
# evaluaciones numericas sobre variables de tipo
# string. Recordemos que la funcion que ingreso el
# usuario es una cadena de texto.
y = eval(fun_str)
# Graficamos la funcion
plt._ _ _(x, y)
# Agregamos un titulo al grafico
plt._ _ _(f'f(x)={fun_str}')
# Mostramos el grafico creado
plt._ _ _ ()
Con lo anterior podremos graficar funciones polinomiales.
$4.$ Luego, implementaremos el código necesario para graficar funciones racionales, trigonométricas, exponenciales y logarítmicas. El código que utilizaremos será muy similar al utilizado antes.
# Accion del boton graficar_rac
# para graficar funciones racionales
def graficar_rac():
# Rango fijo
x = np.arange(-3, 3, 0.1, dtype=float)
# funcion (la obtenemos de la caja_fun)
fun_str = caja_fun.get()
# Comando para poder evaluar numericamente
# cadenas de texto
y = eval(fun_str)
# Establecemos un limite de rango de graficacion
# del eje y. Esto es preciso para las funciones
# racionales
plt.ylim(-3,3)
# graficamos la funcion
plt._ _ _(x, y)
# Creamos un titulo y mostramos el grafico
plt._ _ _ (f'f(x)={fun_str}')
plt._ _ _ ()
# Accion del boton graficar_trigo
# para graficar funciones trigonometricas. Para esto
# nos auxiliaremos de la libreria numpy
def graficar_trigo():
# Rango fijo. En este caso los rangos de graficacion
# seran en terminos del numero pi
x = np.arange(-2 * np.pi, 2 * np.pi, 0.1, dtype=float)
# funcion (la obtenemos de la caja_fun)
fun_str1 = caja_fun.get()
# Para el caso en que la funcion a graficar sea
# la funcion tangente estableceremos un
# limite de rango de graficacion del eje y.
# (Las primeras tres letras de la cadena que ingreso
# el usuario deben ser exactamente 'tan' para este caso)
if fun_str1[:3] == 'tan':
plt.ylim(-3,3)
# Para trabajar con funciones trigonometricas nos
# auxiliaremos de la libreria numpy.
# Por ejemplo:
# Lo que ingreso|
# el usuario: | resultado
# 'np' + 'sin(x)' | np.sin(x)
# 'np' + 'cos(x)' | np.cos(x)
# 'np' + 'tan(x)' | np.tan(x)
fun_str2 = 'np.' + fun_str1
# Comando para poder evaluar numericamente
# cadenas de texto
y = eval(fun_str2)
# graficamos
plt._ _ _ (x, y)
# Creamos un titulo y mostramos el grafico
plt._ _ _ (f'f(x)={fun_str1}')
plt._ _ _ ()
# Accion del boton graficar_exp_log
# para graficar funciones exponenciales y logaritmicas
def graficar_exp_log():
# Rango fijo
x = np.arange(-3, 3, 0.1, dtype=float)
# funcion (la obtenemos de la caja_fun)
fun_str1 = caja_fun.get()
# Para trabajar con funciones exponenciales y
# logaritmicas nos auxiliaremos de la libreria numpy
fun_str2 = 'np.' + fun_str1
# Comando para poder evaluar numericamente
# cadenas de texto
y = eval(fun_str2)
# Graficamos
plt._ _ _(x, y)
# Mostramos
plt._ _ _ (f'f(x)={fun_str1}')
plt._ _ _ ()
$5.$ Creacion de los botones asociados a las acciones (funciones) que definimos antes.
# Botones:
# --------------------------------------------------------------------------
# BOTON PARA GRAFICAR
# ventana donde| texto a mostrar| funcion o accion a
# lo colocaremos| | asociar al boton
boton_graficar = ttk._ _ _ (vc_graficar, text='Graficar', command = _ _ _ )
# Posicion de este boton
boton_graficar.place(x=20, y=60)
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
# BOTON PARA GRAFICAR FUNCIONES RACIONALES
boton_graficar_rac = ttk._ _ _ (vc_graficar, text='Graficar fun racional',
command = _ _ _ )
# Posicion de este boton
boton_graficar_rac.place(x=330, y=60)
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
# BOTON PARA GRAFICAR FUNCIONES TRIGONOMETRICAS
boton_graficar_trigo = ttk._ _ _ (vc_graficar, text='Graficar Trigonometric',
command = _ _ _ )
# Posicion de este boton
boton_graficar_trigo.place(x=100, y=60)
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
# BOTON PARA GRAFICAR FUNCIONES EXPONENCIALES Y LOGARITMICAS
boton_graficar_exp_log = ttk._ _ _ (vc_graficar, text='Graficar Exp/ log',
command = _ _ _ )
# Posicion de este boton
boton_graficar_exp_log.place(x=230, y=60)
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
# CONFIGURACION DE UN BOTON PARA SALIR DE LA VENTANA DE GRAFICACION
# Para salir de una ventana o cerrarla escribimos:
# <nombre de la ventana>.destroy
# En este caso este boton nos hara salir de la ventana
# vc_graficar.destroy y nos regresara a la ventana principal
boton_graf_salir = ttk._ _ _ (vc_graficar, text='Regresar',
# accion que hara nuestro boton
command = vc_graficar.destroy)
# Posicion de este boton
boton_graf_salir.place(x=20, y=100)
$6.$ Configuramos nuestro menú principal.
# Opciones del menu:
# Agregamos una opcion a nuestra submenu. Esta opcion
# abrira la ventana nueva que creamos con la interfaz
# para graficar funciones.
# nombre de la opcion| accion que hara esta opcion
# agregada a nuestro | en este caso la accion sera
# submenu | ejecutar la funcion c_graficar
# | que crea la ventana con la
# | interfaz para graficar
submenu.add_command(label = 'Graficador', command = c_graficar)
# Mostramos una linea separadora
submenu.add_separator()
# Agregamos la opcion para salir de nuestro programa.
# cerraremos la ventana
# principal
submenu.add_command(label = 'Salir', command = ventana.destroy)
# Agregamos el submenu al menu principal
# nombre del menu | submenu a
# principal | agregar
menu_principal._ _ _ (label='Menú', menu = _ _ _ )
$7.$ Agregaremos algunas etiquetas para darle la bienvenida a nuestro programa al usuario
# Mas etiquetas
# especificamos la tipografia
# y el tamanio de la letra
etiqueta1 = ttk._ _ _ (ventana, text="¡Bienvenido!", font=('Helvetica', 16))
# posicion de la etiqueta
etiqueta1.place(x=50, y=20)
# -------------------------------------------------------------------------------
etiqueta2 = ttk._ _ _ (ventana,
text="Este es un programa para graficar\ny calcular límites y derivadas",
font=('Helvetica', 12))
# posicion de la etiqueta
etiqueta2.place(x=50, y=60)
# Mostramos la ventana principal creada
ventana._ _ _ ()
$8.$ Pondremos a prueba lo que llevamos hasta este momento. Lo que deberás hacer en tu script de Python es juntar todo el código que llevamos hasta ahora y ejecutar dicho script. Tu programa deberá verse como:
Cuando apretamos la opción de salir se debe cerrar la ventana principal. Continuando, apretamos la opción de Graficador
y se nos debe mostrar
Al ingresar una función y apretar un botón
se nos debe mostrar
$9.$ Ahora bien, como pudiste haber notado el manejo de las coordenadas de los componentes fue mediante el método place()
en vez de utilizar el método grid()
. Por ende, lo que deberás hacer será implementar el método grid()
para cada uno de los componentes trabajados anteriormente. Además, deberás realizar la configuración de las filas y columnas de la ventana vc_graficar
utilizando rowconfigure()
y columnconfigure()
, por lo cual también deberás agregar el parámetro sticky
al método grid()
asociado a cada uno de los componentes. Donde además colocamos columnspan=2
en el método grid()
referente a la caja de texto para que ocupe el espacio de dos columnas. Cabe resaltar que el cambio que se te pide realizar entre el método place()
y grid()
es sobre los componentes, únicamente, de la ventana vc_graficar
.
$10.$ Continuando, ahora agregaremos las opciones para calcular el límite de una función, lo cual será muy similar a lo que hicimos antes para agregar la ventana nueva vc_graficar
. Comenzamos pues por definir una función para crear una ventana nueva, con el fin de implementar la interfaz y el código necesario para que nuestra calculadora pueda calcular el límite de la función que se escriba en cierta caja de texto. Aquí utilizaremos además la librería SymPy.
# .
# .
# .
# .
# Ventana correspondiente al calculo de limites
def c_limites():
# Ventana nueva
vc_limites = tk.Toplevel()
vc_limites.geometry('500x200')
# Texto
etiqueta_fun = ttk.Label(vc_limites, text='Ingrese la función:')
etiqueta_fun.place(x = 20, y = 20)
etiqueta_fun_x = ttk.Label(vc_limites, text='Hacía qué valor\ntiende x:')
etiqueta_fun_x.place(x = 20, y = 40)
# Caja para que el usuario ingrese la funcion
# (Consejo: en el ejercicio que se te mencionara lineas abajo,
# cuando implemente el metodo grid omite el parametro width)
caja_fun = ttk.Entry(vc_limites)
caja_fun.place(x = 120, y = 20, width = 100)
caja_x = ttk.Entry(vc_limites)
caja_x.place(x = 120, y = 50, width = 80)
# Acciones asociadas a los botones que definiremos abajo.
# Limpiar celdas de las cajas
def clear_text():
caja_fun.delete(0, tk.END)
caja_x.delete(0, tk.END)
# Funcion para calcular el limite
def calcular_lim():
x = sp.symbols('x')
# funcion
y = caja_fun.get()
# Valor del limite
limite = sp.limit(y,x, eval(caja_x.get()))
# Etiqueta para mostrar el resultado
etiqueta_resul_lim = ttk.Label(vc_limites,
text = f'El límite de f(x)={caja_fun.get()} cuando x tiende a {caja_x.get()} es {limite}')
etiqueta_resul_lim.place(x=20, y=120)
# Botones
# Boton para calcular el limite de una funcion
boton_calc = ttk.Button(vc_limites, text='Calcular', command = calcular_lim)
boton_calc.place(x=20, y=80)
# Boton para limpiar la caja de texto
boton_calc_nuevo = ttk.Button(vc_limites, text='Nuevo', command = clear_text)
boton_calc_nuevo.place(x=110, y=80)
# Boton para salir de la venta vc_limites
boton_calc_salir = ttk.Button(vc_limites, text='Regresar', command = vc_limites.destroy)
boton_calc_salir.place(x=20, y=150)
# .
# .
# .
# .
Con lo cual obtendremos algo como:
Cabe resaltar que dentro de la función clear_text()
utilizamos el método delete(0, tk.END)
con lo cual borraremos el texto que hayamos escrito antes en nuestras cajas de texto, desde el primer caracter ingresado, índice 0, hasta el último (tk.END
). De la función
# Funcion para calcular el limite
def calcular_lim():
x = sp.symbols('x')
# funcion
y = caja_fun.get()
# Valor del limite
limite = sp.limit(y,x, eval(caja_x.get()))
# Etiqueta
etiqueta_resul_lim = ttk.Label(vc_limites,
text = f'El límite de f(x)={caja_fun.get()} cuando x tiende a {caja_x.get()} es {limite}')
etiqueta_resul_lim.place(x=20, y=120)
podemos decir que, primero obtenemos lo que ingresó el usuario en la caja de texto, lo cual hacemos escribiendo caja_fun.get()
. Dado que lo anterior es una cadena de texto utilizaremos el método eval()
; asimismo, como se vió en la primera parte de conocimientos previos de este proyecto, utilizamos la librería SymPy para realizar el cálculo del límite que el usuario nos solicita. Finalmente, lo que haremos será mostrar el resultado obtenido mediante una etiqueta de texto, para lo cual definimos etiqueta_resul_lim
.
Ahora bien, lo que deberás hacer será utilizar el método grid()
en vez del método place()
en el código que escribimos sobre la función c_limites()
así como lo hiciste en el ejercicio del punto 9. Para la etiqueta etiqueta_resul_lim
configura en el grid columnspan=2
; haz lo mismo que lo anterior para el botón boton_calc_salir
.
$11.$ Ahora definiremos una función para calcular la derivada de la función matemática que el usuario ingrese en determinada caja de texto. El proceso será muy similar el hecho en el punto anterior. Mediante el siguiente código
# .
# .
# .
# .
# Ventana correspondiente al calculo de derivadas
def c_derivadas():
# Creamos una ventana nueva
vc_derivadas = tk.Toplevel()
# Titulo de la ventana
vc_derivadas.title('Derivadas')
# Tamanio
vc_derivadas.config(width = 500, height = 200)
# Texto
etiqueta_fun = ttk.Label(vc_derivadas, text='Ingrese la función:')
etiqueta_fun.place(x = 20, y = 20)
etiqueta_fun_ord = ttk.Label(vc_derivadas, text='Orden de \nderivación:')
etiqueta_fun_ord.place(x = 20, y = 40)
# Caja para que el usuario ingrese la funcion
caja_fun = ttk.Entry(vc_derivadas)
caja_fun.place(x = 120, y = 20, width = 100)
caja_ord = ttk.Entry(vc_derivadas)
caja_ord.place(x = 120, y = 50, width = 80)
# Limpiar celdas de las cajas
def clear_text():
caja_fun.delete(0, tk.END)
caja_ord.delete(0, tk.END)
# Funcion para calcular la derivada
def calcular_der():
x = sp.symbols('x')
# funcion
x = sp.symbols('x')
y = caja_fun.get()
# derivada
derivada = sp.diff(y,x,eval(caja_ord.get()))
# Etiqueta
etiqueta_resul_der = ttk.Label(vc_derivadas,
text = f'La derivada de f(x)={caja_fun.get()} de orden {caja_ord.get()} es {derivada}')
etiqueta_resul_der.place(x=20, y=120)
# Botones
boton_calc = ttk.Button(vc_derivadas, text='Calcular', command = calcular_der)
boton_calc.place(x=20, y=80)
boton_calc_nuevo = ttk.Button(vc_derivadas, text='Nuevo', command = clear_text)
boton_calc_nuevo.place(x=110, y=80)
boton_calc_salir = ttk.Button(vc_derivadas, text='Regresar', command = vc_derivadas.destroy)
boton_calc_salir.place(x=20, y=150)
# .
# .
# .
# .
Obtenemos algo como
Lo que deberás hacer será utilizar el método grid()
en vez del método place()
, de la misma manera como lo hiciste en el punto anterior. Recuerda que dentro del método grid()
debes utilizar también el parámetro sticky
y, cuando sea necesario, agregar el parámetro columnspan
.
Deberás obtener algo como:
Recordemos que en el punto 8. juntamos todo el código que se llevaba hasta ese entonces, pero a partir del punto 9. agregamos más funciones para crear otras dos ventanas. De tal manera, es necesario agregar otras dos opciones al menú que ya teníamos:
# .
# .
# .
# Opciones del menu
submenu.add_command(label = 'Graficador', command = c_graficar)
# Agregamos dos opciones adicionales, las cuales hacen alusion a la parte del
# calculo de limites y derivadas.
submenu.add_command(label = 'Limites', command = c_limites)
submenu.add_command(label = 'Derivadas', command = c_derivadas)
# El resto permanece igual.
# Agregamos una linea separadora
submenu.add_separator()
# Agregamos la opcion de salir
submenu.add_command(label = 'Salir', command=ventana.destroy)
menu_principal.add_cascade(label='Menú', menu = submenu)
# Texto
etiqueta1 = ttk.Label(ventana, text="¡Bienvenido!", font=('Helvetica', 16))
etiqueta1.place(x=50, y=20)
etiqueta2 = ttk.Label(ventana,
text="Este es un programa para graficar\ny calcular límites y derivadas
font=('Helvetica', 12))
etiqueta2.place(x=50, y=60)
ventana.mainloop()
De tal manera, al juntar todo el código que tenemos ya, abremos acabado entonces con la programación de nuestra calculadora graficadora (y que calcula límites y derivadas), por lo cual, en este punto, el proyecto ha terminada.