En este proyecto comenzaremos creando una clase denominada graficar
, con la cual conseguiremos graficar funciones. Para lograrlo nos valdremos del código ya creado en el anterior proyecto, más especificamente en Proyecto 1 (parte I): Graficador de funciones
. Nuestra labor será adaptar dicho código a una clase. Para ello
# Importamos las librerías que más adelante ocuparemos
import matplotlib.pyplot as mplot
import numpy as np
# Menú:
print("De que tipo es tu función: ")
print("_" * 30)
print("1: Algebraicas")
print("2: Trigonométricas")
print("3: Exponencial")
print("4: Logarítmica")
print("_" * 30)
# Número del tipo de función que ingresa el usuario
n_aux = input("Coloca un número del 1 al 4: ")
print("_" * 30)
# Controlamos posibles errores
if int(n_aux) not in (1,2,3,4):
print("Error, debes ingresar un número del 1 al 4")
print("Fin del proceso")
else:
# Función ingresada por el usuario
fun = input("Ingresa tu función: ")
# -------------------------------------------------
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________ Coloca un número del 1 al 4: 1 ______________________________ Ingresa tu función: x**2
Agregamos un condicional para manejar las funciones trigonométricas, exponenciales y logarítmicas mediante la librería numpy
if int(n_aux) != 1:
fun = "np." + fun
else:
fun = fun
graficar
colocando en el constructor los atributos necesarios para que el usuario ingrese un intervalo de graficación (que denominaremos rango) y la función en sí a graficar. Asimismo, crearemos la clase str
para mostrar el rango de graficación de dicha función y la expresión de dicha función.# Creación de la clase graficar
class graficar:
# Constructor
def __init__(self, rango, funcion):
# Atributos de la clase
self.rango_inf = rango[0]
self.rango_sup = rango[1]
self.funcion = funcion
# Método str
def __str__(self):
return f'Rango:({self.rango_inf},{self.rango_sup})\nf(x) = {self.funcion}'
cabe resaltar que supondremos que el parámetro de rango
será o una tupla o una lista. Probemos lo que llevamos:
# Instanciamos la clase
prueba = graficar((-1,1), fun)
# Utilizamos el método str
print(prueba)
Rango:(-1,1) f(x) = x**2
graficar
agregaremos el método Graficador()
para que se grafique la función que el usuario ha ingresado:# Creación de la clase graficar
class graficar:
# Constructor
def __init__(self, rango, funcion):
# Atributos de la clase
self.rango_inf = rango[0]
self.rango_sup = rango[1]
self.funcion = funcion
# Método str
def __str__(self):
return f'Rango:({self.rango_inf},{self.rango_sup})\nf(x) = {self.funcion}'
# Método para graficar
def Graficador(self):
# Rango
x = np.arange(self.rango_inf, self.rango_sup, 0.01)
# definimos la función f(x)=y
y = self.funcion
# creamos la gráfica
mplot.plot(x, eval(y))
# mostramos la cuadrícula en el gráfico
mplot.grid()
# mostramos la gráfica
mplot.show()
Ponemos a prueba la clase creada:
# Instanciamos la clase
prueba = graficar((-1,1), fun)
# Utilizamos el método str
print(prueba)
# Invocamos el método Graficador()
prueba.Graficador()
Rango:(-1,1) f(x) = x**2
De modo que, por el momento, la clase graficar
ha quedado terminada.
# Creamos la clase menú
class menu:
# Creamos el método str para mostrar el mensaje inicial
def __str__(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
return self.cadena1 + "\n" + self.cadena2 + "\n" + self.cadena3 \
+ "\n" + self.cadena4 + "\n" + self.cadena5 + "\n" + self.cadena6 \
+ "\n" + self.cadena7
# Realizamos una prueba
prueba = menu()
print(prueba)
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________
adaptamos el resto del código a un método de la clase menu
:
# Creamos la clase menú
class menu:
# Constructor
def __init__(self):
self.fun = ""
# Creamos el método str para mostrar el mensaje inicial
def __str__(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
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):
# Número del tipo de función que ingresa el usuario
self.n_aux = input("Coloca un número del 1 al 4: ")
print("_" * 30)
# Controlamos posibles errores
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:
# Función ingresada por el usuario
self.fun = input("Ingresa tu función: ")
# Adaptamos
if int(self.n_aux) != 1:
self.fun = "np." + self.fun
else:
self.fun = self.fun
Nos vimos en la necesidad de crear un constructor para almacenar un valor para el atributo self.fun
al cual le asignaremos la expresión de la función que ingrese el usuario más adelante con el método info_usuario
.
# Probamos
prueba = menu()
print(prueba)
# Invocamos el método info_usuario()
prueba.info_usuario()
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________ Coloca un número del 1 al 4: 1 ______________________________ Ingresa tu función: x**2
Veamos que expresión tiene asignado el objeto prueba
en el atributo fun
prueba.fun
'x**2'
De modo que la clase menú
ah quedado realizada ( por el momento :) ).
menu
le agregamos como atributo el rango de graficación, entonces esta clase junto con la clase graficar
tendrán los mismos atributos en el constructor. Además, de la clase menu
podemos extraer la expresión de la función que ocupamos en la clase graficar
. Así, podemos intuir que la clase graficar
en realidad puede ser parte de la clase menu
, o en otras palabras, la clase menu
es superclase de la clase graficar
. De tal manera, tendríamos que agregar solamente el atributo rango
al constructor de la clase menu
, pero eso lo podemos ingresar como se ingresa la expresión de la función en el método info_usuario()
# Creamos la clase menú
class menu:
# Constructor
def __init__(self):
# Atributos de la clase
self.fun = ""
self_rango = ""
# Creamos el método mensaje_inicial para mostrar el mensaje inicial
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
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):
# Número del tipo de función que ingresa el usuario
self.n_aux = input("Coloca un número del 1 al 4: ")
print("_" * 30)
# Controlamos posibles errores
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:
# Función y rango ingresados por el usuario
self.fun = input("Ingresa tu función: ")
# Rango
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(")")]
# Adaptamos
if int(self.n_aux) != 1:
self.fun = "np." + self.fun
else:
self.fun = self.fun
Para después definir la clase hija graficar
adaptando los cambios pertinentes. Notemos que self.rango
será una cadena de texto, de modo que el código para definir las variables self.rango_inf
y self.rango_sup
extraen los valores numéricos de dicha cadena de texto; por ejemplo, si se ingresó la cadena "(0,-4)"
, entonces extraeremos sólo las cadenas "0"
y "-4"
para estas variables respectivamente. Continuando
# Creación de la clase hija graficar
class graficar(menu):
# Sobreescritura del método init
def __init__(self):
super().__init__()
# Método str
def __str__(self):
return f'Rango:({self.rango_inf},{self.rango_sup})\nf(x) = {self.fun}'
# Método para graficar
def Graficador(self):
# Rango
x = np.arange(eval(self.rango_inf), eval(self.rango_sup), 0.01)
# definimos la función f(x)=y
y = self.fun
# creamos la gráfica
mplot.plot(x, eval(y))
# mostramos la cuadrícula en el gráfico
mplot.grid()
# mostramos la gráfica
mplot.show()
donde con la fucnión eval()
podemos extraer un número de una cadena de texto; por ejemplo, la cadena "0"
se transforma en el número 0
al emplear eval("0")
.
Finalmente probamos cada método de la clase graficar
:
# instanciamos la clase
prueba = graficar()
# Mensaje inicial (proviene de la clase menu)
print(prueba.mensaje_inicial())
De que tipo es tu función: ______________________________ 1: Algebraicas 2: Trigonométricas 3: Exponencial 4: Logarítmica ______________________________
# información dle usuario (proviene de la clase menu)
prueba.info_usuario()
Coloca un número del 1 al 4: 1 ______________________________ Ingresa tu función: x**2 Ingresa el rango de graficación: (-1,1)
# método str (proviene de la clase graficar)
print(prueba)
Rango:(-1,1) f(x) = x**2
# graficamos (proviene de la clase graficar)
prueba.Graficador()