Soluciones de ejercicios de programación orientada a objetos – 100 días de Python #11

Soluciones de ejercicios de programación orientada a objetos – 100 días de Python #11

Esta página contiene las soluciones de programación orientada a objetos para los ejercicios del día 11 del curso.

  1. 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
  1. 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"
  1. __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
  1. 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
  1. 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
  1. 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)
  1. 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
    )
  1. 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.

  1. Aquí tienes un ejemplo.
motocicleta_harley_1.precio = 27000
  1. 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} $.")
  1. 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'
  1. 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.

8 comentarios en «0»

  1. 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»)

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

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

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

curso de Python Entrada anterior Ejercicios de Programación Orientada a Objetos en Python – 100 días de Python #11
curso de Python Entrada siguiente Introducción a los eventos de ratón (mouse) y teclado con Tkinter – 100 días de Python #12