Vending Machine Demo -- Commentary and Description

Program Description and General Comments

This program is the longest of my demo programs, but it is also the most involved. This program simulates the action of a vending machine. To implement this I design the program around the idea of machine states. Starting with the initial state of the machine in which it is waiting for user input, it will either progress to a more advanced state or return to its current state when given user input. Once the user reaches the final state in which all conditions are fulfilled and a selection of a candy is made, output from the machine is given in the form of candy and change. This is simulated by changing the contents of the text boxes in the form. The overall model is similar in idea to the Finite State Machine concept, but it is not a strict FSM since it allows multiple states to be true at a given time. The machine states, therefore, acts more like boolean flags than anything else.

Overview of Classes Used In The Program

CoinsQuantity:
This is used to hold the quantity of each coin to be given out as change.

CoinSlotData:
This is used to represent the contents in the coin return slot of the machine. The contents in the slot can include any valid coins dropped from the coin reserves of the machine as well as any invalid coins that are rejected by the machine.

CoinsHold:
This is used to represent the coin reserves of the machine. The current quantity of each unique coin is kept as well as the whether or not the reserve is full, the capacity of the coin reserve, the dollar amount that is "spilled over" and the residing slot of the most recently inserted coin.

CandyData:
This is used to hold the information of each unique kind or brand of candy stored in the machine. The information includes: the remaining quantity and the price of the candy.

Vendor:
This is the main class of the program and it is used to represent the entire vending machine.
The data items that it hold are:

Overview of How The Program Works

The program attempts to simulate as realistically as possible all the operations that would happen in a real physical vending machine. These would include all possible cases of input into the machine and output from the machine. It also takes into account all exceptional conditions such as invalid input or internal error states of the machine.

All input into the machine goes through main procedure: HandleInput
HandleInput will then pass the user input data to the appropriate handler function depending on the type of input. The types of input are:

Each of these specific inputs are handled by their corresponding handler functions:

Input Handler Functions Overview

The CoinDepositHandler function takes input as the coin deposited by the user and does the following:
  1. checks whether or not the coin inserted is a valid coin. If not the coin is dropped otherwise the machine state: coin_deposited is set to true.
  2. if the preceeding check is passed successfully then check if machine is initialized. If not the initialization procedures are called to initialize the machine. This include checking whether or not the machine is empty (all shelves are empty).
  3. If the machine is empty then the inserted coin is dropped and a message is displayed indicating this to the user otherwise the machine performs the following checks:
    1. checks to see if all possible combinations of change can be given for the current amount inserted.
    2. checks whether or not the current amount inserted exceeds the ceiling limit for the machine.

    if all possible combinations of change cannot be generated from the current coin reserves given the current amount inserted into the machine then the coin inserted along with the current amount stored is dropped to the coin return slot and the machine is reset to its starting state.

    if the ceiling limit for the machine is exceeded by the sum of the coin value and the current amount then the coin inserted is dropped. If the current amount excluding the coin value is zero then the machine is reset to its starting state.
The CoinReturnHandler function is executed if the coin return button is pressed. The function does the following:
  1. Test if coin has been inserted and accepted by the machine and the machine is in an initialized state. If test is successfull then:
    1. drop the current amount deposited into the coin return slot.
    2. reset the machine to its initial state.
The CandyRequestHandler function takes input as the candy button pressed by the user and does the following:
  1. Test if coin has been inserted and accepted by the machine and the machine is in an initialized state. If test is successfull then:
    1. check the shelf which stores the specified candy.
    2. if the specified candy shelf is empty then display a message indicating this to the user, otherwise:
      1. check if the current amount deposited by the user is equal or greater than the listed price of the specified candy.
      2. if the current amount deposited by the user is sufficient then drop the specified candy into the candy slot and drop any resulting change into the coin return slot, otherwise display a message indicating to the user that the current amount deposited is insufficient.
To describe the operations of the vending machine more clearly, here is an illustrated diagram of the top-level algorithm.

Testing The Program

In trying out the program to check if it works, you can test it haphazardly in which case you may not be able to catch all the bugs that the program potentially may have or you can plan a more detailed and complete test of the program by testing all potential inputs into the program and verifying that each input generates the corresponding valid output. This should be easy for the vending machine demo, since it has a small set of inputs which generates a predictable and specific set of outputs. Testing all cases is important since if this is a serious program which is loaded into an actual vending machine, errors could mean angry customers or loss of revenue or both. Although this is just a simulation program you should always have a serious approach to testing. This is just good programming practice.

The following list outlines a fairly complete test plan for the vending machine:

  1. Test if the coin deposited state is accounted for:
    To do this, press all the buttons except the ones for inserting coins.
    The correct response from the program should be: <no response>
  2. Test if the machine can detect if it is empty of all merchandise:
    to do this, replace the value in the quantity box for all candies with zero then insert any amount of coins and attempt a purchase by pressing any of the candy buttons.
    The correct response from the program should be:
  3. Test if correct change is given out:
    Test if the purchasing algorithm is correct:
    To do this, insert an amount which is over the price of a particular candy then purchase the candy by pressing the correctly labeled button.
    The correct response from the program should be:
    Note: this is far from an exhaustive test of the coin return algorithm. In order to verify that the algorithm is reliable in all potential cases it is necessary to really stress it by putting it through a wider range of input values. To do this, it is common practice to use a driver program. In the driver program we test the algorithm by giving it a large subset of all the possible input values (or the entire set of possible input values if the set is finite and the testing time is acceptable). Another method is to mathematically prove the correctness of the algorithm, but this is more difficult to implement.
    Here is the driver program written in C++: vendtest.cpp
  4. Test if out of change condition is detected:
    To do this, zero out all coin hold boxes in the vending machine then press the coin return button to reinitialize the program. Press the quarter button to insert a quarter.
    The correct response from the program should be: Note: this is far from a exhaustive test of the coin return algorithm. See the previous item.
  5. Test if the price ceiling of the machine is implemented correctly:
    To do this, insert up to $2.00 in coins then insert any valid coin to go over the $2.00 limit.
    The correct response from the program should be:
  6. Test if program only accepts valid coins:
    To do this, insert an invalid coin.
    The correct response from the program should be: The invalid coin dropped into the coin return slot.
  7. Test if the machine can detect if a specific candy is out of stock.
    To do this, zero out the quantity box of a particular candy then attempt to purchase the candy.
    The correct response from the program should be: a popped message box with the message "out of stock" and the same message displayed in the panel display box.
  8. Test if the machine can detect if the amount inserted is sufficient for purchasing a particular candy:
    To do this, insert an amount which is less than the listed price of a particular candy then attempt to purchase the candy.

    The correct response from the program should be: A popped message box with the message "insufficient funds" and the same message displayed in the panel display box.

    Next insert enough money to buy the candy and try again to purchase it.
    The correct response from the program should be: (see test #3)
  9. Test if coin return function works:
    To do this, insert any amount into the machine then press the coin return button.
    The correct response from the program should be: the amount inserted into the machine dropped into to coin return slot.

Peculiarities of The Vending Machine Program

You may notice that the vending machine complains that it is out of change when there are no coins in the coin reserves and you insert a coin or when there is only a nickel in the reserves and you insert a quarter. The reason it does this is that it checks ahead of time that the machine is able to give change for all multiples of 5 up to and including the total amount deposited. What is the reason for designing the machine this way? For one thing it is not possible to check if the machine can give change for all the listed prices of items in the machine until the actual selection is made. Another reason is that it is bad manners for the machine to accept your money which gives the false impression that it is ready to give you some candy and then when you choose a candy whine and groan that it is out of change and spits the money back out at you. But then again, this is a matter of personal preferences, so an alternative implementation could also work.

Experimenting With The Vending Machine Program

You can experiment with the vending machine program by directly changing the values in some of the text boxes. The program takes its input from the candy quantity text boxes and the coin reserves and spill over bucket text boxes. You can play around with various situations by modifying these values. The program is quite robust so you could enter any sensible value into the boxes and the program should handle them correctly. However, make sure the program is in its initial state when it is waiting for coins to be deposited before applying your modifications.

Summary

As you may have noticed that this is far from a comprehensive dismantling of the program. Describing the entire program in every detail would take far too much space and far too much time. Furthermore, although a full formal description of the program may be necessary in production quality software, this is not the goal of a demo program. The preceeding should provide a good Top-Level or Executive overview of general operations in the program. The vending machine demo program gives a good simulation of an embedded system. In a true embedded system there will be no fancy GUI, but the logic of the program will still be used to operate hardware devices for dropping coins, dropping candy and informing the user. A vending machine is a classic textbook case of a FSM implementation. Although this program does not implement a true FSM it borrows some ideas from the concept to implement the boolean status flags used in the program.

Also available for viewing is the accompanying pseudo-code for the program. Pseudo-code should always be written in the design phase of software development. This allows you to draw up a conceptual plan of how the program should work without worrying about technical specifics. Once the pseudo-code is written coding in the actual programming language should proceed smoothly, since most of the time translation from pseudo-code to a high-level language is straight forward. When viewing the pseudo-code you may notice missing parts and parts which may be different from the actual program. This is okay because pseudo-code is meant to be used as a rough first draft of the program. It is not meant to be used in formal program specifications. Here's the pseudo-code: vendalgo.txt