Hi all,

I am in my first Java class at the local community college but my class is online and my teacher takes DAYS to respond via email. I need some help with my homework and thought I would try here. I'm not looking for someone to give me the answers, but push me in the right direction.

So the code I have written contains a Scanner. The Scanner does not have a problem accepting the first variable passed to it, but when I put the second variable into it, the program abruptly ends.

There is a menu of 3 items, each contains it's own item number, item name, and item price. The user is shown the menu and asked to choose an item. The menu is presented again for the user to choose another item. Once three items have been selected the user enters a 0 to get his total bill.

I have not learned loops yet, as that is the next chapter so I cannot use them for this assignment. What I really need to know is why can my Scanner not take multiple items and how can I work with it?

Thanks in advance, here's my code:

/*display menu of 3 items in a restaurant
  (1) Cheeseburger  4.99
  (2) Pepsi         2.00
  (3) Chips         0.75
  
  prompt user to choose item (1,2,or 3) or 0 to quit application.
  if first choice is 0, display $0., otherwise display menu again. 
  if user enters 0, display cost of 1 item.  If user types 1,2, or 3
  add cost to original item.  
*/

import java.util.Scanner;
public class FastFood_fix
{
    private static double foodTotal = 0.0;
	 private static int selection, selection2, selection3;
    private final static double CBURGER_PRICE = 4.99;
	 private final static double PEPSI_PRICE = 2.00;
	 private final static double CHIPS_PRICE = 0.75;
	 private final static String CBURGER_NAME = "Cheeseburger";
	 private final static String PEPSI_NAME = "Pepsi";
	 private final static String CHIPS_NAME = "Chips";
	 private final static int CBURGER_ITEM = 1;
	 private final static int PEPSI_ITEM = 2;
	 private final static int CHIPS_ITEM = 3;
	 private final static int REQUEST_TOTAL = 0;

  public static void main(String[] args)
  {
	 menu();
	 chooseYourItem();
	 chosenItem(selection, foodTotal);
  }
  	 public static void menu()
	 {
	   System.out.println("    FAST FOOD MENU\n(" + CBURGER_ITEM + ") " + CBURGER_NAME + 
		  "  " + CBURGER_PRICE + "\n(" + PEPSI_ITEM + ") " + PEPSI_NAME + "         " +
		  PEPSI_PRICE + "0\n(" + CHIPS_ITEM + ") " + CHIPS_NAME + "         " + CHIPS_PRICE);
	 }
    public static void chooseYourItem()
	 {
  	 Scanner input = new Scanner(System.in);
	 System.out.println("\nPlease choose an item from the menu above:" + "\n(Enter " + 
	   CBURGER_ITEM + " for a " + CBURGER_NAME + ", " + PEPSI_ITEM + " for a " + 
		PEPSI_NAME + ", or " + CHIPS_ITEM + " for " + CHIPS_NAME + ")" + 
		"\nTo receive your total, please enter a " + REQUEST_TOTAL);
	 selection = input.nextInt();
    }
	 public static void chosenItem(int selection, double total)
	 {  
		switch(selection)
	   {
	   case CBURGER_ITEM:
		  foodTotal = total + CBURGER_PRICE;
	     System.out.println(selection + " " + total + " " + foodTotal);
		  menu();
	     chooseYourItem();
		  break;
		case PEPSI_ITEM:
		  foodTotal = total + PEPSI_PRICE;
		  System.out.println(selection + " " + total + " " + foodTotal);
		  menu();
	     chooseYourItem();
		  break;
	   case CHIPS_ITEM:
		  foodTotal = total + CHIPS_PRICE;
		  System.out.println(selection + " " + total + " " + foodTotal);
		  menu();
	     chooseYourItem();
	     break;
		case REQUEST_TOTAL:
		  System.out.println("Your total comes to: $" + foodTotal + "0");	
		  break;
		default:
		  System.out.println("You have entered " + selection + ", an invalid code, please try again.");
	   }
	 }	 
}

You only call chosenItem() once. If you add

chosenItem(selection, foodTotal);

in the end of chooseYourItem() it should work. It's not very nice but if you dont want to work with loops just yet it should do the trick.

You only call chosenItem() once. If you add

chosenItem(selection, foodTotal);

in the end of chooseYourItem() it should work. It's not very nice but if you dont want to work with loops just yet it should do the trick.

Is something like this what you mean for each case?

switch(selection)
	   {
	   case CBURGER_ITEM:
             foodTotal = total + CBURGER_PRICE;
	     System.out.println(selection + " " + total + " " + foodTotal);
	     menu();
	     chooseYourItem();
	     chosenItem(selection, foodTotal);

Ok, I tried that and it ended up letting me add items to the tab, but the Scanner is still stuck on the first number I input. For example, if I put a 1, then a 2, then a 3, the Scanner's selection variable remains at a 1 and keeps adding a Cheeseburger for every time I choose another item.

Also, because of this, 0 will not end the program like it should.

So though your recommendation helped with a different area (that I really needed) it did not fix the scanner issue.

Any more thoughts? Thanks for your help!

Thats because you have two different 'selection' variables. One static global declared at the top and the local one in chosenItem(int selection, double total)

I wouldnt recommend this usually but since you are just starting off with programming and it would require substantial re-work of your code to make it "programmatically nice" you should try this

public static void chooseYourItem() {
		Scanner input = new Scanner(System.in);
		System.out.println("\nPlease choose an item from the menu above:"
				+ "\n(Enter " + CBURGER_ITEM + " for a " + CBURGER_NAME + ", "
				+ PEPSI_ITEM + " for a " + PEPSI_NAME + ", or " + CHIPS_ITEM
				+ " for " + CHIPS_NAME + ")"
				+ "\nTo receive your total, please enter a " + REQUEST_TOTAL);
		selection = input.nextInt();
		[B]chosenItem(selection, foodTotal);[/B]
	}

Edited 6 Years Ago by Slimmy: Fixed bold text

Slimmy,
thank you! That worked! I wanted to make sure I understand WHY it worked. It would make sense if this was the reason: (would you mind confirming it?)

When a variable receives a value inside of a method, and is then passed out of that method, the variable ceases to exist within the method it is passed from?

thanks again, sorry I didn't get it the first time!

When a variable receives a value inside of a method, and is then passed out of that method, the variable ceases to exist within the method it is passed from?

No that is not entirely correct. It has to do with the scope of variables. The scope of a variable is determined where it is defined. This simple example will hopefully explain it.

public class Scope {

	private int A = 1;

	public void foo() {
		int A = 2;
		System.out.println("A = " + A + " in foo()");
	}

	public void foo2(int A) {
		A = 3;
		System.out.println("A = " + A + " in foo2(int " + A + ")");
	}

	public void setA(int newA) {
		A = newA;
	}

	public int getA() {
		return A;
	}

	public static void main(String args[]) {
		Scope s = new Scope();
		s.foo();
		s.foo2(100);
		System.out.println("A = " + s.getA() + " after calling foo() and foo2()");
		s.setA(10);
		System.out.println("A = " + s.getA() + " after calling setA()");
	}

}

Briefly, there are three types of variables to keep track of, and they are static, instance, and local.

Static variables belong to a class: each has one value for all members of that class, and all members of that class have read and write access to them. If they have public access, then other classes can access them by class name: ClassName.variableName

Instance variables belong to an object: each instance of a class has its own copy of that variable, and that object has read/write access to it. If they have public access, then other objects which have a reference to that object can access them by reference name: ref.variable

Static and instance variables are declared at the class level, outside of any method body, and within the class definition's curly braces, preferably at the head of the file before any methods.

Local variables are declared within a method, and they belong to that method. They exist only as long as that method is executing, and no other object ever has access to them. You can pass their value to other objects via method calls, but other objects have no idea that they even exist, because usually they don't.


Shadowing:Local variables can shadow class-level variables, and they can shadow other local variables. Strictly speaking, a local variable exists only in a context, which is defined by a pair of curly braces defining a statement block. It is legal to use a variable name twice within a given source file, as long as both definitions are not declared within the same context, or statement block. If this happens, the compiler assumes that the most local version of this variable is what's meant: the most local variable of a given name "shadows" other variables with the same name.

This is a very quick statement of what you're seeing, and you should do a bit of reading up on these things. The Java Language Spec is probably a bit dense reading for a novice, but give it a try. Also try searching on terms like "java [static/instance/local] variable" and "java shadowing". Often a complex topic like this is best understood by reading a number of different explanations until they all add up to an insight, which you then test in a piece of junk code.

Slimmy, thanks for educating me on that! Great example in which I will refer back to often!

Jon, thank you for your explanation. Believe it or not I have read my textbook word for word and am on page 226 of 804. I have read over all of that but like you said, it is best to read many different explanations of the same topic to get a good insight. Testing ideas in junk code is my most frequent exercise. :) I call it "spinning my wheels." :)

The Java Language Spec is probably a bit dense reading for a novice, but give it a try. Also try searching on terms like "java [static/instance/local] variable" and "java shadowing". Often a complex topic like this is best understood by reading a number of different explanations until they all add up to an insight, which you then test in a piece of junk code.

Update: My teacher finally emailed me back (took 3 full days) and said that I was thinking too hard. I have updated my code to the following:

import java.util.Scanner;
public class FastFood
{
  public static void main(String[] args)
  {
    double foodTotal = 0.0;
    double item1 = 0.0;
    double item2 = 0.0;
    double item3 = 0.0;
	 
    item1 = order();
     
    if (item1 > 0)
      item2 = order();
      if (item2 > 0)
        item3 = order();
	 
   foodTotal = item1 + item2 + item3;
   System.out.println("The meal comes to " + foodTotal);
  }
  public static double order()
  {
    int selection;
	 System.out.println("(1) Cheeseburger 4.99");
	 System.out.println("(2) Pepsi        2.00");
	 System.out.println("(3) Chips        0.75");
	 
	 Scanner input = new Scanner(System.in);
	 
	 System.out.println("\nWhich item would you like to order?");
	 System.out.println("Press 0 to receive your total.");
	 selection = input.nextInt();
	 
	 if(selection == 1)
	   return 4.99;
		
	 else if (selection == 2)
	   return 2.00;
		
	 else if (selection == 3)
	   return 0.75;
	
	 else 
	   return 0;

The next part of the problem, we'll call it part 2, tells me to modify my code so that each item can be selected only once. If an item is selected twice, ignore the input and present the menu again. The user is still allowed only three entries.

I'm having a hard time figuring out the logic on this one, meaning where should I start? I thought of declaring a boolean variable "isValid" and setting it to false if the user has already selected one of the menu items. Besides that my mind is blank. I'll go back through the chapter and then come back to the forum to see if anyone has other ideas.

Oh I just had another idea, what if I put a counter in for how many selections the user has made? then it will end at three no matter if there are two "0"s entered or none. I'm still searching how to ignore the user selection if it has already been selected...

I thought of declaring a boolean variable "isValid" and setting it to false if the user has already selected one of the menu items.

Thats a good start, however you will need more than one variable to keep track of the three items. But start with your initial thought and implement it on one of the items. When you get that to work, expand your solution to work for all the items. Good Luck!

Edited 6 Years Ago by Slimmy: Aestethics

Ok, I think I got it. Please let me know if you would change anything or if this is considered "good programming" Obviously the shortest distance between point A and point B is a straight line, I'm looking for the straight line in programming. haha. :P

import java.util.Scanner;
public class FastFood2
{
  public static double check1 = 0.0;
  public static double check2 = 0.0;
  public static double check3 = 0.0;
  
  public static void main(String[] args)
  {
    double foodTotal = 0.0;
	 double item1 = 0.0;
	 double item2 = 0.0;
	 double item3 = 0.0;
	 
	 //
	 //boolean isValid = true;
	 
	 item1 = order();
	 if ((item1 > 0) && (check1 != 4.99) || (check2 != 2.00) || (check3 != 0.75))
	   item2 = order();
	 if ((item2 > 0) && (check1 != 4.99) || (check2 != 2.00) || (check3 != 0.75))
	   item3 = order();
	 
	 foodTotal = check1 + check2 + check3;
	 System.out.println("The meal comes to " + foodTotal);
	 System.out.println(check1 + " " + check2 + " " + check3);
  }
  public static double order()
  {
    int selection;
	 System.out.println("(1) Cheeseburger 4.99");
	 System.out.println("(2) Pepsi        2.00");
	 System.out.println("(3) Chips        0.75");
	 
	 Scanner input = new Scanner(System.in);
	 
	 System.out.println("\nWhich item would you like to order?");
	 System.out.println("Press 0 to receive your total.");
	 selection = input.nextInt();
	 
	 if(selection == 1)
	 {  
		check1 = 4.99;  
		return 4.99;
	 }	
	 else if (selection == 2)
	 { 
	   check2 = 2.00;
	   return 2.00;
	 }	
	 else if (selection == 3)
	 { 
	   check3 = 0.75;  
		return 0.75;
	 }
	 else 
	   return 0;
This question has already been answered. Start a new discussion instead.