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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Cash Register
---
The requirement for this program is to create a cash register application that takes transaction data as input, and outputs change instructions. Change should be handled in the lowest number of bills and coins, unless the amount due is divisible by 3. If the amount due is divisible by 3, then the number of each denomination is randomized to give the customer correct change, but in mixed up denominations eg. 80 cents change could return as 1 nickel, 75 pennies.

This program is divided into three main packages;


1. com.kuhn.cashRegister
* the cashRegister package contains a hierarchy of classes used to control the money changing process.
a.Denomination is the lowest class in the cashRegister hierarchy, and contains only two parameters: Denomination and value.

b.Currency is the middle class in the cashRegister hierarchy, and contains a set of denomination instances. These instances can be modified to add support for non-standard currency types.

c.Till is the highest class in the cashRegister hierarchy, and contains the opening till value, instantiated currency object, and all money handling methods.
i. The transaction method detects errors and calls get change methods based on change divisibility.
ii. The getBasicChange method calculates the number and type of denominations to return using the fewest bills and coins.
iii. The getRandomChange method calculates the number and type of denominations to return using a randomized mix of denominations.
iv. The grammar method takes the denomination index and number of bills or coins and returns the proper plurality of the denomination.

2. com.kuhn.cashRegisterInputReader
* the cashRegisterInputReader package contains the classes necessary for reading from and writing to files.

3. com.kuhn.cashRegisterApplication
* the cashRegisterApplication package contains the runnable class as well as supporting documentation.

# Limitations
---
Input files formatted as charge,payment do not specify the amount and type of bills or coins given in the transaction. since this is not present, there is not good way to track individual denominations. If a Till object was initialized with a finite number of each bill and coin, the getChange methods would have to handle shortages. eg. 40 cents in change is due but only 3 dimes are left to give. two nickels are substituted for the "4th" dime. As transactions are completed, the transaction amount is added to the till as a lump sum, making it impossible to track denomination shorting.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
2.12,3.00
1.97,2.00
3.33,5.00
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.kuhn.cashRegister;

/**
* The Currency class is the middle class of the cashRegister package hierarchy.
* Currency contains the definitions and methods for all usable currency.
* This class can be modified to add support for non US based currency without modifying any other class..
*
* @author Sean Kuhn
* @Date 10/25/2019
*
*/
public class Currency {
private Denomination currency[];

//Initializes Currency with denominations common in the united states. Excluded $2 bills and half dollar coins.
public Currency() {
currency = new Denomination[] {
new Denomination("hundreds",10000),
new Denomination("fifties",5000),
new Denomination("twenties",2000),
new Denomination("tens",1000),
new Denomination("fives",500),
new Denomination("ones",100),
new Denomination("quarters",25),
new Denomination("dimes",10),
new Denomination("nickel",5),
new Denomination("pennies",1)
};
}
public Denomination getDenomination(int index) {
return this.currency[index];
}
public int getCurrencyLength() {
return this.currency.length;
}
public String getCurrencyDenomination(int index) {
return currency[index].getDenomination();
}
public int getCurrencyValue(int index) {
return currency[index].getValue();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.kuhn.cashRegister;

/**
* The Denomination class is the bottom class of the cashRegister package hierarchy.
* Denomination defines the methods and values inherent to a denomination object
*
* @author Sean Kuhn
* @Date 10/25/2019
*
*/
public class Denomination {
private String denomination;
private int value;

public Denomination(String denomination, int value) {
this.denomination = denomination;
this.value = value;
}

public void setDenomination(String denomination) {
this.denomination = denomination;
}
public String getDenomination() {
return this.denomination;
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
204 changes: 204 additions & 0 deletions SoftWriters/SeanKuhn_CashRegister/src/com/kuhn/cashRegister/Till.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package com.kuhn.cashRegister;
import java.lang.StringBuilder;
import java.util.Random;
/**
* The Till class is the top class of the cashRegister package hierarchy.
* Till contains all money handling methods, as well as all Currency instantiations.
*
* @author Sean Kuhn
* @Date 10/25/2019
*
*/
public class Till {
private Currency currency;
private int value;
public Till() {
currency = new Currency();
this.value = 25000;
}

public Till(double value) {
currency = new Currency();
this.value = (int) (value * 100);
}

public void setTillTotal(double value) {
this.value = (int) (value * 100);
}

public double getTillTotal() {
return this.value;
}

/**
* The transaction method detects errors and calls get change methods based on change divisibility.
* @param charge The amount to be paid.
* @param payment The actual amount paid.
* @return Returns the string containing change instructions.
* @throws Exception Contains information for relevant errors.
*/
public String transaction(double charge, double payment) throws Exception {
int change = (int) ((payment * 100) - (charge * 100));
this.setTillTotal(this.getTillTotal() + 100 * payment);
String output = "";

if( change > (this.value)) {
throw new Exception("Change ammount is greater than available funds!");
}else if( ((charge * 100) % 1) > 0){
throw new Exception("Change ammount includes fractions of a penny!");
}else if((charge * 100) % 3 == 0){
output = getRandomChange((int) (change));
}else if(change <= (this.value)){
output = getBasicChange((int) (change));
}

return output;
}

/**
* The getBasicChange method calculates the number and type of denominations to return using the fewest bills and coins.
*
* @param change The number of cents to be returned to the purchaser.
* @return Returns a grammatically correct string of change instructions.
*/
public String getBasicChange(int change) {
StringBuilder output = new StringBuilder();

for(int i = 0; i < currency.getCurrencyLength(); i++) {
double j = (change / currency.getCurrencyValue(i));

if(j >= 1) {
this.setTillTotal(this.getTillTotal() - (Math.floor(j) * currency.getCurrencyValue(i)));
change -= (Math.floor(j) * currency.getCurrencyValue(i));
output.append((int)Math.floor(j));
output.append(grammar(i,j));

if(i < currency.getCurrencyLength()-1) {
output.append(", ");
}
}
}

return output.toString();
}

/**
* The getRandomChange method calculates the number and type of denominations to return using a randomized mix of denominations.
*
* @param change The number of cents to be returned to the purchaser.
* @return Returns a grammatically correct string of change instructions.
*/
public String getRandomChange(int change) {
StringBuilder output = new StringBuilder();

for(int i = 0; i < currency.getCurrencyLength(); i++) {
double j = (change / currency.getCurrencyValue(i));
int tempRand = new Random().nextInt((int)Math.floor(j)+1);

if(i == (currency.getCurrencyLength()-1)) {
tempRand = change;
}

if(j >= 1 && change <= (this.value) && tempRand > 0) {
this.setTillTotal(this.getTillTotal() - (tempRand * currency.getCurrencyValue(i)));
change -= (tempRand * currency.getCurrencyValue(i));
output.append(tempRand);
output.append(grammar(i,j));

if(i < currency.getCurrencyLength()-1) {
output.append(", ");
}
}
}

return output.toString();
}

/**
* The grammar method takes the denomination index and number of bills or coins and returns the proper plurality of the denomination.
*
* @param i The index of a denomination in currency.getDenomination().
* @param j The number of bills or coins to consider. Relevant states are essentially <= 1 and > 1.
* @return Returns a string containing the name of a denomination in it's proper plurality."
*/
public String grammar(int i, double j) {
String grammer = "";

switch(i) {
case 0:
if((int)Math.floor(j) > 1) {
grammer = " hundreds";
} else {
grammer = " hundred";
}
break;
case 1:
if((int)Math.floor(j) > 1) {
grammer = " fifties";
} else {
grammer = " fifty";
}
break;
case 2:
if((int)Math.floor(j) > 1) {
grammer = " twenties";
} else {
grammer =" twenty";
}
break;
case 3:
if((int)Math.floor(j) > 1) {
grammer = " tens";
} else {
grammer = " ten";
}
break;
case 4:
if((int)Math.floor(j) > 1) {
grammer = " fives";
} else {
grammer = " five";
}
break;
case 5:
if((int)Math.floor(j) > 1) {
grammer = " dollars";
} else {
grammer = " dollar";
}
break;
case 6:
if((int)Math.floor(j) > 1) {
grammer = " quarters";
} else {
grammer = " quarter";
}
break;
case 7:
if((int)Math.floor(j) > 1) {
grammer = " dimes";
} else {
grammer = " dime";
}
break;
case 8:
if((int)Math.floor(j) > 1) {
grammer = " nickels";
} else {
grammer = " nickel";
}
break;
case 9:
if((int)Math.floor(j) > 1) {
grammer = " pennies";
} else {
grammer = " penny";
}
break;
default :
break;
}

return grammer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.kuhn.cashRegisterApplication;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import com.kuhn.cashRegister.*;
import com.kuhn.cashRegisterInputReader.*;

/**
* The Application class contains the main runnable method for the CashRegister project
*
* @author Sean Kuhn
* @Date 10/27/2019
*
*/
public class Application {
public static void main(String[] Args) throws Exception {
Till till = new Till();
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));

//read in the input and output paths.
System.out.println("Fully qualified Input Path:");
String inputPath = consoleReader.readLine();
System.out.println("Fully Qualified Output Path:");
String outputPath = consoleReader.readLine();
consoleReader.close();

//read in the input file
InputReader inputReader = new InputReader(inputPath);
StringBuilder output = new StringBuilder();
double[][] transactions = inputReader.getTransactions();

//Builds output file from transaction array
for(int i = 0; i < inputReader.getLines(); i++) {
String change = till.transaction(transactions[i][0], transactions[i][1]);
System.out.println(change);
output.append(change);
if(i != (inputReader.getLines()-1)) {
output.append(System.getProperty("line.separator"));
}

}

OutputWriter outputWriter = new OutputWriter(output.toString(),outputPath);
outputWriter.writeResults();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Cash Register
---
The requirement for this program is to create a cash register application that takes transaction data as input, and outputs change instructions. Change should be handled in the lowest number of bills and coins, unless the amount due is divisible by 3. If the amount due is divisible by 3, then the number of each denomination is randomized to give the customer correct change, but in mixed up denominations eg. 80 cents change could return as 1 nickel, 75 pennies.

This program is divided into three main packages;


1. com.kuhn.cashRegister
* the cashRegister package contains a hierarchy of classes used to control the money changing process.
a.Denomination is the lowest class in the cashRegister hierarchy, and contains only two parameters: Denomination and value.

b.Currency is the middle class in the cashRegister hierarchy, and contains a set of denomination instances. These instances can be modified to add support for non-standard currency types.

c.Till is the highest class in the cashRegister hierarchy, and contains the opening till value, instantiated currency object, and all money handling methods.
i. The transaction method detects errors and calls get change methods based on change divisibility.
ii. The getBasicChange method calculates the number and type of denominations to return using the fewest bills and coins.
iii. The getRandomChange method calculates the number and type of denominations to return using a randomized mix of denominations.
iv. The grammar method takes the denomination index and number of bills or coins and returns the proper plurality of the denomination.

2. com.kuhn.cashRegisterInputReader
* the cashRegisterInputReader package contains the classes necessary for reading from and writing to files.

3. com.kuhn.cashRegisterApplication
* the cashRegisterApplication package contains the runnable class as well as supporting documentation.

# Limitations
---
Input files formatted as charge,payment do not specify the amount and type of bills or coins given in the transaction. since this is not present, there is not good way to track individual denominations. If a Till object was initialized with a finite number of each bill and coin, the getChange methods would have to handle shortages. eg. 40 cents in change is due but only 3 dimes are left to give. two nickels are substituted for the "4th" dime. As transactions are completed, the transaction amount is added to the till as a lump sum, making it impossible to track denomination shorting.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
2.12,3
9.99,10
1.97,2
3.33,5
26.63,50
Loading