I have a problem in a Java coding problem, and I could use a little bit of help in understanding the thought process of a condition mentioned in the problem (highlighted below).
The goal of this question is to design a cash register program. Your register currently has the following notes/coins within it:
One Pence: .01
Two Pence: .02
Five Pence: .05
Ten Pence: .10
Twenty Pence: .20
Fifty Pence: .50
One Pound: 1
Two Pounds: 2
Five Pounds: 5
Ten Pounds: 10
Twenty Pounds: 20
Fifty Pounds: 50
The aim of the program is to calculate the change that has to be returned to the customer with the least number of coins/notes. Note that the expectation is to have an object-oriented solution - think about creating classes for better reusability.
Now there is a similar post for this question on this platform, but I want to know how to use classes in this problem instead of hardcoding the denominations? I would highly appreciate if anyone can shed some light on it! I have written the following code for this, any help on changing this according to the condition above will be appreciated:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.io.*;
public class Main {
/**
* Iterate through each line of input.
*/
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(reader);
try {
double purchasePrice = Double.parseDouble(in.readLine());
double cash = Double.parseDouble(in.readLine());
Main.calculateChange(purchasePrice, cash);
} catch (Exception e) {
System.out.println(e);
}
}
public static void calculateChange(double purchasePrice, double cash) {
float cashBack = (float) (cash - purchasePrice);
if (cashBack < 0) {
System.out.println("ERROR");
return ;
}
else if (cashBack == 0){
System.out.println(0);
}
StringBuilder change = new StringBuilder();
while (cashBack > 0.01) {
if (cashBack >= 50.0) {
change.append("Fifty Pounds");
cashBack -= 50.0;
} else if (cashBack >= 20.0) {
change.append("Twenty Pounds");
cashBack -= 20.0;
} else if (cashBack >= 10.0) {
change.append("Ten Pounds");
cashBack -= 10.0;
} else if (cashBack >= 5.0) {
change.append("Five Pounds");
cashBack -= 5.0;
} else if (cashBack >= 2.0) {
change.append("Two Pounds");
cashBack -= 2.0;
} else if (cashBack >= 1.0) {
change.append("One Pound");
cashBack -= 1.0;
} else if (cashBack >= 0.5) {
change.append("Fifty Pence");
cashBack -= 0.5;
} else if (cashBack >= 0.20) {
change.append("Twenty Pence");
cashBack -= 0.20;
} else if (cashBack >= 0.1) {
change.append("Ten Pence");
cashBack -= 0.1;
} else if (cashBack >= 0.05) {
change.append("Five Pence");
cashBack -= 0.05;
} else if (cashBack >= 0.02) {
change.append("Two Pence");
cashBack -= 0.02;
} else {
change.append("One Pence");
cashBack -= 0.01;
}
change.append(", ");
}
change.setLength(change.length() - 2);
System.out.println(change.toString());
// Access your code here. Feel free to create other classes as required
}
}
Complete solution is here:
Coin class: Holds a coin value and its name.
public class Coin {
double value;
String name;
public Coin(double value, String name) {
this.value = value;
this.name = name;
}
public double getValue() {
return value;
}
public String getName() {
return name;
}
}
Cash Register class: This holds different types of coins in descending order.
public class CashRegister {
LinkedHashSet<Coin> coins = new LinkedHashSet<>();
public String calculateChange(double purchasePrice, double cash) {
double cashBack = cash - purchasePrice;
if (cashBack < 0) {
System.out.println("ERROR");
return "";
}
StringBuilder change = new StringBuilder();
while (cashBack > 0) {
Iterator<Coin> iterator = coins.iterator();
while (iterator.hasNext()) {
Coin coin = iterator.next();
int count = 0;
while (cashBack >= coin.getValue()) {
count++;
cashBack -= coin.getValue();
}
if (count > 0) {
change.append(count).append(" " + coin.getName());
change.append("\n");
}
}
}
return change.toString();
}
public LinkedHashSet<Coin> init() {
coins.add(new Coin(50, "Fifty Pound"));
coins.add(new Coin(20, "Twenty Pound"));
coins.add(new Coin(10, "Ten Pound"));
coins.add(new Coin(5, "Five Pound"));
coins.add(new Coin(2, "Two Pound"));
coins.add(new Coin(1, "One Pound"));
coins.add(new Coin(0.5, "Fifty Pence"));
coins.add(new Coin(0.2, "Twenty Pence"));
coins.add(new Coin(0.1, "Ten Pence"));
coins.add(new Coin(0.05, "Five Pence"));
coins.add(new Coin(0.02, "Two Pence"));
coins.add(new Coin(0.01, "One Pence"));
return coins;
}
}
Instantiation and invocation of the cash register to get change:
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(reader);
try {
// Initialise cash register.
CashRegister cashRegister = new CashRegister();
cashRegister.init();
double purchasePrice = Double.parseDouble(in.readLine());
double cash = Double.parseDouble(in.readLine());
// Calculate change.
String result = cashRegister.calculateChange(purchasePrice, cash);
System.out.println(result);
} catch (Exception e) {
System.out.println(e);
}
}
Any denominations of coins can be added in Cash register via the init() method. You can also add a lot of other features to Cash register like
Maintain a balance.
Support to add new denominations dynamically.
Support to remove denomination dynamically.
Related
I just tried to get an integer value from the user for a variable in another a method that created differently from main but it gives an error message like this:
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:941)
at java.base/java.util.Scanner.next(Scanner.java:1598)
at java.base/java.util.Scanner.nextInt(Scanner.java:2263)
at java.base/java.util.Scanner.nextInt(Scanner.java:2217)
at StoreUsingArrays_20210808043.menu(StoreUsingArrays_20210808043.java:14)
at StoreUsingArrays_20210808043.storeRun(StoreUsingArrays_20210808043.java:57)
at StoreUsingArrays_20210808043.main(StoreUsingArrays_20210808043.java:90)
Code:
import java.util.Arrays;
import java.util.Scanner;
public class StoreUsingArrays_20210808043 {
public static int menu(String[] items,double[] prices,int answer) {
Scanner input = new Scanner(System.in);
for (int i = 1;i <= items.length;i++) {
System.out.println(i+" - for "+items[i-1]+" ("+prices[i-1]+")");
}
System.out.println("0 - to checkout");
System.out.print("Please enter what would you like : ");
answer = input.nextInt();
System.out.println("Your choice was : "+answer);
input.close();
return answer;
}
public static void returnedAmounts(double amount) {
double bill200,bill100,bill50,bill20,bill10,bill5,bill1,coin50,coin25,coin10,coin1;
bill200 = (amount - (amount%200)) / 200;
amount = amount%200;
bill100 = (amount - (amount%100)) / 100;
amount = amount%100;
bill50 = (amount - (amount%50)) / 50;
amount = amount%50;
bill20 = (amount - (amount%20)) / 20;
amount = amount%20;
bill10 = (amount - (amount%10)) / 10;
amount = amount%10;
bill5 = (amount -(amount%5)) / 5;
amount = amount%5;
bill1 = (amount - (amount%1)) / 1;
amount = amount%1;
coin50 = (amount - (amount%0.50)) / 0.50;
amount = amount%0.50;
coin25 = (amount - (amount%0.25)) / 0.25;
amount = amount%0.25;
coin10 = (amount - (amount%0.10)) / 0.10;
amount = amount%0.10;
coin1 = (amount - (amount%0.01)) / 0.01;
double[] returnedNumbers = {bill200,bill100,bill50,bill20,bill10,bill5,bill1,coin50,coin25,coin10,coin1};
double[] returnedValues = {200,100,50,20,10,5,1,0.50,0.25,0.10,0.01};
for (int i = 0;i < returnedNumbers.length;i++) {
if ((returnedNumbers[i] > 0) && (returnedValues[i] > 0)) {
System.out.println((int)returnedNumbers[i]+" - "+returnedValues[i]);
}
}
}
public static void storeRun(String[] item,int[] quantity,double[] price) {
Scanner input = new Scanner(System.in);
capitalizeArray(item);
int choice,req = 0;
while (true) {
choice = menu(item, price, 0);
if (choice == 0) break;
else if (choice > item.length && choice < 0) {
System.out.println("ERROR:Invalid choice");
break;
}
else {
System.out.println("How many "+item[choice-1]+" would you like? ");
if (input.hasNextInt()) req = input.nextInt();
System.out.println(req);
}
}
input.close();
}
public static String capitalizeString(String text) {
return text.substring(0, 1).toUpperCase() + text.substring(1).toLowerCase();
}
public static String[] capitalizeArray(String[] name) {
for (int i = 0;i < name.length;i++) {
name[i] = capitalizeString(name[i]);
}
return name;
}
public static void main(String[] args) {
String[] item = {"bRead","cOLA","ROLL","BaKe"};
double[] price = {4,2,6,5};
int[] quantity = {10,25,17,22};
//capitalizeArray(item);
//System.out.println(Arrays.toString(item));
//menu(item, price, 0);
storeRun(item, quantity, price);
//returnedAmounts(167.5);
}
}
I expected to get a value for the req variable from user and use it for another purposes but I tried a lot of things like that:
Initializing the variable at the begin.
Removing the input.close() line.
(etc.)
But all of them didn't work.
Replace all input.close() by input.reset()
In method menu, replace answer = input.nextInt(); by if (input.hasNextInt()) answer = input.nextInt();
and it should work
I am having a tough time understanding the mistake. The mistake is somewhere in the object making or using. VS code is showing me calIncom cannot be resolved to a typeJava(16777218)
import java.util.Scanner;
class incomtax {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int salary;
System.out.println("Give the salary");
salary = sc.nextInt();
calIncom obj = new calIncom();
obj(salary);
}
public void calIncom(int a) {
if (a <= 50000) {
System.out.println("No incom tax");
}
else if (a <= 60000 && a > 50000) {
System.out.println("Your incom tax is: " + a / 10);
} else if (a <= 150000 && a > 60000) {
System.out.println("Your incom tax is: " + a / 20);
} else if (a >= 150000) {
System.out.println("Your incom tax is: " + a / 30);
}
}
}
That's not possible in Java. Methods are not classes.
You have to create an instance of the incomtax class
incomtax obj = new incomtax();
obj.calIncom(salary);
When I run the program everything works fine until I get to the last line where I want to to multiply the price of gas depending on the type, however that part does not print out.
{
public static void main(String[] args)
{
double R = 2.19;
double M = 2.49;
double P = 2.71;
System.out.println("What type of gas?");
System.out.println("(R)egular: 2.19");
System.out.println("(M)idgrade: 2.49");
System.out.println("(P)remium: 2.71");
String gastype;
gastype = S.nextLine();
System.out.println("How many gallons?");
double gallons;
gallons = S.nextDouble();
if ((R * gallons) == 0)
{
System.out.println("You owe: " +R * gallons+ "");
}
if ((M * gallons) == 0)
{
System.out.println("You owe: " +M * gallons+ "");
}
if ((P * gallons) == 0)
{
System.out.println("You owe: " +P * gallons+ "");
}
}
}
For your code snippet to print total price, it should be something like:
double total;
// check for user input of "gas type"
// calculate total = gas type * gallons
if (gasType.equals("R")) {
total = R * gallons;
} else if (gasType.equals("M")) {
total = M * gallons;
} else if (gasType.equals("P")) {
total = P * gallons;
} else {
System.out.println("Invalid type of gas");
return;
}
System.out.println("You owe: %f", total);
Use this
public static void main(String[] args) {
double R = 2.19;
double M = 2.49;
double P = 2.71;
System.out.println("What type of gas?");
System.out.println("(R)egular: 2.19");
System.out.println("(M)idgrade: 2.49");
System.out.println("(P)remium: 2.71");
String gastype;
gastype = S.nextLine();
System.out.println("How many gallons?");
double gallons;
gallons = S.nextDouble();
if ((gasType == 'R') {
System.out.println("You owe: " +R * gallons+ "");
}
else if (gasType == 'M') {
System.out.println("You owe: " +M * gallons+ "");
}
else if (gasType == 'P') {
System.out.println("You owe: " +P * gallons+ "");
}
else {
System.out.println("Wrong GasType")
}
}
Your if statements will only execute if gallons = 0. Not only that, but you aren’t checking to see which gas the customer wanted. You’re essentially ignoring the gastype altogether for your final answer.
Try this if statement as an example
if (gasType.equals(“Regular”) {
//Stuff you want to print
}
So for yet ANOTHER project I am doing an RPG code. Like Dungeons and dragons. My particular problem is the attributes. Basically the application gives statistics to the player and then, in case the player does not like the stats they have recieved, the application gives them the option to reroll. The first roll does fine, however, if the user chooses to reroll, the stats (both the first and the next) add on to each other. Here is my code:
The Main Method:
package bagOfHolding;
public class Advanced {
public static void main(String [] args){
GameMaster.game();
}
}
The Dice Class (this rolls the stats for the statistics):
package bagOfHolding;
import java.util.Random;
public class DiceBag {
private static int sum;
public static int rollD6() {
int[] Dice = new int[3];
Random num = new Random();
for (int i = 0; i < Dice.length; i++) {
Dice[i] = num.nextInt((6)) + 1;
}
for (int i : Dice) {
sum += i;
}
return sum;
}
// public static int getSum() {
// return sum;
// }
// public static void setSum(int sum) {
// DiceBag.sum = sum;
// }
}
The Game Master (This does the whole game):
package bagOfHolding;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class GameMaster {
public static void game() {
Hero.attributes();
}
public static void ReRoll() {
BufferedReader delta = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Would you like to reroll your hero? 1) Yes or 2) No");
System.out.println("Please enter a number");
System.out.println("Any number other than 1 or 2 will exit the application");
try {
String userInput = delta.readLine();
int input = Integer.parseInt(userInput);
if (input == 1) {
Hero.setStrength(DiceBag.rollD6());
Hero.setDexterity(DiceBag.rollD6());
Hero.setIntelligence(DiceBag.rollD6());
Hero.attributes();
} else if (input == 2) {
System.exit(0);
} else {
System.exit(0);
}
} catch (NumberFormatException NFE) {
System.out.println("Invalid");
} catch (IOException IOE) {
System.out.println("Invalid");
}
}
}
And the Hero class (this has all the statistics):
package bagOfHolding;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Hero {
/*
* Attributes - Randomly determined by 3d6
*
*/
/*
* -3 attributes - Strength - Damage bonus - If over 15 every pt = +1 (_++;)
* - Negative Damage Bonus - If under 10 every pt = -1 (_--;) - Dexterity
* -Strike bonus - every 2 pts over 14 = (_%2 + 1) - Negative Strike bonus -
* every 2 pts below 10 = (_%2 -1) - Dodge bonus - every 2 pts over 15 =
* (_%2 + 1) - Negative dodge bonus - every 2 pts below 11 = (_%2 -1) -
* Intelligence -Spell Strength Bonus - every pt over 15 = (++2) - Negative
* Spell Strength Bonus - every pt below 11 = (--2)
*
* Base Attributes - Health -Strength * 10 - MP - Intelligence *5
*/
private static int strength = DiceBag.rollD6();
private static int intelligence = DiceBag.rollD6();
private static int dexterity = DiceBag.rollD6();
public static int getIntelligence() {
return intelligence;
}
public static void setIntelligence(int intelligence) {
Hero.intelligence = intelligence;
}
public static int getDexterity() {
return dexterity;
}
public static void setDexterity(int dexterity) {
Hero.dexterity = dexterity;
}
public static int getStrength() {
return strength;
}
public static void setStrength(int strength) {
Hero.strength = strength;
}
public static void attributes() {
strength = getStrength();
System.out.println("Here is your hero: ");
// DiceBag.rollD6();
System.out.println("Strength = " + strength);
if (strength > 15) {
System.out.println("Damage Bonus = " + "+" + (strength - 15));
} else if (strength < 10) {
System.out.println("Negative Damage Bonus = " + "-" + (10 - strength));
} else {
System.out.println("You do not have damage bonus");
}
intelligence = getIntelligence();
System.out.println("Intelligence = " + intelligence);
if (intelligence > 15) {
System.out.println("Spell Strength Bonus = " + "+" + ((intelligence - 15) * 2));
} else if (strength < 11) {
System.out.println("Negative Spell Strength Bonus = " + "-" + ((11 - intelligence) * 2));
} else {
System.out.println("You do not have a spell strength bonus");
}
dexterity = getDexterity();
System.out.println("Dexterity = " + dexterity);
if (dexterity > 15 && dexterity % 2 == 0) {
System.out.println("Dodge Bonus = " + "+" + (dexterity - 15));
} else if (dexterity < 11 && dexterity % 2 == 0) {
System.out.println("Negative Dodge Bonus = " + "-" + (11 - dexterity));
} else {
System.out.println("You do not have a dodge bonus");
}
if (dexterity > 14 && dexterity % 2 == 0) {
System.out.println("Strike Bonus = " + "+" + (dexterity - 14));
} else if (dexterity < 10 && dexterity % 2 == 0) {
System.out.println("Negative Strike bonus = " + "-" + (10 - dexterity));
} else {
System.out.println("You do not have a strike bonus");
}
int health = strength * 10;
System.out.println("Health = " + health);
int MP = intelligence * 5;
System.out.println("MP = " + MP);
GameMaster.ReRoll();
}
}
DiceBag sum should be local to rollD6 rather than static.
I'm trying to make it so my methods payGourmet and payEconomical balance don't change if there's not enough money and don't drop below zero. Also so that my loadMoney method does not exceed 150 but still adds the specified number from the main. What am I doing wrong?
Import java.util.Scanner;
public class LyyraCard {
private double balance;
public LyyraCard(double balanceAtStart) {
this.balance = balanceAtStart;
}
public String toString() {
return "The card has " + this.balance + " euros";
}
public void payEconomical() {
if (this.balance > 0) {
this.balance -= 2.5;
}
}
public void payGourmet() {
if (this.balance > 0) {
this.balance -= 4.0;
}
}
public void loadMoney(double amount) {
if (this.balance < 150) {
this.balance += amount;
}
}
}
public class Main {
public static void main(String[] args) {
// add here code that tests LyraCard. However before doing 77.6 remove the
// other code
LyyraCard card = new LyyraCard(10);
System.out.println(card);
card.payEconomical();
System.out.println(card);
card.payGourmet();
System.out.println(card);
card.payGourmet();
System.out.println(card);
card.loadMoney(10);
System.out.println(card);
card.loadMoney(200);
System.out.println(card);
}
}
When you check if the balance is greater than 0 and then subtract an amount you could end up in a negative balance:
public void payEconomical() {
if (this.balance > 0) {
this.balance -= 2.5;
}
}
If balance = 1 this would yield a negative balance (-1.5).
You need to check if the balance is equal or greater than the amount you are to subtract
public void payEconomical() {
if (this.balance >= 2.5) {
this.balance -= 2.5;
}
else {
// There isn't enough money
}
}
Likewise for payGourmet:
if (this.balance >= 4.0) {
...
And in loadMoney you need to check if the current balance plus the added money is equal or less than 150:
if (this.balance + amount <= 150.0) {
this.balance += amount;
}
else {
// Amount too large.
}
To limit values to minimum or maximum values, use Math.min() or Math.max().
int valueA = -50;
valueA = Math.max(valueA, 0); //valueA is now 0;
int valueB = 200;
valueB = Math.min(valueB, 150); //valueB is now 150;
If you want to limit it to upper and lower bounds, just use both methods
int valueC = -50;
valueC = Math.min(Math.max(valueC, 0), 150); //valueC is now 0
int valueD = 200;
valueD = Math.min(Math.max(valueC, 0), 150); //valueD is now 150
edit: so for your example, use
public void loadMoney(double amount) {
this.balance = Math.min(this.balance + amount, 150);
}