# Paquetes que ocuparemos en esta parte del proyecto
import matplotlib.pyplot as mplot
import numpy as np
En la parte final de la primer parte de este proyecto probamos nuestro código creando el objeto prueba
, donde ejecutamos el código
# Instanciamos la clase
prueba = graficar()
# Invocamos el método str
print(prueba.mensaje_inicial())
# Información dle usuario (proviene de la clase menu)
prueba.info_usuario()
# Método str (proviene de la clase graficar)
print(prueba)
# Graficamos (proviene de la clase graficar)
prueba.Graficador()
ejecutando dicho código en ese orden. Para este punto podemos notar que requerimos de cierto control de flujo en nuestras clases pues, como vemos en el código anterior, debemos primero ejecuar print(prueba.mensaje_inicial())
y prueba.info_usuario()
para que el resto del código funcione; asimismo, lo último que debe ejecutarse es el método Graficador()
, pues de ejecutarse antes causará un error. Comenzaremos implementando primero un control de flujo en la clase graficar
, donde por ejemplo desearemos que el método str
deba ejecutarse primero antes que el métodoGraficador()
.
Lo que haremos será definir un atributo con un valor lógico con el cual estableceremos el correcto control de flujo a la hora de llamar a los métodos de esta clase:
class graficar(menu):
def __init__(self):
super().__init__()
# Atributo lógico para el control de flujo
self.control_f = False
def __str__(self):
# Cambiamos el valor lógico para poder ejecutar
# el return de este método
self.control_f = True
return f'Rango:({self.rango_inf},{self.rango_sup})\nf(x) = {self.fun}'
def Graficador(self):
if self.control_f:
x = np.arange(eval(self.rango_inf), eval(self.rango_sup), 0.01)
y = self.fun
mplot.plot(x, eval(y))
mplot.grid()
mplot.show()
else:
print("Debe ejecutarse primero el método str!")
lo anterior puede explicarse como:
De forma inicial self.control_f=False
de tal manera, si invocamos el método Graficador()
antes del método str
, self.control_f
seguirá siendo falso. Por ende, debido al if
, se imprimirá el mensaje "Debe ejecutarse primero el método str!"
.
Al invocar primero el método str
cambiamos el valor de self.control_f
a verdadero, de modo que, después de invocar el método str
, podremos invocar el método Graficador()
de forma correcta.
Hagamos una prueba:
# Instanciamos la clase e ingresamos la información del usuario
prueba = graficar()
prueba.info_usuario()
______________________________
# Invocamos el método Graficador antes del str
prueba.Graficador()
Debe ejecutarse primero el método str!
# Correcto control de flujo:
# Invocamos primero el método str
print(prueba)
# Graficamos (proviene de la clase graficar)
prueba.Graficador()
Rango:(0,1) f(x) = x**2
Ahora bien, adaptaremos también la clase menu
para adaptar un control de flujo con el siguiente orden:
mensaje_inicial
info_usuario
str
de la clase graficar
Graficador()
La idea para implementar lo anterior es análoga a lo que hicimos antes, salvo que el atributo self.control_f
será parte del constructor de la super clase.
Así, escribimos
class menu:
def __init__(self):
self.fun = ""
self.rango = ""
# Atributo para control de flujo
self.control_f = False
def mensaje_inicial(self):
self.cadena1 = "De que tipo es tu función:"
self.cadena2 = "_" * 30
self.cadena3 = "1: Algebraicas"
self.cadena4 = "2: Trigonométricas"
self.cadena5 = "3: Exponencial"
self.cadena6 = "4: Logarítmica"
self.cadena7 = "_" * 30
# Cambiamos valor lógico de control_f
self.control_f = True
return self.cadena1 + "\n" + self.cadena2 + "\n" + self.cadena3 \
+ "\n" + self.cadena4 + "\n" + self.cadena5 + "\n" + self.cadena6 \
+ "\n" + self.cadena7
def info_usuario(self):
# Implementamos el if para el control del flujo
if self.control_f:
self.n_aux = input("Coloca un número del 1 al 4: ")
print("_" * 30)
if int(self.n_aux) not in (1,2,3,4):
print("Error, debes ingresar un número del 1 al 4")
print("Fin del proceso")
else:
self.fun = input("Ingresa tu función: ")
self.rango = input("Ingresa el rango de graficación: ")
self.rango_inf = self.rango[self.rango.find("(") + 1: self.rango.find(",")]
self.rango_sup = self.rango[self.rango.find(",") + 1: self.rango.find(")")]
if int(self.n_aux) != 1:
self.fun = "np." + self.fun
else:
self.fun = self.fun
else:
print("Debe invocarse primero el método mensaje inicial")
Notemos que al invocar el método info_usuario()
de la clase menú, tendremos que self.control_f
tendrá asignado el valor de True
. Así, el control del flujo de la clase graficar()
se verá afectado y podremos invocar el método Graficador()
antes del método str
. Para resolver este conflicto escribimos
class graficar(menu):
def __init__(self):
super().__init__()
# Cambiamos nuevamente el valor lógico de control_f
def __str__(self):
# Cambiamos el valor lógico para poder ejecutar
# el return de este método
self.control_f = False
return f'Rango:({self.rango_inf},{self.rango_sup})\nf(x) = {self.fun}'
def Graficador(self):
if not self.control_f:
x = np.arange(eval(self.rango_inf), eval(self.rango_sup), 0.01)
y = self.fun
mplot.plot(x, eval(y))
mplot.grid()
mplot.show()
else:
print("Debe ejecutarse primero el método str!")
es decir, como self.control_f
tiene asignado el valor True
, el método Graficador()
sólo se ejecutará si self.control_f
es False
. Luego, el método str
lo que hace es cambiar el valor de True
de control_f
a False
, con lo cual conseguimos el control de flujo deseado. Hagamos unas pruebas:
# Invocamos primero el método info_usuario antes del mensaje_inicial
prueba = graficar()
prueba.info_usuario()
Debe invocarse primero el método mensaje inicial
# Correcto control de flujo en la clase Menu
print(prueba.mensaje_inicial())
prueba.info_usuario()
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________
______________________________
Probamos ahora el control de flujo en la clase graficar()
# Invocamos el método graficar antes que el str
prueba.Graficador()
Debe ejecutarse primero el método str!
# Correcto control de flujo
print(prueba)
prueba.Graficador()
Rango:(0,1) f(x) = x**2
Para finalizar esta parte del proyecto grafiquemos las siguientes funciones
# Instanciamos la clase
prueba2 = graficar()
# Invocamos el método str
print(prueba2.mensaje_inicial())
# Información dle usuario (proviene de la clase menu)
prueba2.info_usuario()
# Método str (proviene de la clase graficar)
print(prueba2)
# Graficamos (proviene de la clase graficar)
prueba2.Graficador()
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________
______________________________
Rango:(-np.pi,np.pi) f(x) = np.cos(x)
# Instanciamos la clase
prueba3 = graficar()
# Invocamos el método str
print(prueba3.mensaje_inicial())
# Información dle usuario (proviene de la clase menu)
prueba3.info_usuario()
# Método str (proviene de la clase graficar)
print(prueba3)
# Graficamos (proviene de la clase graficar)
prueba3.Graficador()
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________
______________________________
Rango:(1,5) f(x) = np.log(x)