diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..a98a00a3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+
+#ignore thumbnails created by windows
+Thumbs.db
+#Ignore files build by Visual Studio
+*.obj
+*.exe
+*.pdb
+*.user
+*.aps
+*.pch
+*.vspscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.cache
+*.ilk
+*.log
+*.dll
+*.lib
+*.sbr
+bin/
+obj/
+packages/
+.vs/
+
+
+# .NET
+obj/
+bin/
+.vs/
+*.user
+
+# local env files
+.env.local
+.env.*.local
diff --git a/CashRegister.sln b/CashRegister.sln
new file mode 100644
index 00000000..b7612ba6
--- /dev/null
+++ b/CashRegister.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31321.278
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CashRegister", "CashRegister\CashRegister.csproj", "{0665BD27-5519-4B5D-A292-FE2FC9932ADD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CashRegisterTests", "CashRegisterTests\CashRegisterTests.csproj", "{F1439C9C-5A59-4716-9189-36A5D2F5CEFC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0665BD27-5519-4B5D-A292-FE2FC9932ADD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0665BD27-5519-4B5D-A292-FE2FC9932ADD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0665BD27-5519-4B5D-A292-FE2FC9932ADD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0665BD27-5519-4B5D-A292-FE2FC9932ADD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F1439C9C-5A59-4716-9189-36A5D2F5CEFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1439C9C-5A59-4716-9189-36A5D2F5CEFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1439C9C-5A59-4716-9189-36A5D2F5CEFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1439C9C-5A59-4716-9189-36A5D2F5CEFC}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4370CBE7-F5AC-48A3-995F-3A0818052959}
+ EndGlobalSection
+EndGlobal
diff --git a/CashRegister/CashRegister.cs b/CashRegister/CashRegister.cs
new file mode 100644
index 00000000..9d579a53
--- /dev/null
+++ b/CashRegister/CashRegister.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CashRegister
+{
+ public class CashRegister : ICashRegister
+ {
+ private decimal Change;
+
+ public Change GetChange(decimal price, decimal totalPaid)
+ {
+ // Return Empty Change Object if inputs are less than 0
+ if(price < 0 || totalPaid < 0)
+ {
+ return new Change();
+ }
+ this.Change = totalPaid - price;
+ if ((price * 100) % 3 == 0)
+ {
+ return RandomChange();
+ }
+ else
+ {
+ return RegularChange();
+ }
+
+ }
+
+ private Change RandomChange()
+ {
+ Change ChangeReturn = new Change();
+ int randomNumber;
+ while (Change > 0)
+ {
+
+ randomNumber = new Random().Next(1, 6);
+
+ switch (randomNumber)
+ {
+ case 1:
+ if (Change >= 1.00M)
+ {
+ ChangeReturn.AddDollar();
+ Change -= 1.00M;
+ }
+ break;
+ case 2:
+ if (Change >= 0.25M)
+ {
+ ChangeReturn.AddQuarter();
+ Change -= 0.25M;
+ }
+ break;
+ case 3:
+ if (Change >= 0.10M)
+ {
+ ChangeReturn.AddDime();
+ Change -= 0.10M;
+ }
+ break;
+ case 4:
+ if (Change >= 0.05M)
+ {
+ ChangeReturn.AddNickel();
+ Change -= 0.05M;
+ }
+ break;
+ case 5:
+ if (Change >= 0.01M)
+ {
+ ChangeReturn.AddPenny();
+ Change -= 0.01M;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return ChangeReturn;
+ }
+
+ private Change RegularChange()
+ {
+ Change ChangeReturn = new Change();
+ while (Change > 0)
+ {
+ if (Change >= 1.00M)
+ {
+ ChangeReturn.AddDollar();
+ Change -= 1.00M;
+ }
+ else if (Change >= 0.25M)
+ {
+ ChangeReturn.AddQuarter();
+ Change -= 0.25M;
+ }
+ else if (Change >= 0.10M)
+ {
+ ChangeReturn.AddDime();
+ Change -= 0.10M;
+ }
+ else if (Change >= 0.05M)
+ {
+ ChangeReturn.AddNickel();
+ Change -= 0.05M;
+ }
+ else if (Change >= 0.01M)
+ {
+ ChangeReturn.AddPenny();
+ Change -= 0.01M;
+ }
+ }
+ return ChangeReturn;
+ }
+ }
+}
diff --git a/CashRegister/CashRegister.csproj b/CashRegister/CashRegister.csproj
new file mode 100644
index 00000000..c73e0d16
--- /dev/null
+++ b/CashRegister/CashRegister.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
diff --git a/CashRegister/Program.cs b/CashRegister/Program.cs
new file mode 100644
index 00000000..7a22f77b
--- /dev/null
+++ b/CashRegister/Program.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+
+namespace CashRegister
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+
+ ICashRegister cr = new CashRegister();
+ IReadService reader = new ReadService();
+ IWriteService writer = new WriteService();
+
+ List output = new List();
+
+ try
+ {
+ output = reader.ReadFile();
+ } catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+
+
+ List changeList = new List();
+
+ for (int i = 0; i < output.Count - 1; i += 2)
+ {
+ Change change = new Change();
+ change = cr.GetChange(output[i], output[i + 1]);
+ changeList.Add(change);
+ }
+
+ writer.WriteFile(changeList);
+
+ }
+ }
+}
diff --git a/CashRegister/Services/ReadService.cs b/CashRegister/Services/ReadService.cs
new file mode 100644
index 00000000..18851c61
--- /dev/null
+++ b/CashRegister/Services/ReadService.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Reflection;
+
+namespace CashRegister
+{
+ public class ReadService : IReadService
+ {
+ private static string FileName { get; } = "input.txt";
+ //private static string Dir { get; } = Environment.CurrentDirectory;
+ //private static string outputDir { get; } = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
+
+ private static readonly string WorkingDirectory = Directory.GetParent(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName).Parent.FullName;
+
+ private readonly string FilePath = Path.Combine(WorkingDirectory, FileName);
+
+ public List ReadFile()
+ {
+
+
+
+ List output = new List();
+
+ try
+ {
+ using(StreamReader streamReader = new StreamReader(FilePath))
+ {
+ while (!streamReader.EndOfStream)
+ {
+ string line = streamReader.ReadLine();
+ string[] temp = new string[2];
+ temp = line.Split(',');
+
+ output.Add(decimal.Parse(temp[0]));
+ output.Add(decimal.Parse(temp[1]));
+ }
+ }
+ }
+ catch (Exception e)
+ {
+
+ throw e;
+ }
+ return output;
+ }
+ }
+}
diff --git a/CashRegister/Services/WriteService.cs b/CashRegister/Services/WriteService.cs
new file mode 100644
index 00000000..a02ec8c0
--- /dev/null
+++ b/CashRegister/Services/WriteService.cs
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+namespace CashRegister
+{
+ public class WriteService : IWriteService
+ {
+ private static string FileName { get; } = "output.txt";
+ private static readonly string WorkingDirectory = Directory.GetParent(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName).Parent.FullName;
+
+ private readonly string FilePath = Path.Combine(WorkingDirectory, FileName);
+
+ public void WriteFile(List changeList)
+ {
+ try
+ {
+ using(StreamWriter streamWriter = new StreamWriter(FilePath, true))
+ {
+ foreach(Change change in changeList)
+ {
+ string message = CreateChangeMessage(change);
+ streamWriter.WriteLine(message);
+ }
+
+ }
+ }
+ catch (Exception)
+ {
+
+ throw;
+ }
+ }
+
+ private string CreateChangeMessage(Change change)
+ {
+ string message = "";
+ if(change.Dollar > 0)
+ {
+ message += change.Dollar + " dollar";
+ if(change.Dollar != 1)
+ {
+ message += "s";
+ }
+ }
+
+ if(change.Quarter > 0)
+ {
+ if (message.Length != 0)
+ {
+ message += ", ";
+ }
+ message += change.Quarter + " quarter";
+ if(change.Quarter != 1)
+ {
+ message += "s";
+ }
+ }
+
+ if(change.Dime > 0)
+ {
+ if (message.Length != 0)
+ {
+ message += ", ";
+ }
+ message += change.Dime + " dime";
+
+ if(change.Dime != 1)
+ {
+ message += "s";
+ }
+ }
+
+ if(change.Nickel > 0)
+ {
+ if (message.Length != 0)
+ {
+ message += ", ";
+ }
+ message += change.Nickel + " nickel";
+
+ if (change.Nickel != 1)
+ {
+ message += "s";
+ }
+ }
+
+ if(change.Penny > 0)
+ {
+ if (message.Length != 0)
+ {
+ message += ", ";
+ }
+ message += change.Penny + " penn";
+ if(change.Penny != 1)
+ {
+ message += "ies";
+ } else
+ {
+ message += "y";
+ }
+ }
+
+ return message;
+ }
+ }
+
+
+}
diff --git a/CashRegister/interfaces/ICashRegister.cs b/CashRegister/interfaces/ICashRegister.cs
new file mode 100644
index 00000000..22cfeb9f
--- /dev/null
+++ b/CashRegister/interfaces/ICashRegister.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CashRegister
+{
+ public interface ICashRegister
+ {
+ public Change GetChange(decimal price, decimal totalPaid);
+ }
+}
diff --git a/CashRegister/interfaces/IReadService.cs b/CashRegister/interfaces/IReadService.cs
new file mode 100644
index 00000000..d3dc5d8e
--- /dev/null
+++ b/CashRegister/interfaces/IReadService.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CashRegister
+{
+ public interface IReadService
+ {
+ public List ReadFile();
+ }
+}
diff --git a/CashRegister/interfaces/IWriteService.cs b/CashRegister/interfaces/IWriteService.cs
new file mode 100644
index 00000000..75aa2969
--- /dev/null
+++ b/CashRegister/interfaces/IWriteService.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CashRegister
+{
+ public interface IWriteService
+ {
+ public void WriteFile(List changeList);
+ }
+}
diff --git a/CashRegister/models/Change.cs b/CashRegister/models/Change.cs
new file mode 100644
index 00000000..3bfd90c1
--- /dev/null
+++ b/CashRegister/models/Change.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CashRegister
+{
+ public class Change
+ {
+ //private decimal Dollar { get; } = 1.00M;
+ //private decimal Quarter { get; } = 0.25M;
+ //private decimal Dime { get; } = 0.10M;
+ //private decimal Nickel { get; } = 0.05M;
+ //private decimal Penny { get; } = 0.01M;
+
+ public int Dollar { get; private set; }
+
+ public int Quarter { get; private set; }
+ public int Dime { get; private set; }
+ public int Nickel { get; private set; }
+ public int Penny { get; private set; }
+
+ public Change()
+ {
+ Dollar = 0;
+ Quarter = 0;
+ Dime = 0;
+ Nickel = 0;
+ Penny = 0;
+ }
+
+ public void AddDollar()
+ {
+ Dollar++;
+ }
+
+ public void AddQuarter()
+ {
+ Quarter++;
+ }
+
+ public void AddDime()
+ {
+ Dime++;
+ }
+
+ public void AddNickel()
+ {
+ Nickel++;
+ }
+
+ public void AddPenny()
+ {
+ Penny++;
+ }
+
+
+
+ }
+}
diff --git a/CashRegisterTests/CashRegisterTests.cs b/CashRegisterTests/CashRegisterTests.cs
new file mode 100644
index 00000000..5d77766f
--- /dev/null
+++ b/CashRegisterTests/CashRegisterTests.cs
@@ -0,0 +1,132 @@
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace CashRegister
+{
+ [TestClass]
+ public class CashRegisterTests
+ {
+ [TestMethod]
+ public void RandomChange()
+ {
+ CashRegister cr = new CashRegister();
+ Change actualChange = cr.GetChange(3.33M, 5.00M);
+ decimal actualTotal = GetTotal(actualChange);
+ decimal expectedTotal = 1.67M;
+ Assert.AreEqual(expectedTotal, actualTotal, "Unequal Total");
+ }
+
+ private decimal GetTotal(Change change)
+ {
+ decimal total = 0;
+
+ total += change.Dollar * 1.00M;
+ total += change.Quarter * 0.25M;
+ total += change.Dime * 0.10M;
+ total += change.Nickel * 0.05M;
+ total += change.Penny * 0.01M;
+
+ return total;
+ }
+
+ [TestMethod]
+ public void Return1Dollar()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(1.00M, 2.00M);
+ Change expected = new Change();
+ expected.AddDollar();
+
+ CompareChangeObject(expected, actual);
+ }
+
+ private void CompareChangeObject(Change expectedChange, Change actualChange)
+ {
+ Assert.AreEqual(expectedChange.Dollar, actualChange.Dollar, "Unequal Dollars");
+ Assert.AreEqual(expectedChange.Quarter, actualChange.Quarter, "Unequal Quarters");
+ Assert.AreEqual(expectedChange.Dime, actualChange.Dime, "Unequal Dimes");
+ Assert.AreEqual(expectedChange.Nickel, actualChange.Nickel, "Unequal Nickels");
+ Assert.AreEqual(expectedChange.Penny, actualChange.Penny, "Unequal Pennies");
+ }
+
+ [TestMethod]
+ public void Return1Dollar1Quarter()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(1.25M, 2.50M);
+ Change expected = new Change();
+ expected.AddDollar();
+ expected.AddQuarter();
+ CompareChangeObject(expected, actual);
+ }
+
+ [TestMethod]
+ public void Return1Dollar1Quarter1Dime()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(1.00M, 2.35M);
+ Change expected = new Change();
+ expected.AddDollar();
+ expected.AddQuarter();
+ expected.AddDime();
+ CompareChangeObject(expected, actual);
+ }
+
+ [TestMethod]
+ public void Return1Dollar1Quarter1Dime1Nickel()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(1.00M, 2.40M);
+ Change expected = new Change();
+ expected.AddDollar();
+ expected.AddQuarter();
+ expected.AddDime();
+ expected.AddNickel();
+ CompareChangeObject(expected, actual);
+ }
+
+ [TestMethod]
+ public void Return1Dollar1Quater1Dime1Nickel4Pennies()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(1.00M, 2.44M);
+ Change expected = new Change();
+ expected.AddDollar();
+ expected.AddQuarter();
+ expected.AddDime();
+ expected.AddNickel();
+ expected.AddPenny();
+ expected.AddPenny();
+ expected.AddPenny();
+ expected.AddPenny();
+ CompareChangeObject(expected, actual);
+ }
+
+ [TestMethod]
+ public void NegativePriceAndNegativeTotalPaidReturnEmptyChange()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(-1.00M, -2.00M);
+ Change expected = new Change();
+
+ CompareChangeObject(expected, actual);
+ }
+
+ public void NegativePriceAndPositiveTotalPaidReturnEmptyChange()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(-1.00M, 2.00M);
+ Change expected = new Change();
+
+ CompareChangeObject(expected, actual);
+ }
+ public void PositivePriceAndNegativeTotalPaidReturnEmptyChange()
+ {
+ CashRegister cr = new CashRegister();
+ Change actual = cr.GetChange(1.00M, -2.00M);
+ Change expected = new Change();
+
+ CompareChangeObject(expected, actual);
+ }
+ }
+}
diff --git a/CashRegisterTests/CashRegisterTests.csproj b/CashRegisterTests/CashRegisterTests.csproj
new file mode 100644
index 00000000..ab4acb48
--- /dev/null
+++ b/CashRegisterTests/CashRegisterTests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 62a96fc3..12fdb9f5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,13 @@
Cash Register
============
+IMPORTANT USER INSTRUCTIONS****
+-------------------------------
+
+The "input.txt" file must be located in "~/CashRegister" path in order for the program to run correctly.
+
+The change will be output to the casher via "output.txt" and will be located in the same directory location as input.txt after the program runs for the first time. Subsequent reruns of the program will keep a log of all change dispended in "output.txt" and will not override any previous data.
+
The Problem
-----------
Creative Cash Draw Solutions is a client who wants to provide something different for the cashiers who use their system. The function of the application is to tell the cashier how much change is owed and what denominations should be used. In most cases the app should return the minimum amount of physical change, but the client would like to add a twist. If the total due in cents is divisible by 3, the app should randomly generate the change denominations (but the math still needs to be right :))
diff --git a/input.txt b/input.txt
new file mode 100644
index 00000000..fba6116f
--- /dev/null
+++ b/input.txt
@@ -0,0 +1,3 @@
+2.12,3.00
+1.97,2.00
+3.33,5.00
\ No newline at end of file