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 thereadDouble
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)
orif ([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 useif ([booleanVariable])
orif (![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.