I am very new to Java and I am trying to learn as best as I can.The actual question of the problem I am trying to solve is in the picture above. Please do refer to the picture in case I am not detailed enough in the description of my problem. I am currently writing a java program that has to do with buying coffee. I have a method that computes the cost of buying the coffee(BuyCoffee) and the amount of resources used. There are also different types of coffee, with each coffee using different amount of resources. I also have another method that computes the resources left after any coffee is sold**(getRemainingResources)**. I do have a problem looping my getRemainingResources method. So when I buy coffee once, the amount of resources I have reduces. I have a method to fill this resources. But everytime I try to buy the same coffee again, the amount of resources I have left does not reduce. My code is below
import java.util.Scanner;
public class MethodsTest {
//global variable--starting quantity of resources in machine
static final int water = 400;
static final int milk = 540;
static final int coffeeBean = 120; // in g
static int disposableCups = 9;
static final int cost = 550; //in $
//global variable --refill quantity of resources in machine
static int fillWater, fillMilk, fillCoffeeBeans, fillDisposableCups;
//global variable -- remaining quantity of resources in machine
static int newRemCost, remCost, remWater, remMilk, remCoffeeBean, remDisposableCups;
static int espressoWater, espressoMilk, espressoCoffeeBeans, espressoCost; // Resources for espresso
static int latteWater, latteMilk, latteCoffeeBeans, latteCost;
static int cappuccinoWater, cappuccinoMilk, cappuccinoCoffeeBeans, cappuccinoCost;
static int regWater, regMilk, regCoffeeBeans, regCost; //Resources for regular coffees
static void FillCoffeeMachine() {
Scanner input = new Scanner(System.in);
System.out.println("Write how many ml of water you want to add: ");
fillWater = input.nextInt();
System.out.println("Write how many ml of milk you want to add: ");
fillMilk = input.nextInt();
System.out.println("Write how many grams of coffee beans you want to add: ");
fillCoffeeBeans = input.nextInt();
System.out.println("Write how many disposable cups of coffee you want to add: ");
fillDisposableCups = input.nextInt();
MainMenu();
}
static void BuyCoffee() { //method for buying coffee
disposableCups--;// always decreasing when coffee is sold
class TypesOfCoffee {
void Espresso() { //nested class, since there are different kind of coffee
espressoWater = 250;
espressoMilk = 0;
espressoCoffeeBeans = 16;
espressoCost = 4;
if (remWater > espressoWater && remMilk > espressoMilk && remCoffeeBean > espressoCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < espressoWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remCoffeeBean < espressoCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
void Latte() {
latteWater = 350;
latteMilk = 75;
latteCoffeeBeans = 20;
latteCost = 7;
if (remWater > latteWater && remMilk > latteMilk && remCoffeeBean > latteCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < latteWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remMilk < latteMilk) {
System.out.println("Sorry, not enough milk!");
disposableCups ;
} else if (remCoffeeBean < latteCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
void Cappuccino() {
cappuccinoWater = 200;
cappuccinoMilk = 100;
cappuccinoCoffeeBeans = 12;
cappuccinoCost = 6;
if (remWater > cappuccinoWater && remMilk > cappuccinoMilk && remCoffeeBean > cappuccinoCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < cappuccinoWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remMilk < cappuccinoMilk) {
System.out.println("Sorry, not enough milk!");
disposableCups ;
} else if (remCoffeeBean < cappuccinoCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
void regularCoffee() {
regWater = 200;
regMilk = 50;
regCoffeeBeans = 15;
regCost = 0;
if (remWater > regWater && remMilk > regMilk && remCoffeeBean > regCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < regWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remMilk < regMilk) {
System.out.println("Sorry, not enough milk!");
disposableCups ;
} else if (remCoffeeBean < regCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
}
Scanner input = new Scanner(System.in);
System.out.println("What kind of coffee would you like to buy today?");
System.out.println("""
Please enter:
1 for espresso
2 for latte
3 for cappuccino
4 for a regular coffee
back - to go back to main menu""");
String choice = input.next();
switch (choice) { //lets user choose what type of coffee to buy
case "1":
new TypesOfCoffee().Espresso();
break;
case "2":
new TypesOfCoffee().Latte();
break;
case "3":
new TypesOfCoffee().Cappuccino();
break;
case "4":
new TypesOfCoffee().regularCoffee();
break;
case "back":
MainMenu();
break;
default:
System.out.println("Please enter an option from the above");
}
MainMenu();
}
static void takeMoney() { //method to take the money
System.out.println("I gave you" " " "$" remCost);
newRemCost = remCost;
MainMenu();
}
static void getRemainingResources() {
//TODO --has to loop..but it works only once
remDisposableCups = fillDisposableCups disposableCups;
boolean found = remDisposableCups > 0; // true for coffee to be sold
while (found) {
remWater = water fillWater - espressoWater - cappuccinoWater - latteWater;//
remMilk = milk fillMilk - espressoMilk - cappuccinoMilk - latteMilk;
remCoffeeBean = coffeeBean fillCoffeeBeans - espressoCoffeeBeans - cappuccinoCoffeeBeans - latteCoffeeBeans;
remCost = cost espressoCost cappuccinoCost latteCost - newRemCost;
//found = remDisposableCups > 0 && remWater>=water && remMilk>=milk&&remCoffeeBean>=coffeeBean;
System.out.println("The coffee machine has: ");
System.out.println(remWater " " "ml of water");
System.out.println(remMilk " " "ml of milk ");
System.out.println(remCoffeeBean " " "g of coffee beans ");
System.out.println(remDisposableCups " " "disposable cups ");
System.out.println("$" remCost " " "of money");
found = remDisposableCups < 0;
}
MainMenu();
}
static void MainMenu() { // Gives user option to decide what they want to do
Scanner input = new Scanner(System.in);
System.out.println("Main Menu: " "\n");
System.out.println("Please choose from the following options below");
System.out.println("""
To buy coffee - Enter buy
To fill the machine - Enter fill
To get cash from machine - Enter take
To see remaining resources - Enter remaining
To exit program - Enter exit""");
String choice = input.next();
switch (choice) {
case "buy":
BuyCoffee();
break;
case "fill":
FillCoffeeMachine();
break;
case "take":
takeMoney();
break;
case "remaining":
getRemainingResources();
break;
case "exit":
System.exit(0);
break;
default:
MainMenu();//goes back to main menu if user types in an unknown value
}
}
public static void main(String[] args) {
MainMenu();
}
}
CodePudding user response:
It should go now But there are other errors (besides the scanner, which they have already told you about) For example, you can't buy coffee without "remaining" first (and also: too many static variables, OO not used ...). This is just one example. I corrected the code for the error you asked for, but there would be a lot to change.
import java.util.Scanner;
public class MethodsTest {
//global variable--starting quantity of resources in machine
static final int water = 40000;
static final int milk = 54000;
static final int coffeeBean = 12000; // in g
static int disposableCups = 900;
static final int cost = 550; //in $
static int remCost = 550; //in $
//global variable --refill quantity of resources in machine
static int fillWater, fillMilk, fillCoffeeBeans, fillDisposableCups;
//global variable -- remaining quantity of resources in machine
static int newRemCost, remWater, remMilk, remCoffeeBean, remDisposableCups;
static int espressoWater, espressoMilk, espressoCoffeeBeans, espressoCost; // Resources for espresso
static int latteWater, latteMilk, latteCoffeeBeans, latteCost;
static int cappuccinoWater, cappuccinoMilk, cappuccinoCoffeeBeans, cappuccinoCost;
static int regWater, regMilk, regCoffeeBeans, regCost; //Resources for regular coffees
static void FillCoffeeMachine() {
Scanner input = new Scanner(System.in);
System.out.println("Write how many ml of water you want to add: ");
fillWater = input.nextInt();
System.out.println("Write how many ml of milk you want to add: ");
fillMilk = input.nextInt();
System.out.println("Write how many grams of coffee beans you want to add: ");
fillCoffeeBeans = input.nextInt();
System.out.println("Write how many disposable cups of coffee you want to add: ");
fillDisposableCups = input.nextInt();
MainMenu();
}
static void BuyCoffee() { //method for buying coffee
disposableCups--;// always decreasing when coffee is sold
class TypesOfCoffee {
void Espresso() { //nested class, since there are different kind of coffee
espressoWater = 250;
espressoMilk = 0;
espressoCoffeeBeans = 16;
espressoCost = 4;
if (remWater > espressoWater && remMilk > espressoMilk && remCoffeeBean > espressoCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < espressoWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remCoffeeBean < espressoCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
void Latte() {
latteWater = 350;
latteMilk = 75;
latteCoffeeBeans = 20;
latteCost = 7;
if (remWater > latteWater && remMilk > latteMilk && remCoffeeBean > latteCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < latteWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remMilk < latteMilk) {
System.out.println("Sorry, not enough milk!");
disposableCups ;
} else if (remCoffeeBean < latteCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
void Cappuccino() {
cappuccinoWater = 200;
cappuccinoMilk = 100;
cappuccinoCoffeeBeans = 12;
cappuccinoCost = 6;
if (remWater > cappuccinoWater && remMilk > cappuccinoMilk && remCoffeeBean > cappuccinoCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < cappuccinoWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remMilk < cappuccinoMilk) {
System.out.println("Sorry, not enough milk!");
disposableCups ;
} else if (remCoffeeBean < cappuccinoCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
void regularCoffee() {
regWater = 200;
regMilk = 50;
regCoffeeBeans = 15;
regCost = 0;
if (remWater > regWater && remMilk > regMilk && remCoffeeBean > regCoffeeBeans) {
System.out.println("I have enough resources, making you a coffee!");
} else if (remWater < regWater) {
System.out.println("Sorry, not enough water!");
disposableCups ;
} else if (remMilk < regMilk) {
System.out.println("Sorry, not enough milk!");
disposableCups ;
} else if (remCoffeeBean < regCoffeeBeans) {
System.out.println("Sorry, not enough coffee beans!");
disposableCups ;
} else
disposableCups ;
}
}
Scanner input = new Scanner(System.in);
System.out.println("What kind of coffee would you like to buy today?");
System.out.println("""
Please enter:
1 for espresso
2 for latte
3 for cappuccino
4 for a regular coffee
back - to go back to main menu""");
String choice = input.next();
switch (choice) { //lets user choose what type of coffee to buy
case "1":
new TypesOfCoffee().Espresso();
break;
case "2":
new TypesOfCoffee().Latte();
break;
case "3":
new TypesOfCoffee().Cappuccino();
break;
case "4":
new TypesOfCoffee().regularCoffee();
break;
case "back":
MainMenu();
break;
default:
System.out.println("Please enter an option from the above");
}
MainMenu();
}
static void takeMoney() { //method to take the money
System.out.println("I gave you" " " "$" remCost);
newRemCost = remCost;
MainMenu();
}
static void getRemainingResources() {
//TODO --has to loop..but it works only once
remDisposableCups = fillDisposableCups disposableCups;
boolean found = remDisposableCups > 0; // true for coffee to be sold
while (found) {
remWater = water fillWater - espressoWater - cappuccinoWater - latteWater;//
remMilk = milk fillMilk - espressoMilk - cappuccinoMilk - latteMilk;
remCoffeeBean = coffeeBean fillCoffeeBeans - espressoCoffeeBeans - cappuccinoCoffeeBeans - latteCoffeeBeans;
remCost = remCost espressoCost cappuccinoCost latteCost - newRemCost;
espressoCost = 0;
cappuccinoCost = 0;
latteCost = 0;
//found = remDisposableCups > 0 && remWater>=water && remMilk>=milk&&remCoffeeBean>=coffeeBean;
System.out.println("The coffee machine has: ");
System.out.println(remWater " " "ml of water");
System.out.println(remMilk " " "ml of milk ");
System.out.println(remCoffeeBean " " "g of coffee beans ");
System.out.println(remDisposableCups " " "disposable cups ");
System.out.println("$" remCost " " "of money");
found = remDisposableCups < 0;
}
MainMenu();
}
static void MainMenu() { // Gives user option to decide what they want to do
Scanner input = new Scanner(System.in);
System.out.println("Main Menu: " "\n");
System.out.println("Please choose from the following options below");
System.out.println("""
To buy coffee - Enter buy
To fill the machine - Enter fill
To get cash from machine - Enter take
To see remaining resources - Enter remaining
To exit program - Enter exit""");
String choice = input.next();
switch (choice) {
case "buy":
BuyCoffee();
break;
case "fill":
FillCoffeeMachine();
break;
case "take":
takeMoney();
break;
case "remaining":
getRemainingResources();
break;
case "exit":
System.exit(0);
break;
default:
MainMenu();//goes back to main menu if user types in an unknown value
}
}
public static void main(String[] args) {
MainMenu();
}
}
CodePudding user response:
The code you wrote is extremely complicated and that's why you cannot see where the errors are. A couple of comments:
- Java is an object oriented (OO) language. The OO paradigm revolves around creating classes and objects of them, inheritance and polymorphism (inheriting behavior from parent classes but behaving differently in each subclass).
- Your code looks like you are trying to recreate structural programming like an old version of Basic or Macro Assembler, just by complying with the syntax of Java. You need to really understand how OO programming works, so first try and find some tutorial about that.
- Don't implement everything in one big class. Try and identify the distinct entities in your application. For example: CoffeMachine, Coffee, Espresso, Latte, RegularCoffee, ... Create a class for each identified entity. The classes that resemble each other should probably be part of an inheritance, for example Espresso, Lattte, etc. should inherit a more generic class Coffee (A inherits B when you could say "A is a kind of B").
- Don't use static variables (unless there is a very good reason for that, but this is very rare). Let each class has its own instance properties when you create objects of them: remainingWater, remainingMilk, etc. are properties of the object CoffeeMachine. They are not global things.
- Don't use static methods like subroutines in C or Basic. Instead, create objects of your classes and call their instance methods.
- Don't use jumps and labels like in Basic or Assembler. Instead, call objects' methods in a loop and break the loop when necessary.
- If you detect an error in the application, make use of the Exception mechanism of Java - throw the exception and let the caller process the error.
- Method names start with a small letter in Java (it's a generally accepted convention, not a syntactic rule).
I created a different design for your application honoring the above principles, so first learn the basics of object oriented programming from a tutorial and then compare the following code with yours to see what is different.
Main class (entry point to the main menu loop):
public class Main
{
public static void main(String[] args)
{
new Main().run();
}
void run()
{
CoffeeMachine coffeeMachine = new CoffeeMachine(400, 540, 120, 9, 550);
while (coffeeMachine.mainMenu()); // loops until mainMenu returns false
}
}
CoffeeMachine:
import java.util.Scanner;
public class CoffeeMachine
{
private Scanner input = new Scanner(System.in);
private int water;
private int milk;
private int coffeeBeans;
private int disposableCups;
private int money;
public CoffeeMachine(int water, int milk, int coffeeBeans, int disposableCups, int money)
{
this.water = water;
this.milk = milk;
this.coffeeBeans = coffeeBeans;
this.disposableCups = disposableCups;
this.money = money;
}
void fill() {
System.out.println("Write how many ml of water you want to add: ");
water = input.nextInt();
System.out.println("Write how many ml of milk you want to add: ");
milk = input.nextInt();
System.out.println("Write how many grams of coffee beans you want to add: ");
coffeeBeans = input.nextInt();
System.out.println("Write how many disposable cups for coffee you want to add: ");
disposableCups = input.nextInt();
}
public void selectCoffee()
{
while (true)
{
System.out.println("What kind of coffee would you like to buy today?");
System.out.println(
" Please enter:\n"
" 1 for espresso\n"
" 2 for latte\n"
" 3 for cappuccino\n"
" 4 for a regular coffee\n"
" back - to go back to main menu");
String choice = input.next();
try {
switch (choice) { //lets user choose what type of coffee to buy
case "1":
buy(new Espresso());
return;
case "2":
buy(new Latte());
return;
case "3":
buy(new Cappuccino());
return;
case "4":
buy(new RegularCoffee());
return;
case "back":
return;
default:
System.err.println("Please enter an option from the above");
}
}
catch (InsufficientResourcesException exception) {
System.err.println("Error buying coffee: " exception.getLocalizedMessage());
}
}
}
public void buy(Coffee coffee) throws InsufficientResourcesException
{
if (coffee.getWaterCost() > water)
throw new InsufficientResourcesException("water", "ml", coffee.getWaterCost(), water);
if (coffee.getMilkCost() > milk)
throw new InsufficientResourcesException("milk", "ml", coffee.getMilkCost(), milk);
if (coffee.getCoffeeBeansCost() > coffeeBeans)
throw new InsufficientResourcesException("coffee beans", "g", coffee.getCoffeeBeansCost(), coffeeBeans);
if (disposableCups < 1)
throw new InsufficientResourcesException("disposable cups", "units", 1, disposableCups);
System.out.println("Buying 1 cup of " coffee.getClass().getSimpleName());
water -= coffee.getWaterCost();
milk -= coffee.getMilkCost();
coffeeBeans -= coffee.getCoffeeBeansCost();
disposableCups--;
money = coffee.getMoneyCost();
}
public void takeMoney()
{
System.out.println("I gave you $" money ". The money tray is now empty.");
money = 0;
}
public void showResources()
{
System.out.println("The coffee machine has: ");
System.out.println(water " ml of water");
System.out.println(milk " ml of milk ");
System.out.println(coffeeBeans " g of coffee beans ");
System.out.println(disposableCups " disposable cups ");
System.out.println("$" money " of money");
}
public boolean mainMenu() { // Gives user option to decide what they want to do
System.out.println("Main Menu: " "\n");
System.out.println("Please choose from the following options below");
System.out.println(
" To buy coffee - Enter buy\n"
" To fill the machine - Enter fill\n"
" To get cash from machine - Enter take\n"
" To see remaining resources - Enter remaining\n"
" To exit program - Enter exit");
String choice = input.next();
switch (choice) {
case "buy":
selectCoffee();
break;
case "fill":
fill();
break;
case "take":
takeMoney();
break;
case "remaining":
showResources();
break;
case "exit":
return false;
}
return true;
}
}
And the Coffee classes:
public abstract class Coffee
{
private int waterCost;
private int milkCost;
private int coffeeBeansCost;
private int moneyCost;
protected Coffee(int waterCost, int milkCost, int coffeeBeansCost, int moneyCost)
{
this.waterCost = waterCost;
this.milkCost = milkCost;
this.coffeeBeansCost = coffeeBeansCost;
this.moneyCost = moneyCost;
}
public int getWaterCost()
{
return this.waterCost;
}
public int getMilkCost()
{
return this.milkCost;
}
public int getCoffeeBeansCost()
{
return this.coffeeBeansCost;
}
public int getMoneyCost()
{
return this.moneyCost;
}
}
public class Espresso extends Coffee
{
public Espresso()
{
super(250, 0, 16, 4);
}
}
public class Cappuccino extends Coffee
{
public Cappuccino()
{
super(200, 100, 12, 6);
}
}
public class Latte extends Coffee
{
public Latte()
{
super(350, 75, 20, 7);
}
}
public class RegularCoffee extends Coffee
{
public RegularCoffee()
{
super(200, 50, 15, 0);
}
}
Last but not least, the exception class:
public class InsufficientResourcesException extends Exception
{
private static final long serialVersionUID = 1L;
public InsufficientResourcesException(String whatResource, String unit, int required, int available)
{
super("Insufficient resources: required " required " " unit " of " whatResource " but available " available " " unit);
}
}
Having a good architecture is most important in software. If your architecture is correctly applied, errors would be improbable and if they ocurred they would be easy to fix. Also, changing an application with good architecture is easy and safe.
Bad architecture on the other hand makes errors almost certain, hard to find and fix and the app cannot be easily changed.