0

I have this bit of code to return to the beginning of the program if an answer is not expected.

...
else // returns to start for unsatisfactory
{   
    System.out.println();
    System.out.println();
    System.out.println("Check your spelling and try again");
    main (args);                                       
}   
...   

however when I enter a different word then go through again and enter an expected word the program outputs two different results


Current Salary: $100.00

Amount of your raise: $4.00

Your new salary: $104.00


Current Salary: $100.00

Amount of your raise: $0.00

Your new salary: $100.00


I tried using an else if statement to possibly eliminate that as a cause but it caused the same thing.


import java.util.Scanner;
import java.text.NumberFormat;

 public class Salary {
     public static void main (String[] args) {
         double currentSalary; // employee's current salary
         double raise = 0.0;         // amount of the raise
         double newSalary;     // new salary for the employee
         String rating;         // performance rating

         Scanner scan = new Scanner(System.in);
         System.out.print ("Enter the current salary: ");
         currentSalary = scan.nextDouble();

        System.out.print ("Enter the performance rating (Excellent, Good, or Poor): ");

        rating = scan.next();

        // Computes raise with if-else
        if ((rating.equals("Excellent")) || (rating.equals("excellent"))) {
            // calculates raise for excellent
            raise = .06 * currentSalary;
        }
        else if ((rating.equals("Good")) || (rating.equals("good"))) {
            // calculates raise for good
            raise = .04 * currentSalary;
        }
        else if ((rating.equals("Poor")) || (rating.equals("poor"))) {
            // calculates raise for poor
            raise = .015 * currentSalary;
        }   
        else {
            // returns to start for unsatisfactory
            System.out.println();
            System.out.println();
            System.out.println("Check your spelling and try again");
            main (args);
        }      

        newSalary = currentSalary + raise;

        // Print the results

        NumberFormat money = NumberFormat.getCurrencyInstance();
        System.out.println();
        System.out.println("Current Salary:       " + money.format(currentSalary));
        System.out.println("Amount of your raise: " + money.format(raise));
        System.out.println("Your new salary:     " + money.format(newSalary));
        System.out.println();
    }
}
3
  • 4
    Dont call main recursively, instead use while/for loop Commented Sep 16, 2016 at 4:08
  • 1
    Why don't you use equalsIgnoreCase? Commented Sep 16, 2016 at 4:40
  • You may want a write a decent parsing function (which is not main) to verify the input. In case the input is invalid it can return false, in that case you can call another function requesting new input (or how you want to handle it). I am also the kind of guy thinking that a program called with the wrong input argument is better not started as all. In that case it is better if the user start the program again and gets it right. This does not always hold (eg. if the input comes from a large configuration file and you need to repair it for example), but often this is a good approach. Commented Sep 16, 2016 at 5:01

5 Answers 5

2

That is because you call main recursively (which is not considered good practice BTW) when you don't get an expected input. After you enter (the 2nd time) an expected input, the remainder of the initial main must still be executed which will then work with a raise of 0.0 as the input was invalid.

A pragmatic solution for your issue could be avoiding the recursive call to main and wrap e.g. the input validation in a loop like so

...
System.out.print ("Enter the performance rating (Excellent, Good, or Poor): ");
while (true) {
   rating = scan.next();   
   if ((rating.equals("Excellent")) || (rating.equals("excellent")))
   { 
       raise = .06 * currentSalary; break;
   }
   else if ((rating.equals("Good")) || (rating.equals("good")))
   {
       raise = .04 * currentSalary; break;
   }
   else if ((rating.equals("Poor")) || (rating.equals("poor")))
   {
       raise = .015 * currentSalary; break;
   }   
   else 
   {   
      System.out.println();
      System.out.println();
      System.out.println("Check your spelling and try again");     
   } 
}
...
Sign up to request clarification or add additional context in comments.

Comments

1

You're not returning after you call main (args); so every iteration of your program will continue.

You should add return; after main (args);

{   
       System.out.println();
       System.out.println();
       System.out.println("Check your spelling and try again");
       main (args);
       return;

}   

edit: as pointed out by John3136 you shouldn't be calling main (args) recursively either.

1 Comment

I assume there are other ways to check inputs than actually calling main again at all...
1

That (second) call you make to main() "finishes" and comes back out to the "first" one that was invoked by starting the program.

So the first lot of results are from your explicit call to main(). The second lot is from when that call ends and you are back to where you called from.

Calling main() recursively is not recommended. You should use a while loop inside main(). i.e. Keep asking for input until you know the input is valid, and then actually use it.

1 Comment

what would be a better alternative?
0

You should not call main recursively.you should use do while loop as I update code and it's working fine.

  import java.util.Scanner;

  import java.text.NumberFormat;



  public class Salary {

  public static void main (String[] args) {

     double currentSalary; // employee's current salary

     double raise = 0.0;         // amount of the raise

     double newSalary;     // new salary for the employee

     String rating;         // performance rating

     boolean flag=false; // to check input 


     Scanner scan = new Scanner(System.in);


 do{

       System.out.print ("Enter the current salary: ");

       currentSalary = scan.nextDouble();

       System.out.print ("Enter the performance rating (Excellent, Good, or Poor): ");

       rating = scan.next();


       // Computes raise with if-else
         if ((rating.equals("Excellent")) || (rating.equals("excellent"))) // calculates raise for excellent
            { 
                   raise = .06 * currentSalary;
                   flag=true;

            }
            else if ((rating.equals("Good")) || (rating.equals("good")))   // calculates raise for good
               {
                   raise = .04 * currentSalary;
                     flag=true;

               }
            else if ((rating.equals("Poor")) || (rating.equals("poor"))) // calculates raise for poor
               {
                   raise = .015 * currentSalary;
                     flag=true;

               }   
         else                                                     // returns to start for unsatisfactory
            {   
                   System.out.println();
                   System.out.println();
                   System.out.println("Check your spelling and try again");
                   flag=false;

            }      

 }while(!flag);


     newSalary = currentSalary + raise;



     // Print the results

    NumberFormat money = NumberFormat.getCurrencyInstance();

    System.out.println();

    System.out.println("Current Salary:       " + money.format(currentSalary));

    System.out.println("Amount of your raise: " + money.format(raise));

    System.out.println("Your new salary:     " + money.format(newSalary));

    System.out.println();






       }

  }

Comments

0

You may want to consider another approach. Either terminate the problem in case the input is invalid or try to repair it. The following example is for the "repair" approach,

public class Salary {
    public static void main(String[] args) {
        IPM ipm;
        if (verify(args)) {
            ipm = new IPM(args);
        } else {
            Scanner scan = new Scanner(System.in);
            String[] update;
            do {
                update = repair(scan);
            } while (!verify(update)); // You may want a loop count as well...
            ipm = new IPM(update);
        }
        ipm.print();
    }

    public static boolean verify(String[] s) {
        return IPM.verify(s);
    }

    public static String[] repair (Scanner s) {
        // Request new input and store it in an array of strings.
        // This method does not validate the input.
    }
}

public class IPM {
    double currentSalary;
    double raise = 0.0;
    double newSalary;
    String rating;

    IPM(String[] input) {
        // Set attributes of IPM.
    }

    public static boolean verify(String[] s) {
        //Determine if the input is valid.
    }

    public void print() {
        // Print IPM object.
    }
}

Note that the call to IPM.verify() from salary. This should be a part of the responsibility of IPM since Salary is not require to know anything about main. Also, the class IPM might change and a call to IPM.verify() will not require that all classes which verifies the IPM are changed as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.