Простой калькулятор консоли

Это мой код Java 8 для консольного калькулятора. Я просто хочу знать, можно ли его каким-то образом улучшить. Просто, чтобы вы знали, что я настоящий начинающий, только что попал в джаву пару недель назад.

    import java.util.Scanner;

public class Algorithm1 {
public static int FirstNumber, SecondNumber;
public static float TheAnswer;
public static String Action;
public static Scanner ScanInt1, ScanString;
public static boolean hasString;
public static boolean hasString2, hasInt;
public static void main(String args[]){
hasString = false;//sets up the booleans
hasString = false;
hasInt = false;
ScanInt1 = new Scanner(System.in);
ScanString = new Scanner(System.in);
System.out.println("Give your First input please.");
while  (FirstNumber < 1){
FirstNumber = ScanInt1.nextInt();   
}
System.out.println("Give your Second input please.");
hasString = true;
if (SecondNumber < 1){
SecondNumber = ScanInt1.nextInt();      
}
else {
System.out.println("Now * or / or + or -");
hasString2 = true;
}
Action = ScanString.nextLine();
System.out.println(Answer());
}
public static float Answer(){
//This method is for the math
    if (Action.equals("*")){
        TheAnswer = FirstNumber * SecondNumber;

    } 
if (Action.equals("/")){
    TheAnswer = FirstNumber / SecondNumber;

}
if (Action.equals("+")){
    TheAnswer = FirstNumber + SecondNumber;

}
if (Action.equals("-")){
    TheAnswer = FirstNumber - SecondNumber;

}
return TheAnswer;
}

}
11 голосов | спросил user77204 9 J000000Thursday15 2015, 13:21:17

5 ответов


4

В приведенном выше тексте есть отличные рекомендации, и я бы откликнулся на большинство из них.

Ключевым элементом написания лучшего кода является понимание цели вашего исходного кода.

Это может быть немного выше вашего уровня, но подумайте об этом так: почему мы пишем исходный код на языках более высокого уровня?

Почему язык поддерживает верхний и нижний регистр? Почему язык поддерживает белый пробел? Почему язык поддерживает комментарии?

По правде говоря, java-компилятор не заботится о большинстве этих вещей (смешение в сторону).

Причина, по которой мы пишем на языках более высокого уровня, - это облегчить для кого-то (кто может быть вам!) понять, что было ПРЕДНАЗНАЧЕНЫ ПО. Исходный код предназначен для чтения и записи человеческих существ.

Итак, мой совет - сделать исходный код понятным, легким для чтения и легко понять, насколько возможно.

Как h.j.k. сказал выше, вы должны использовать метод верблюда и имена переменных, а также имена типов /классов типа Pascal. Зачем? Потому что это соглашение, которое используется программистами по всей планете. Это облегчает для других людей читать программное обеспечение, которое вы написали, если следовать стандарту /стилю, который они используют для чтения.

Те же правила, касающиеся белого пространства, например, отступы. Согласование фигурных скобок, чтобы найти блоки, которые находятся под if /then /else, - это не идея хорошего времени. Помогите им найти, где заканчиваются блоки.

Я бы отличался h.j.k. в одной точке, и это использование нескольких операторов возврата в методе Answer (). Я, конечно, могу видеть его точку зрения; его способ мышления уменьшает количество строк в методе и упрощает обзор с первого взгляда на то, что возвращается методом. Это все замечательные цели.

Однако в нетривиальном программном обеспечении я предпочитаю видеть один оператор возврата в нижней части подпрограммы, потому что это означает, что я могу установить одну точку останова при возврате, и я могу видеть, что возвращает функция в отладчике. Это большая помощь при разработке /поддержании программного обеспечения, написанного несколькими людьми в течение нескольких лет.

Я также предпочитаю, чтобы возвращаемая локальная переменная была инициализирована некоторым известным хорошим начальным значением. Это гарантирует, что возвращаемое значение из функции всегда будет установлено в SOMETHING.

Это одна вещь, которую вы сейчас не делаете. Вы в зависимости от глобальной переменной должны быть равны нулю, а не явно устанавливаете значение TheAnswer для любого значения.

Что произойдет, если пользователь вводит оператор, который не является * /+ -?

Это становится длинным, поэтому я попробую показать вам, как я думаю, он должен выглядеть. НЕ ВКЛЮЧАЙТЕ ЭТО В КАЧЕСТВЕ ВАШИХ ПОМЕЩЕНИЙ. Для вашего учителя будет очень очевидно, что вы его не пишете. Я не собираюсь исправлять объявления переменных и т. Д., Только попытаюсь показать вам, как другие программисты пишут программное обеспечение.

Поверьте мне, я могу сделать больше, но я не исправляю никаких ошибок, которые могут возникнуть.

Вы задаете правильные вопросы, и я рад видеть, что вы хотите сделать лучше.

Древняя книга по этой самой теме называлась «Профессиональный Паскаль» Генри Ледгардом. Не позволяйте Паскалю в названии дурачить вас; речь идет о написании профессионального программного обеспечения на любом языке.

Профессиональный Паскаль (Google Книги)

Надеюсь, это поможет.

-Джон

/*
**  Algorithm1
**
**  A simple console-based calculator.
**
**  USAGE:  
**      java Algorithm1
**
**  Example:
**      java Algorthim1
**          Give your First input please.
**          10
**          Give your Second input please.
**          10
**          Now * or / or + or -
**          *
**          100
**
*/
import java.util.Scanner;

public class Algorithm1 
{
    public static int FirstNumber, SecondNumber;
    public static float TheAnswer;
    public static String Action;
    public static Scanner ScanInt1, ScanString;
    public static boolean hasString;
    public static boolean hasString2, hasInt;

    /*  Answer()
    **
    **  Compute the result of FirstNumber <operator> SecondNumber, and return the value.
    */
    public static float Answer()
    {
        TheAnswer = -1.0f;  /*  Initialize to some value; this should, in best practice, be a local variable. */

        //This method is for the math

        /*  Multiplication */
        if( Action.equals( "*" ) )
        {
            TheAnswer = FirstNumber * SecondNumber;
        } 

        /*  Division */
        if( Action.equals( "/" ) )
        {
            TheAnswer = FirstNumber / SecondNumber;
        }

        /*  Addition */
        if( Action.equals( "+" ) )
        {
            TheAnswer = FirstNumber + SecondNumber;
        }

        /*  Subtraction */
        if( Action.equals( "-" ) )
        {
            TheAnswer = FirstNumber - SecondNumber;
        }
        return TheAnswer;
    }

    /*  Main
    **      No arguments.
    */
    public static void main( String args[] )
    {
        hasString = false;  //sets up the booleans
        hasString = false;
        hasInt = false;
        ScanInt1 = new Scanner(System.in);
        ScanString = new Scanner(System.in);
        System.out.println("Give your First input please.");
        while  (FirstNumber < 1)
        {
            FirstNumber = ScanInt1.nextInt();   
        }
        System.out.println("Give your Second input please.");
        hasString = true;
        if (SecondNumber < 1)
        {
            SecondNumber = ScanInt1.nextInt();      
        }
        else 
        {
            System.out.println("Now * or / or + or -");
            hasString2 = true;
        }
        Action = ScanString.nextLine();
        System.out.println(Answer());
    }
}
ответил John Gordos 10 J000000Friday15 2015, 00:08:52
12

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

Отступ

Нет другого способа поставить это, но ваш отступ крайне беден . Вложенные кодовые блоки внутри скобок { } должны иметь отступ, соответственно, вместо выравнивания по левому краю.

Стиль именования

Используйте camelCase вместо PascalCase для имен переменных и . Как вы можете сказать из выделения синтаксиса на вашем нынешнем коде, PascalCase - это соглашение об именах для имен типа /класса. Это упрощает чтение вашего кода слегка , так как другим разработчикам приходится «повторно анализировать» ваши имена переменных /методов из того, что выглядит как имена классов.

try-with-resources

Так как Java 7, try-with-resources - рекомендуемый подход к чтению из источника ввода-вывода, например, обертка Scanner over System.in:

try (Scanner scanner = new Scanner(System.in)) {
    // ...
    String line = scanner.nextLine();
    // ...
}

Это позволяет JVM закрывать ресурсы ввода-вывода автоматически для вас.

Меньшая зависимость от глобальных переменных static

Вам следует постепенно применять более совершенные объектно-ориентированные (OO) методы программирования, например, меньше полагаться на переменные static. Лучше сделать более эффективное использование аргументов метода, чтобы другие разработчики могли понять, что требует этот метод. Подробнее об этом будет показано ниже.

return ранний

Внутри метода Answer() вы должны return рано, чтобы вы могли избавиться от временных переменных. На мой взгляд, временные переменные часто являются костылем для написания более длинных методов, что делает код более трудным для чтения и понимания в долгосрочной перспективе. Возможное улучшение может быть:

private static float getAnswer(String action, int first, int second) {
    switch (action) {
    case "+":
        return (float) first + second;
    case "-":
        return (float) first - second;
    // ...
    }
}
ответил h.j.k. 9 J000000Thursday15 2015, 13:39:05
4

Отступ

Автоматическое форматирование дает:

import java.util.Scanner;

public class Algorithm1 {
    public static int FirstNumber, SecondNumber;
    public static float TheAnswer;
    public static String Action;
    public static Scanner ScanInt1, ScanString;
    public static boolean hasString;
    public static boolean hasString2, hasInt;
    public static void main(String args[]) {
        hasString = false; //sets up the booleans
        hasString = false;
        hasInt = false;
        ScanInt1 = new Scanner(System. in );
        ScanString = new Scanner(System. in );
        System.out.println("Give your First input please.");
        while (FirstNumber < 1) {
            FirstNumber = ScanInt1.nextInt();
        }
        System.out.println("Give your Second input please.");
        hasString = true;
        if (SecondNumber < 1) {
            SecondNumber = ScanInt1.nextInt();
        } else {
            System.out.println("Now * or / or + or -");
            hasString2 = true;
        }
        Action = ScanString.nextLine();
        System.out.println(Answer());
    }
    public static float Answer() {
        //This method is for the math
        if (Action.equals("*")) {
            TheAnswer = FirstNumber * SecondNumber;

        }
        if (Action.equals("/")) {
            TheAnswer = FirstNumber / SecondNumber;

        }
        if (Action.equals("+")) {
            TheAnswer = FirstNumber + SecondNumber;

        }
        if (Action.equals("-")) {
            TheAnswer = FirstNumber - SecondNumber;

        }
        return TheAnswer;
    }

}

Форматирование фактически показывает, что:

  • Вы указали одну и ту же переменную два раза:

    hasString = false; //sets up the booleans
    hasString = false;
    
  • У вас есть неиспользуемая переменная:

    hasInt = false;
    

Также, пожалуйста, будьте более точными и последовательными в пользовательском интерфейсе:

  • Запросить целое число, а не для 'input'
  • Отобразите приглашение также для операнда, как и для чисел.

Я предлагаю разложить логику askInteger:

public static int askInteger(String prompt, Scanner scanner) {
    int n = 0;
    System.out.println(prompt);
    while (n < 1) {
        n = scanner.nextInt();
    }
    return n;
}

Вы можете называть его так:

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int a = askInteger("a: ", scanner);
    int b = askInteger("b: ", scanner);

    System.out.println(a);
    System.out.println(b);

}

Связывая эту функцию и функцию @ h.j.k, вы можете иметь очень читаемый код.

ответил Caridorc 9 J000000Thursday15 2015, 13:45:32
3

2 Сканеры, обертывающие один и тот же входной поток, будут конфликтовать друг с другом. Каждый из них будет считывать часть ввода и интерпретировать данные, а затем сохранять «оставшиеся» данные в кэше для следующего вызова next*(). Этот кеш не , используемый между сканерами.

Лучше использовать только один сканер.

ответил ratchet freak 9 J000000Thursday15 2015, 13:55:00
3

Определенно следуйте инструкциям h.j.k здесь, особенно в отношении имен переменных, они выделяются как нетрадиционные и выглядят как классы, с первого взгляда.

Так как это предназначено для использования в качестве консольного калькулятора, возможно, вам захочется рассмотреть возможность чтения и запуска из аргументов.

Что-то по строкам:

public static void main(String[] args) {
        if (args.length == 3) {
            parse(args);
        } else {
            // run your current version
        }
    }

    public static void parse(String[] args) {
        double first = Double.parseDouble(args[0]);
        char operator = args[1].charAt(0);
        double second = Double.parseDouble(args[2]);

        System.out.println(compute(first, operator, second));
    }

    public static double compute(double num1, char operator, double num2) {
        double result = 0;

        switch(operator) {
            case '+':
                result = num1 + num2;
            break;
            case '-':
                result = num1 - num2;
            break;
            case 'x':
                result = num1 * num2;
            break;
            case '/':
                result = num1 / num2;
            break;
            case '%':
                result = num1 % num2;
            break;
        }

        return result;
    }

Таким образом, вы можете по желанию сделать это методом вывода -response-output или просто называть его тем, что вы хотите вычислить:

Образец вывода :

  

Java Algorithm1 3 * 5
  15,0

     

Java Algorithm1 120% 14
  8.0

Конечно, хотите ли вы, чтобы оператор пришел первым, хотите добавить поддержку для неограниченных аргументов, проверки на деление на 0 или более зависит от вас и сделают для хорошего упражнения.

ответил Legato 9 J000000Thursday15 2015, 14:07:34

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132