4
\$\begingroup\$

The specifications are:

The first 36 hours worked are paid at a rate of 15.0, then the next 5 hours are paid at a rate of 15 * 1.5. Hours after that up to a max of 48 are paid at a rate of 15 * 2.

It works, but I'm new and might've gone about this in a complicated fashion.

import java.util.*;

class Task3
{
public static void main()
{
    // Scanner object
    Scanner inputText = new Scanner(System.in);

    // Variables
    double hoursWorked, pay = 15, overtime, totalPay = 0;
    String employee;

    // Ask user for employees name
    System.out.println ("Enter employee's name");
    employee = inputText.nextLine();

    // Ask user for employees weekly hours worked
    System.out.println ("Type in the total hours worked this week:");
    hoursWorked = inputText.nextDouble();

    overtime = hoursWorked;

    if (hoursWorked <= 36)
    {
        totalPay = hoursWorked * pay;
    }        
    else if (hoursWorked > 36 && hoursWorked <= 41)
    {
        totalPay += 36 * pay;
        hoursWorked -=36;
        overtime = hoursWorked * pay * 1.5;
        totalPay += overtime;
        hoursWorked += 36;
    }
    else
    {
        totalPay += 36 * pay;
        hoursWorked -= 36;
        overtime = hoursWorked * pay * 1.5;
        totalPay += overtime;
        hoursWorked -=5;
        overtime = hoursWorked * pay * 0.5;
        totalPay += overtime;
        hoursWorked += 41;
        }
\$\endgroup\$
0
3
\$\begingroup\$

try-with-resources

Since Java 7, it's recommend to use try-with-resources on AutoCloseable instances, e.g. Scanner in this case, for safe and efficient handling of the underlying I/O resource.

Methods

The calculation itself can be encapsulated into a method:

private static double getPay(double hoursWorked) {
    // calculation
}

Given that, your main() method can be refactored as such:

public static void main() {
    try (Scanner scanner = new Scanner(System.in)) {
        System.out.println ("Enter employee's name");
        employee = inputText.nextLine();
        System.out.println ("Type in the total hours worked this week:");
        hoursWorked = getDouble(scanner);
        System.out.println("Total pay: " + getPay(hoursWorked));
    }
}

getDouble(Scanner) is a helper method that performs some basic validation on getting a double value from the Scanner instance by calling its hasNextDouble() method first, for example:

private static double getDouble(Scanner scanner) {
    while (!scanner.hasNextDouble()) {
        System.out.println("Invalid input, enter a number.");
        scanner.next();
    }
    return scanner.nextDouble();
}

Of course, you may want to perform extra validation, for example making sure that the input is a positive number.

Hard-coding (and approach)

else if (hoursWorked > 36 && hoursWorked <= 41)

The 41 is not immediately obvious from the problem statement, because that's really just adding the next 5 hours (are paid...) to the initial 36 hours. You should avoid the hard-coding and instead rely more on declaring suitable constants so that it's easier to update these values in the future.

You can also avoid unnecessary subtractions and additions above the base hours to hoursWorked for the following reaons:

  1. Since your approach is self-contained per if clause (as opposed to a 'waterfall'-like approach), you can simply perform the one or two subtractions required to obtain the reminder hours for multiplication with the extra rates.

  2. When the hours worked is above the base hours, you can simply calculate the base pay to be that multiplied with the base rate. When the hours worked is above the base hours and that 5 hours mentioned, the new 'base' pay is the original plus the multiplication of 5 hours with the overtime rate.

  3. When you use methods, the original value hoursWorked is still preserved in the main() method. This remedies point 1 as well.

Putting it altogether

private static final int BASE_HOURS = 36;
private static final int STEP = 5;
private static final int MAX_HOURS = 48;
private static final double BASE_RATE = 15.0;
private static final double STEP_MULTIPLIER = 1.5;
private static final double MAX_MULTIPLIER = 2.0;

private static double getPay(double hoursWorked) {
    if (hoursWorked > MAX_HOURS) {
        // perhaps not as dramatic as below, 
        // but this should be handled appropriately too?
        // System.err.println("Overworked!!! Quitting...");
        // System.exit(1);
    }
    if (hoursWorked <= BASE_HOURS) {
        return /* ... */ ;
    } else if (hoursWorked <= BASE_HOURS + STEP) {
        return /* ... */ ;
    } else {
        return /* ... */ ;
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.