Nano Hash - криптовалюты, майнинг, программирование

Как вернуться в меню enum в C#

Я написал небольшое консольное приложение, похожее на небольшой магазин, где вы можете выбирать предметы, которые хотели бы купить, из меню enum. Один из вариантов, который может выбрать человек, заключается в том, что после того, как он перешел в «подперечисление», он может вернуться обратно в «главное меню перечисления».

После того, как пользователь перешел к опции «сладости», я хочу иметь возможность выбрать опцию 4, которая вернет их к параметрам меню, где они могут выбрать: получить больше сладостей, получить мясо, получить продукты или выйти из меню и перейти туда, где они могут увидеть их общее количество.

Я использую операторы switch параметров.

            Console.WriteLine("Please select an option between 1 and 4: ");
            Console.WriteLine("1. Sweets");
            Console.WriteLine("2. Meats");
            Console.WriteLine("3. Produce");
            Console.WriteLine("4. Exit");
            Option = Console.ReadLine();

        if (Option == "1")
        {
            Console.Clear();
            Console.WriteLine("Please select an option between 1 and 4: ");
            Console.WriteLine("1. Chocolate R10");
            Console.WriteLine("2. Winegums R12");
            Console.WriteLine("3. Astros R15");
            Console.WriteLine("4. Back");
            int sweets = Convert.ToInt32(Console.ReadLine());
05.01.2020

  • Пожалуйста, поделитесь полным образцом 05.01.2020
  • Я пытался, к сожалению, это слишком долго, поэтому пришлось бы отправлять его несколькими ответами. 05.01.2020
  • Здесь нет ответов, так как это вики, а не ваш обычный формат форума. Вопрос должен фокусироваться на сути проблемы. Если это так долго, как вы говорите, вам нужно разбить проблему на что-то меньшее и представить минимально воспроизводимый пример . То, что вы показали, является неполным. 05.01.2020
  • Так в чем проблема? Поместите весь этот код в while(true){...}. ???? 05.01.2020
  • Проверьте этот похожий вопрос (и ответ): stackoverflow.com/a/59595555/583037 05.01.2020

Ответы:


1

На самом деле я сделал что-то подобное на Turbo Pascal еще в 1994 году :-) Веселые времена... Это рекурсивная штука. Разделите все подопции на отдельные классы в памяти, удерживая идентификатор и текст. Затем создайте общую функцию, которая превращает набор меню в текст в консоли и отображает правильное меню внутри функции, которая вызывает себя (с параметрами для правильного набора меню), если не выбран «выход».

05.01.2020

2

Мне нечего было делать дома, поэтому я сделал эту программу для вас. Он использует структуру данных TreeNode. Структура данных TreeNode позволяет иметь «неограниченное» количество подкатегорий/продуктов. Его также легко обойти, установив узел menu в его родительский или выбранный дочерний элемент. Вам нужно добавить/изменить продукты в метод Populate() и, возможно, изменить свойства MenuItem по вашему выбору (т.е. Price из Product относится к типу int).

using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;

public class Program
{
    private static List<Product> _cart = new List<Product>();
    static void Main()
    {
        var menu = Populate();
        Run(menu);
    }

    private static void ClickToContinue(string message)
    {
        Console.WriteLine($"{message}");
        Console.ReadLine();
    }

    private static void ShowCart()
    {
        Console.WriteLine($"Your cart:");
        for (int i = 0; i < _cart.Count; i++)
        {
            Console.WriteLine(String.Format("{0,-4} | {1,-15} | {2,5}", (i + 1).ToString(), _cart[i].Name, _cart[i].Price));
        }
        Console.WriteLine(String.Format("{0,-4} | {1,-15} | {2,5}", "Tot:", $"{_cart.Count()} items", _cart.Sum(item => item.Price).ToString()));
    }

    private static void PrintMenu(TreeNode<MenuItem> menu, string title)
    {
        title = string.IsNullOrEmpty(title) ? string.Empty : $"> {title.Trim()}";
        var menuTitle = $"{menu.Value.Id}. {menu.Value.Name}".Trim();
        if (menu.Parent == null)
        {
            Console.WriteLine($"{menuTitle} {title}\n");
            return;
        }
        PrintMenu(menu.Parent, $"{menuTitle} {title}");
    }

    private static void Run(TreeNode<MenuItem> menu)
    {
        while (true)
        {
            Console.Clear();
            PrintMenu(menu, string.Empty);
            var selectedItem = SelectMenuItem(menu);
            switch (selectedItem.Value)
            {
                case Category _:
                    menu = selectedItem;
                    break;
                case Product p:
                    Console.WriteLine($"\nYou added {p.Name} to the cart.\n");
                    _cart.Add(p);
                    if (selectedItem.Parent != null)
                        menu = selectedItem.Parent;
                    ClickToContinue("\n\nPress any key to continue");
                    break;
                case Cart _:
                    Console.WriteLine();
                    ShowCart();
                    if (selectedItem.Parent != null)
                        menu = selectedItem.Parent;
                    ClickToContinue("\n\nPress any key to continue");
                    break;
                case GoBack b:
                    Console.WriteLine();
                    if (b.IsExit)
                    {
                        ShowCart();
                        ClickToContinue("\n\nGoodbye!\n\nPress any key to continue");
                        return;
                    }
                    menu = (selectedItem.Parent?.Parent != null) ? selectedItem.Parent.Parent : selectedItem.Parent;
                    break;
                default:
                    throw new Exception($"{selectedItem.Value} not implemented");
                case null:
                    throw new ArgumentNullException(nameof(selectedItem.Value));
            }
        }
    }

    private static TreeNode<MenuItem> SelectMenuItem(TreeNode<MenuItem> menuItem)
    {
        var minValue = menuItem.Children.OrderBy(i => i.Value.Id).FirstOrDefault().Value.Id;
        var maxValue = menuItem.Children.OrderBy(i => i.Value.Id).LastOrDefault().Value.Id;
        Console.WriteLine($"Please select an option between {minValue} and {maxValue}: ");
        foreach (var child in menuItem.Children)
        {
            var price = child.Value is Product ? $"{(child.Value as Product).Price}" : string.Empty;
            Console.WriteLine(String.Format("{0,-4} | {1,-15} | {2,5}", child.Value.Id.ToString(), child.Value.Name, price));
        }

        var selectedId = TryParseInput();

        while (true)
        {
            var selectedItem = menuItem.Children.FirstOrDefault(m => m.Value.Id == selectedId);
            if (selectedItem != null)
            {
                return selectedItem;
            }

            //Selected id does not exist in the menu
            Console.WriteLine($"Please choose from one of the options.");
            selectedId = TryParseInput();
        }
    }

    private static TreeNode<MenuItem> Populate()
    {
        var menu = new TreeNode<MenuItem>(new Category(1, "Menu"));
        var sweets = new TreeNode<MenuItem>(new Category(1, "Sweets"));
        sweets.AddChildren(new List<MenuItem> {
                new Product(1, "Chocolate R10", 15),
                new Product(2, "Winegums R12", 20),
                new Product(3, "Astros R15", 11),
                new GoBack(9, "Back"),
            });
        var meats = new TreeNode<MenuItem>(new Category(2, "Meats"));
        meats.AddChildren(new List<MenuItem> {
                new Product(1, "Chicken", 13),
                new Product(2, "Beef", 14),
                new Product(3, "Seafood", 17),
                new GoBack(9, "Back"),
            });
        var produce = new TreeNode<MenuItem>(new Category(3, "Produce"));
        produce.AddChildren(new List<MenuItem> {
                new Product(1, "Apple", 17),
                new Product(2, "Tomato", 25),
                new Product(3, "Orange", 24),
                new GoBack(9, "Back"),
            });
        var cart = new TreeNode<MenuItem>(new Cart(4, "Cart"));
        var exit = new TreeNode<MenuItem>(new GoBack(5, "Exit", true));
        menu.AddChildren(new List<TreeNode<MenuItem>> {
                sweets,
                meats,
                produce,
                cart,
                exit,
            });

        return menu;
    }

    private static int TryParseInput()
    {
        int returnInt;
        while (!int.TryParse(Console.ReadLine(), out returnInt))
        {
            //Cannot parse input as an integer
            Console.WriteLine($"Selection is not a number. Please try again.");
        }

        return returnInt;
    }
}

public abstract class MenuItem
{
    public MenuItem(int id, string name)
    {
        Id = id;
        Name = name;
    }
    public int Id { get; private set; }
    public string Name { get; private set; }
}

public class GoBack : MenuItem
{
    public GoBack(int id, string name, bool isExit = false) : base(id, name)
    {
        IsExit = isExit;
    }

    public bool IsExit { get; set; }
}

public class Cart : MenuItem
{
    public Cart(int id, string name) : base(id, name) { }
}

public class Category : MenuItem
{
    public Category(int id, string name) : base(id, name) { }
}

public class Product : MenuItem
{
    public Product(int id, string name, int price) : base(id, name)
    {
        Price = price;
    }
    public int Price { get; private set; }
}

public class TreeNode<T>
{
    private readonly T _value;
    private readonly List<TreeNode<T>> _children = new List<TreeNode<T>>();

    public TreeNode(T value)
    {
        _value = value;
    }

    public TreeNode<T> this[int i] => _children[i];

    public TreeNode<T> Parent { get; private set; }

    public T Value { get { return _value; } }

    public ReadOnlyCollection<TreeNode<T>> Children
    {
        get { return _children.AsReadOnly(); }
    }

    public TreeNode<T> AddChild(T value)
    {
        var node = new TreeNode<T>(value) { Parent = this };
        _children.Add(node);
        return node;
    }

    public TreeNode<T> AddChild(TreeNode<T> node)
    {
        node.Parent = this;
        _children.Add(node);
        return node;
    }

    public ReadOnlyCollection<TreeNode<T>> AddChildren(List<T> nodes)
    {
        foreach (var node in nodes)
        {
            AddChild(node);
        }
        return Children;
    }

    public ReadOnlyCollection<TreeNode<T>> AddChildren(List<TreeNode<T>> nodes)
    {
        foreach (var node in nodes)
        {
            AddChild(node);
        }
        return Children;
    }
}

Выход:

1. Menu

Please select an option between 1 and 5:
1    | Sweets          |
2    | Meats           |
3    | Produce         |
4    | Cart            |
5    | Exit            |
4

Your cart:
1    | Apple           |    17
2    | Orange          |    24
3    | Apple           |    17
4    | Astros R15      |    11
Tot: | 4 items         |    69


Press any key to continue
05.01.2020
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..