Skip to content

Instantly share code, notes, and snippets.

@Rahandi
Created October 19, 2017 17:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Rahandi/16877b60214f779772de9f8c1af99961 to your computer and use it in GitHub Desktop.
Save Rahandi/16877b60214f779772de9f8c1af99961 to your computer and use it in GitHub Desktop.
ATM
public class Account
{
private int accountNumber; // account number
private int pin; // PIN for authentication
private double availableBalance; // funds available for withdrawal
private double totalBalance; // funds available + pending deposits
// Account constructor initializes attributes
public Account(int theAccountNumber, int thePIN, double theAvailableBalance, double theTotalBalance){
accountNumber = theAccountNumber;
pin = thePIN;
availableBalance = theAvailableBalance;
totalBalance = theTotalBalance;
} // end Account constructor
// determines whether a user-specified PIN matches PIN in Account
public boolean validatePIN(int userPIN){
if(userPIN == pin){
return true; // means the PIN input is match with the user's PIN
}
else{
return false; // means the PIN input is not match with the user's PIN
}
} // end method validatePIN
// returns available balance
public double getAvailableBalance(){
return availableBalance;
}
// returns the total balance
public double getTotalBalance(){
return totalBalance;
}
// credits an amount to the account
public void credit(double amount){
totalBalance += amount; // add to total balance
}
// debits an amount from the account
public void debit(double amount){
availableBalance -= amount; // substract from available balance
totalBalance -= amount; // substract from total balance
}
// returns account number
public int getAccountNumber(){
return accountNumber;
}
} // end class Account
public class ATM
{
private boolean userAuthenticated;
private int currentAccountNumber;
private Screen screen;
private Keypad keypad;
private CashDispenser cashDispenser;
private DepositSlot depositSlot;
private BankDatabase bankDatabase;
private static final int BALANCE_INQUIRY = 1;
private static final int WITHDRAWAL = 2;
private static final int DEPOSIT = 3;
private static final int EXIT = 4;
public ATM(){
userAuthenticated = false;
currentAccountNumber = 0;
screen = new Screen();
keypad = new Keypad();
cashDispenser = new CashDispenser();
depositSlot = new DepositSlot();
bankDatabase = new BankDatabase();
}
public void run(){
while(true){
while(!userAuthenticated){
screen.displayMessageLine("\nWelcome!");
authenticateUser();
}
performTransactions();
userAuthenticated = false;
currentAccountNumber = 0;
screen.displayMessageLine("\nThank You!\nGoodbye!");
}
}
private void authenticateUser(){
screen.displayMessage("\nPlease enter your account number : ");
int accountNumber = keypad.getInput();
screen.displayMessage("\nEnter your PIN : ");
int pin = keypad.getInput();
userAuthenticated = bankDatabase.authenticateUser(accountNumber, pin);
if(userAuthenticated){
currentAccountNumber = accountNumber;
}
else{
screen.displayMessageLine("Invalid Account Number or PIN.");
screen.displayMessageLine("Please Try Again.");
}
}
private void performTransactions(){
Transaction currentTransaction = null;
boolean userExited = false;
while(!userExited){
int mainMenuSelection = displayMainMenu();
switch(mainMenuSelection){
case BALANCE_INQUIRY :
case WITHDRAWAL :
case DEPOSIT :
currentTransaction = createTransaction(mainMenuSelection);
currentTransaction.execute();
break;
case EXIT :
screen.displayMessageLine("\nExiting the system...");
userExited = true;
break;
default :
screen.displayMessageLine("\nYou did not enter a valid selection.");
screen.displayMessageLine("Please try again.");
break;
}
}
}
private int displayMainMenu(){
screen.displayMessageLine("\nMain Menu :");
screen.displayMessageLine("1 - View my balance");
screen.displayMessageLine("2 - Withdraw cash");
screen.displayMessageLine("3 - Deposit funds");
screen.displayMessageLine("4 - Exit\n");
screen.displayMessage("Enter a choice : ");
return keypad.getInput();
}
private Transaction createTransaction(int type){
Transaction temp = null;
switch(type){
case BALANCE_INQUIRY :
temp = new BalanceInquiry(currentAccountNumber, screen, bankDatabase);
break;
case WITHDRAWAL :
temp = new Withdrawal(currentAccountNumber, screen, bankDatabase, keypad, cashDispenser);
break;
case DEPOSIT :
temp = new Deposit(currentAccountNumber, screen, bankDatabase, keypad, depositSlot);
break;
}
return temp;
}
}
public class BalanceInquiry extends Transaction
{
// BalanceInquiry constructor
public BalanceInquiry(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase){
super(userAccountNumber, atmScreen, atmBankDatabase);
} // end BalanceInquiry constructor
// performs the transaction
@Override
public void execute(){
// get references to bank database and screen
BankDatabase bankDatabase = getBankDatabase();
Screen screen = getScreen();
// get the available balance for the account involved
double availableBalance = bankDatabase.getAvailableBalance(getAccountNumber());
// get the total balance for the account involved
double totalBalance = bankDatabase.getTotalBalance(getAccountNumber());
// display the balance information on the screen
screen.displayMessageLine("\nBalance Information : ");
screen.displayMessage(" - Available Balance : ");
screen.displayDollarAmount(availableBalance);
screen.displayMessage("\n - Total Balance : ");
screen.displayDollarAmount(totalBalance);
screen.displayMessageLine("");
} // end method execute
} // end class BalanceInquiry
public class BankDatabase
{
private Account[] accounts; // array of Accounts
// no-argument BankDatabase constructor initializes accounts
public BankDatabase(){
accounts = new Account[2]; // just 2 accounts for testing
accounts[0] = new Account(12345, 54321, 1000.0, 1200.0);
accounts[1] = new Account(98765, 56789, 200.0, 200.0);
} // end no-argument BankDatabase constructor
// retrieve Account object containing specified account number
private Account getAccount(int accountNumber){
// loop through accounts searching for matching account number
for(Account currentAccount : accounts){
// return current account if match found
if(currentAccount.getAccountNumber() == accountNumber) return currentAccount;
} // end for
return null; // if no matching account was found, return null
} // end method
// determine whether user-specified account number and PIN match
// those of an account in the database
public boolean authenticateUser(int userAccountNumber, int userPIN){
// attempt to retrieve the account with the account number
Account userAccount = getAccount(userAccountNumber);
if(userAccount != null){
return userAccount.validatePIN(userPIN);
}
else{
return false; // account number not found, so return false
}
} // end method
// return available balance of Account with specified account number
public double getAvailableBalance(int userAccountNumber){
return getAccount(userAccountNumber).getAvailableBalance();
} // end method
public double getTotalBalance(int userAccountNumber){
return getAccount(userAccountNumber).getTotalBalance();
} // end method
public void credit(int userAccountNumber, double amount){
getAccount(userAccountNumber).credit(amount);
} // end method
public void debit(int userAccountNumber, double amount){
getAccount(userAccountNumber).debit(amount);
} // end method
} // end class BankDatabase
public class CashDispenser
{
// the default initial number of bills in the cash dispenser
private final static int INITIAL_COUNT = 500;
private int count; // number of $20 bills remaining
// no-argument CashDispenser constructor initializes count to default
public CashDispenser(){
count = INITIAL_COUNT; // set count attribute to default
} // end CashDispenser constructor
// simulates dispensing of specified amount of cash
public void dispenseCash(int amount){
int billsRequired = amount / 20; // number of $20 bills required
count -= billsRequired; // update the count of bills
} // end method dispenseCash
// indicates whether cash dispenser can dispense desired amount
public boolean isSufficientCashAvailable(int amount){
int billsRequired = amount / 20;
if(count >= billsRequired){
return true; // enough bills required
}
else{
return false; // not enough bills required
}
} // end method isSufficientCashAvailable
} // end class CashDispenser
public class Deposit extends Transaction
{
private double amount; // amount to deposit
private Keypad keypad; // references to keypad
private DepositSlot depositSlot; // references to deposit slot
private final static int CANCELED = 0; // constant for cancel option
// Deposit constructor
public Deposit(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase, Keypad atmKeypad, DepositSlot atmDepositSlot){
// initializes superclass variables
super(userAccountNumber, atmScreen, atmBankDatabase);
// initialize references to keypad and deposit slot
keypad = atmKeypad;
depositSlot = atmDepositSlot;
} // end Deposit constructor
// perform transaction
@Override
public void execute(){
BankDatabase bankDatabase = getBankDatabase(); // get reference
Screen screen = getScreen(); // get reference
amount = promptForDepositAmount(); // get deposit amount from user
// check whether the user entered a deposit amount or canceled
if(amount != CANCELED){
// request deposit envelope containing specified amount
screen.displayMessage("\nPlease insert a deposit envelope containing ");
screen.displayDollarAmount(amount);
screen.displayMessage(".");
// receive deposit envelope
boolean envelopeReceived = depositSlot.isEnvelopeReceived();
// check whether deposit envelope was received
if(envelopeReceived){
screen.displayMessageLine("\nYour envelope has been received.");
screen.displayMessage("NOTE: The money just deposited will not be available until we verify the amount");
screen.displayMessage("of any enclosed cash and your checks clear.");
// credit account to reflect the deposit
bankDatabase.credit(getAccountNumber(), amount);
} // end if
else{
// deposit envelope not received
screen.displayMessageLine("\nYou did not insert an envelope");
screen.displayMessageLine("So, the ATM has canceled your transaction.");
} // end else
} // end if
else{
// user canceled instead of entering amount
screen.displayMessageLine("\nCanceling transaction...");
} // end else
} // end method execute
// prompt user to enter a deposit amount in cents
private double promptForDepositAmount(){
Screen screen = getScreen(); // get references to screen
// display the prompt
screen.displayMessage("\nPlease enter a deposit amount in CENTS (or 0 to cancel)");
int input = keypad.getInput(); // receive input of deposit amount
// check whether the user canceled or entered a valid amount
if(input == CANCELED) return CANCELED;
else{
return (double) input / 100; // return dollar amount
} // end else
} // end method
} // end class Deposit
public class DepositSlot
{
// indicate whether envelope was received (always returns true)
// because this is only a software simulation of a real deposit slot
public boolean isEnvelopeReceived(){
return true; // deposit envelope was received
} // end method isEnvelopeReceived
} // end class DepositSlot
import java.util.Scanner;
public class Keypad
{
private Scanner input; // reads data from the command line
// no-argument constructor initializes the Scanner
public Keypad(){
input = new Scanner(System.in);
} // end no-argument Keypad constructor
// return an integer value entered by user
public int getInput(){
return input.nextInt(); // we assume that user enters an integer
} // end method getInput
} // end class Keypad
public class Screen
{
// display a message without a carriage return
public void displayMessage(String message){
System.out.print(message);
} // end method displayMessage
// display a message with a carriage return
public void displayMessageLine(String message){
System.out.println(message);
} // end method displayMessageLine
// displays a dollar amount
public void displayDollarAmount(double amount){
System.out.printf("$%,.2f", amount);
} // end method displayDollarAmount
} // end class Screen
public abstract class Transaction
{
private int accountNumber; // indicates account involved
private Screen screen; // ATM's screen
private BankDatabase bankDatabase; // account info database
// Transaction constructor invoked by subclasses using super()
public Transaction(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase){
accountNumber = userAccountNumber;
screen = atmScreen;
bankDatabase = atmBankDatabase;
} // end Transaction constructor
// return account number
public int getAccountNumber(){
return accountNumber;
} // end method
// return reference to screen
public Screen getScreen(){
return screen;
} // end method
// return reference to bank database
public BankDatabase getBankDatabase(){
return bankDatabase;
} // end method
// perform the transaction (overridden by each subclass)
abstract public void execute();
} // end class Transaction
public class Withdrawal extends Transaction
{
private int amount; // amount to withdraw
private Keypad keypad; // references to keypad
private CashDispenser cashDispenser; // references to cash dispenser
// constant corresponding to menu option to cancel
private final static int CANCELED = 6;
// Withdrawal constructor
public Withdrawal(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase, Keypad atmKeypad, CashDispenser atmCashDispenser){
// initializes superclass variables
super(userAccountNumber, atmScreen, atmBankDatabase);
// initializes references to keypad and cash dispenser
keypad = atmKeypad;
cashDispenser = atmCashDispenser;
} // end Withdrawal constructor
// perform transaction
@Override
public void execute(){
boolean cashDispensed = false; // cash was not dispensed yet
double availableBalance; // amount available for withdrawal
// get references to bank database and screen
BankDatabase bankDatabase = getBankDatabase();
Screen screen = getScreen();
// loop until cash is dispensed or the user cancels
do{
// obtain a chosen withdrawal amount from the user
amount = displayMenuOfAmounts();
// check whether user choose a withdrawal amount or canceled
if(amount != CANCELED){
// get available balance of account involved
availableBalance = bankDatabase.getAvailableBalance(getAccountNumber());
// check whether the user has enough money in the account
if(amount <= availableBalance){
// check whether the cash dispenser has enough money
if(cashDispenser.isSufficientCashAvailable(amount)){
// update the account involved to reflect the withdrawal
bankDatabase.debit(getAccountNumber(), amount);
cashDispenser.dispenseCash(amount); // dispense cash
cashDispensed = true; // cash was dispensed
// instructs user to take cash
screen.displayMessageLine("\nYour cash has been dispensed. Please take your cash now.");
} // end if
else{
// cash dispenser does not have enough cash
screen.displayMessageLine("\nInsufficient cash available in the ATM.");
screen.displayMessageLine("\nPlease choose a smaller amount.");
} // end if
} // end if
else{
// not enough money available in user's account
screen.displayMessageLine("\nInsufficient funds in your account.");
screen.displayMessageLine("\nPlease choose a smaller amount.");
} // end if
} // end if
else{
// user choose cancel menu option
screen.displayMessageLine("\nCancelling transactions...");
return; // return to main menu because user canceled
} // end if
} while(!cashDispensed);
} // end method execute
// display a menu of withdrawal amounts and the options to cancel
// return the chosen amount or 0 if the user chooses to cancel
private int displayMenuOfAmounts(){
int userChoice = 0; // local variable to store return value
Screen screen = getScreen(); // get screen references
// array of amounts to correspond to menu numbers
int[] amounts = {0, 20, 40, 60, 100, 200};
// loop while no valid choice has been made
while(userChoice == 0){
// display the withdrawal menu
screen.displayMessageLine("\nWithdrawal Menu : ");
screen.displayMessageLine("1 - $20");
screen.displayMessageLine("2 - $40");
screen.displayMessageLine("3 - $60");
screen.displayMessageLine("4 - $100");
screen.displayMessageLine("5 - $200");
screen.displayMessageLine("6 - Cancel Transaction");
screen.displayMessage("\nChoose a withdrawal amount : ");
int input = keypad.getInput(); // get user input through keypad
// determine how to proceed based on the input value
switch(input){
// if the user choose a withdrawal amount
// i.e choose option 1, 2, 3, 4 or 5
// return the corresponding amount from amounts's array
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
userChoice = amounts[input]; // save user's choice
break;
case CANCELED :
// the user choose to cancel
userChoice = CANCELED; // save user's choice
break;
default :
// the user did not enter value between 1-6
screen.displayMessageLine("\nInvalid selection.");
screen.displayMessageLine("Try again.");
} // end switch
} // end while
return userChoice; // return withdrawal amount or CANCELED
} // end method displayMenuOfAmounts
} // end class Withdrawal
@dineshkumarDK47
Copy link

I have doubt . U have written all the class as public class . U have written separately all public class . How to done this in command prompt to run all in one .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment