// header files #include #include "Console_IO_Utility.h" #include "File_Output_Utility.h" #include "File_Input_Utility.h" #include "StandardConstants.h" // global constants // enumerator for column indexes typedef enum { COLUMN_A, COLUMN_B, COLUMN_C, COLUMN_D, COLUMN_E } TableColumns; // enumarator for filing type typedef enum { MARRIED, SINGLE, NONE } FilingFlag; // conversion into percent rate const double PERCENT_CONVERSION = 0.01; // tax table properties const char TAX_TABLE_R_COUNT = 4; const char TAX_TABLE_C_COUNT = 5; // on demand data files const char MARRIED_TAX_DATA[] = "married.csv"; const char SINGLE_TAX_DATA[] = "single.csv"; const int TAX_DATA_TITLE_SIZE = 60; // output table columns size const int OUT_TABLE_COLUMN_SIZE = 15; // function declaration void printProgramTitle(); void uploadTaxTable(); void skipOneRow(); int getTaxReturnType(); void displayTaxTable(); void displayCorrectTable(); double calculateTax(); int main() { // initialize variables double income, taxTotal; char returnType; double taxData[TAX_TABLE_R_COUNT][TAX_TABLE_C_COUNT]; // display title printProgramTitle(); // get user input income = promptForDouble("Provide your income: "); returnType = getTaxReturnType(); printEndline(); if (returnType == 0) { uploadTaxTable(MARRIED_TAX_DATA, taxData); // do calculations taxTotal = calculateTax(taxData, income); // display results displayTaxTable(taxData, returnType); printf("\n\n"); if (taxTotal != 0) { printf("Total tax is: %.2f\n\n", taxTotal); } else { printf("The income you provided is invalid.\n\n"); } } else if (returnType == 1) { uploadTaxTable(SINGLE_TAX_DATA, taxData); // do calculations taxTotal = calculateTax(taxData, income); // display results displayTaxTable(taxData, returnType); printf("\n\n"); if (taxTotal != 0) { printf("Total tax is: %.2f\n\n", taxTotal); } else { printf("The income you provided is invalid.\n\n"); } } else { printf("You provided wrong filing type.\n"); printf("Program Aborted.\n\n"); } // return value, end program printf("End Program\n"); return 0; } // function prototypes /* Name: printProgramTitle Process: displays program title Function Input/Parameters: none Function Output/Parameters: none Function Output/Returned: none Device Input/Keyboard: none Device Output/Monitor: title displayed as specified Dependencies: Console IO Utilities tools */ void printProgramTitle() { // initialize variables // none // get user input // none // do calculations // none // display results printf("Basic Arizona Tax Calculator\n"); printf("==============================\n\n"); // return value // none, void function. } /* Name: uploadTaxTable Process: uploads table from file into 2d array Function Input/Parameters: accepts name of the file which stores tax table and reference to tax data array in which to store tax data (use constants to set size of array) Function Output/Parameters: none Function Output/Returned: none Device Input/Keyboard: none Device Output/Monitor: none Dependencies: openInputFile, readDoubleFromFile, skipOneRow, readCharacterFromFile */ void uploadTaxTable(char dataFileName[], double taxDataArray[TAX_TABLE_R_COUNT][TAX_TABLE_C_COUNT]) { // initialize variables int incrementerRow, incrementerCol; double currentValue; // get user input // input passed in through parameters. // do calculations // printf("part working 1\n"); //debug // check if the file is open. if (openInputFile(dataFileName)) { // printf("part working 2\n"); //debug // skip the first row. its junk otherwise. skipOneRow(); // printf("part working 3\n"); //debug // read in the data, use a loop, // use the constant for how many rows and columns there are. // in the loop, read the double, then the character. // read double 5x, character 4x. "fencepost problem?" currentValue = readDoubleFromFile(); for(incrementerRow = 0; incrementerRow < TAX_TABLE_R_COUNT; incrementerRow++) { for(incrementerCol = 0; incrementerCol < TAX_TABLE_C_COUNT; incrementerCol++) { if (incrementerCol == COLUMN_E) { taxDataArray[incrementerRow][incrementerCol] = currentValue; // printf("part working, %d, %d, %f\n", incrementerRow, incrementerCol, currentValue); // debug currentValue = readDoubleFromFile(); } else { readCharacterFromFile(); taxDataArray[incrementerRow][incrementerCol] = currentValue; // printf("part working, %d, %d, %f\n", incrementerRow, incrementerCol, currentValue); // debug currentValue = readDoubleFromFile(); } } } closeInputFile(); } else { printf("File didn't read. Please try again.\n"); } // display results // displays nothing. // return value // none, void function. } /* Name: skipOneRow Process: skips one line of input file Function Input/Parameters: none Function Output/Parameters: none Function Output/Returned: none Device Input/Keyboard: none Device Output/Monitor: none Dependencies: readStringToDelimiterFromFile OR readStringToLineEndFromFile */ void skipOneRow() { // initialize variables char throwawayData[STD_STR_LEN]; // get user input // none // do calculations // use readStringToLineEndFromFile and move to the end of the line. // don't save any output. shouldn't need it. readStringToLineEndFromFile(throwawayData); // display results // none // return value // none } /* Name: getTaxReturnType Process: ask user for input and based on input assigns appropriate filing type Function Input/Parameters: none Function Output/Parameters: none Function Output/Returned: returns filling type either SINGLE or MARRIED Device Input/Keyboard: character either m/M/s/S Device Output/Monitor: none Dependencies: promptForCharacter */ int getTaxReturnType() { // initialize variables char fileType; int fileFlag; // get user input fileType = promptForCharacter("Choose filing type(M/S): "); // do calculations // check for the filing type if (fileType == 'M' || fileType == 'm') { fileFlag = MARRIED; } else if (fileType == 'S' || fileType == 's') { fileFlag = SINGLE; } else { fileFlag = NONE; } // display results // return value return fileFlag; } /* Name: displayTaxTable Process: based on filling type prints apropriate title for table and calls for table to be displayed Function Input/Parameters: table containing tax data and filing type Function Output/Parameters: none Function Output/Returned: none Device Input/Keyboard: none Device Output/Monitor: title for table Dependencies: displayCorrectTable, printf */ void displayTaxTable(double *taxDataArray, int filingType) { // initialize variables // none // show table title. if (filingType == 0) { printf("Table 1. Filing as MARRIED.\n"); } else if (filingType == 1) { printf("Table 1. Filing as SINGLE.\n"); } else { printf("Table 1. Filing as NaN.\n"); } // get user input // input passed in through parameters. // do calculations // display results displayCorrectTable(taxDataArray); // return value // none } /* Name: displayCorrectTable Process: displays tax data table Function Input/Parameters: table containing tax data Function Output/Parameters: none Function Output/Returned: none Device Input/Keyboard: none Device Output/Monitor: iteratively prints table as shown in examples Dependencies: printCharacter, printDoubleJustified, printf */ void displayCorrectTable(double taxDataArray[TAX_TABLE_R_COUNT][TAX_TABLE_C_COUNT]) { // initialize variables int rowIndex, colIndex; // get user input // input passed in through parameters. // do calculations/display results, loop, use the below as the template for what each iteration does. for (rowIndex = 0; rowIndex < TAX_TABLE_R_COUNT; rowIndex++) { for (colIndex = 0; colIndex < TAX_TABLE_C_COUNT; colIndex++) { printCharacter(PIPE); printCharacter(SPACE); printDoubleJustified(taxDataArray[rowIndex][colIndex], PRECISION, OUT_TABLE_COLUMN_SIZE, "CENTER"); } printCharacter(PIPE); } // return value // none, void function. } /* Name: calculateTax Process: identifies correct tax bracket using tax data from array and income calculates tax using tax data from array as well as with formula presented below TT = ((TI + Col_C) * Col_D %) + Col_E , where TT - Total Tax TI - Total Income Col_C - COLUMN_C (same as maximum limit of previous tax bracket) Col_D - COLUMN_D (same as rate, must be converted into %) Col_E - COLUMN_E (same as max possible tax for all previous brackets) Function Input/Parameters: tax data aray and total income Function Output/Parameters: none Function Output/Returned: total tax Device Input/Keyboard: none Device Output/Monitor: none Dependencies: none */ double calculateTax(double taxDataArray[TAX_TABLE_R_COUNT][TAX_TABLE_C_COUNT], double totalIncome) { // initialize variables double totalTax = 0; int rowValue; // get user input // input passed in though parameters // do calculations // check total income valid. if (totalIncome <= 0) { return 0; } // totalTax should use the process above to calculate. // column a is the tax bracket minimum // column b is the tax bracket maximum // check to see where total income falls to figure out what rate to use. for (rowValue = 0; rowValue < TAX_TABLE_R_COUNT; rowValue++) { if ((totalIncome >= taxDataArray[rowValue][COLUMN_A]) || (taxDataArray[rowValue][COLUMN_B] <= totalIncome)) { totalTax = ((totalIncome + taxDataArray[rowValue][COLUMN_C]) * taxDataArray[rowValue][COLUMN_D] * PERCENT_CONVERSION) + taxDataArray[rowValue][COLUMN_E]; } } // display results // none // return value return totalTax; }