Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Cash_Register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'''
Author: Connor Johnson
Completed: 09/06/2021
Contains the main code to be run for the Cash Register project
'''

import sys
from calculate_change import *

# Read in data from text file
with open(sys.argv[1], 'r') as f:
lines = f.readlines()


# Loop through each line in the text file
counter = 0 # Counter for tracking which line the loop is on
for s in lines:
counter = counter + 1

# Input from text file is checked that it's formatted correctly and values are assigned
nums = s.split(",")
if len(nums) != 2:
print("Line " + str(counter) + " of input.txt must contain 2 numbers separated by a comma.")
continue
try:
cents = float(nums[1]) - float(nums[0]) #Calculate the change to be given
except ValueError:
print("Line " + str(counter) + " of input.txt must contain 2 numbers separated by a comma.")
continue

cents = int(cents*100+0.5) # Change cents to an integer that represents the total cents in change

final_change = calculate_change(cents)
if final_change == None:
print("Invalid Input. Total due can't be more than amount paid.")
else:
print(final_change[0])



37 changes: 37 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Connor Johnson
Cash Register Project
Completed: 09/06/2021


This project is used to find the coins that would be needed to give a certain amount of change. It takes a text file as input that should contain a list of values.
Each line in the text file should contain 2 numbers separated by a comma. The first number is the price of something that is being payed for. The second number is the amount
of money that the customer payed with. The program takes these numbers and returns the change that should be given back to the customers in dollars and coins. It normally
gives change in the least possible number of coins, except when the total change in cents is divisible by three. In this case, the different denominations of change given
is randomized while still adding up to the correct amount of change. If any lines in the input file are formatted incorrectly, they will be skipped, and the user will be
notified of the incorrectly formatted lines. The test python file contains unit tests to make sure the calculate change method works correctly for a range of values.

Files: Cash_Register.py, calculate_change.py, calculate_change_test.py

Cash_Register.py: This is the file that contains the main and is used to the run the applicaiton.
calculate_change.py: Contains a method that calculates the change and is called by Cash_Register.py
calculate_change_test.py: Contains a few unit tests to test the functionality of calculate_change.py

Running the application: Type the following command in the terminal
python Cash_Register.py [filename]
Example: python Cash_Register.py input.txt

Example Input:
1.33, 2.00
2.71,4.00
1.45,%4.00^
1.50

Example Output:
2 quarters, 1 dime, 1 nickel, 2 pennies
3 quarters, 1 dime, 1 nickel, 39 pennies
Line 3 of input.txt must contain 2 numbers separated by a comma.
Line 4 of input.txt must contain 2 numbers separated by a comma.

Modules: random, numpy, sys

Known Bugs: There are currently no known bugs contained in this project.
59 changes: 59 additions & 0 deletions calculate_change.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'''
Author: Connor Johnson
Completed: 09/06/2021
Contains the calculate_change method used in Cash_Register.py
'''

import random

# Names and values of coin denominations, pennies are excluded because they are handled differently
coin_values = [100, 25, 10, 5]
coin_names = ['dollar', 'quarter', 'dime', 'nickel']


def calculate_change(cents):
'''
calculate_change takes an amount in cents and calculates the change in coins that would be given for this amount
cents: The amount of cents in change as an integer
return: Returns a tuple containing a string that has the description of change and a list containing the value of each denomination; dollars, quarters, etc.
Returns None if cents is not a positive integer
'''
# Checks that cents is a positive integer
if type(cents) != int or cents < 0:
return None
# Handles if cents is equal to zero
if cents == 0:
return ('No change', [0,0,0,0,0])

coin_string = '' # Final string to be returned
div_by_3 = cents%3 == 0 # Boolean variable that is true if the total change is divisible by 3

coin_cents = [0] * 5 # Tracks the number of each denomination, will be returned by this function

for i in range(0,4):
# Number of each denomination is determined, picked randomly if the total cents is divisible by 3
if(div_by_3):
num_coins = random.randint(0,int(cents/coin_values[i]))
cents = cents - num_coins*coin_values[i]
else:
num_coins = int(cents/coin_values[i])
cents = cents%coin_values[i]

coin_cents[i] = num_coins

if num_coins == 0: # Add nothing to string if number of that coin type is zero
continue

# Add the number of each denomination to the final string
coin_string = coin_string + str(num_coins) + ' ' + coin_names[i]
if num_coins > 1:
coin_string = coin_string + 's'
coin_string = coin_string + ', '

# All remaining cents are set as pennies
coin_cents[4] = cents
if cents > 0:
coin_string = coin_string + '1 penny' if cents == 1 else coin_string + str(cents) + ' pennies'

# The resulting string and array of coins is returned
return (coin_string, coin_cents)
22 changes: 22 additions & 0 deletions calculate_change_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'''
Author: Connor Johnson
Completed: 09/06/2021
Contains some unit tests for calculate_change method
'''

from calculate_change import *
import numpy

coin_values = [100, 25, 10, 5, 1]

# Testing a range of positive values
for t in range(0, 500):
change = numpy.dot(calculate_change(t)[1], coin_values)
assert change == t, "Change is not the correct amount. Should be " + str(t) + ", but return is " + str(change)

# Testing a range of negative values
for t in range(-100, 0):
assert calculate_change(t) == None, "Method should return None since it is passed a negative integer"

# Testing a non integer argument
assert calculate_change("some_string") == None, "Method chould return none since it is passed a non integer"