Use a scanner alongside a Throttle class

67 Views Asked by At

I have a project where we have a used a Throttle class and MainClass. We have to now create a new while loop that prompts the user for the position data, using a scanner, from 0 to 6.

When the user enters -1 the code needs exit. I am just having issues implementing a scanner with throttle class. I was able to without using Throttle class but that's not the assignment.

Full instructions(copy & pasted):

  • Modify the MainClass by deleting the while loop.
  • Create a new while loop that prompts the user for the position data, using a scanner.
  • When the user enters -1 the code shall exit.

The user should enter a position between 0 and 6. With the exception of -1, the data must be between 0 and 6; all other data shall be ignored. Each time a valid position is entered by the user, the flow shall be recalculated and displayed.

Here is the MainClass:

package Pck1;

public class MainClass {

    public static void main(String[] args) {
        int position = 3;
        //position is used in-case of using something different from 3
        Throttle throttle = new Throttle(position);
        
        while (throttle.is_on())
        {
            System.out.println("The throttle is on." + "flow = " 
                    + throttle.flow());
            throttle.shift(-1);
        }
            System.out.println("The throttle is off." );
        }
}

AND here is the throttle class:

package Pck1;

public class Throttle {

    // Data Members
    private int position;
    // Constructors
    public Throttle(int position) {
    this.position = position;
    }
    // Membership Functions
    public boolean is_on() {
    return flow() > 0;
    }
    
    public double flow() {
    return position / 6.0;
    }
    
    public void shift(int amount) {
    position += amount;
    
    if (position < 0)
    position = 0;
    else if (position > 6)
    position = 6;
    }
    
    public void shut_off() {
    position = 0;
    }
}

I tried the following but I know its HORRIBLE.

package Pck1;

import java.util.Scanner;

public class MainClass {
    public static void main(String[] args) {
    
    int j = 0;
    
    Scanner input =  new Scanner(System.in);
    System.out.println("Enter speed between 0 and 6: ");
        j = input.nextInt();


        Throttle throttle = new Throttle(j);
        
          while(j > 6){

                j = input.nextInt();//read input from user
                System.out.println();

                if (j >=0 && j <=6 ) {
                    System.out.println("Validated input: " + j);
                    input.close();          
                }//end if statement

                else {
                    System.out.println("Enter a number between 1 and 6");
                    j = input.nextInt();
                }//end else statement

            }//end while loop       

            }//end main method

        }//end class
1

There are 1 best solutions below

3
larsks On

With the caveat that I am not all that experienced with Java, here's one option that satisfies the instructions (with a few comments to explain the implementation).

Fundamentally, I think this assignment is broken: your Throttle class has no method to directly manipulate the throttle position; you can only shift up or down relative amounts. It would make much more sense to prompt the user for a positive or negative number and then feed that to the Throttle.shift method; alternatively, this assignment would also be more sensible if the Throttle class had something like a setPosition method. It doesn't, which means the only way to fulfill the instructions it to create a new Throttle instance in response to each input from the user. That is complete nonsense.

Anyway, here you go:

package Pck1;

import java.util.Scanner;

public class MainClass {
    /**
     * Prompt the user for a new Throttle position. This routine will
     * loop until the user enters valid data, re-prompting the user each
     * time.
     */
    private static int readPosition(Scanner input) {
        int position;

        // Keep prompting until we get valid input.
        while (true) {
            System.out.print("Enter throttle position (0-6); enter -1 to quit: ");
            try {
                position = input.nextInt();
                if (position >= -1 && position <= 6)
                    // Exit the loop if we have valid data.
                    break;
            } catch (java.util.InputMismatchException e) {
                /**
                 * We end up here if the user enters a non-integer response.
                 * This call discards the invalid token so that we can try
                 * reading new input.
                 */
                input.next();
            }

            /**
             * If we get here, the user entered invalid data. Either they entered
             * a number that it out of range, or they entered some non-numeric
             * response. In either case, display an error and re-prompt.
             */
            System.out.println("Invalid input.");
        }

        return position;
    }

    public static void main(String[] args) {
        Throttle throttle;
        Scanner input =  new Scanner(System.in);

        /**
         * This is a try-with-resources [1] statement; it ensures that we properly
         * close the scanner when we exit the try block. That's not strictly necessary
         * in this code, but it stops my IDE from complaining about the unclosed scanner.
         *
         * [1]: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
         */
        try (input) {
            while(true) {
                int position = readPosition(input);

                if (position == -1) {
                    // Exit if user enters -1.
                    break;
                } else {
                    // Otherwise create a new Throttle with updated position.
                    throttle = new Throttle(position);
                }

                System.out.println("Flow is now: " + throttle.flow());
            }
        }
    }
}