Issue with refactoring of a switch statement - java

Here is the method that performs the switch(Note The switch statement works correctly and according to the requirements)
public void performChecks() {
priceInput = priceReader.nextDouble();
loop: while(true){
nameInput = nameReader.nextLine();
switch(nameInput){
case "A1": Cola colaItem = new Cola();
if(colaItem.checkPrice(priceInput)){
System.out.println("You ordered " + colaItem.getName()+ ", here is it");
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
}
break loop;
case "B2": Chips chipsItem = new Chips();
if(chipsItem.checkPrice(priceInput)){
System.out.println("You ordered " + chipsItem.getName()+ ", here is it");
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
}
break loop;
case "C3": Crackers crackerItem = new Crackers();
if(crackerItem.checkPrice(priceInput)){
System.out.println("You ordered " + crackerItem.getName()+ ", here is it");
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
}
break loop;
default:
System.out.println("Sorry, we don't have item with such a code");
}
}
}
Now I started doing some refactoring and put the method in the super class of the items(Cola, Chips and Crackers) and it looks like this:
public void performChecks(){
inputPrice = priceReader.nextDouble();
inputCode = codeReader.nextLine();
initializeItems();
for(int i = 0; i < items.length; i++){
if(items[i].checkCode(inputCode)){
if(items[i].checkPrice(inputPrice)){
System.out.println("You ordered " + items[i].getName() + " here it is");
break;
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
break;
}
} else if(!items[i].checkCode(inputCode)){
continue;
} else {
System.out.println("Sorry, we don't have item with such a code");
inputCode = codeReader.nextLine();
}
}
}
The issue is the following: When I enter correct/incorrect price and incorrect item code, I should be getting the "Sorry, we don't have an item with such a code" message and the option to enter the item code again. I've ran out of ideas on how to implement this option inside the
else if(!items[i].checkCode(inputCode)){
continue;
Since I'm pretty sure, it just gets stuck there and returns nothing(for incorrect item code).

What you are trying to achieve can be solved with a simple "found" boolean. Like this:
boolean found = false;
for(Item item : items) {
if(item.checkCode(inputCode)){
found = true;
[...] // Here you found the item and you can check the price and other stuff
}
}
if(!found) {
[...] // Here you can handle the case of the incorrect code
}

I'm not absolutely sure, but I guess you can do sth like this:
inputCode = codeReader.nextLine();
do{
if(items[i].checkCode(inputCode)){
if(items[i].checkPrice(inputPrice)){
System.out.println("You ordered " + items[i].getName() + " here it is");
break;
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
break;
}
} else {
inputCode = codeReader.nextLine();
}
} while(!items[i].checkCode(inputCode));

Related

I'm trying to calculate and return the user change and I don't know how

I'm newbie in programming and I need to do a final project.
I can calculate and return the user change.
I tried with the for loop but and it will calculate just the first product from the list.
public class ChangeCalculator{
public double moneyInserted;
ChangeCalculator(double moneyInserted){
}
public static void dispence (double moneyInserted) {
for(Product product: Product.values()) {
if(moneyInserted >= product.getPrice()){
System.out.println("Vending");
double changeReturn = (double)moneyInserted - (double)product.getPrice();
System.out.println(" ");
System.out.println("Here is your $" +changeReturn+" in change");
System.out.println("Thank You");
break;
}
else {
System.out.println("Unsuffient funds");
}
break;
}
}
}
I don't know why you put those break statements.
A break will break the loop, that's why you're not getting past the first item. Drop the breaks and it should work.
for(Product product: Product.values()) {
if(moneyInserted >= product.getPrice()){
System.out.println("Vending");
double changeReturn = (double)moneyInserted - (double)product.getPrice();
System.out.println(" ");
System.out.println("Here is your $" +changeReturn+" in change");
System.out.println("Thank You");
break; // this will end the loop the first time you return change
}
else {
System.out.println("Unsuffient funds");
}
break; // this will end the loop after the first product, regardless of the outcome
}

How to continue an if else statement (?) with another if else statement

A little confused on where to put another if-else statement after one. like do I put it under the if statement ("have you registered to vote yet?" ) or do i put it under the else statement?
I wanted it to answer if yes then it would print out "you can vote" and if no then it would print out "You must register before you can vote"
here's the code
import java.util.Scanner;
public class voting {
public static void main(String[] args) {
int yourage, votersage;
votersage = 18;
Scanner input = new Scanner(System.in);
System.out.println("How old are you? ");
yourage = input.nextInt();
if (yourage >= votersage) {
System.out.println("Have you registered to vote?");
}
else {
System.out.println("You are too young to vote");
}
}
}
I think this works to how you want it. You may need to change around the input'Registered as I am a bit rusty with inputs but I think this should work?
if (yourage >= votersage) {
Scanner input = new Scanner(System.in)
System.out.println("Have you registered to vote?");
Registered = input.next();
if Registered = ("Yes") {
System.out.println("You can vote");
}
else if Registered = ("No"){
System.out.println("You need to register to vote");
}
else:
System.out.println("INVALID INPUT")
}
else {
System.out.println("You are too young to vote");
}
For elif statements you put the elif before the else, but make sure to add a clause for the elif statement to run just like you did with the original if statement.
if (yourage >= votersage) {
System.out.println("Have you registered to vote?");
}
else if (yourage <= votersage){
System.out.println("You must register before you can vote.");
}
else {
System.out.println("You are too young to vote");
}
Nested if statement work in these scenarios...
if (yourage >= votersage)
{
System.out.println("Have you registered to vote?");
bool registered = input.next();
if(registered)
{
System.out.println("You can vote");
}
else
{
System.out.println("Please get yourself register on voting portal!");
}
}
else {
System.out.println("You are too young to vote");
}

How to exit java method

Sorry for the poor title, i didn't know a better paraphrase..
Sooo i am currently writing a Grocery List program and i am stuck on my addItemsToList method. Basically i want it to have to 'exit' points. One of which will bring you back to the main menu of the application and one of which will bring you back to the context menu of that addItemsToList method.
Unfortunately i am completely stuck.
Here is my code for the method:
private static void addItemsToList(){
System.out.println("To which category do you want to add? ");
categoryInstructions();
int choice2 = scan.nextInt();
if(choice2 == 5){ // i am "getting out" here just fine
interact(); // this is the method that instructs everything to happen in the main method
}else {
System.out.println("What do you want to add? Type 'exit' for menu");
i = scan.next(); // this is where the second "exit" point is supposed to be if someone types "exit"
if (i.compareTo(exit) != 0) {
System.out.println("Please enter the quantity ");
int quant = scan.nextInt();
if (choice2 == 1) {
GrocerieList.foodstuffsList.add(i);
GrocerieList.foodstuffsAmount.add(quant);
} else if (choice2 == 2) {
GrocerieList.hygeneList.add(i);
GrocerieList.hygeneAmount.add(quant);
} else if (choice2 == 3) {
GrocerieList.drinkList.add(i);
GrocerieList.drinkAmount.add(quant);
} else if (choice2 == 4) {
GrocerieList.otherList.add(i);
GrocerieList.otherAmount.add(quant);
}
} else {
addItemsToList();
}
}
}
Just for a better understanding here is categoryInstructions():
public static void categoryInstructions(){
System.out.println("Press");
System.out.println(" ");
System.out.println("\t\t" + "(1)" + "\t--\t" + "for foodstuffs");
System.out.println("\t\t" + "(2)" + "\t--\t" + "for hygene");
System.out.println("\t\t" + "(3)" + "\t--\t" + "for drinks");
System.out.println("\t\t" + "(4)" + "\t--\t" + "for others");
System.out.println(" ");
System.out.println("\t\t" + "(5)" + "\t--\t" + "to get back main menu");
}
Now whats happening is that i can exit addItemsToList perfectly fine if choice2 == 5 but i cannot seem to find the logical solution fo exiting if i is equal to "exit". I got it to work quick and dirty with the application first asking for the quantity and then exiting but that isn't quite what i want.
Since i am (obviously) a beginner any other comments on my style or else would also be greatly appreciated!!
You could use a switch case for this purpose, a flag to know when to execute an elegant exit and a while loop to help you stay in the menu until a user provides the correct input.
For instance:
public class Controller {
private GroceriesController groceriesController;
private boolean isRunning; // our flag that will help us to quit the menu
public Controller(GroceriesController groceriesController) {
this.groceriesController = groceriesController;
}
public void run() {
isRunning = true;
while (isRunning) {
clearScreen();
displayLogo();
displayMainMenu();
handleMainMenu(); // method that will do all the job;
}
}
private void handleMainMenu() {
int userChoice = scanner.nextInt();
switch (userChoice) {
case 1:
groceriesController.handleGroceriesMenu();
break;
case 2:
returnItems();
break;
case 0:
isRunning = false; // exit from the menu
break;
default:
System.out.println("Invalid input");
break;
}
}
private void displayMainMenu() {
System.out.println("\n Grocery store:\n"
+ "[1] Buy stuff\n"
+ "[2] Return stuff\n"
+ "[0] Leave store");
}
}
public class GroceriesController {
private boolean isRunning; // same strategy as before
public void handleGroceriesMenu() {
isRunning = true;
while (isRunning) {
clearScreen();
displayLogo();
displayMenu();
handleMenu();
}
}
private void handleMenu() {
int userChoice = scanner.nextInt();
switch (userChoice) {
case 1:
addItemToCart(item);
System.out.println("The item: " + item + "has been added.");
break;
case 2:
removeItemFromCart(item);
System.out.println("The item: " + item + "has been removed.");
break;
case 0:
isRunning = false; // exit from the menu
break;
default:
System.out.println("Invalid input");
break;
}
}
private void displayMenu() {
System.out.println("\n Select:\n"
+ "[1] Buy item\n"
+ "[2] Put back\n"
+ "[0] Leave");
}
}
In this way, you can have multiple menus that are calling each other and at the end, the program finishes on its own, without wild return; or System.exit(0);
Edit: Added one more class for better insight.

Java For Loop data validation

I am currently doing some java excersises in uni and ive been stuck on this one for about 5 hours now! I am practising For loops and have the loop ask 5 times for a number from 1 to 3. When testing, if I enter an invalid selection it carries on and includes the invalid selection as a zero, I have got an error message working when an invalid input is entered but it still carries on until the loop finishes, I know there is a way to return to the beggining of the selection but I cant figure it out.
I have searched everywhere for a solution but cannot find it! I know it cant be much and I'm not back in uni for a few days so I cant ask the lecturer and I would really like to crack on to the next chapter.
Here is my code (I know its probably a bit scrappy!!), thanks, Rob
import java.util.Scanner;
/* this is s a survey of how 5 people sweeten thier coffee */
class coffee
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
int person, preference, nothing, sugar, sweetner;
String pluralone = "People dont";
String pluraltwo = "People use";
String pluralthree = "People use";
person = 0;
preference = 0;
nothing = 0;
sugar = 0;
sweetner = 0;
for (person = 1; person <= 5; person++)
{
System.out.println("How do you sweeten your coffee");
System.out.println("1. I Don't");
System.out.println("2. With Sweetner");
System.out.println("3. With Sugar");
preference = input.nextInt();
if (preference != 1 && preference != 2 && preference != 3)
System.out.println("Sorry that is not a valid option");
else if (preference == 1)
nothing++;
else if (preference == 1)
sweetner++;
else
sugar++;
}
System.out.println("Survey Report");
System.out.println("#############");
if (nothing < 2)
{
pluralone = "person doesnt";
}
System.out.println(nothing + " " + " " + pluralone + " sweeten thier coffee");
if (sweetner < 2)
{
pluraltwo = "person uses";
}
System.out.println(sweetner + " " + pluraltwo + " " + "sweetner to sweeten thier coffee");
if (sugar < 2)
{
pluralthree = "person uses";
}
System.out.println(sugar + " " + pluralthree + " " + "sugar to sweeten thier coffee ");
}
}
just ask for the users selection in a while loop so that it doesn't continue until a valid option has been entered, something like:
preference = input.nextInt();
while (preference != 1 && preference != 2 && preference != 3) {
System.out.println("Sorry that is not a valid option");
preference = input.nextInt();
}
alternatively you could decrement person in your if statement to cause another iteration of the for loop, but that's a bit hacky:
if (preference != 1 && preference != 2 && preference != 3) {
System.out.println("Sorry that is not a valid option");
person--;
}
If you change your for loop to this
for (person = 1; person <= 5; person ++)
{
System.out.println ("How do you sweeten your coffee");
System.out.println ("1. I Don't");
System.out.println ("2. With Sweetner");
System.out.println ("3. With Sugar");
preference = input.nextInt();
while(preference != 1 && preference != 2 && preference != 3) {
System.out.println ("Sorry that is not a valid option");
System.out.println ("How do you sweeten your coffee");
System.out.println ("1. I Don't");
System.out.println ("2. With Sweetner");
System.out.println ("3. With Sugar");
preference = input.nextInt();
}
if(preference == 1) {
nothing ++;
} else if(preference == 2) {
sweetner ++;
} else if(preference == 3) {
sugar ++;
}
}
This will fix it
Replace the if/else with an Switch/Case:
preference = input.nextInt();
switch(preference) {
case 1:
nothing++;
break;
case 2:
sweetner++;
break;
case 3:
sugar++;
break;
default:
System.out.println("Sorry, thats not a valid option! Please pick a valid option");
preference = input.nextInt();
person--;
break;
}
I did the while loop and it works, thank you very much Dan. While loops are the next part in the book that im moving onto so its given me a head start too. Many thanks to you and everyone else who replied, a couple of the other things suggested seem a little advanced for me but I know I can always refer to the comments if I need them in the future. Thanks again, Robin.

Issue with file processing

I'm a novice java programmer and I am having trouble with file output with my java project. In this project, I'm supposed to have a "Rock, Paper, Scissors" program which will output the results onto a separate file. When I run the program and then look at the file, it only records the most recent result instead of every one. Any advice on what to do would be great. Please excuse the poor form; I will clean it up later. I've also erased most of the comments in order to shorten it. Thanks.
import java.util.*;
import java.awt.*;
import java.io.*;
public class RockPaperScissors {
public static int count = 0;
public static void main(String[] args) {
execute();
}
public static void execute(){
System.out.println("This program will allow you to play \n\"Rock, Paper, Scissors\" against a computer.");
System.out.println();
System.out.println("Enter 'r' for Rock, 'p' for Paper, or s for Scissors.");
System.out.println("Enter 'w' to have an insta-win for that round. Enter '-1' at anytime to exit program.");
String info = userInput();
int value = guessCode();
decideOutcome(value, info);
again();
}
public static String userInput() {
Scanner console = new Scanner (System.in);
String s = console.next();
return s;
}
public static int guessCode() {
Random r = new Random ();
return (r.nextInt(3)+1); // Random integer between 1 and 3;
}
public static void decideOutcome(int i, String j) {
try {
PrintStream output = new PrintStream(new File ("records.txt"));
if (j.equalsIgnoreCase("rock")|| j.equalsIgnoreCase("r")) {
count++;
switch (i){
case 1:
System.out.println("You've won! Computer picked scissors.");
output.println(count + " Win ");
break;
case 2:
System.out.println("You've tied.... Computer also picked rock.");
output.println(count + " Tie ");
break;
case 3:
System.out.println("You've lost. Computer picked paper.");
output.println(count + " Loss ");
break;
}
} else if (j.equalsIgnoreCase("paper")|| j.equalsIgnoreCase("p")) {
count++;
switch (i){
case 1:
System.out.println("You've lost; Computer picked scissors.");
output.println(count + " Loss ");
break;
case 2:
System.out.println("You've won! Computer picked rock.");
output.println(count + " Win ");
break;
case 3:
System.out.println("You've tied.... Computer also picked paper.");
output.println(count + " Tie ");
break;
}
} else if (j.equalsIgnoreCase("scissors")|| j.equalsIgnoreCase("s")) {
count++;
switch (i){
case 1:
System.out.println("You've tied.... Computer picked scissors.");
output.println(count + " Tie ");
break;
case 2:
System.out.println("You've lost; Computer picked rock.");
output.println(count + " Loss ");
break;
case 3:
System.out.println("You've won! Computer also picked paper.");
output.println(count + " Win ");
break;
}
} else if (j.equalsIgnoreCase("w")) {
count++;
System.out.println("You've effortlessly defeated the computer!");
output.println(count + " Win ");
} else if (j.equals("-1")) {
System.out.println("Thanks for playing!"); // need to find way to reach end.
if (count == 1) { // If the user terminates after the first match.
System.out.println("You've played a single match.");
} else if (count > 1) { // Anything more than 1 match played upon termination.
System.out.println("You've played " + count + " matches total.");
} else { // This is for exceptions when user inputs gibberish for their sign and then 'no' for the second input.
System.out.println("No matches were played.");
}
System.out.println("Good Bye!");
System.exit(0);
} else {
System.out.println("You didn't input the right thing.");
}
} catch (FileNotFoundException e) {
System.out.println("File was not found; try again");
}
}
public static void again() {
System.out.println("Do you want to play again? (Type in 'y' for Yes or 'n' for No.)");
Scanner console2 = new Scanner (System.in);
String t = console2.next();
while (t.equalsIgnoreCase("yes")||t.equalsIgnoreCase("y")) {
System.out.println();
System.out.println();
execute(); //
}
if (t.equalsIgnoreCase("no") || t.equalsIgnoreCase("n") || t.equals("-1")) {
System.out.println("Hope you had fun! I'm sure I've had just as much fun with making this program! Good Bye!");
if (count == 1) { // If the user terminates after the first match.
System.out.println("You've played a single match.");
} else if (count > 1) { // Anything more than 1 match played upon termination.
System.out.println("You've played " + count + " matches total.");
} else { // This is for exceptions when user inputs gibberish for their sign and then 'no' for the second input.
System.out.println("No matches were played.");
}
System.exit(0);
} else { // If the user doesn't input 'yes' or 'no.'
System.out.println("Not the proper response, but it's assumed that you don't want to continue.");
if (count == 1) { // If the user terminates after the first match.
System.out.println("You've completed a single match.");
} else if (count >= 2) { // Anything more than 1 match played upon termination.
System.out.println("You've completed " + count + " matches total.");
} else { // The user haphazardly messes up both inputs.
System.out.println("No matches were finished.");
}
System.exit(0);
}
}
}
When you decideOutcome(), you reopen a PrintStream to the file each time.
But this constructor does not seek to the end of the file! Which means you overwrite the contents each time.
Try using a FileWriter instead, with the appropriate constructor.
Edit: since the assignment seems to require that you use a PrintStream (why?), you will have to do this instead:
PrintStream output = new PrintStream(new FileOutputStream("records.txt", true));
But in real life, you will probably use a BufferedWriter instead; pretty much nobody uses PrintStream.
The Printstream you are using starts writing to the file from the beginning and not from where the last line is.
It will be better to use Filewriter to work on files as it has append and insert modes.
What you need is the append mode.
You can never use a PrintStream to accomplish this task in the way you are doing it. The API clearly states that the constructor of the PrintStream does the following:
PrintStream(File file)
Creates a new print stream, without automatic line flushing, with the specified file.
file - The file to use as the destination of this print stream. If the
file exists, then it will be truncated to zero size; otherwise, a new file will be created. The output will be written to the file and is buffered.
There are no constructors that allow you to append to the previous file.
The solution therefore lies in the fact that you can only use the PrintStream constructor exactly ONCE. This can be achieved by making your output variable a class variable and getting rid of your declaration (as well as the try-catch) in decideOutcome().
private static PrintStream output;
public static void main(String[] args) {
try {
output = new PrintStream(new File("records.txt"));
execute();
} catch (FileNotFoundException e) {
System.out.println("File was not found; try again");
} finally {
output.close();
}
}
Another important thing to note is that whenevre you open a stream such as a Scanner or a PrintStream you should always close it. The best place to close them is in a finally clause as that part of your code is guaranteed to run.

Categories