Issue with a double value - java

Whenever the deposit or withdraw method is used it will add or subtract from the original balance but if you try to add or subtract again it does not recognize the previous transactions and will add or subtract from the original balance again instead of the new balance after a transaction has been made.
For example: If I deposit $10 into a $20 account it will equal $30. If I then try to deposit another $5, it will equal $25 instead of $35. It bases all transactions of the original balance and that is the issue. I am not sure how to fix it.
//This program will create a functioning mock ATM with the usual features of a real ATM.
import java.util.*;
public class ATM {
public static Scanner kbd;
/**
* This is the main method, everything that is returned from other methods is sent here to be processed and initialized into the atm.
* #param args
*/
public static void main(String[] args) {
String acctNum, acctPword;
String balance;
boolean menu = false;
double depAmnt = 0.0, withAmnt = 0.0;
int x = 1;
kbd = new Scanner(System.in);
//getting the user account username
System.out.print("Enter your account number: ");
acctNum = kbd.nextLine();
//getting the users password
System.out.print("Enter your account password: ");
acctPword = kbd.nextLine();
//incase the user enters invalid information
balance = checkID(acctNum, acctPword);
while (balance.equals("error") && x <4){
System.out.println("Wrong password try again.");
System.out.print("Enter your account password: ");
acctPword = kbd.nextLine();
x++;
}
//once they gained access to the atm machine, the balance will print for informative purposes.
double balance1 = Double.parseDouble(balance);
System.out.println("You currently have $" + String.format("%.2f",balance1));
//they only get 3 attempts to enter the correct password.
if (x == 4)
System.out.println("Maximum number of attempts reached, Please try again later.");
//This switch and while statement controls the main menu of the atm machine and is capable of calling all methods.
while (menu == false){
switch (menu()) {
case 1:
System.out.println("Your balance is $" + String.format("%.2f",balance1));
break;
case 2:
deposit(balance1, depAmnt);
break;
case 3:
withdraw(balance1, withAmnt);
break;
case 4:
System.out.println("Have a nice day.");
menu = true;
break;
}
}
kbd.close();
}
/**
* Determines if acctNum is a valid account number, and pwd is the correct
* password for the account.
* #param acctNum The account number to be checked
* #param pwd The password to be checked
* #return If the account information is valid, returns the current account
* balance, as a string. If the account information is invalid, returns
* the string "error".
*/
public static String checkID(String acctNum, String pwd)
{
String result = "error";
// Strings a, b, and c contain the valid account numbers and passwords.
// For each string, the account number is listed first, followed by
// a space, followed by the password for the account, followed by a space,
// followed by the current balance.
String a = "44567-5 mypassword 520.36";
String b = "1234567-6 anotherpassword 48.20";
String c = "4321-0 betterpassword 96.74";
//these 3 if statements and everything declared right before the if statements, first checks the users name and pword for gained access and allows the user to enter the code and change the password and username if they so please.
int pos1, pos2;
pos1 = a.indexOf(" ");
pos2 = a.lastIndexOf(" ");
String account, password;
account = a.substring(0, pos1);
password = a.substring(pos1+1,pos2);
if (acctNum.equals(account) && pwd.equals(password)){
result = a.substring(pos2+1);
return result;
}
int pos1b, pos2b;
pos1b = b.indexOf(" ");
pos2b = b.lastIndexOf(" ");
String accountb, passwordb;
accountb = b.substring(0, pos1b);
passwordb = b.substring(pos1b+1,pos2b);
if (acctNum.equals(accountb) && pwd.equals(passwordb)){
result = b.substring(pos2b+1);
return result;
}
int pos1c, pos2c;
pos1c = c.indexOf(" ");
pos2c = c.lastIndexOf(" ");
String accountc, passwordc;
accountc = c.substring(0, pos1c);
passwordc = c.substring(pos1c+1,pos2c);
if (acctNum.equals(accountc) && pwd.equals(passwordc)){
result = c.substring(pos2c+1);
return result;
}
return result;
}
/**
* This menu method will get the users input and allow them to choose 4 options otherwise they will receive an error message.
* #return x is returned as the users input and will dictate which option they choose.
*/
public static int menu(){
int x = 1;
// the physical aspect of the menu
System.out.println("1. Display Balance \n2. Deposit\n3. Withdraw\n4. Log Out");
x = kbd.nextInt();
//incase they dont enter valid info
if(x > 4){
System.out.println("That is not an option.");
x = 0;
x = kbd.nextInt();
}
return x;
}
/**
* This method will allow the user to use a deposit feature found on every atm if they wish to deposit money into their account.
* #param acctBal this is the account balance and will dictate how much they have before and after the deposit
* #param depAmnt this is how much they so choose to deposit to their accounts
* #return the account balance is returned and revised to what ever amount they chose to add.
*/
public static double deposit(double acctBal, double depAmnt){
System.out.print("How much money would you like to deposit? $");
depAmnt = kbd.nextDouble();
acctBal = acctBal + depAmnt;
System.out.println("Your balance is now at $" + String.format("%.2f", acctBal));
return acctBal;
}
/**
* This allows the user to take money from their account if they have money in the first place.
* #param acctBal the account balance will be returned as a new lesser value once the withdraw is made
* #param withAmnt this dictates how much is taken from the acct.
* #return the now lesser acct balance is returned
*/
public static double withdraw(double acctBal, double withAmnt){
System.out.print("How much money would you like to withdraw? $");
withAmnt = kbd.nextDouble();
if (acctBal <= 0){
System.out.println("You do not have any money.");
return acctBal;
}
if (acctBal < withAmnt){
System.out.print("You do not have enough money.\nHow much money would you like to withdraw? $");
withAmnt = kbd.nextDouble();
}
else{
acctBal = acctBal - withAmnt;
}
System.out.println("You now have $" + String.format("%.2f",acctBal));
return acctBal;
}
/**
* all this does is simply display the current balance of the user
* #param balance the balance as it stands during the program.
* #return
*/
public static double displayBalance(double balance){
System.out.println("Your balance is $" + String.format("%.2f", balance));
return balance;
}
}

The problem is in your switch statement:
switch (menu()) {
case 1:
System.out.println("Your balance is $" + String.format("%.2f",balance1));
break;
case 2:
deposit(balance1, depAmnt);
break;
case 3:
withdraw(balance1, withAmnt);
break;
case 4:
System.out.println("Have a nice day.");
menu = true;
break;
}
Your deposit and withdraw functions both return the new balance but do not update it. Hence you have to store the new value in balance1. Just do balance1 = deposit(...) and balance1 = withdraw(...).

When you call deposit(balance1, depAmnt), you do not save the return value anywhere. Note that that method increments the value of the variable balance1 that is local to the deposit() method, not the one that is in main().
You will encounter a lot of problems when using a double to store the value of the account. You should use a long int to save the number of cents instead.
For example, if you add $0.01 one hundred times, you might be surprised what happens when you withdraw $1.00

Related

How to prompt the user to only enter one of three options they can choose from and display an error message for wrong input

This program will prompt the user to enter a medium (either air, water or steel) and the distance. Then calculate the distance a sound wave will travel through the medium.
I wrote the whole program but I didn't read the last bit that my professor added to the homework which is the following paragraph. Now I'm stuck because I'm not quite sure how to add this to my program. I was using an if statements but maybe I can add it in one?
The program prompts for the medium with: "Enter one of the following: air, water, or steel:" and reads the medium. If the medium is not air, water, or steel the program prints the message: "Sorry, you must enter air, water, or steel" and nothing else. Otherwise the program prompts for the following distance input.
I tried a while loop and adding another if statement but really my problem is the syntax. Because I've never had to command the user to type in specific strings.
public class SpeedOfSound {
public static void main(String[] args) {
double distance;
double time;
Scanner keyboard = new Scanner(System.in);
//prompt the user to enter the medium through which sound will
System.out.print("Enter one of the following: air, water, or steel:");
String input;
input = keyboard.nextLine();
// prompt the user to enter a distance
System.out.print("Enter distance in feet: ");
distance = keyboard.nextDouble();
// determine if medium is air, water, steele and calculate
if (input.equals("air")) {
time = (distance / 1100);
System.out.println("The total time traveled is " + time + " feet per second.");
}
else if (input.equals("water"))
{
time = (distance / 4900);
System.out.println("The total time traveled is " + time + " feet per second.");
}
else if (input.equals("steel"))
{
time = (distance / 16400);
System.out.println("The total time traveled is " + time + " feet per second.");
}
}
}
My expected result is to make the user only type in either Air, water, or Steel.
There was several issue with your code and I've taken the liberty of correcting them. Read through the comments to better understand each part of the code.
public class SpeedOfSound
{
/* Best to declare it here so other methods have access to it. */
private static final Scanner keyboard = new Scanner(System.in);
/*
* Declared as a class field so you can use it if you
* have a need for it in addition to time calculated in main.
*/
private static double distance;
/**
* Blocks program execution until a number has been detected as user input.
* #return numeric representation of user input.
*/
public static double getDistance()
{
System.out.println("Enter distance in feet: ");
// CAREFUL: This will throw an exception if the user enters a String
// return keyboard.nextDouble();
while (keyboard.hasNext())
{
/*
* Check if the user input is actually a number
* and if it isn't print an error and get next token
*/
String input = keyboard.nextLine();
try {
return Double.valueOf(input);
}
catch (NumberFormatException e) {
System.out.println("Incorrect input, try again.");
}
}
throw new IllegalStateException("Scanner doesn't have any more tokens.");
}
/**
* Calculate the speed of sound for user input which is limited to:
* <ul>
* <li>Air</li>
* <li>Water</li>
* <li>Steel</li>
* </ul>
* #return total time traveled in feet per second.
*/
public static Double calculate()
{
Double time = null;
//prompt the user to enter the medium through which sound will travel through
System.out.println("Enter one of the following: air, water, or steel:");
// The loop will break the moment time is calculated
while (time == null && keyboard.hasNext())
{
double distance;
String input = keyboard.nextLine();
//determine if medium is air, water, steele and calculate
if (input.equals("air"))
{
distance = getDistance();
time = (distance / 1100);
}
else if (input.equals("water"))
{
distance = getDistance();
time = (distance / 4900);
}
else if (input.equals("steel"))
{
distance = getDistance();
time = (distance / 16400);
}
else System.out.println("Incorrect input, try again.");
}
return time;
}
public static void main(String[ ] args)
{
Double time = calculate();
System.out.println("The total time traveled is " + time + " feet per second.");
}
}
However the way I would tackle this assignment would be to implement the elements in an enum of sort and move the bulk of the calculate() method there. This will allow you to quickly create more elements like air, water and steel without having to create additional if blocks to process them.
Element Enumerator
public enum Element {
AIR("air", 1100),
WATER("water", 4900),
STEEL("steel", 16400);
private final String name;
private final int factor;
Element(String name, int factor) {
this.name = name;
this.factor = factor;
}
/**
* #param element name of the element to calculate time for
* #return total time traveled in feet per second for given element or
* {#code null} if no element matched the given name.
*/
public static Double getTimeTraveledFor(String element)
{
/* Find an element that matches the given name */
for (Element e : Element.values()) {
/*
* Validate the parameter without case consideration.
* This might be a better way of validating input unless
* for some reason you really want a case-sensitive input
*/
if (e.name.equalsIgnoreCase(element)) {
return SpeedOfSound.getDistance() / e.factor;
}
}
return null;
}
}
Revised method
public static Double calculate()
{
Double time = null;
//prompt the user to enter the medium through which sound will travel through
System.out.println("Enter one of the following: air, water, or steel:");
// The loop will break the moment time is calculated
while (time == null && keyboard.hasNext())
{
String input = keyboard.nextLine();
time = Element.getTimeTraveledFor(input);
if (time == null) {
System.out.printf("%s is not a recognized element, try again.", input);
}
}
return time;
}
while(true){
System.out.print("Enter distance in feet: ");
String input;
input = keyboard.nextLine();
//prompt the user to enter a distance
System.out.print("Enter distance in feet: ");
distance = keyboard.nextDouble();
//determine if medium is air, water, steele and calculate
if (input.equals("air"))
{
time = (distance / 1100);
System.out.println("The total time traveled is " + time + "
feet per second.");
break;
}
else if (input.equals("water"))
{
time = (distance / 4900);
System.out.println("The total time traveled is " + time + "
feet per second.");
break;
}
else if (input.equals("steel"))
{
time = (distance / 16400);
System.out.println("The total time traveled is " + time + "
feet per second.");
break;
}
else
System.out.println("wrong choice");
}

How to use an object, save the value into an arrayList, and reuse the same object to keep getting user input

I am trying to create a SavingsAccount object and then use a method create account to take user inputs (account name, account number, and starting balance) and then store that information into an arrayList to access later.
I was thinking that I could just have one instance of the object (Savings account) save the data into the arrayList and then reuse the object so that I do not have multiple objects ( was thinking this would be more memory efficient).
I am new to Java, and this is homework, I have posted my code below that I have so far. I also am not exactly sure how I should be using the toString method in order to later print out a list of all the accounts that have been created.
The main problem I am having is how to store the objects data into the arrayList I know to use the .add() however, it seems to be overwriting all the information stored into the array with the last value entered. So I unsure how to do this, I have read many posts here that are on the same topic or something similar and still do not understand the correct way to do this.
I would welcome any guidance or advice, thank you for taking the time to read my post.
package bankingSystem;
/**
*
* #author xxxx
*
*/
public class SavingsAccount {
private String accountNumber;
private String accountName;
private double accountBalance;
/**
* Constructor to create a new savings account object that takes in a new
account number and a new account name
* #param newAccountNumber
* #param newAccountName
*/
public SavingsAccount(String newAccountNumber, String newAccountName){
this.accountNumber = newAccountNumber;
this.accountName = newAccountName;
this.accountBalance = 0;
}
/**
* Creates a new savings account with passed in data of new account name,
number, and starting balance.
* #param newAccountNumber
* #param newAccountName
* #param startingAccountBalance
* #return true always as the information is stored in an arrayList and
will not fill up.
*/
public SavingsAccount(String newAccountNumber, String newAccountName,
double startingAccountBalance){
this.accountNumber = newAccountNumber;
this.accountName = newAccountName;
this.accountBalance = startingAccountBalance;
}
/**
* Gets the banking account number
* #return the bank account number
*/
public String getAccountNumber(){
return accountNumber;
}
/**
* Gets the requested account name
* #return
*/
public String getAccountName(){
return accountName;
}
/**
* Gets the requsted account balance
* #return the account balace;
*/
public double getAccountBalance(){
return accountBalance;
}
/**
* Changes a bank account name.
* #param updateAccountName
* #return the updated value for accountName
*/
public String setAccountName(String updateAccountName){
accountName = updateAccountName;
return accountName;
}
/**
* Deposit funds into account.
* #param depositAmount
* #return true, as this would always be true for a realistic amount.
*/
public boolean deposit(double depositAmount){
accountBalance += depositAmount;
return true;
}
/**
* withdraws the specified amount of funds from the account.
* #param withdrawlAmount
* #return true if successful, else return false if there is an ISF
transaction.
*/
public boolean withdrawl(double withdrawlAmount){
if(accountBalance - withdrawlAmount < 0){
return false;
}else{
accountBalance -= withdrawlAmount;
return true;
}
}
#Override
public String toString(){
StringBuilder results = new StringBuilder();
results.append("The account number is " + accountNumber + " The
account name is " + accountName + " The account balance is " +
accountBalance + "\n");
return results.toString();
}
}
package bankingSystem;
import java.util.Scanner;
import java.util.ArrayList;
/**
*
* #author xxxx
*
*/
public class BankingSystem {
public static void main(String[] args) {
ArrayList<SavingsAccount> arrayOfSavingsAccounts = new \
ArrayList<SavingsAccount>();
int totalNumberOfAccounts = 0;
Scanner input = new Scanner(System.in);
int menuSelection = 0;
do{
System.out.println("\nPlease select from the following options: \n1.
Create a new account\t\t\t2. Deposit funds\n3. Withdrawl funds\t\t\t\t4.
Transfer funds between accounts\n5. Display all accounts\t\t\t6. Exit
Program\n");
if (input.hasNextInt()){
int temp = input.nextInt(); //used a temp variable to compare the
if statement below
if (temp > 0 && temp < 7){
menuSelection = temp;
}else{
System.err.println("INVALID ENTRY, Please try again");
}
}else{
System.err.println("INVALID ENTRY, Please try again");
}
input.nextLine(); //used this to clear the value being held in
scanner
}
while (menuSelection < 1 || menuSelection > 6);
switch (menuSelection){
case 1: System.out.println("\t\t\t\tCREATE NEW ACCOUNT:\nPlease enter
the account holders name: \n");
String AccountName = input.nextLine();
System.out.println("Please enter an account number: ");
String AccountNumber = input.nextLine();
if (totalNumberOfAccounts == 0){
//search for duplicate account number
}
System.out.println("Please enter starting account balance e.g.
2500.50 :");
double startingAccountBalance = input.nextDouble();
SavingsAccount createSavingsAccount = new
SavingsAccount(AccountNumber, AccountName, startingAccountBalance);
arrayOfSavingsAccounts.add(createSavingsAccount);
SavingsAccount createSavingsAccount = new
}
}
}
You don't need the last line:
SavingsAccount createSavingsAccount = new SavingsAccount(AccountNumber, AccountName, startingAccountBalance);
because you initialize a new instance just remove it and then any new operation will overwrite the object old values just it.
Have you thought about just creating an array of SavingAccounts with a fixed number of accounts?
SavingAccounts[] savingArray;
savingsArray = new SavingAccounts[10];
Since the value stored into the ArrayList is a reference(to the memory location of the object), you must create a new object or all the instances of that referenced object in the ArrayList will be of the same value.
I changed my code to create a new object each time a new account was created and then store the value of the newly created object.
Thank you everyone for your assistance.

How to allow the user to access methods of a class

I am working a programming project from Java textbook that says:
The L&L bank can handle up to 30 customers who have savings accounts. Design and implement a program that manages the accounts. Keep track of key information and let each customer make deposits and withdrawals. Produce error messages for invalid transactions. Hint: You may want to base your accounts on the Account class from Chapter 4. Also provide a method to add 3 percent interest to all accounts whenever the method is invoked.
I am not certain on what the question is specifically asking but my guess is to allow and enable the user to add accounts, deposit, withdraw, add interest, get balance, and print the accounts being managed into an array. I am not entirely sure that I have to make an array but the whole chapter is on arrays.
My problem is that I am not sure how to enable the user to make an account
(EX: Account acct1 = new Account ("Ted Murphy", 72354, 102.56);),
to deposit money (EX: acct1.deposit (25.85);),
withdraw money (EX: acct3.withdraw (800.00, 0.0);),
add interest (EX: acct1.addInterest();),
or to print an array for all the accounts.
Here is the Account class found in the Java textbook with all the methods:
//********************************************************************
// Account.java Author: Lewis/Loftus/Cocking
//
// Represents a bank account with basic services such as deposit
// and withdraw.
//********************************************************************
import java.text.NumberFormat;
public class Accounts
{
private NumberFormat fmt = NumberFormat.getCurrencyInstance();
private final double RATE = 0.035; // interest rate of 3.5%
private int acctNumber;
private double balance;
private String name;
//-----------------------------------------------------------------
// Sets up the account by defining its owner, account number,
// and initial balance.
//-----------------------------------------------------------------
public Accounts (String owner, int account, double initial)
{
name = owner;
acctNumber = account;
balance = initial;
}
//-----------------------------------------------------------------
// Validates the transaction, then deposits the specified amount
// into the account. Returns the new balance.
//-----------------------------------------------------------------
public double deposit (double amount)
{
if (amount < 0) // deposit value is negative
{
System.out.println ();
System.out.println ("Error: Deposit amount is invalid.");
System.out.println (acctNumber + " " + fmt.format(amount));
}
else
balance = balance + amount;
return balance;
}
//-----------------------------------------------------------------
// Validates the transaction, then withdraws the specified amount
// from the account. Returns the new balance.
//-----------------------------------------------------------------
public double withdraw (double amount, double fee)
{
amount += fee;
if (amount < 0) // withdraw value is negative
{
System.out.println ();
System.out.println ("Error: Withdraw amount is invalid.");
System.out.println ("Account: " + acctNumber);
System.out.println ("Requested: " + fmt.format(amount));
}
else
if (amount > balance) // withdraw value exceeds balance
{
System.out.println ();
System.out.println ("Error: Insufficient funds.");
System.out.println ("Account: " + acctNumber);
System.out.println ("Requested: " + fmt.format(amount));
System.out.println ("Available: " + fmt.format(balance));
}
else
balance = balance - amount;
return balance;
}
//-----------------------------------------------------------------
// Adds interest to the account and returns the new balance.
//-----------------------------------------------------------------
public double addInterest ()
{
balance += (balance * RATE);
return balance;
}
public double addInterestAll ()// I made this method myself but I am not sure if it is correct
{
balance += (balance * 0.03);
return balance;
}
//-----------------------------------------------------------------
// Returns the current balance of the account.
//-----------------------------------------------------------------
public double getBalance ()
{
return balance;
}
//-----------------------------------------------------------------
// Returns the account number.
//-----------------------------------------------------------------
public int getAccountNumber ()
{
return acctNumber;
}
//-----------------------------------------------------------------
// Returns a one-line description of the account as a string.
//-----------------------------------------------------------------
public String toString ()
{
return (acctNumber + "\t" + name + "\t" + fmt.format(balance));
}
}
Here is the main method that is under construction and I am not sure if I am on the right track:
import java.util.Scanner;
public class SixSix
{
public static void main (String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Input (0) to add account, (1) to deposit,");
System.out.println("(2) to withdraw, (3) to add interest, (4) to add interest to all");
System.out.println("(5) to get balance, (6) to get account number, (7) to print");
int input = scan.nextInt();
while (input == 0){
System.out.println("To create an account, please enter your name");
String name = scan.nextLine();
System.out.println("Please enter your account number");
int accNum = scan.nextInt();
System.out.println("Please Enter account balance");
double accBalance = scan.nextDouble();
//System.out.format
}
while (input == 1)
{
System.out.println("To deposit money to an account");
}
while (input == 2)
{
System.out.println("To withdraw money from an account");
}
while (input == 3)
{
System.out.println("To add Interest");
}
while (input == 4)
{
System.out.println("To add Interest to all");
}
while (input == 5)
{
System.out.println("To get balance");
}
while (input == 6)
{
System.out.println("To get account number");
}
while (input == 7)
{
System.out.println("Printing account");
}
}
}
It seems to me like you're on the right track. I'm inferring from the way the question (in the book) is phrased and the code that you've posted that the accounts don't already exist, in which case you need to allow the user of the system to create them. Then when altering an account, the user would first have to supply the account number so that you can identify the proper Accounts object.
I'm guessing that since the chapter was on arrays, it probably hasn't covered Maps yet (which would otherwise be a convenient way of associating account numbers to Accounts objects). If you use arrays, then having the account numbers range from 0 to 29 seems like a good idea.
Here's an example of how you could implement an AccountsManager class that helps you add and retrieve accounts from an array of accounts.
public class AccountsManager {
private Accounts[] accounts;
private final int capacity;
private int current;
public AccountsManager(int capacity) {
this.capacity = capacity;
accounts = new Accounts[capacity];
current = 0;
}
// returns the account number of the new account
// or -1 if no account could be made
public int addAccount(String name) {
if (current >= capacity) {
return -1;
}
accounts[current] = new Accounts(name, current, 0);
return current++;
}
public Accounts getAccount(int number) {
if (number >= current || number < 0) {
return null;
}
return accounts[number];
}
}
In the above, the capacity attribute is simply the size of the array, which is the maximum number of Accounts objects that can be created (this should be 30, according to the exercise). The current attribute (feel free to rename to something more informative!) keeps track of where in the array the next Accounts object should be created. This grows by one each time an account is added.
In your code, you could now do something like this:
AccountsManager manager = new AccountsManager(30);
// ...
if (input == 0) {
// Create new account
System.out.println("To create an account, please enter your name");
String name = scan.nextLine();
int accountNumber = manager.addAccount(name);
if (accountNumber == -1)
System.out.println("The bank can't handle any more accounts.");
else
System.out.println("Your account number is "+accountNumber);
} else if (input == 1) {
// Deposit money to account
System.out.println("What is your account number?");
int accountNumber = scan.nextInt();
// Check if account exists
if (manager.getAccount(accountNumber) == null) {
System.out.println("That account doesn't exist!");
} else {
System.out.println("How much do you want to deposit?");
double amount = scan.nextDouble();
manager.getAccount(accountNumber).deposit(amount);
}
}
Perhaps it might be preferable to create new methods in the AccountsManager class to make deposits etc, but this shows at least what the general structure could be like.

How do I make my program continue only if the user enters certain values?

My code is supposed to simulate something similar to a vending machine. But there is a problem when I enter a price that is not one of my options, e.g. 0.82 the program still runs. How do I get it to only accept one of my options?
import java.util.Scanner;
public class VendingMachine
{
public static void main (String[] args)
{
double price;
Scanner keyboard = new Scanner(System.in);
System.out.println("Choose your price. Your options are: ");
double i;
for (i=0.25; i<=1.25; i+=0.25)
System.out.printf("$%.2f\n", i );
System.out.println("Enter your selection now: ");
price=keyboard.nextDouble();
System.out.printf("You chose the $%.2f option. ",price);
double deposit;
if (price<=1.00) {
System.out.println("Please insert 1 dollar. *This machine only accepts Loonies*");
deposit=1;
} else {
System.out.println("Please insert 2 dollars.*This machine only accepts Loonies*");
deposit=2;
}
System.out.println("Please press 'Enter' to simulate inserting money. ");
new Scanner(System.in).nextLine();
double change;
change = deposit-price;
System.out.printf("Your change is $%.2f\n",change);
}
}
I tried something like this but it doesn't work. What is the best way to do this.
if (price==i)
System.out.println("You entered " + price);
else {
System.out.println("Invalide choice. Please try again.")
System.exit(0);
}
Here is an image if you find it easier to read.
You can use some sort of loop (while, do-while, for), which will continue to excecute the code until a condition is (or isn't) met.
Here is an example:
do {
code line 1;
code line 2;
code line 3;
...
} while(yourCondition);
If yourCondition is satisfied (yourCondition == true), the code will go back to code line 1 (will perform the code block between do and while) and it'll stop once the condition isn't satisfied(yourCondition == false). yourCondition could be any expression that returns a true/false result (boolean), such as 2+2==4.
If you want to keep looping for as long as yourCondition isn't met, you can add a ! before your expression, which will evaluate the opposite of your boolean like this (!yourCondition).
Now, if you understood how that works, you can easily apply it to your code.
If you want the user to enter only your displayed prices, I suggest the following, you shall edit to your exact desires.
//given you an open scanner
boolean isCorrectPrice = false;
System.out.println("enter price");
price = in.nextDouble();
while(!isCorrectPrice)
{
if(price%0.25==0 && price<=1.25 && price>0)
{
System.out.println("you entered "+price);
IsCorrectPrice = true;
continue;
}
System.out.println("incorrect price, re-enter ");
price = in.nextDouble();
}
//your code after user enters correct price
That will do the check. If your prices change, all you have to do is change the maximum price provided its still dividable with 0.25 or the condition price check.
Use BigDecimal (instead of double) to work with money. Its exact -- double isn't.
http://docs.oracle.com/javase/6/docs/api/java/math/BigDecimal.html
I would write a function to get the user input. It would not return until the
user had entered an allowed value.
Although my real answer is the one on the comments, you can use something like this. To check recursively if the correct value was given.
import java.util.Scanner;
public class VendingMachine {
static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Choose your price. Your options are: ");
for (double i = 0.25; i <= 1.25; i += 0.25) {
System.out.printf("$%.2f\n", i);
}
double price = checkMultipleValues(0.25,1.25, 0.25);
System.out.printf("You chose the $%.2f option. ", price);
double deposit;
if (price <= 1.00) {
System.out.println("Please insert 1 dollar. *This machine only accepts Loonies*");
deposit = 1;
} else {
System.out.println("Please insert 2 dollars.*This machine only accepts Loonies*");
deposit = 2;
}
System.out.println("Please press 'Enter' to simulate inserting money. ");
new Scanner(System.in).nextLine();
double change;
change = deposit - price;
System.out.printf("Your change is $%.2f\n", change);
}
private static double checkMultipleValues(double initial,double last,double step) {
System.out.println("Enter your selection now: ");
double price = keyboard.nextDouble();
for (double i = initial; i <= last; i += step) {
if (price == i) {
return price;
}
}
return checkMultipleValues( initial, last, step);
}
}
ADDENDUM
Since you like #Sello answer why don't you combine it with #MrD and have something like
do {
System.out.println("enter price");
price = in.nextDouble();
// System.out.println("you entered " + price);
} while (!(price % 0.25 == 0 && price <= 1.25 && price > 0));

Java is not reading a variable I am passing to it after the user modifies it

I have a really long problem. I am creating a bank account and setting the balance to 0. If the user chooses to withdraw or deposit money to the account, the balance never changes. I choose to show the balance and it still says 0. This is probably a no brainer but I am spent right now. Here is my long code(The switch statement is in my main class and the methods are in an object class):
public class MyProgram2{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
Scanner input = new Scanner (System.in);
String menu, outputString, poo;
int option = 1;
int id = 0;
double balance = 0, amount = 0;
Account acc = new Account();
menu ="\n\t1 Create Account and ID" +
"\n\t2 Check balance" +
"\n\t3 Withdraw" +
"\n\t4 Deposit" +
"\n\t5 Get account ID" +
"\n\t6 Display Account Info" +
"\n\t0 Quit\n\n\n";
System.out.println(menu);
System.out.println("\tEnter your selection: ");
option = scan.nextInt();
while (option != 0) {
switch (option) {
case 1: //Create an account and set ID
System.out.print("Enter Your Account ID to create account:\t");
id = input.nextInt();
System.out.println("Account created!");
break;
case 2: //check balance
acc.checkBalance(balance);
break;
case 3: //withdraw money
acc.withdraw(balance, amount);
break;
case 4: //deposit money
acc.deposit(balance, amount);
break;
case 5: //get account id
acc.getID(id);
break;
case 7: //display account info
System.out.print("option 7");
break;
default: outputString = "\nInvalid Selection\n";
System.out.println(outputString);
break;
}
System.out.println(menu);
System.out.print("\tEnter your selection: ");
option = scan.nextInt();
}
And these are the methods I am calling:
public class Account{
Scanner input = new Scanner (System.in);
public Account(){
}
public void getID(int id){
System.out.println("Your account ID is:\t" + id);
}
public void checkBalance(double balance){
System.out.println("Your balance is:\t$" + balance);
}
public double withdraw(double amount, double balance){
System.out.println("How much do you want to withdraw?:\t$");
amount = input.nextDouble();
balance -= amount;
return balance;
}
public double deposit(double amount, double balance){
System.out.println("How much do you want to deposit?:\t");
amount = input.nextDouble();
balance += amount;
return balance;
}
public void getAccountInfo(int id, double balance){
}
}
The variable double balance cannot be passed as a reference. It does a copy so when you try to manipulate it, it won't affect the original that you pass as an argument. You need to update the value using the return value that you have in the function.
In order to make it work, you should do:
case 4: //deposit money
// note here that you need to update the balance variable using the return value that
// you put in the function
balance = acc.deposit(balance, amount);
break;
Note: Your design separating the balance from the Account class is not ideal per #Psyrus's answer. You should keep the balance as part of the Account class. The reason being that balance is part of the account and if your program grows to handle multiple accounts (just for the sake of examples), separating the variable balance from the account would create maintenance headache (imagine that with two instances of Account, you will have balance1 and balance2 variables (or whatever you will call it) in MyProgram2, the main application). While I gave the cause of your problem in regards of variable passing, you should refactor your code to follow #Psyrus suggestion.
You have your whole Account class set up but without the actual balance variable inside it. Move that variable from your program to your class and it should work. Upon looking further, you have kind of jumbled up bits between the two so do this:
public class MyProgram2{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
Scanner input = new Scanner (System.in);
String menu, outputString, poo;
int option = 1;
int id = 0;
Account acc = new Account();
menu ="\n\t1 Create Account and ID" +
"\n\t2 Check balance" +
"\n\t3 Withdraw" +
"\n\t4 Deposit" +
"\n\t5 Get account ID" +
"\n\t6 Display Account Info" +
"\n\t0 Quit\n\n\n";
do {
System.out.println(menu);
System.out.println("\tEnter your selection: ");
option = scan.nextInt();
switch (option) {
case 1: //Create an account and set ID
System.out.print("Enter Your Account ID to create account:\t");
id = input.nextInt();
System.out.println("Account created!");
break;
case 2: //check balance
acc.checkBalance();
break;
case 3: //withdraw money
acc.withdraw();
break;
case 4: //deposit money
acc.deposit();
break;
case 5: //get account id
acc.getID(id);
break;
case 7: //display account info
System.out.print("option 7");
break;
default: outputString = "\nInvalid Selection\n";
System.out.println(outputString);
break;
}
} while (option != 0);
}
}
public class Account{
Scanner scan = new Scanner(System.in);
Scanner input = new Scanner (System.in); double balance = 0;
public Account(){
}
public void getID(id){
System.out.println("Your account ID is:\t" + id);
}
public void checkBalance(){
System.out.println("Your balance is:\t$" + balance);
}
public double withdraw(){
System.out.println("How much do you want to withdraw?:\t$");
double amount = input.nextDouble();
balance -= amount;
}
public double deposit(){
System.out.println("How much do you want to deposit?:\t");
double amount = input.nextDouble();
balance += amount;
return balance;
}
public void getAccountInfo(int id, double balance){
}
}
That is one way of doing it, but like I say, your design is a bit of a cross between classes. You should try to keep all properties for an object within that class and create functions for that class to obtain / modify the properties. Printing to the user should be contained in the class responsible for giving the user the interface.
Edit: Oops forgot the while at the end of the do while loop...
You just need to modify the instance you created like this:
public double deposit(){
System.out.println("How much do you want to deposit?:\t");
this.amount = input.nextDouble();
this.balance += amount;
return balance;
}
The this keyword refers to the object that is calling this method in this case acc, so this.amount will modify the amount for that instance.
In your current code, you are just modifying the local variables.
You also need to update your Account class to have the amount and balance attributes:
public class Account{
Scanner input = new Scanner (System.in);
double balance = 0, amount = 0;

Categories

Resources