Prevent an Added Variable from Exceeding Specified Number - java

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);
}

Related

Checking account - Problem with withdrawing with overdraft

I'm having trouble with a Java OOP exercise. The program uses two classes, the object class Account and the Main class to print whatever the user wants.
It's a standard checkings account with an overdraft limit, the issue I'm having is printing out the account balance if the user decides to withdraw more than the account balance, I can't seem to get the overdraft logic down, can anyone help me out?
Account classs
public boolean withdraw(double amount) {
balance = this.getBalance() + overDraftLimit;
if ((balance - amount) >= 0) {
this.setBalance(this.getBalance() - amount);
balance -= amount;
return true;
} else if ((balance - amount) <= 0) {
System.out.println("The amount you wish to withdraw is more than your balance -> Using overdraft to complete your transaction!");
this.setBalance((this.getBalance() - amount) + overDraftLimit);
return true;
}
return false;
} // ***** WITHDRAW *****
// ***** toString *****
#Override
public String toString() {
return "Account numer: " + accountNumber + "\nYour current balance is: $" + balance + "\nYour overdraft limit is: $" + overDraftLimit;
}
}
### Main class
Account ac1 = new Account();
ac1.setAccountNumber(1234);
ac1.setOverDraftLimit(50);
System.out.println(ac1);
System.out.println("\nSucessful deposit");
ac1.deposit(100);
System.out.println("Your current balance is: $" + ac1.getBalance());
makeWithdraw(ac1, 50);
makeWithdraw(ac1, 50);
makeWithdraw(ac1, 25);
}
public static void makeWithdraw (Account ac1, double amount) {
if (ac1.withdraw(amount)) {
System.out.println("Withdraw was sucessful! Your new balance is: $" + ac1.getBalance());
} else {
System.out.println("Insufficient funds! Cannot withdraw " + amount + "Your current balance is: $" + ac1.getBalance());
}
}
}
This is the output:
This will be the proper logic to handle the overdraft during withdrawl.
public boolean withdraw(double amount) {
if(balance < -overDraftLimit) {
return false;
}
if ((balance - amount) >= -overDraftLimit) {
this.setBalance(this.getBalance() - amount);
balance -= amount;
return true;
}
return false;
} // ***** WITHDRAW *****
[EDIT]
Here is an running example
public class Test{
public static class A {
private int balance = 20;
private int overDraftLimit = 50;
public boolean withdraw(double amount) {
if(balance < -overDraftLimit) {
return false;
}
if ((balance - amount) >= -overDraftLimit) {
balance -= amount;
return true;
}
return false;
}
public int getBalance() {
return balance;
}
}
public static void main(String []args){
A a = new A();
System.out.println(a.getBalance());
System.out.println(a.withdraw(30));
System.out.println(a.getBalance());
System.out.println(a.withdraw(40));
System.out.println(a.getBalance());
System.out.println(a.withdraw(1));
System.out.println(a.getBalance());
}
}
Output:
20
true
-10
true
-50
false
-50

Problem with class creation specific to the below problem

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.

Java - use void return type to allow customer to gain admission into event

I'm trying to make a method that allows a customer to gain admission into an event. As a requirement, the payAdmission() method should have a void return type. My method should also be one line long, making use of the computeFee() and spend() methods that are already written. I don't quite understand how I'm supposed to determine how a customer is supposed to pay admission when the return type is just void and I'm unable to subtract any values or return anything?
Code for Customer Class:
public class Customer {
String name;
int age;
float money;
public Customer(String initName){
name = initName;
}
public Customer(String initName, int initAge){
name = initName;
age = initAge;
}
public Customer(String initName, int initAge, float initMoney){
name = initName;
age = initAge;
money = initMoney;
}
public Customer(){
}
public float computeFee(){
if(age >= 18 && age <65){
return 12.75f;
}
if(age >= 65){
return 0.5f;
}
if(age >= 4 && age <= 17){
return 8.50f;
}
return 0.0f;
}
public boolean spend(float amount){
if(amount <= money){
money -= amount;
return true;
}else{
return false;
}
}
public boolean hasMoreMoneyThan(Customer c){
if(this.money > c.money){
return true;
}
return false;
}
public void payAdmission(){
float comF = computeFee();
float spe = spend();
float moneyLeft -= (comF + spe);
}
}
Code for CustomerAdmissionTestProgram:
public class CustomerAdmissionTestProgram {
public static void main(String args[]) {
Customer c1, c2, c3, c4;
c1 = new Customer("Bob", 17, 100);
c2 = new Customer("Dottie", 3, 10);
c3 = new Customer("Jane", 24, 40);
c4 = new Customer("Sam", 72, 5);
System.out.println("Here is the money before going into the circus:");
System.out.println(" Bob has $" + c1.money);
System.out.println(" Dottie has $" + c2.money);
System.out.println(" Jane has $" + c3.money);
System.out.println(" Sam has $" + c4.money);
// Simulate people going into the circus
c1.payAdmission();
c2.payAdmission();
c3.payAdmission();
c4.payAdmission();
System.out.println("Here is the money after going into the circus:");
System.out.println(" Bob has $" + c1.money);
System.out.println(" Dottie has $" + c2.money);
System.out.println(" Jane has $" + c3.money);
System.out.println(" Sam has $" + c4.money);
}
}
Look carefully at what the spend and computeFee methods do. spend takes in an amount and subtracts it from the money (if the person has enough money to spend, of course). The computeFee method calculates and returns the fee.
So what should payAdmission do? It naturally follows that it should spend the fee. How do you get the fee? By calling computeFee. How do you spend it? By calling spend.
So your method should be implemented like this:
spend(computeFee());
public static void main(String... args) {
List<Customer> customers = Arrays.asList(
new Customer("Bob", 17, 100),
new Customer("Dottie", 3, 10),
new Customer("Jane", 24, 40),
new Customer("Sam", 72, 5));
System.out.println("Here is the money before going into the circus:");
customers.forEach(customer -> System.out.format(" %s has $%.2f\n", customer.name, customer.money));
customers.forEach(Customer::payAdmission);
System.out.println("Here is the money after going into the circus:");
customers.forEach(customer -> System.out.format(" %s has $%.2f\n", customer.name, customer.money));
}
public static class Customer {
private final String name;
private final int age;
private double money;
public Customer(String name) {
this(name, 0);
}
public Customer(String name, int age) {
this(name, age, 0);
}
public Customer(String name, int age, double money) {
this.name = name;
this.age = Math.max(0, age);
this.money = Math.max(0, money);
}
public double computeFee() {
if (age >= 65)
return 0.5;
if (age >= 18)
return 12.75;
if (age >= 4)
return 8.50;
return 0;
}
public boolean spend(double amount) {
amount = Math.max(0, amount);
if (Double.compare(amount, money) > 0)
return false;
money -= amount;
return true;
}
public boolean hasMoreMoneyThan(Customer customer) {
return Double.compare(money, customer.money) > 0;
}
public void payAdmission() {
if (!spend(computeFee()))
throw new RuntimeException();
}
}

Not getting the right output

Probably just a small error, but I cant seem to find it anywhere. When I run the program, it prints "After depositing $100: Savings Account:, also my withdraw class seems not to be working, as the balance after withdrawing money does not change.
public class CheckingandSavings
{
public static void main(String[] args) {
Savings savings = new Savings(1001,1000.0);
Checking checking = new Checking(1002, 2000.0);
System.out.println("At the beginning: " + savings);
savings.deposit(100);
System.out.println("After depositing $100: " + savings);
savings.withdraw(500);
System.out.println("After withdrawing $500: " + savings);
System.out.println("");
System.out.println("At the beginning: " + checking);
checking.deposit(100);
System.out.println("After depositing $100: " + checking);
checking.withdraw(500);
System.out.println("After withdrawing $500: " + checking);
}
}
public class Account {
private int accountNumber;
private double accountBalance;
//The Two-Arg Constructor
public Account(int accountNumber, double accountBalance)
{
setAccountBalance(accountBalance);
setAccountNumber(accountNumber);
}
//Getter for accountNumber
public int getAccountNumber()
{
return accountNumber;
}
//Setter for accountNumber
public void setAccountNumber(int accountNumber)
{
if (accountNumber >= 0)
this.accountNumber = accountNumber;
}
//Getter for accountBalance
public double getAccountBalance()
{
return accountBalance;
}
//Setter for accountBalance
public void setAccountBalance(double accountBalance)
{
if (accountNumber >= 0)
this.accountBalance = accountBalance;
}
//Deposit to accountBalance
public void deposit(double amount)
{
if (amount > 0)
this.accountBalance += amount;
}
//Withdraw from accountBalance
public double withdraw(double amount)
{
if (amount > 0 || amount > this.accountBalance)
return 0;
this.accountBalance -= amount;
return this.;
}
//Returns a string of the instance data
public String toString()
{
String result = "";
result += "Account Number: " + this.accountNumber;
result += "\nAccount Balance: $" + String.format("%.2f", this.accountBalance);
return result;
}
}
public class Savings extends Account {
//The two-arg constructor
public Savings(int accountNumber, double accountBalance)
{
super(accountNumber, accountBalance);
}
//Returns a string of the instance data
public String toString()
{
String result = "";
result += "Savings Account: \n" + super.toString();
return result;
}
}
public class Checking extends Account {
//The two-arg constructor
public Checking(int accountNumber, double accountBalance)
{
super(accountNumber,accountBalance);
}
//Returns a string of the instance data
public String toString() {
String result = "";
result += "Checking Account: \n" + super.toString();
return result;
}
}
Taking a look at your withdraw method:
//Withdraw from accountBalance
public double withdraw(double amount)
{
if (amount > 0 || amount > this.accountBalance) //This needs to be &&
return 0;
this.accountBalance -= amount;
return this.; //I am assuming you meant this to be this.accountBalance?
}
You are saying if the amount you want to withdraw is greater than 0 OR it is greater than your account balance, return 0. I think you want to say AND so instead put amount > 0 && amount > this.accountBalance
Also, you should be returning this.accountBalance.
Lastly, you should really put the #Override annotation above your toString methods. This lets the compiler know you are overriding a parents method.

Calling Methods (Java)

Summary, I am to write a class called BankAccount and my professor has provided me with a driver.
Here is my class so far:
import java.util.Date;
public class BankAccount implements AccountInterface
{
private double balance;
private String name;
private Date creationDate = new Date ();
private boolean frozen;
private double limit;
private final double MAXLIMIT = 500;
private int accountNumber;
private static int howMany;
public BankAccount( )
{
this.name = "Classified";
this.creationDate.getTime();
this.frozen = false;
this.limit = 300;
this.howMany++;
this.accountNumber = howMany;
this.balance = 0;
}
public BankAccount (String creationName)
{
this.name = creationName;
this.creationDate.getTime();
this.frozen = false;
this.limit = 300;
this.howMany++;
this.accountNumber = howMany;
this.balance = 0;
}
public static int getNumAccounts ( )
{
return howMany;
}
public void deposit(double theMoney)
{
if (frozen = true)
throw new IllegalStateException ("Cannot Deposit - Account Is Frozen");
else if (theMoney < 0)
throw new IllegalArgumentException("Insufficient funds");
else
balance = balance + theMoney;
}
public double withdraw(double theMoney)
{
if (theMoney < 0 || balance == 0 || theMoney > limit || theMoney % 20 !=0)
throw new IllegalArgumentException ("There was an error in your withdraw.");
else if (frozen = true)
throw new IllegalStateException ("Cannot Deposit - Account Is Frozen");
else
balance = balance - theMoney;
return balance;
}
public double getBalance()
{
return balance;
}
public void freeze()
{
frozen = true;
}
public void unfreeze()
{
frozen = false;
}
public void setLimit(double newLimit)
{
if (newLimit < 0 || newLimit > MAXLIMIT)
throw new IllegalArgumentException ("There was a limit error.");
else if (frozen = true)
throw new IllegalStateException ("Cannot Deposit - Account Is Frozen");
else
limit = newLimit;
}
public double getLimit( )
{
return limit;
}
public String toString( )
{
return "\nAccount number: " + accountNumber + "\nName: " + name + "\nCreation Date: " + creationDate + "\nBalance: " + balance + "\nWithdrawal Limit: " + limit ;
}
}
The problem that I am running into is when the driver calls myAccount.unfreeze(); in my class it does not set the account to unfreeze. So When the driver goes to deposit any money my class returns Cannot Deposit - Account Is Frozen even though I have a method called unfreeze. I thought at first I might have missed spelled frozen or unfreeze wrong, but that is not the case. Hopefully, some fresh pair of eyes can spot something that I am skipping over.
Thank you for your help!
When you use single equation sign, you are assigning the value. Use double equal sign to check for equality. In your case you should be using if(frozen==false) and if(frozen==true) whenever you are checking for its value.

Categories

Resources