VendingMachine class [35 pts]
Write the VendingMachine class so that it passes testVendingMachineClass, and
uses the OOP constructs we learned this week as appropriate.
Hint: Make sure you're representing money properly wherever it might appear in the string representation of a Vending Machine. The test cases shown here don't cover every possible case...
def testVendingMachineClass():
print("Testing Vending Machine class...", end="")
# Vending machines have three main properties:
# how many bottles they contain, the price of a bottle, and
# how much money has been paid. A new vending machine starts with no
# money paid.
vm1 = VendingMachine(100, 125)
assert(str(vm1) == "Vending Machine:<100 bottles; $1.25 each; $0 paid>")
assert(vm1.isEmpty() == False)
assert(vm1.getBottleCount() == 100)
assert(vm1.stillOwe() == 125)
# When the user inserts money, the machine returns a message about their
# status and any change they need as a tuple.
assert(vm1.insertMoney(20) == ("Still owe $1.05", 0))
assert(str(vm1) == "Vending Machine:<100 bottles; $1.25 each; $0.20 paid>")
assert(vm1.stillOwe() == 105)
assert(vm1.getBottleCount() == 100)
assert(vm1.insertMoney(5) == ("Still owe $1", 0))
# When the user has paid enough money, they get a bottle and
# the money owed resets.
assert(vm1.insertMoney(100) == ("Got a bottle!", 0))
assert(vm1.getBottleCount() == 99)
assert(vm1.stillOwe() == 125)
assert(str(vm1) == "Vending Machine:<99 bottles; $1.25 each; $0 paid>")
# If the user pays too much money, they get their change back with the
# bottle.
assert(vm1.insertMoney(500) == ("Got a bottle!", 375))
assert(vm1.getBottleCount() == 98)
assert(vm1.stillOwe() == 125)
# Machines can become empty
vm2 = VendingMachine(1, 120)
assert(str(vm2) == "Vending Machine:<1 bottle; $1.20 each; $0 paid>")
assert(vm2.isEmpty() == False)
assert(vm2.insertMoney(120) == ("Got a bottle!", 0))
assert(vm2.getBottleCount() == 0)
assert(vm2.isEmpty() == True)
# Once a machine is empty, it should not accept money until it is restocked.
assert(str(vm2) == "Vending Machine:<0 bottles; $1.20 each; $0 paid>")
assert(vm2.insertMoney(25) == ("Machine is empty", 25))
assert(vm2.insertMoney(120) == ("Machine is empty", 120))
assert(vm2.stillOwe() == 120)
vm2.stockMachine(20) # Does not return anything
assert(vm2.getBottleCount() == 20)
assert(vm2.isEmpty() == False)
assert(str(vm2) == "Vending Machine:<20 bottles; $1.20 each; $0 paid>")
assert(vm2.insertMoney(25) == ("Still owe $0.95", 0))
assert(vm2.stillOwe() == 95)
vm2.stockMachine(20)
assert(vm2.getBottleCount() == 40)
# We should be able to test machines for basic functionality
vm3 = VendingMachine(50, 100)
vm4 = VendingMachine(50, 100)
vm5 = VendingMachine(20, 100)
vm6 = VendingMachine(50, 200)
vm7 = "Vending Machine"
assert(vm3 == vm4)
assert(vm3 != vm5)
assert(vm3 != vm6)
assert(vm3 != vm7) # should not crash!
s = set()
assert(vm3 not in s)
s.add(vm4)
assert(vm3 in s)
s.remove(vm4)
assert(vm3 not in s)
assert(vm4.insertMoney(50) == ("Still owe $0.50", 0))
assert(vm3 != vm4)
print("Done!")
Gate class and Subclasses [30 pts]
A logic gate is a physical device that creates the functional equivalent of a logic operation in code [and, or, not]. It takes some number of input values, such as two values for and (input1 and input2), and produces a single output value. Write the Gate classes required to make the following test function work properly.
def getLocalMethods(clss):
import types
# This is a helper function for the test function below.
# It returns a sorted list of the names of the methods
# defined in a class.
result = [ ]
for var in clss.__dict__:
val = clss.__dict__[var]
if (isinstance(val, types.FunctionType)):
result.append(var)
return sorted(result)
def testGateClasses():
print("Testing Gate Classes... ", end="")
# require methods be written in appropriate classes
assert(getLocalMethods(Gate) == ['__init__', '__str__',
'numberOfInputs', 'setInput'])
assert(getLocalMethods(AndGate) == ['getOutput'])
assert(getLocalMethods(OrGate) == ['getOutput'])
assert(getLocalMethods(NotGate) == ['getOutput', 'numberOfInputs'])
# make a simple And gate
and1 = AndGate()
assert(type(and1) == AndGate)
assert(isinstance(and1, Gate) == True)
assert(and1.numberOfInputs() == 2)
and1.setInput(0, True)
and1.setInput(1, False)
# Hint: to get the name of the class given an object obj,
# you can do this: type(obj).__name__
# You might do this in the Gate.__str__ method...
assert(str(and1) == "And(True,False)")
assert(and1.getOutput() == False)
and1.setInput(1, True) # now both inputs are True
assert(and1.getOutput() == True)
assert(str(and1) == "And(True,True)")
# make a simple Or gate
or1 = OrGate()
assert(type(or1) == OrGate)
assert(isinstance(or1, Gate) == True)
assert(or1.numberOfInputs() == 2)
or1.setInput(0, False)
or1.setInput(1, False)
assert(or1.getOutput() == False)
assert(str(or1) == "Or(False,False)")
or1.setInput(1, True)
assert(or1.getOutput() == True)
assert(str(or1) == "Or(False,True)")
# make a simple Not gate
not1 = NotGate()
assert(type(not1) == NotGate)
assert(isinstance(not1, Gate) == True)
assert(not1.numberOfInputs() == 1)
not1.setInput(0, False)
assert(not1.getOutput() == True)
assert(str(not1) == "Not(False)")
not1.setInput(0, True)
assert(not1.getOutput() == False)
assert(str(not1) == "Not(True)")
print("Passed!")
testGateClasses()