Question

01.7) (13 pts) Modeling using a finite state machine. (a) (10 pts) Design and Draw a Vending Machine (VM) that accepts only I
0 0
Add a comment Improve this question Transcribed image text
Answer #1

VendingMachine.java
The public API of vending machine, usually all high-level functionality should go in this class

package vending;

import java.util.List;

/**
  * Decleare public API for Vending Machine
  */
public interface VendingMachine {   
    public long selectItemAndGetPrice(Item item);
    public void insertAed(Aed Aed);
    public List<Aed> refund();
    public Bucket<Item, List<Aed>> collectItemAndChange();   
    public void reset();
}

VendingMachineImpl.java
A sample implementation of VendingMachine interface represents a real world Vending Machine , which you see in your office, bus stand, railway station and public places.

package vending;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
  * Sample implementation of Vending Machine in Java
  */
public class VendingMachineImpl implements VendingMachine {   
    private Inventory<Aed> cashInventory = new Inventory<Aed>();
    private Inventory<Item> itemInventory = new Inventory<Item>();  
    private long totalSales;
    private Item currentItem;
    private long currentBalance; 
   
    public VendingMachineImpl(){
        initialize();
    }
   
    private void initialize(){       
        //initialize machine with 1 aed of each denomination     
        for(Aed c : Aed.values()){
            cashInventory.put(c, 1);
        }
       
        for(Item i : Item.values()){
            itemInventory.put(i, 1);
        }
       
    }
   
   @Override
    public long selectItemAndGetPrice(Item item) {
        if(itemInventory.hasItem(item)){
            currentItem = item;
            return currentItem.getPrice();
        }
        throw new SoldOutException("Sold Out, Please buy another item");
    }

    @Override
    public void insertAed(Aed aed) {
        currentBalance = currentBalance + coin.getDenomination();
        cashInventory.add(aed);
    }

    @Override
    public Bucket<Item, List<Aed>> collectItemAndChange() {
        Item item = collectItem();
        totalSales = totalSales + currentItem.getPrice();
       
        List<Aed> change = collectChange();
       
        return new Bucket<Item, List<Aed>>(item, change);
    }
       
    private Item collectItem() throws NotSufficientChangeException,
            NotFullPaidException{
        if(isFullPaid()){
            if(hasSufficientChange()){
                itemInventory.deduct(currentItem);
                return currentItem;
            }           
            throw new NotSufficientChangeException("Not Sufficient change in 
                                                    Inventory");
           
        }
        long remainingBalance = currentItem.getPrice() - currentBalance;
        throw new NotFullPaidException("Price not full paid, remaining : ", 
                                          remainingBalance);
    }
   
    private List<Coin> collectChange() {
        long changeAmount = currentBalance - currentItem.getPrice();
        List<Coin> change = getChange(changeAmount);
        updateCashInventory(change);
        currentBalance = 0;
        currentItem = null;
        return change;
    }
   
    @Override
    public List<Aed> refund(){
        List<Aed> refund = getChange(currentBalance);
        updateCashInventory(refund);
        currentBalance = 0;
        currentItem = null;
        return refund;
    }
   
   
    private boolean isFullPaid() {
        if(currentBalance >= currentItem.getPrice()){
            return true;
        }
        return false;
    }

      
    private List<Aed> getChange(long amount) throws NotSufficientChangeException{
        List<Aed> changes = Collections.EMPTY_LIST;
       
        if(amount > 0){
            changes = new ArrayList<Aed>();
            long balance = amount;
            while(balance > 0){
                if(balance >= Aed.QUARTER.getDenomination() 
                            && cashInventory.hasItem(Aed.QUARTER)){
                    changes.add(Aed.QUARTER);
                    balance = balance - Aed.QUARTER.getDenomination();
                    continue;
                   
                }else if(balance >= Aed.DIME.getDenomination() 
                                 && cashInventory.hasItem(Aed.DIME)) {
                    changes.add(Aed.DIME);
                    balance = balance - Aed.DIME.getDenomination();
                    continue;
                   
                }else if(balance >= Aed.NICKLE.getDenomination() 
                                 && cashInventory.hasItem(Aed.NICKLE)) {
                    changes.add(Aed.NICKLE);
                    balance = balance - Aed.NICKLE.getDenomination();
                    continue;
                   
                }else if(balance >= Aed.PENNY.getDenomination() 
                                 && cashInventory.hasItem(Aed.PENNY)) {
                    changes.add(Aed.PENNY);
                    balance = balance - Aed.PENNY.getDenomination();
                    continue;
                   
                }else{
                    throw new NotSufficientChangeException("NotSufficientChange,
                                       Please try another product");
                }
            }
        }
       
        return changes;
    }
   
    @Override
    public void reset(){
        cashInventory.clear();
        itemInventory.clear();
        totalSales = 0;
        currentItem = null;
        currentBalance = 0;
    } 
       
    public void printStats(){
        System.out.println("Total Sales : " + totalSales);
        System.out.println("Current Item Inventory : " + itemInventory);
        System.out.println("Current Cash Inventory : " + cashInventory);
    }   
   
  
    private boolean hasSufficientChange(){
        return hasSufficientChangeForAmount(currentBalance - currentItem.getPrice());
    }
   
    private boolean hasSufficientChangeForAmount(long amount){
        boolean hasChange = true;
        try{
            getChange(amount);
        }catch(NotSufficientChangeException nsce){
            return hasChange = false;
        }
       
        return hasChange;
    }

    private void updateCashInventory(List change) {
        for(Aed c : change){
            cashInventory.deduct(c);
        }
    }
   
    public long getTotalSales(){
        return totalSales;
    }
   
}

VendingMachineFactory.java

A Factory class to create different kinds of Vending Machine

package vending;

/**
  * Factory class to create instance of Vending Machine, this can be extended to create instance of
  * different types of vending machines.
  */
public class VendingMachineFactory {      
    public static VendingMachine createVendingMachine() {
        return new VendingMachineImpl();
    }
}

Item.java
Java Enum to represent Item served by Vending Machine

package vending;
/**
  * Items or products supported by Vending Machine.
  */
public enum Item{
   COLA("Cola", 2), MASAFI("Masafi", 1);
   
    private String name;
    private int price;
   
    private Item(String name, int price){
        this.name = name;
        this.price = price;
    }
   
    public String getName(){
        return name;
    }
   
    public long getPrice(){
        return price;
    }
}


Aed.java
Another Java Enum to represent Aeds supported by Vending Machine

package vending;

/**
  * Aeds supported by Vending Machine.
  */
public enum Aed {
    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
   
    private int denomination;
   
    private Aed(int denomination){
        this.denomination = denomination;
    }
   
    public int getDenomination(){
        return denomination;
    }
}
Inventory.java
A Java class to represent an Inventory, used for creating case and item inventory inside Vending Machine.

package vending;
import java.util.HashMap;
import java.util.Map;

/**
  * An Adapter over Map to create Inventory to hold cash and 
  * Items inside Vending Machine
  */
public class Inventory<T> {
    private Map<T, Integer> inventory = new HashMap<T, Integer>();
   
    public int getQuantity(T item){
        Integer value = inventory.get(item);
        return value == null? 0 : value ;
    }
   
    public void add(T item){
        int count = inventory.get(item);
        inventory.put(item, count+1);
    }
   
    public void deduct(T item) {
        if (hasItem(item)) {
            int count = inventory.get(item);
            inventory.put(item, count - 1);
        }
    }
   
    public boolean hasItem(T item){
        return getQuantity(item) > 0;
    }
   
    public void clear(){
        inventory.clear();
    }

    public void put(T item, int quantity) {
        inventory.put(item, quantity);
    }
}

Bucket.java
A parameterized utility class to hold two objects.

package vending;
/**
  * A parameterized utility class to hold two different object.
  */
public class Bucket<E1, E2> {
    private E1 first;
    private E2 second;
   
    public Bucket(E1 first, E2 second){
        this.first = first;
        this.second = second;
    }
   
    public E1 getFirst(){
        return first;
    }
   
    public E2 getSecond(){
        return second;
    }
}

NotFullPaidException.java
An Exception, thrown by Vending Machine when a user tries to collect an item, without paying the full amount.

package vending;
public class NotFullPaidException extends RuntimeException {
    private String message;
    private long remaining;
   
    public NotFullPaidException(String message, long remaining) {
        this.message = message;
        this.remaining = remaining;
    }
   
    public long getRemaining(){
        return remaining;
    }
   
    @Override
    public String getMessage(){
        return message + remaining;
    } 
   
}

NotSufficientChangeException.java
Vending Machine throws this exception to indicate that it doesn't have sufficient change to complete this request.

package vending;
public class NotSufficientChangeException extends RuntimeException {
    private String message;
   
    public NotSufficientChangeException(String string) {
        this.message = string;
    }
   
    @Override
    public String getMessage(){
        return message;
    }
   
}

SoldOutException.java
The Vending Machine throws this exception if the user request for a product which is sold out

package vending;
public class SoldOutException extends RuntimeException {
    private String message;
   
    public SoldOutException(String string) {
        this.message = string;
    }
   
    @Override
    public String getMessage(){
        return message;
    }
   
}
Add a comment
Know the answer?
Add Answer to:
01.7) (13 pts) Modeling using a finite state machine. (a) (10 pts) Design and Draw a Vending Machine (VM) that acce...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • 3. Finite State Machine. Using a ROM based finite state machine (FSM), design a bi-directional repetitive...

    3. Finite State Machine. Using a ROM based finite state machine (FSM), design a bi-directional repetitive 3-bit modulo-6 (0,1,2,3,4,5) counter (see Table 3). The design has one input named Dir and three outputs named B2, B1 and BO. The outputs (B2, B1 and BO) are dependent upon being in the present state only. After each clock pulse, when Dir is at logic "O', the outputs (B2, B1, BO) step through the count sequence in following order:- 0,1,2,3,4,5. After each clock...

  • Question 4 State Machines (25 marks) A state machine is required for a simple vending machine....

    Question 4 State Machines (25 marks) A state machine is required for a simple vending machine. The machine takes one dollar coins only. Each time a coin is added the input signal "coin" is set to 1 for one clock cycle When a total of $4 has been added the output signal "deliver" is set to 1 for one clock cycle and the state machine starts counting coins for the next delivery a) (5 marks) Draw a state diagram for...

  • C++ HW Question Your program will simulate a simple change maker for a vending machine. It...

    C++ HW Question Your program will simulate a simple change maker for a vending machine. It will start with a stock of coins and dollars. It will then repeatedly request the price for an item to be purchased or to quit. If given a price, it will accept nickels, dimes, quarters, one-dollar and five-dollar bills—deposited one at a time—in payment. When the user has deposited enough to cover the cost of the item, the program will calculate the coins to...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT