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

    Autor: Luis Fernando Apáez Álvarez
    -Curso PyM-
    Proyecto 1: Instrucciones
    Fecha: 27 de Agosto del 2022
    Tiempo aproximado: 90 minutos.


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.

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:

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

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

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
    # 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.

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

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

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._ _ _ (label='Menú', menu = _ _ _ )

$7.$ Agregaremos algunas etiquetas para darle la bienvenida a nuestro programa al usuario

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

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. 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.

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
    # (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:

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. 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

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.

Deberás obtener algo como:

p15.PNG

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:

In [ ]:
# .
# .
# .

# 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.