from abc import ABC, abstractmethod class Car: def __init__(self): self.seats = None self.engine = None self.trip_computer = None self.gps = None def __str__(self): return (f"Car with {self.seats} seats, {self.engine} engine, " f"trip computer: {self.trip_computer}, GPS: {self.gps}") class CarManual: def __init__(self): self.seats = None self.engine = None self.trip_computer = None self.gps = None def __str__(self): return (f"Car manual:\nSeats: {self.seats}\nEngine: {self.engine}\n" f"trip computer: {self.trip_computer}\nGPS: {self.gps}") class Builder(ABC): @abstractmethod def reset(self): pass @abstractmethod def set_seats(self, number): pass @abstractmethod def set_engine(self, engine_type): pass @abstractmethod def set_trip_computer(self, has_trip_computer): pass @abstractmethod def set_gps(self, has_gps): pass @abstractmethod def get_result(self): pass class CarBuilder(Builder): def __init__(self): self.reset() def reset(self): self._car = Car() return self def set_seats(self, number): self._car.seats = number return self def set_engine(self, engine_type): self._car.engine = engine_type return self def set_trip_computer(self, has_trip_computer): self._car.trip_computer = has_trip_computer return self def set_gps(self, has_gps): self._car.gps = has_gps return self def get_result(self): car = self._car self.reset() return car class CarManualBuilder(Builder): def __init__(self): self.reset() def reset(self): self._manual = CarManual() return self def set_seats(self, number): self._manual.seats = f"{number} seats" return self def set_engine(self, engine_type): self._manual.engine = f"engine type: {engine_type}" return self def set_trip_computer(self, has_trip_computer): self._manual.trip_computer = "Equipped with a trip computer" if has_trip_computer else "No trip computer" return self def set_gps(self, has_gps): self._manual.gps = "includes GPS navigation" if has_gps else "No GPS navigation" return self def get_result(self): manual = self._manual self.reset() return manual class Director: def __init__(self, builder: Builder): self._builder = builder def set_builder(self, builder: Builder): self._builder = builder def construct_sport_car(self): self._builder.reset() self._builder.set_seats(2) self._builder.set_engine("V8") self._builder.set_trip_computer(True) self._builder.set_gps(True) def construct_suv(self): self._builder.reset() self._builder.set_seats(7) self._builder.set_engine("V6") self._builder.set_trip_computer(True) self._builder.set_gps(False) director = Director(CarBuilder()) director.construct_sport_car() print(director._builder.get_result()) director.set_builder(CarManualBuilder()) director.construct_sport_car() print(director._builder.get_result()) director.set_builder(CarBuilder()) director.construct_suv() print(director._builder.get_result()) director.set_builder(CarManualBuilder()) director.construct_suv() print(director._builder.get_result())