Я делаю пользовательский интерфейс для интернет-кафе. Мне нужно вызвать уже созданные методы. Пользователь также может настроить свой заказ напитка, например, выбрать другой вид молока, коричневого или белого сахара и т. Д. После того, как выбор пользователя сделан, он добавит напиток в свою корзину. Пользователь также имеет возможность редактировать свою корзину с напитками и удалять напиток, если они того пожелают.
Он получит информацию из файла. Этот код работает, но очень запутан. Есть ли способы очистить его и сделать более аккуратным / менее повторяющимся?
from display.output import ConsoleOutput
from user import User
from user.drinks import Drink
from user.drinks.customisations import CustomisationManager, Customisation
from user.drinks.drinks_manager import DrinksManager
from user.drinks.types import SoftDrink, Coffee
class Strings:
add_customisation_to_drink_yn = "Would you like to add a customisation to your drink? y/n"
remove_customisation_from_drink = "Would you like to remove a customisation from your drink? y/n"
change_customisation = "Would you like to change the customisations of your drink? y/n"
change_size = "Would you like to change the size of your drink? y/n"
current_drinks = "We currently have these drinks available:"
add_customisations = "Would you like to add any customisations? y/n"
current_customisations = "nWe currently have these customisations available:"
commands = "na: add new drink, u: update drink, b: show basket, q: quit, r: remove drink from basket"
@staticmethod
def items_in_basket_cost(basket):
return f"You currently have these items in your basket costing {basket.calculate_cost()}"
@staticmethod
def add_drink_to_basket(drinks_manager):
return f"Which drink would you like to add to your basket? 0-{len(drinks_manager.all_drinks()) - 1}"
@staticmethod
def add_size_to_drink(drink, sizes):
return f"Which size of {drink.name} would you like to add to your drink? 0-{len(sizes) - 1}"
@staticmethod
def add_customisation_to_drink(customisations_manager, drink):
return f"Which customisation would you like to add to your {drink.name}?"
+ f"0-{len(customisations_manager.all_customisations()) - 1}"
@staticmethod
def remove_drink_from_basket(user):
return f"Which drink would you like to remove from your basket? 0-{len(user.basket.items) - 1}"
@staticmethod
def update_drink_in_basket(user):
return f"Which drink would you like to update in your basket? 0-{len(user.basket.items) - 1}"
@staticmethod
def customisation_to_remove(drink):
return f"Which customisation would you like to remove from your drink? 0-{len(drink.customisations) - 1}"
class Main:
def __init__(self):
self.display = Display(input_handler=ConsoleInput(), output_handler=ConsoleOutput())
self.drink_manager = DrinksManager()
self.customisation_manager = CustomisationManager()
self.drink_manager.register_drink(Coffee(1.0, 1, 'Coffee'))
self.drink_manager.register_drink(SoftDrink(1.0, 2, 'Juice'))
self.drink_manager.register_drink(Coffee(1.0, 3, 'Milk'))
self.drink_manager.register_drink(Coffee(1.0, 4, 'Mocha'))
self.drink_manager.register_drink(Coffee(1.0, 5, 'Cappuccino'))
self.drink_manager.register_drink(Coffee(1.0, 6, 'Water'))
self.customisation_manager.register_customisation(Customisation(1, 'White Sugar', 0.3))
self.customisation_manager.register_customisation(Customisation(2, 'Brown Sugar', 0.6))
self.customisation_manager.register_customisation(Customisation(3, 'Milk', 0.3))
self.customisation_manager.register_customisation(Customisation(4, 'Almond Milk', 0.2))
self.customisation_manager.register_customisation(Customisation(5, 'Cream', 0.8))
self.user = User()
self.main_menu()
def main_menu(self):
while True:
print(Strings.commands)
command = self.display.input.get('Enter a command:')
print('n')
if command == 'a':
self.list_drinks()
self.add_drink_to_basket()
elif command == 'u':
self.display_basket()
self.update_drink_in_basket()
elif command == 'q':
break
elif command == 'b':
self.display_basket()
elif command == 'r':
self.remove_drink_from_basket()
def list_drinks(self):
self.display.output.print(Strings.current_drinks)
all_drinks = self.drink_manager.all_drinks()
for index, drink in enumerate(all_drinks):
self.display.output.print(f"{index}. {drink.name} -- £{drink.cost}")
def add_drink_to_basket(self):
drink_index = int(self.display.input.get(Strings.add_drink_to_basket(self.drink_manager)))
drink = self.add_customisation_to_drink(self.drink_manager.all_drinks()[drink_index])
drink = self.add_size_to_drink(drink)
self.user.basket.add_drink(drink)
def add_size_to_drink(self, drink: Drink) -> Drink:
self.list_sizes(drink)
sizes = drink.available_sizes
size_index = int(self.display.input.get(Strings.add_size_to_drink(drink, sizes)))
drink.size = sizes[size_index]
return drink
def list_sizes(self, drink: Drink):
for index, size in enumerate(drink.available_sizes):
print(f"{index}. {size.value.name} -- {size.value.volume}L, £{size.value.cost_multiplier * drink.cost}")
def list_customisations(self):
self.display.output.print(Strings.current_customisations)
all_customisations = self.customisation_manager.all_customisations()
for index, customisation in enumerate(all_customisations):
self.display.output.print(f"{index}. {customisation.name} -- £{customisation.cost}")
def add_customisation_to_drink(self, drink: Drink) -> Drink:
while True:
add_customisation = self.display.input.get(Strings.add_customisations)
if add_customisation == 'n':
return drink
self.list_customisations()
customisation_index = int(self.display.input.get(
Strings.add_customisation_to_drink(self.customisation_manager, drink)
))
drink.add_customisation(self.customisation_manager.all_customisations()[customisation_index])
def display_basket(self):
basket = self.user.basket
self.display.output.print(Strings.items_in_basket_cost(basket))
for drink_index, item in enumerate(basket.items):
self.display.output.print(f"{drink_index}. {item.name} ({item.size.value.name}): £{item.calculate_cost()}")
for customisation_index, customisation in enumerate(item.customisations):
self.display.output.print(f"{' ' * 4} {customisation.name}: {customisation.cost}")
def remove_drink_from_basket(self):
self.display_basket()
drink_index = int(self.display.input.get(
Strings.remove_drink_from_basket(self.user)
))
self.user.basket.remove_drink(self.user.basket.items[drink_index].id)
def update_drink_in_basket(self):
drink_index = int(self.display.input.get(
Strings.update_drink_in_basket(self.user)
))
drink = self.user.basket.items[drink_index]
change_size = self.display.input.get(Strings.change_size)
if change_size == 'y':
drink = self.add_size_to_drink(drink)
change_customisation = self.display.input.get(Strings.change_customisation)
if change_customisation == 'y':
remove_customisation = self.display.input.get(Strings.remove_customisation_from_drink)
if remove_customisation == 'y':
for index, customisation in enumerate(drink.customisations):
self.display.output.print(f"{index}. {customisation.name}: {customisation.cost}")
customisation_index = int(self.display.input.get(
Strings.customisation_to_remove(drink)
))
drink.remove_customisation(drink.customisations[customisation_index])
add_customisation = self.display.input.get(Strings.add_customisation_to_drink_yn)
if add_customisation == 'y':
drink = self.add_customisation_to_drink(drink)
self.user.basket.items[drink_index] = drink
if __name__ == "__main__":
Main()
1 ответ
Струны
Учитывая ваш текущий код, нет смысла иметь Strings
. Такая централизация строк обычно наблюдается, если вы проводите интернационализацию, но свидетельств этого нет.
Среди других проблем Strings
вообще не используется в качестве класса — все в нем статично, поэтому, если вы сохраните централизованные строки (чего не следует делать), работы можно было бы превратить в модуль.
Взорвать свой Strings
class и поместите отдельные строки там, где они используются.
В этом классе есть еще один запах кода — все y/n
строки предполагают, что вам следует выделить метод ввода да / нет, который печатает этот суффикс, а не вставлять его в каждое отдельное приглашение. Также, commands
следует генерировать из последовательности команд, а не жестко запрограммировать.
Все на строительстве
Main()
делает всю работу main_menu()
прямо в конструкторе. Этого следует избегать; переместить main_menu()
позвоните в вашу точку входа.
Форматирование встроенной валюты
£{size.value.cost_multiplier * drink.cost}
следует заменить на звонок locale.currency()
. Убедитесь, что ваш языковой стандарт установлен правильно, и символ фунта будет добавлен за вас.