Esta página contiene las soluciones de programación orientada a objetos para los ejercicios del día 11 del curso.
- Para este ejercicio, solo tenías que crear la clase con la M de motocicleta en mayúscula, recuerda la convención y darle un «pass» para que no diera error.
class Motocicleta(): pass
- Recuerda que los atributos de clase, dan un valor por defecto que no podemos declarar en la instanciación, más adelante si, mediante reasignación de valores a los atributos.
class Motocicleta(): estado = "nueva"
- __init__ es un método, los métodos, te he dicho que eran funciones pertenecientes a una clase. Por lo tanto, se puede usar «pass» en cualquier método de clase.
class Motocicleta(): # Atributos de clase estado = "nueva" # Métodos def __init__(): pass
- He añadido todos los parámetros. Recuerda que siempre se pone self, por eso no te lo he puesto en la lista de parámetros. 😉 Pequeña trampa para ver si has prestado atención.
class Motocicleta(): # Atributos de clase estado = "nueva" # Métodos def __init__(self, color, matricula, combustible_litros, numero_ruedas, marca, modelo, fecha_fabricacion, velocidad_punta, peso): self.color = color self.matricula = matricula self.combustible_litros = combustible_litros self.numero_ruedas = numero_ruedas self.marca = marca self.modelo = modelo self.fecha_fabricacion = fecha_fabricacion self.velocidad_punta = velocidad_punta self.peso = peso
- De momento, va quedando así, he añadido la línea 4 para este ejercicio.
class Motocicleta(): # Atributos de clase estado = "nueva" motor = False # Métodos def __init__(self, color, matricula, combustible_litros, numero_ruedas, marca, modelo, fecha_fabricacion, velocidad_punta, peso): self.color = color self.matricula = matricula self.combustible_litros = combustible_litros self.numero_ruedas = numero_ruedas self.marca = marca self.modelo = modelo self.fecha_fabricacion = fecha_fabricacion self.velocidad_punta = velocidad_punta self.peso = peso
- A partir de la línea 18, tienes los dos métodos nuevos. El if, solo evalúa el estado de la variable motor y saca una conclusión u otra.
class Motocicleta(): # Atributos de clase estado = "nueva" motor = False # Métodos def __init__(self, color, matricula, combustible_litros, numero_ruedas, marca, modelo, fecha_fabricacion, velocidad_punta, peso): self.color = color self.matricula = matricula self.combustible_litros = combustible_litros self.numero_ruedas = numero_ruedas self.marca = marca self.modelo = modelo self.fecha_fabricacion = fecha_fabricacion self.velocidad_punta = velocidad_punta self.peso = peso def arrancar(self): if self.motor: print("Se escucha un molesto sonido al girar la llave. El motor ya estaba arrancado.") else: print("Se ha arrancado el motor. Ruge como un león.") def detener(self): if self.motor: print("Se detiene el motor.") else: print("No puedes parar el motor, porque ya está apagado. ¿No lo oyes?")
motocicleta_yamaha_1 = Motocicleta("Roja y blanca", "45663-FHDY", 10, 2, "Yamaha", "YZF-R1", "20/02/2020", 288, 199)
- En este caso, la instanciación ocupa más líneas, pero evita que cometamos errores posicionales. Recuerda que el orden quería que fuera diferente a la especificación posicional de parámetros.
motocicleta_harley_1 = Motocicleta( matricula="48659-FHEZ", combustible_litros=0, color="Negra", marca="Harley Davidson", modelo="Fat Boy", numero_ruedas=2, peso=304, fecha_fabricacion="29/09/2020", velocidad_punta=160 )
- Aquí se trata de saber como se llama a un método de un objeto.
Por aquí tienes una muestra, prueba todo lo que creas conveniente:
motocicleta_harley_1.detener()
En este caso, me dice: «No puedes parar el motor, porque ya está apagado. ¿No lo oyes?», dado que el motor por defecto está apagado.
- Aquí tienes un ejemplo.
motocicleta_harley_1.precio = 27000
- Sería algo así:
print(f"El precio de la motocicleta {motocicleta_harley_1.marca} {motocicleta_harley_1.modelo} es de {motocicleta_harley_1.precio} $.")
def consulta_precio(self): print(f"El precio de la motocicleta {self.marca} {self.modelo} es de {self.precio} $.")
- Si llamamos al método con la motocicleta que tiene el atributo precio, nos lo muestra correctamente:
motocicleta_harley_1.consulta_precio()
Resultado en la consola
El precio de la motocicleta Harley Davidson Fat Boy es de 27000 $.
Sin embargo, puesto que el atributo ha sido declarado fuera de la clase, para un solo objeto, los otros no lo tendrán, y al intentar consultarlo, nos dirá que hay un error por atributo inexistente. Este error se puede omitir con el manejo de excepciones que verás en otro capítulo del curso. Gracias a esto, podríamos indicar en la consola, con un print() que la motocicleta no tiene precio e incluso decirle al usuario si quiere añadírselo. De momento, no lo vamos a tocar, ya es mucho temario por hoy.
Error en la consola
AttributeError: ‘Motocicleta’ object has no attribute ‘precio’
- Este es el método para comprobar el depósito.
Lo más destacable aquí, es la operación en la línea 5. Una resta entre la capacidad del depósito y el combustible que ya tiene. De esa forma, el resultado indica los litros que quedan para llenar el depósito.
def comprobar_deposito(self): print(f"--->REPORTE DE DEPÓSITO DE {self.marca} {self.modelo}<---") print(f"El depósito tiene {self.combustible_litros} litros.") print(f"La capacidad máxima del tanque de combustible es de {self.combustible_maximo}.") print(f"Faltan {self.combustible_maximo - self.combustible_litros} litros para llenar el depósito.") print(f"--->FIN DEL REPORTE<---\n")
Consultando esta información, ya sabemos cuanto combustible tiene una motocicleta en concreto y cuanto le podemos poner. Con dos, está muy fácil de ver, pero imagina esto como un programa con Tkinter que lleva el inventario de todas las motocicletas, con todos estos datos de cada una de ellas.
El método para repostar es un poco más elaborado, ya que cuenta con un bucle infinito por si el usuario introduce una cantidad errónea de combustible.
El if es para indicar que si el total de combustible en el depósito y lo que queremos repostar, es menor o igual a la capacidad máxima de este. Es una operación sencilla, pero hay que llegar a esta conclusión para expresarla.
Por cierto, no había indicado que se pueden hacer operaciones aritméticas directamente en las expresiones del if, pero como su nombre indica, es una expresión y una suma es una expresión.
Si la cantidad de combustible que introducimos por consola, no se pasa del límite, se informa de ciertas cosas y se incrementa el valor de combustible_litros con el de repostar_litros. Así, el objeto actualiza su valor del combustible que lleva.
Finalmente, se rompe el bucle.
Si se añade un valor a repostar mayor que lo que cabe en el depósito, se le da un error al usuario y se le permite poner otro.
def repostar(self): while True: self.repostar_litros = float(input("Por favor, introduzca la cantidad de litros que desea repostar:\n")) if self.combustible_litros + self.repostar_litros <= self.combustible_maximo: print("Repostaje exitoso.") print(f"Se han repostado {self.repostar_litros} litros.") self.combustible_litros += self.repostar_litros print(f"El depósito tiene {self.combustible_litros} litros de combustible.") break else: print("No cabe tanto combustible. ¿Quieres encharcar el concesionario?")
Ves realizando las pruebas que consideres necesarias con estos métodos.
Te dejo el código final completo para que vayas probando con él si lo crees necesario:
class Motocicleta(): # Atributos de clase estado = "nueva" motor = False # Métodos def __init__(self, color, matricula, combustible_litros, numero_ruedas, marca, modelo, fecha_fabricacion, velocidad_punta, peso, combustible_maximo): self.color = color self.matricula = matricula self.combustible_litros = combustible_litros self.numero_ruedas = numero_ruedas self.marca = marca self.modelo = modelo self.fecha_fabricacion = fecha_fabricacion self.velocidad_punta = velocidad_punta self.peso = peso self.combustible_maximo = combustible_maximo def arrancar(self): if self.motor: print("Se escucha un molesto sonido al girar la llave. El motor ya estaba arrancado.") else: print("Se ha arrancado el motor. Ruge como un león.") def detener(self): if self.motor: print("Se detiene el motor.") else: print("No puedes parar el motor, porque ya está apagado. ¿No lo oyes?") def consulta_precio(self): print(f"El precio de la motocicleta {self.marca} {self.modelo} es de {self.precio} $.") def comprobar_deposito(self): print(f"--->REPORTE DE DEPÓSITO DE {self.marca} {self.modelo}<---") print(f"El depósito tiene {self.combustible_litros} litros.") print(f"La capacidad máxima del tanque de combustible es de {self.combustible_maximo}.") print(f"Faltan {self.combustible_maximo - self.combustible_litros} litros para llenar el depósito.") print(f"--->FIN DEL REPORTE<---\n") def repostar(self): while True: self.repostar_litros = float(input("Por favor, introduzca la cantidad de litros que desea repostar:\n")) if self.combustible_litros + self.repostar_litros <= self.combustible_maximo: print("Repostaje exitoso.") print(f"Se han repostado {self.repostar_litros} litros.") self.combustible_litros += self.repostar_litros print(f"El depósito tiene {self.combustible_litros} litros de combustible.") break else: print("No cabe tanto combustible. ¿Quieres encharcar el concesionario?") # Instancias de la clase Motocicleta motocicleta_yamaha_1 = Motocicleta("Roja y blanca", "45663-FHDY", 10, 2, "Yamaha", "YZF-R1", "20/02/2020", 288, 199, 17) motocicleta_harley_1 = Motocicleta( matricula="48659-FHEZ", combustible_litros=0, color="Negra", marca="Harley Davidson", modelo="Fat Boy", numero_ruedas=2, peso=304, fecha_fabricacion="29/09/2020", velocidad_punta=160, combustible_maximo=20 ) motocicleta_harley_1.precio = 27000
Recuerda que los valores de combustible solo se mantienen en tiempo de ejecución, cuando finalices el programa todo vuelve a estar como antes. Necesitarás una base de datos si quieres que tus programas guarden valores y el programa no empiece cada vez de cero.
No te preocupes por esto, porque ya llegará el tema en el curso.
from abc import ABC,abstractmethod
class Mecanica(ABC): #clase abstracta
#si no pongo el ABC abstractmethod no funciona
@abstractmethod #obligo a crear este metodo en sus sub clases
def arrancar(self):
pass
class Motocicleta(Mecanica):
«»» Aca se ven los atributos de clase definidos como «estado» y «motor» \n
Y los atributos de instancia:
self.color = color |str| \n
self.matricula = matricula |str|\n
self.__combustible = combustible #private |int|\n
self.ruedas = ruedas |int|\n
self.marca = marca |str|\n
self.modelo = modelo |str|\n
self.fecha_fab = fecha_fab |str|\n
self.velocidad_max = velocidad_max |int|\n
self.peso = peso |str|\n
\n
Estos son los atributos a definir por el usuario que crea la instancia
«»»
#atributos de clase
estado = «Nueva»
motor = False
ubicacion = 0
#atributos de instancia
def __init__(self, color, matricula, combustible, ruedas, marca, modelo, fecha_fab, velocidad_max, peso) -> None:
self.color = color
self.matricula = matricula
self.__combustible = combustible #private
self.ruedas = ruedas
self.marca = marca
self.modelo = modelo
self.fecha_fab = fecha_fab
self.velocidad_max = velocidad_max
self.peso = peso
def arrancar(self):
if self.motor == False:
self.motor = True
print(«Se ha prendido el motor»)
elif self.motor == True:
print(«El motor ya esta en marcha»)
def detenerse(self):
if self.motor == True:
self.motor = False
print(«Se ha apagado el motor»)
elif self.motor == False:
print(«El motor ya está detenido»)
@property
def saber_combustible(self):
return self.__combustible
@saber_combustible.setter
def saber_combustible(self, combustible):
self.__combustible += combustible
print(f»Se ha cargado {combustible}L. de combustible»)
def cargar_combustible(self,cantidad_comb):
print(«—-«)
print(«Analizando datos del vehiculo:»)
print(f»El tanque tiene una capacidad de {self.tanque}L»)
print(f»{self.saber_combustible} y se le quiere agregar {cantidad_comb}»)
if (self.__combustible + cantidad_comb) = km*0.20: #gasta el 20% de nafta por cada km
self.ubicacion += km
self.__combustible -= km*0.20
recorrido_faltante = self.__combustible / 0.2
print(f»Se han recorrido los {km}km. Es posible recorrer todavia {recorrido_faltante}km.»)
print(f»El combustible restante es de: {zanella.saber_combustible}L.»)
else:
print(«El tanque esta a su máxima capacidad y no puede hacer el recorrido o hay falta de combustible»)
#instancia 1
yamahaa = Motocicleta(«Marron», «XD365», 10, 2, «Yamahaa», «c44″, 2010, 160,»540 kg»)
yamahaa.precio = 50000
yamahaa.tanque = 30
#instancia 2
zanella = Motocicleta(color=»Verde», combustible=10, matricula=»123ASD»,marca=»zanella», ruedas=2, fecha_fab=2005, modelo=»c44″, peso=»390 kg», velocidad_max=120)
zanella.precio = 25000
zanella.tanque = 25
## usos
yamahaa.arrancar()
print(yamahaa.saber_combustible) #el unico que es privado
print(f»El precio de la la yamahaa es: {yamahaa.consultar_precio()}$») #le agrego un precio
yamahaa.cargar_combustible(4)
print(«\n»)
zanella.arrancar()
print(zanella.saber_combustible)
print(f»El precio de la la Zanella es: {zanella.consultar_precio()}$»)
zanella.cargar_combustible(44)
zanella.recorrer(5)
zanella.recorrer(10)
print(f»La ubicacion del vehiculo es de {zanella.get_ubicacion()}km. desde su punto de partida»)
Lo hice asi gente, si a alguno les copo avise, sino pruebo de otra forma!
Bueno, el código con el que pude conseguir realizar el proyecto es el siguiente.
class Motocicleta():
estado = «nueva»
motor = False
def __init__(self,color,matricula,combustible_litros,numero_ruedas,marca,modelo,fecha_fabricacion,velocidad_punta,peso,capacidad_maxima):
self.color = color
self.matricula = matricula
self.combustible_litros = combustible_litros
self.numero_ruedas = numero_ruedas
self.marca = marca
self.modelo = modelo
self.fecha_fabricacion = fecha_fabricacion
self.velocidad_punta = velocidad_punta
self.peso = peso
self.capacidad_maxima = capacidad_maxima
def arrancar(self):
if self.motor == True:
print(«El motor ya estaba encendido»)
else:
print(«El motor ha arrancado.»)
def detener(self):
if self.motor == True:
print(«El motor se ha detenido.»)
else:
print(«El motor ya estaba detenido.»)
def consulta_precio(self):
print(f»El precio de la motocicleta {self.marca} {self.modelo} es de {self.precio}»)
def comprobar_combustible(self):
print(f»—> Reporte del deposito de {self.marca} {self.modelo}. (self.capacidad_maxima – self.combustible_litros):
print(«No se puede repostar esa cantidad. \nIntentelo nuevamente.»)
else:
self.combustible_litros = repostar_litros + self.combustible_litros
print(f»Repostaje exitoso. \nTiene {self.combustible_litros} litros de combustible en el deposito.»)
break
motocicleta_ducati = Motocicleta(«rojo»,»DRK578″,10,2,»Ducati»,»Monster»,»11/12/1999″,»250km/h»,»180Kg»,17)
motocicleta_bmw = Motocicleta(
color=»blanco»,
matricula=»OJC202″,
peso=»175Kg»,
numero_ruedas=2,
modelo=»S1000RR»,
fecha_fabricacion=»10/23/2002″,
combustible_litros=0,
velocidad_punta=»300km/h»,
marca=»Bmw»,
capacidad_maxima=20
)
motocicleta_ducati.precio = «$ 78.000.000»
motocicleta_ducati.comprobar_combustible()
motocicleta_ducati.repostar()
motocicleta_bmw.comprobar_combustible()
motocicleta_bmw.repostar()
Una pregunta, si el motor por defecto esta en False como sabrá que al usar los métodos esta apagado o encendido? y también agregaría algo mas, se que se esta vendiendo la moto pero es algo que yo pensé aparte del ejercicio. es hacer un sistema para que la gasolina vaya bajando cada que se recorra una distancia y además para hacerlo mas realista, usar time.sleep con un tiempo especifico. esto es solamente mi opinion no se que piensan.
Se puede agregar un metodo que se en el que se muestren todos los atributos de la moto.
Una consulta, teniendo en cuenta que la variable repostar_litros, solo sirve para hacer operaciones internas del método repostar, y no se va a asociar al objeto instanciado. ¿Puede utilizarse repostar_litros en lugar de self.repostar_litros? Imagino que sí, yo lo hice así y funciona, pero es realmente por eso por que no se usa más que para una operación interna o puede provocar un error en otro momento?.
Gracias
Tengo la misma duda.