Curso de introducción a la programación con Python¶

    Autor: Luis Fernando Apáez Álvarez
    -Curso PyM-
    Proyecto 1: SOLUCIÓN
    Fecha: 27 de Agosto del 2022


Instrucciones¶

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.

1. Importaciones necesarias:
In [ ]:
# Realiza la importacion de las librerias tkinter 
# (asi como del modulo ttk), matplotlib.pyplot,
# numpy y sympy:
import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
import numpy as np
import sympy as sp

# Configura el estilo de graficacion ggplot
plt.style.use('ggplot')
2. Creación de la ventana principal, así como su configuración.
In [ ]:
# Configuracion de la ventana principal
# Crea un objeto ventana 
ventana = tk.Tk()
# Asignale un titulo
ventana.title('Cálculo Diferencial')
# Configura un tamanio de 500 px por 300 px
ventana.geometry('500x300')

# 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 funcione 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.
In [ ]:
# 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
    vc_graficar = tk.Toplevel()
    # Configura el tamanio de esta nueva ventana en
    # 500px por 200px
    vc_graficar.geometry('500x200')
    # ------------------------------------------------------
    
    # Ahora agregaremos una etiqueta de texto a esta 
    # nueva ventana:
    #                         ventana donde| texto que
    #                         colocaremos  | se mostrara
    #                         la etiqueta  |
    etiqueta_fun = ttk.Label(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.Entry(vc_graficar)
    # Posicion de la caja de texto
    caja_fun.place(x = 120, y = 20, width = 80)
    # ------------------------------------------------------
    
    # Ahora definiremos las funciones que realizaran
    # las acciones de nuestros botones.
    # Accion del boton _graficar_
    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 funcion 
        #          que el usuario ingreso
        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.plot(x, y)
        # Agregamos un titulo al grafico
        plt.title(f'f(x)={fun_str}')
        # Mostramos el grafico creado
        plt.show()

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.
In [ ]:
  # Accion del boton graficar_rac
    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
        plt.ylim(-3,3)
        # graficamos la funcion
        plt.plot(x, y)
        # Creamos un titulo y mostramos el grafico
        plt.title(f'f(x)={fun_str}')
        plt.show()

    # Accion del boton graficar_trigo
    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 cambiaremos el 
        # limite de rango de graficacion del eje y
        if fun_str1[:3] == 'tan':
            plt.ylim(-3,3)
            
        # Para trabajar con funciones trigonometricas 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.plot(x, y)
        # Creamos un titulo y mostramos el grafico
        plt.title(f'f(x)={fun_str1}')
        plt.show()

    # Accion del boton  graficar_exp_log 
    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.plot(x, y)
        # Mostramos
        plt.title(f'f(x)={fun_str1}')
        plt.show()
5. Creacion de los botones asociados a las acciones (funciones) que definimos antes.
In [ ]:
    # Botones:
    # --------------------------------------------------------------------------
    # BOTON PARA GRAFICAR
    #                          ventana donde| texto a mostrar| funcion o accion a 
    #                         lo colocaremos|                | asociar al boton
    boton_graficar = ttk.Button(vc_graficar, text='Graficar', command = graficar)
    # Posicion de este boton
    boton_graficar.place(x=20, y=60)
    # --------------------------------------------------------------------------
    # --------------------------------------------------------------------------
    # BOTON PARA GRAFICAR FUNCIONES RACIONALES
    boton_graficar_rac = ttk.Button(vc_graficar, text='Graficar fun racional', 
                                    command = graficar_rac)
    # Posicion de este boton
    boton_graficar_rac.place(x=330, y=60)
    # --------------------------------------------------------------------------
    # --------------------------------------------------------------------------
    # BOTON PARA GRAFICAR FUNCIONES TRIGONOMETRICAS
    boton_graficar_trigo = ttk.Button(vc_graficar, text='Graficar Trigonometric', 
                                      command = graficar_trigo)
    # Posicion de este boton
    boton_graficar_trigo.place(x=100, y=60)
    # --------------------------------------------------------------------------
    # --------------------------------------------------------------------------
    # BOTON PARA GRAFICAR FUNCIONES EXPONENCIALES Y LOGARITMICAS
    boton_graficar_exp_log = ttk.Button(vc_graficar, text='Graficar Exp/ log', 
                                        command = graficar_exp_log)
    # 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 sallir de una ventana o cerrarla escribimos: 
    # <nombre de la ventana>.destroy
    boton_graf_salir = ttk.Button(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.
In [ ]:
# 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.add_cascade(label='Menú', menu = submenu)
7. Agregaremos algunas etiquetas para darle la bienvenida a nuestro programa al usuario
In [ ]:
# Mas etiquetas
#                                                    especificamos la tipografia
#                                                    y el tamaño de la letra
etiqueta1 = ttk.Label(ventana, text="¡Bienvenido!", font=('Helvetica', 16))
# posicion de la etiqueta
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))
# posicion de la etiqueta
etiqueta2.place(x=50, y=60)

# Mostramos la ventana principal creada
ventana.mainloop()
    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:

    p1.PNG

p2.PNG

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

p3.PNG

Al ingresar una función y apretar un botón

p4.PNG

se nos debe mostrar

p5.PNG

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.

La configuración que se pide antes la haremos dentro de la función c_graficar():

In [ ]:
# .
# .
# .
# .
# Configuramos una nueva ventana correspondiente a
# la opcion de calculadora graficadora
def c_graficar():
    # Creamos una nueva ventana y la denominamos vc_graficar
    vc_graficar = tk.Toplevel()
    # Configura el tamanio de esta nueva ventana en
    # 500px por 200px
    vc_graficar.geometry('500x200')
    # Configuracion de las filas. Establecemos una 
    # proporcion de 1:2 respecto a la fila 0 y 
    # el resto de las filas, entorno al espacio
    # total de dicha ventana
    vc_graficar.rowconfigure(0, weight=1)
    vc_graficar.rowconfigure(1, weight=2)
    vc_graficar.rowconfigure(2, weight=2)
    vc_graficar.rowconfigure(3, weight=2)
    
    # Configuramos las columnas Establecemos una 
    # proporcion de 1:3 respecto a la columna 0 y 
    # columnas 1, entorno al espacio
    # total de dicha ventana
    vc_graficar.columnconfigure(0, weight=1)
    vc_graficar.columnconfigure(1, weight=3)
# .
# .
# .
# .

Adicionalmente, a cada componente respectiva a esta ventana (vc_graficar) agregaremos dentro del método grid() el código sticky='NSWE', de modo que la interfaz de esta ventana debe verse como:

pp10.PNG

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. Puedes consultar el código completo de la parte anterior mediante el siguiente link:

script_codigo_ej9_p1

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 y la derivada 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.
In [ ]:
# .
# .
# .
# .
# 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
    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:

pp11.PNG

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.

In [ ]:
# SOLUCION
# .
# .
# .
# Ventana limites
def c_limites():
    # Ventana nueva
    vc_limites = tk.Toplevel()
    vc_limites.geometry('500x200')
    # Configuracion de las filas. Establecemos una 
    # proporcion de 1:2 respecto a la fila 0 y 1 
    # el resto de las filas, entorno al espacio
    # total de dicha ventana.
    # (Sugerencia)
    vc_limites.rowconfigure(0, weight=1)
    vc_limites.rowconfigure(1, weight=1)
    vc_limites.rowconfigure(2, weight=2)
    vc_limites.rowconfigure(3, weight=2)
    # Configuramos las columnas Establecemos una 
    # proporcion de 1:2 respecto a la columna 0 y 
    # columnas 1, entorno al espacio
    # total de dicha ventana
    vc_limites.columnconfigure(0, weight=1)
    vc_limites.columnconfigure(1, weight=2)
    
    # Texto
    etiqueta_fun = ttk.Label(vc_limites, text='Ingrese la función:')
    etiqueta_fun.grid(row=0, column=0, sticky='NSWE')
    etiqueta_fun_x = ttk.Label(vc_limites, text='Hacía qué valor\ntiende x:')
    etiqueta_fun_x.grid(row=1, column=0, sticky='NSWE')

    # Caja para que el usuario ingrese la funcion
    caja_fun = ttk.Entry(vc_limites)
    caja_fun.grid(row=0, column=1, sticky='NSWE')
    caja_x = ttk.Entry(vc_limites)
    caja_x.grid(row=1, column=1, sticky='NSWE')
    
    # 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.grid(row=3, column=0, columnspan=2, sticky='NSWE')
        
    # Botones
    # Boton para calcular el limite de una funcion
    boton_calc = ttk.Button(vc_limites, text='Calcular', command = calcular_lim)
    boton_calc.grid(row=2, column=0, sticky='NSWE')
    # Boton para limpiar la caja de texto
    boton_calc_nuevo = ttk.Button(vc_limites, text='Nuevo', command = clear_text)
    boton_calc_nuevo.grid(row=2, column=1, sticky='NSWE')
    # Boton para salir de la venta vc_limites
    boton_calc_salir = ttk.Button(vc_limites, text='Regresar', command = vc_limites.destroy)
    boton_calc_salir.grid(row=4, column=0, columnspan=2, sticky='NSWE')
# .
# .
# .
# .

Con lo cual obtenemos algo como:

pp12.PNG

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
In [ ]:
# .
# .
# .
# .
# 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

p14.PNG

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.

In [ ]:
# SOLUCION
# .
# .
# .
# 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.geometry('500x200')
    # Configuracion de las filas. Establecemos una 
    # proporcion de 1:2 respecto a la fila 0 y 
    # el resto de las filas, entorno al espacio
    # total de dicha ventana
    vc_derivadas.rowconfigure(0, weight=1)
    vc_derivadas.rowconfigure(1, weight=1)
    vc_derivadas.rowconfigure(2, weight=4)
    vc_derivadas.rowconfigure(3, weight=4)
    
    # Configuramos las columnas Establecemos una 
    # proporcion de 1:3 respecto a la columna 0 y 
    # columnas 1, entorno al espacio
    # total de dicha ventana
    vc_derivadas.columnconfigure(0, weight=1)
    vc_derivadas.columnconfigure(1, weight=2)

    # Texto
    etiqueta_fun = ttk.Label(vc_derivadas, text='Ingrese la función:')
    etiqueta_fun.grid(row=0, column=0, sticky='NSWE')
    etiqueta_fun_ord = ttk.Label(vc_derivadas, text='Orden de \nderivación:')
    etiqueta_fun_ord.grid(row=1, column=0, sticky='NSWE')

    # Caja para que el usuario ingrese la funcion
    caja_fun = ttk.Entry(vc_derivadas)
    caja_fun.grid(row=0, column=1, sticky='NSWE')
    caja_ord = ttk.Entry(vc_derivadas)
    caja_ord.grid(row=1, column=1, sticky='NSWE')
    # 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.grid(row=3, column=0, sticky='NSWE', columnspan=2)

    # Botones
    boton_calc = ttk.Button(vc_derivadas, text='Calcular', command = calcular_der)
    boton_calc.grid(row=2, column=0, sticky='NSWE')
    boton_calc_nuevo = ttk.Button(vc_derivadas, text='Nuevo', command = clear_text)
    boton_calc_nuevo.grid(row=2, column=1, sticky='NSWE')
    boton_calc_salir = ttk.Button(vc_derivadas, text='Regresar', command = vc_derivadas.destroy)
    boton_calc_salir.grid(row=4, column=0, sticky='NSWE', columnspan=2)
# .
# .
# .
# .

p15.PNG

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.

El código completo del proyecto es el siguiente:

In [ ]:
import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
import numpy as np
import sympy as sp
plt.style.use('ggplot')

ventana = tk.Tk()
ventana.title('Cálculo Diferencial')
ventana.geometry('500x300')

menu_principal = tk.Menu(ventana)
ventana.config(menu=menu_principal)
submenu = tk.Menu(menu_principal, tearoff=False)

# ----------------------------------------------------------------------

def c_graficar():
    vc_graficar = tk.Toplevel()
    vc_graficar.geometry('500x200')
    vc_graficar.rowconfigure(0, weight=1)
    vc_graficar.rowconfigure(1, weight=2)
    vc_graficar.rowconfigure(2, weight=2)
    vc_graficar.rowconfigure(3, weight=2)
    vc_graficar.columnconfigure(0, weight=1)
    vc_graficar.columnconfigure(1, weight=3)

    etiqueta_fun = ttk.Label(vc_graficar, text='Ingrese la función: ')
    # Posicion de la etiqueta
    etiqueta_fun.grid(row=0, column=0, sticky='NSWE')
    
    # ------------------------------------------------------

    caja_fun = ttk.Entry(vc_graficar, width=15)
    caja_fun.grid(row=0, column=1, sticky='NSWE', columnspan=2, padx=5, pady=5)

    # ------------------------------------------------------

    def graficar():
        # Rango fijo de graficacion
        x = np.arange(-3, 3, 0.1)
        fun_str = caja_fun.get()
        y = eval(fun_str)
        plt.plot(x, y)
        plt.title(f'f(x)={fun_str}')
        plt.show()

    def graficar_rac():
        # Rango fijo
        x = np.arange(-3, 3, 0.1, dtype=float)
        fun_str = caja_fun.get()
        y = eval(fun_str)
        plt.ylim(-3, 3)
        plt.plot(x, y)
        plt.title(f'f(x)={fun_str}')
        plt.show()

    def graficar_trigo():
        x = np.arange(-2 * np.pi, 2 * np.pi, 0.1, dtype=float)
        fun_str1 = caja_fun.get()
        if fun_str1[:3] == 'tan':
            plt.ylim(-3, 3)
        fun_str2 = 'np.' + fun_str1
        y = eval(fun_str2)
        plt.plot(x, y)
        plt.title(f'f(x)={fun_str1}')
        plt.show()

    def graficar_exp_log():
        x = np.arange(-3, 3, 0.1, dtype=float)
        fun_str1 = caja_fun.get()
        fun_str2 = 'np.' + fun_str1
        y = eval(fun_str2)
        plt.ylim(-3, 3)
        plt.plot(x, y)
        plt.title(f'f(x)={fun_str1}')
        plt.show()
        
    # Botones:
    boton_graficar = ttk.Button(vc_graficar, text='Graficar', command=graficar)
    boton_graficar.grid(row=1, column=0, sticky='NSWE')
    
    boton_graficar_rac = ttk.Button(vc_graficar,
                                    text='Graficar fun racional',
                                    command=graficar_rac)
    boton_graficar_rac.grid(row=1, column=1, sticky='NSWE')
    
    boton_graficar_trigo = ttk.Button(vc_graficar,
                                      text='Graficar Trigonometric',
                                      command=graficar_trigo)
    boton_graficar_trigo.grid(row=1, column=2, sticky='NSWE')

    boton_graficar_exp_log = ttk.Button(vc_graficar,
                                        text='Graficar Exp/ log',
                                        command=graficar_exp_log)
    boton_graficar_exp_log.grid(row=2, column=0, sticky='NSWE')
    
    boton_graf_salir = ttk.Button(vc_graficar, text='Regresar', command=vc_graficar.destroy)
    boton_graf_salir.grid(row=2, column=1, sticky='NSWE')

    
# Ventana limites
def c_limites():
    vc_limites = tk.Toplevel()
    vc_limites.geometry('500x200')
    vc_limites.rowconfigure(0, weight=1)
    vc_limites.rowconfigure(1, weight=1)
    vc_limites.rowconfigure(2, weight=2)
    vc_limites.rowconfigure(3, weight=2)
    vc_limites.columnconfigure(0, weight=1)
    vc_limites.columnconfigure(1, weight=2)
    
    etiqueta_fun = ttk.Label(vc_limites, text='Ingrese la función:')
    etiqueta_fun.grid(row=0, column=0, sticky='NSWE')
    etiqueta_fun_x = ttk.Label(vc_limites, text='Hacía qué valor\ntiende x:')
    etiqueta_fun_x.grid(row=1, column=0, sticky='NSWE')

    caja_fun = ttk.Entry(vc_limites)
    caja_fun.grid(row=0, column=1, sticky='NSWE')
    caja_x = ttk.Entry(vc_limites)
    caja_x.grid(row=1, column=1, sticky='NSWE')
    
    def clear_text():
        caja_fun.delete(0, tk.END)
        caja_x.delete(0, tk.END)
            
    def calcular_lim():
        x = sp.symbols('x')
        y = caja_fun.get()
        limite = sp.limit(y,x, eval(caja_x.get()))
        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.grid(row=3, column=0, columnspan=2, sticky='NSWE')
        
    # Botones
    boton_calc = ttk.Button(vc_limites, text='Calcular', command = calcular_lim)
    boton_calc.grid(row=2, column=0, sticky='NSWE')

    boton_calc_nuevo = ttk.Button(vc_limites, text='Nuevo', command = clear_text)
    boton_calc_nuevo.grid(row=2, column=1, sticky='NSWE')

    boton_calc_salir = ttk.Button(vc_limites, text='Regresar', command = vc_limites.destroy)
    boton_calc_salir.grid(row=4, column=0, columnspan=2, sticky='NSWE')
    
# ----------------------------------------------------------------------


def c_derivadas():
    vc_derivadas = tk.Toplevel()
    vc_derivadas.title('Derivadas')
    vc_derivadas.geometry('500x200')
    vc_derivadas.rowconfigure(0, weight=1)
    vc_derivadas.rowconfigure(1, weight=1)
    vc_derivadas.rowconfigure(2, weight=4)
    vc_derivadas.rowconfigure(3, weight=4)
    
    vc_derivadas.columnconfigure(0, weight=1)
    vc_derivadas.columnconfigure(1, weight=2)

    etiqueta_fun = ttk.Label(vc_derivadas, text='Ingrese la función:')
    etiqueta_fun.grid(row=0, column=0, sticky='NSWE')
    
    etiqueta_fun_ord = ttk.Label(vc_derivadas, text='Orden de \nderivación:')
    etiqueta_fun_ord.grid(row=1, column=0, sticky='NSWE')
    
    caja_fun = ttk.Entry(vc_derivadas)
    caja_fun.grid(row=0, column=1, sticky='NSWE')
    
    caja_ord = ttk.Entry(vc_derivadas)
    caja_ord.grid(row=1, column=1, sticky='NSWE')
    
    def clear_text():
        caja_fun.delete(0, tk.END)
        caja_ord.delete(0, tk.END)

    def calcular_der():
        x = sp.symbols('x')
        x = sp.symbols('x')
        y = caja_fun.get()
        derivada = sp.diff(y,x,eval(caja_ord.get()))
        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.grid(row=3, column=0, sticky='NSWE', columnspan=2)

    # Botones
    boton_calc = ttk.Button(vc_derivadas, text='Calcular', command = calcular_der)
    boton_calc.grid(row=2, column=0, sticky='NSWE')
    
    boton_calc_nuevo = ttk.Button(vc_derivadas, text='Nuevo', command = clear_text)
    boton_calc_nuevo.grid(row=2, column=1, sticky='NSWE')
    
    boton_calc_salir = ttk.Button(vc_derivadas, text='Regresar', command = vc_derivadas.destroy)
    boton_calc_salir.grid(row=4, column=0, sticky='NSWE', columnspan=2)
    
# ----------------------------------------------------------------------

# Opciones del menu
submenul.add_command(label = 'Graficador', command = c_graficar)
submenu.add_command(label = 'Limites', command = c_limites)
submenu.add_command(label = 'Derivadas', command = c_derivadas)

submenu.add_separator()
submenu.add_command(label = 'Salir', command = ventana.destroy)
menu_principal.add_cascade(label='Menú', menu = submenu)


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()

O puedes consultar el script del código completo mediante el siguiente link:

scrit_codigo_solucion_p1