Member 13733578 Ответов: 2

Сделайте мой код более чистым работая с методами на языке Си#


Привет, во-первых, это мой первый вопрос, когда-либо заданный здесь, так что полегче со мной.Я пытаюсь выучить C# и думаю, что моя страсть к тяжелой атлетике могла бы создать какую-нибудь автоматизированную программу. В этом случае рассчитайте свою тренировку 5/3/1 автоматически. Моя проблема в том, что я хотел бы научиться использовать методы, и я думаю, что могу очень хорошо реализовать их здесь, проблема в том, что я не знаю, как атаковать эту проблему.Вот мой код на данный момент:

namespace _531Calculator
{
    class Program
    {
        static void Main(string[] args)
        {
            //Default
            Console.WindowHeight = 28;
            Console.WindowWidth = 60;
            Console.ForegroundColor = ConsoleColor.White;


            Console.Title ="5/3/1 Calculator";

            Console.WriteLine("----Your max's---- \n");

            //Bench Max
            Console.Write("Your Bench max: ");
            double benchMax = Convert.ToDouble(Console.ReadLine());

            //Bench Week 1
            double deadliftWeekOne_65 = benchMax * 0.65;
            double deadliftWeekOne_75 = benchMax * 0.75;
            double deadliftWeekOne_85 = benchMax * 0.85;

            //Deadlift Max
            Console.Write("Your Deadlift max: ");
            double deadliftMax = Convert.ToDouble(Console.ReadLine());

            //Deadlift Week 1
            double benchWeekOne_65 = deadliftMax * 0.65;
            double benchWeekOne_75 = deadliftMax * 0.75;
            double benchWeekOne_85 = deadliftMax * 0.85;

            //Squats Max
            Console.Write("Your Squat max: ");
            double squatMax = Convert.ToDouble(Console.ReadLine());

            //Squat Week 1
            double squatWeekOne_65 = squatMax * 0.65;
            double squatWeekOne_75 = squatMax * 0.75;
            double squatWeekOne_85 = squatMax * 0.85;

            //OHP Max
            Console.Write("Your OHP max: ");
            double ohpMax = Convert.ToDouble(Console.ReadLine());

            //OHP Week 1
            double ohpWeekOne_65 = ohpMax * 0.65;
            double ohpWeekOne_75 = ohpMax * 0.75;
            double ohpWeekOne_85 = ohpMax * 0.85;

            Console.WriteLine("\n ----Week 1---- \n");

            Console.WriteLine("----DAY 1----");
            Console.WriteLine("A : Bench: 3 x 5 @ " + benchWeekOne_65 + ", " + benchWeekOne_75 + ", " + benchWeekOne_85);
            Console.WriteLine("B : Dumbbell Chest Press @ 5 x 15");
            Console.WriteLine("C : Barbell Row @ 5 x 10 \n");

            Console.WriteLine("----DAY 2----");
            Console.WriteLine("A : Deadlift: 3 x 5 @ " + deadliftWeekOne_65 + ", " + deadliftWeekOne_75 + ", " + deadliftWeekOne_85);
            Console.WriteLine("B : Hamstring Curls @ 5 x 12");
            Console.WriteLine("C : Assited Work 2: Leg Raises(Abs) @ 5 x 15 \n");

            Console.WriteLine("----DAY 3----");
            Console.WriteLine("A : OHP: 3 x 5 @ " + ohpWeekOne_65 + ", " + ohpWeekOne_75 + ", " + ohpWeekOne_85);
            Console.WriteLine("B : Dip @ 5 x 15");
            Console.WriteLine("C : Chin-Up 5 x 12 \n");

            Console.WriteLine("----DAY 4----");
            Console.WriteLine("A : Squat: 3 x 5 @ " + squatWeekOne_65 + ", " + squatWeekOne_75 + ", " + squatWeekOne_85);
            Console.WriteLine("B : Stiffdead Deadlifts: @ 5 x 10 ");
            Console.WriteLine("C : Leg Press: @ 5 x 15 \n");

            Console.ReadLine(); 

        }

    }
}


Что я уже пробовал:

Ну а поскольку я здесь за помощью и не знаю, как решить эту проблему, любая помощь приветствуется.

2 Ответов

Рейтинг:
20

OriginalGriff

Во-первых, не используйте методы преобразования: пользователи все время вводят неверные данные, и методы преобразования приведут к сбою вашего приложения, если они это сделают. Используй двойника.Вместо этого попробуйте использовать методы tryparse.

На самом деле, это хорошее вступление к использованию метода.
В данный момент Вы делаете одно и то же несколько раз:

            Console.Write("Your Bench max: ");
            double benchMax = Convert.ToDouble(Console.ReadLine());
...
            Console.Write("Your Deadlift max: ");
            double deadliftMax = Convert.ToDouble(Console.ReadLine());
...
            Console.Write("Your Squat max: ");
            double squatMax = Convert.ToDouble(Console.ReadLine());
...
            Console.Write("Your OHP max: ");
            double ohpMax = Convert.ToDouble(Console.ReadLine());
А преобразование их в использование TryParse сделает ваш код довольно громоздким.
Поэтому вместо этого давайте переместим код в метод. Начните с написания метода - он должен возвращать double, и он должен принимать строковое приглашение в качестве входного параметра. Так что его подпись проста:
double GetDouble(string prompt)
И его содержание тоже не сложно:
1) распечатайте приглашение.
2) получить пользовательский ввод
3) преобразуйте его в двойной
4) Если преобразование не удалось, сообщите пользователю, что есть проблема, и вернитесь к (1)
5) верните значение.
Так что давайте напишем его:
double GetDouble(string prompt)
    {
    double result;
    do
        {
        Console.Write(prompt);
        string inp = Console.ReadLine();
        if (double.TryParse(inp, out result))
            {
            return result;
            }
        Console.WriteLine("\"{0}\" is not a valid double value!", inp);
        } while(true);
    }
Все, что нам нужно сделать сейчас, это использовать новый метод:
            double benchMax = GetDouble("Your Bench max: ");
...
            double deadliftMax = GetDouble("Your Deadlift max: ");
...
            double squatMax = GetDouble("Your Squat max: ");
...
            double ohpMax = GetDouble("Your OHP max: ");
Видите, насколько чище этот кусок кода теперь?

Теперь посмотрите на свой код и посмотрите, сможете ли вы найти что-нибудь еще, что могло бы выиграть от такого же внимания!


Member 13733578

Здравствуйте, спасибо за ваш подробный ответ. Я не понимаю часть TryParse, не могли бы вы уточнить, пожалуйста. Например, как и где его использовать. Нужно ли мне только использовать его в методе ?

OriginalGriff

Вы можете использовать TryParse где угодно, а не только "в методе".
Он делает то же самое, что и новообращенный.ToDouble, но он возвращает bool, чтобы указать успех / неудачу вместо того, чтобы создавать исключение.

Поэтому, если пользователь вводит "hello.6" вместо "12345.6", вы можете изящно сказать ему, что было не так, а ваше приложение просто рухнет. Если вы сидите там и набираете дюжину цифр, то приложение выходит из строя, потому что вы набрали два". " вместо одного вы не будете счастливым кроликом! :смеяться:

Member 13733578

Здравствуйте, еще раз спасибо. Я использовал ваш метод, и он действительно работает очень хорошо. Я до сих пор толком не понимаю, что он делает. Но я думаю, что это приходит со временем. Спасибо.

OriginalGriff

Какую часть вы не понимаете - если вы объясните, с чем вы можете справиться, я постараюсь "заполнить пробелы". Но я не вижу ни вас, ни вашего экрана, так что вы должны быть достаточно откровенны в своем понимании! :смеяться:

Не беспокойтесь о том, чтобы "чувствовать себя глупо" или "выглядеть как идиот" - вы не будете: мы понимаем новичков, и что они действительно путаются. Мы не пытаемся заставить вас чувствовать себя глупо, Честное слово!

Member 13733578

Часть "если" действительно витает в облаках для меня.

OriginalGriff

Хорошо: вы знаете, что делает "Если", но быстро резюмирую:
Если (а)
б;
еще
с;

Если "a" имеет значение true, то выполняется "b", в противном случае выполняется "c".
"а" может быть чем угодно, что заканчивается как bool:

i > 16
списке "мой список".Количество == 0

В этом случае "a" - это вызов метода, который возвращает значение bool: double.Метод tryparse.
Поэтому, если TryParse возвращает true, то функция завершает работу и возвращает преобразованное значение. Если он возвращает false, то цикл продолжается с печатью сообщения об ошибке t6he.
Надеюсь, вам все должно быть ясно?
Условие "а" в данном случае немного усложнено, но я намеренно буду "замалчивать" детали, поскольку они появятся позже в вашем курсе.
"double" - это класс (gloss, gloss), который имеет статический (gloss, gloss) метод TryParse, принимающий два параметра.
Первый - это строка, и это данные, введенные пользователем, которые вы хотите преобразовать. Второй - это "специальный" параметр-отсюда и "out" перед ним (gloss, gloss, gloss, gloss, gloss), который говорит: "метод, который вы вызываете, изменит значение этой переменной". Если вы подумаете об этом, TryParse должен вернуть два бита информации: преобразованное значение и флаг, который говорит "он преобразовал OK" или "это было неверное число", и вы не можете вернуть два значения из одного метода (gloss, gloss, gloss, GLOSS), поэтому вам нужен механизм, чтобы вернуть второе значение обратно в ваш код.

Это все, что есть! Есть ли в этом смысл?

F-ES Sitecore

TryParse-это просто другой способ преобразования строки в число. Преобразование предполагает, что строка, которую вы пытаетесь преобразовать, может быть преобразована в нужный тип. Таким образом, если преобразование в int строк, таких как "123", "0" и так далее, в порядке, но если вы даете ему строку, которую он не может преобразовать, как "abc", то он выдает ошибку, и ваша программа останавливается. TryParse более надежен, если строка не может быть преобразована, она просто возвращает false, позволяя вашему коду продолжить работу, чтобы вы могли показать ошибку. Поэтому Convert предполагает, что вы сделали что-то, что проверяет текст перед его использованием, где TryParse делает проверку за вас.

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

Рейтинг:
0

Member 13733578

Эй,

Я не знаю, где публиковать свои обновления. Но это то, что я придумал, я бы хотел получить некоторую обратную связь о том, как сделать его лучше. - Спасибо.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _531Calculator
{
    class Program
    {
        static void Main(string[] args)
        {
            //Default
            Console.WindowHeight = 28;
            Console.WindowWidth = 60;
            Console.ForegroundColor = ConsoleColor.White;

            Console.Title = "5/3/1 Calculator";

            Console.WriteLine("----Your max's---- \n");

            double getDouble(string prompt)
            {
                double result;
                do
                {
                    Console.Write(prompt);                          //Calls benchMax..DeadliftMax..etc(in order)
                    string input = Console.ReadLine();              //Writes the string `Your Bench Max:`
                    if (double.TryParse(input, out result))
                    {
                        return result;
                    }
                    else
                    {
                        Console.WriteLine("Not valid", input);
                    }

                } while (true);
            }


            double benchMax = getDouble("Your Bench max: ");
            double deadliftMax = getDouble("Your Deadlift max: ");
            double squatMax = getDouble("Your Squat max: ");
            double ohpMax = getDouble("Your OHP max: ");


            //Bench Week 1
            double deadliftWeekOne_65, deadliftWeekOne_75, deadliftWeekOne_85;
            deadliftWeekOne(deadliftMax, out deadliftWeekOne_65, out deadliftWeekOne_75, out deadliftWeekOne_85);

            //Deadlift Week 1
            double benchWeekOne_65, benchWeekOne_75, benchWeekOne_85;
            benchWeekOne(benchMax, out benchWeekOne_65, out benchWeekOne_75, out benchWeekOne_85);

            //Deadlift Week 1
            double squatWeekOne_65, squatWeekOne_75, squatWeekOne_85;
            squatWeekOne(squatMax, out squatWeekOne_65, out squatWeekOne_75, out squatWeekOne_85);

            //OHP Week 1
            double ohpWeekOne_65, ohpWeekOne_75, ohpWeekOne_85;
            ophWeekOne(ohpMax, out ohpWeekOne_65, out ohpWeekOne_75, out ohpWeekOne_85);

            Console.WriteLine("\n ----Week 1---- \n");

            Console.WriteLine("----DAY 1----");
            Console.WriteLine("A : Bench: 3 x 5 @ " + benchWeekOne_65 + ", " + benchWeekOne_75 + ", " + benchWeekOne_85);
            Console.WriteLine("B : Dumbbell Chest Press @ 5 x 15");
            Console.WriteLine("C : Barbell Row @ 5 x 10 \n");

            Console.WriteLine("----DAY 2----");
            Console.WriteLine("A : Deadlift: 3 x 5 @ " + deadliftWeekOne_65 + ", " + deadliftWeekOne_75 + ", " + deadliftWeekOne_85);
            Console.WriteLine("B : Hamstring Curls @ 5 x 12");
            Console.WriteLine("C : Assited Work 2: Leg Raises(Abs) @ 5 x 15 \n");

            Console.WriteLine("----DAY 3----");
            Console.WriteLine("A : OHP: 3 x 5 @ " + ohpWeekOne_65 + ", " + ohpWeekOne_75 + ", " + ohpWeekOne_85);
            Console.WriteLine("B : Dip @ 5 x 15");
            Console.WriteLine("C : Chin-Up 5 x 12 \n");

            Console.WriteLine("----DAY 4----");
            Console.WriteLine("A : Squat: 3 x 5 @ " + squatWeekOne_65 + ", " + squatWeekOne_75 + ", " + squatWeekOne_85);
            Console.WriteLine("B : Stiffdead Deadlifts: @ 5 x 10 ");
            Console.WriteLine("C : Leg Press: @ 5 x 15 \n");

            Console.ReadLine();

        }

        private static void ophWeekOne(double ohpMax, out double ohpWeekOne_65, out double ohpWeekOne_75, out double ohpWeekOne_85)
        {
            ohpWeekOne_65 = ohpMax * 0.65;
            ohpWeekOne_75 = ohpMax * 0.75;
            ohpWeekOne_85 = ohpMax * 0.85;
        }

        private static void squatWeekOne(double squatMax, out double squatWeekOne_65, out double squatWeekOne_75, out double squatWeekOne_85)
        {
            squatWeekOne_65 = squatMax * 0.65;
            squatWeekOne_75 = squatMax * 0.75;
            squatWeekOne_85 = squatMax * 0.85;
        }

        private static void benchWeekOne(double benchMax, out double benchWeekOne_65, out double benchWeekOne_75, out double benchWeekOne_85)
        {
            benchWeekOne_65 = benchMax * 0.65;
            benchWeekOne_75 = benchMax * 0.75;
            benchWeekOne_85 = benchMax * 0.85;
        }

        private static void deadliftWeekOne(double deadliftMax, out double deadliftWeekOne_65, out double deadliftWeekOne_75, out double deadliftWeekOne_85)
        {
            deadliftWeekOne_65 = deadliftMax * 0.65;
            deadliftWeekOne_75 = deadliftMax * 0.75;
            deadliftWeekOne_85 = deadliftMax * 0.85;
        }
    }
}


Richard Deeming

То ophWeekOne, squatWeekOne, benchWeekOne и deadliftWeekOne все они делают одно и то же. Вы можете заменить их одним методом:

private static void CalculateWeek1(double max, out double value65, out double value75, out double value85)
{
    value65 = max * .65;
    value75 = max * .75;
    value85 = max * .85;
}
Использование:
// Bench Week 1
double benchWeekOne_65, benchWeekOne_75, benchWeekOne_85;
CalculateWeekOne(benchMax, out benchWeekOne_65, out benchWeekOne_75, out benchWeekOne_85);

// Deadlift Week 1
double deadliftWeekOne_65, deadliftWeekOne_75, deadliftWeekOne_85;
CalculateWeekOne(deadliftMax, out deadliftWeekOne_65, out deadliftWeekOne_75, out deadliftWeekOne_85);

// Squat Week 1
double squatWeekOne_65, squatWeekOne_75, squatWeekOne_85;
CalculateWeekOne(squatMax, out squatWeekOne_65, out squatWeekOne_75, out squatWeekOne_85);

// OHP Week 1
double ohpWeekOne_65, ohpWeekOne_75, ohpWeekOne_85;
CalculateWeekOne(ohpMax, out ohpWeekOne_65, out ohpWeekOne_75, out ohpWeekOne_85);


Вы также можете очистить Console немного с помощью Составное Форматирование[^]:
Console.WriteLine("A : Bench: 3 x 5 @ {0}, {1}, {2}", benchWeekOne_65, benchWeekOne_75, benchWeekOne_85);

Или Интерполированные Строки[^]
Console.WriteLine($"A : Bench: 3 x 5 @ {benchWeekOne_65}, {benchWeekOne_75}, {benchWeekOne_85}");

OriginalGriff

Начните с сброса комментариев.Первый, который вы добавили в getDouble, ошибочен - а неправильные комментарии-это действительно плохая идея! Второе тоже неверно, и еще более неверно, чем первое!
Комментарии существуют для улучшения понимания - поэтому комментируйте, что происходит, если это не ясно и не задокументировано. Так что не комментируйте
Приставка.WriteLine(подсказка);
потому что из чтения его очевидно, что он делает - он печатает "дайте мне эту подсказку данных" пользователю.
Обязательно комментируйте метод и его параметры, но не комментируйте вещи, которые не очевидны. Комментируя "подсказку", чтобы объяснить, что это строка, которая говорит пользователю, что от него ожидается - это прекрасно и чертовски хорошая идея. (И это очень легко сделать: поместите курсор в пустую строку над строкой объявления функции и нажмите "/" три раза. VS автоматически вставит для вас интеллектуальный шаблон с заданными параметрами, готовыми к описанию - просто добавьте его между символами ">" и "<", и Intellisense подберет его для вас, как если бы это был метод .NET framework!)

О - и измените имя метода обратно: существуют правила для соглашений об именовании, и методы не начинаются со строчного символа в C#


Ваши методы, лежащие в основе этого ... разве они не кажутся вам довольно "одинаковыми"? Они делают это со мной...