How to break my code into subroutines? – Java

Posted on

Problem

I have written a code for data management and parallel arrays but it has to be broken into methods/subroutines. Whenever I try to do so, some aspect of my code stops working. Would it be possible for anyone to roughly outline how and what I can break into subroutines without it causing problems in my code?

    Scanner keyedInput = new Scanner(System.in); // input
    
    // variables
    String userInput;
    int numberOfBooks = 0; // setting to 0
    int userChoice = 0; // setting to 0
    final double taxAmount = 1.13;
    boolean valid = false;
    double total = 0; // setting to 0
    double taxedTotal;
    
    // while loop for number of books
    while (valid == false)
    {
        // user enters info
        System.out.print("Please enter the number of books you have purchased: ");
        userInput = keyedInput.nextLine();
        System.out.println();
        
        // try catch statements for invalid input/exceptions
        try
        {
            numberOfBooks = Integer.parseInt(userInput); // converting to int
            valid = true; // setting to true so loop won't repeat
        } // end of try
        
        // outputting invalid input message
        catch (NumberFormatException e)
        {
            System.out.println("Your input is not valid");
            System.out.println();
        } // end of catch
    } // end of valid == false while loop
    
    
    // arrays to hold info user will input
    String bookName [ ] = new String [numberOfBooks];
    double price [ ] = new double [numberOfBooks];
    
    // user enters all data required
    System.out.println("* * * * DATA ENTRY * * * *");

    // for loop that prompts for and stores name of books purchases
    for (int i = 0; i < numberOfBooks; i = i + 1)
    {
        System.out.println();
        System.out.print("Please enter the name of book " + (i + 1) + ": ");
        bookName[i] = keyedInput.nextLine(); // stores the name of each book in the array
        
        // set valid to false again for loop below
        valid = false;
        
        // while loop for price of books
        while (valid == false)
        {
            System.out.println();
            System.out.print("Please enter the price of '" + (bookName[i] + "': "));
            userInput = keyedInput.nextLine();
            
            
            // try catch statements for invalid input/exceptions
            try 
            {
                price[i] = Double.parseDouble(userInput); // converting to double
                valid = true; // setting to true so loop won't repeat
            } // end of try
            
            // outputting invalid input message
            catch (NumberFormatException e) 
            {
                System.out.println("Your input is not valid");
            } // end of catch
        } // end of valid == false while loop
    } // end of for loop
        
    
        // while loop to output data
        while (userChoice != 3)
        {
            // set valid to false for loop below
            valid = false; 
            
            while (valid == false)
            {
                // outputting choices menu
                System.out.println();
                System.out.println("* * * *n" + "1. Output original data n" + "2. Output calculated data n" + "3. Exit n" + "* * * *n");
                
                // user enters their choice
                System.out.print("Please enter the number in front of your choice: ");
                userInput = keyedInput.nextLine();
                System.out.println();
                
                // try catch statements for invalid input/exceptions
                try 
                {
                    userChoice = Integer.parseInt(userInput); // converting to int
                    valid = true; // setting to true so loop won't repeat
                } // end of try
                
                // outputting invalid input message
                catch (NumberFormatException e) 
                {
                    System.out.println("Your input is not valid");
                    System.out.println();
                } // end of catch
            } // end of valid == false while loop
            
           
            // switch statements for each option
            switch (userChoice)
            {
                // option 1
                case 1:
                {
                    // for loop to output existing data
                    for (int i = 0; i < numberOfBooks; i = i + 1)
                    {
                        System.out.println("'" + bookName[i] + "'" + " cost: " + price[i]);
                    } // end of for loop
                    break;
                } // end of case 1
                
                // option 2
                case 2: 
                {
                    // calculations for total + taxed total
                    for (double value : price) 
                    {
                        total = total + value;
                        total = Math.round(total * 100.0) / 100.0; // rounding
                        //totalAmount = totalAmount + total;
                    } // end of for loop    
                    
                    taxedTotal = (total * taxAmount); // calculating total with taxes
                    taxedTotal = Math.round(taxedTotal * 100.0) / 100.0; // rounding
                    
                    System.out.println("Total: $" + total);
                    System.out.println("Taxed total: $" + taxedTotal);
                    break;
                } // end of case 2
                
                // option 3
                case 3:
                {
                    System.out.println("Goodbye!");
                } // end of case 3
            } // end of switch statements
        } // end of userChoice while loop

Solution

How to broke your code into sub rutines

Well, there I see some util things you could do in order to separate the code:

  • First, you could create some functions which job is to request the data to the user and until that data is correctly entered, the function continues requesting data, Example:
    //let this be a static field so you can call it in any other new static function
    private static Scanner scanner = new Scanner(System.in);

    private static readInt(String requirement) {
        System.out.print(requirement + " : ");
        int input;
        boolean correctInput = false;
        do {
            try {
                input = scanner.nextInt();
            } catch (Exception ignored) {
                System.out.println("An error has occurred, introduce the number again");
            }
        } while(!correctInput);
        //equivalent to correctInput != true or correctInput == false
        return input;
    }

(I suppose you’re working with only a main class which has the public static void main)

I would recommend you to create two more functions readString and readDouble so that you are simplifying the data gathering process and not repeat code.

  • Now, you use the readString function to request the user the book name and the readDouble for the book price. and so you are saving more code.

  • Finally, each case in a switch can be turned into a function.

Referent to your code style

  • Do not use comparisons of type if ([booleanVariable] == true) or if ([booleanVariable] == false), until I have knowledge it is also a comparison that your machine has to do in runtime, if you are coding a very large system part the effect will be more notorious. Instead use if ([booleanVariable]) or if (![booleanVariable]) the ! symbol means not.

It doesn’t apply only to Java, it works for many other languages (Python, C++, C, C#, GO, JS, PHP, …), syntax may variate but still applies.

  • Do not over-comment, it is good to have documentation about your code, but writting a lot of comments where it is intuitive what the code does, is bad, it consumes your time and the code gets messy.

  • Last, it perhaps is not the big deal, but most Java programmers uses

[expression] { //this brace opening
}

[expression]
{//rather than this.
 //I may say, it is more likely to be done for someone who comes from C#, C++ or C
}

it doesn’t matter at the end, but you know, some people care about it and well, it is better to work under the same language, using a common terminology.

Note: certainly it is better to use read instead of get according to Roland Illig‘s comment.

Hope it helped you, cheers.

Leave a Reply

Your email address will not be published. Required fields are marked *