Created
November 30, 2019 02:26
-
-
Save matteing/c990716fef7cece9877bc1c20affd8f1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Nombre: Sergio Mattei | |
ID: 801183252 | |
Class/Seccion: CCOM 3033 SEC 001 | |
Nombre de archivo: main_mattei_4a.cpp | |
Descripción: This program calculates the salary for employees based on a simple database format, and places results in another file. | |
Notes: This was fun to make. | |
I went a little overboard improving user experience details (like adding friendly colors), but it's just who I am. | |
I really like making things work nicely. | |
*/ | |
#include <iostream> | |
#include <fstream> | |
#include <string> | |
#include <iomanip> | |
using namespace std; | |
// Define constants | |
const int WINDOW_WIDTH = 80; | |
const int WINDOW_COL_SIZE = WINDOW_WIDTH / 4; | |
const int FILE_WIDTH = 150; | |
const int FILE_COL_SIZE = FILE_WIDTH / 9; | |
// UX: Define a few colors (escape sequences) to make things less awful | |
const string T_RESET = "\x1B[0m"; | |
const string T_RED = "\x1B[31m"; | |
const string T_GRN = "\x1B[32m"; | |
const string T_YEL = "\x1B[33m"; | |
// Declare structs | |
struct Employee | |
{ | |
int id; | |
string name; | |
string period; | |
string ssn; | |
double hours; | |
double salary; | |
}; | |
// Declare functions | |
void askForFilenames(ifstream &, ofstream &); | |
void askRerun(string &); | |
double calculateGross(double, double, double); | |
double calculateExtra(double, double); | |
double calculateDeductions(double); | |
double calculateNet(double, double); | |
void printTermTableHeading(); | |
void printTermTableRow(Employee); | |
void printTermTotal(double); | |
void printFileTableHeading(ofstream &); | |
void printFilePersonRowData(ofstream &, Employee); | |
void printFileSalaryRowData(ofstream &, Employee, double &); | |
void printFileTotal(ofstream &, double); | |
int main() | |
{ | |
// note: see askRerun function | |
string again; | |
do | |
{ | |
ifstream fileToRead; | |
ofstream fileToWrite; | |
askForFilenames(fileToRead, fileToWrite); | |
cout << "\n"; | |
printTermTableHeading(); | |
printFileTableHeading(fileToWrite); | |
// main loop to check emloyee details | |
int index = 0; | |
string period, name, ssn; | |
double net = 0.0, gross = 0.0, total = 0.0, deductions = 0.0, extra = 0.0, hours = 0.0, salary = 0.0; | |
while (fileToRead >> period >> name >> ssn >> hours >> salary) | |
{ | |
Employee e = { | |
index, name, period, ssn, hours, salary}; | |
// Write terminal row | |
printTermTableRow(e); | |
// Write row data (file) | |
printFilePersonRowData(fileToWrite, e); | |
printFileSalaryRowData(fileToWrite, e, total); | |
// end row... | |
fileToWrite << endl; | |
index++; | |
} | |
// Write total to cout | |
printTermTotal(total); | |
// Now send total to file. | |
printFileTotal(fileToWrite, total); | |
// Close all files | |
fileToRead.close(); | |
fileToWrite.close(); | |
askRerun(again); | |
} while (again == "y" || again == "Y"); | |
return 0; | |
} | |
void askForFilenames(ifstream &fileToRead, ofstream &fileToWrite) | |
{ | |
string fileName; | |
// Open stream to file. | |
do | |
{ | |
if (fileToRead.fail()) | |
{ | |
cout << T_RED + "Wrong filename." + T_RESET << endl; | |
} | |
cout << "Input name of file to read: "; | |
getline(cin, fileName); | |
fileToRead.open(fileName.c_str()); // apparently the VM doesn't bundle C++11. | |
} while (!fileToRead); | |
cout << "Input name of file to write results: "; | |
getline(cin, fileName); | |
fileToWrite.open(fileName.c_str()); | |
} | |
void printTermTableHeading() | |
{ | |
cout << setw((WINDOW_WIDTH / 2) + 7) << "NOMINA DE EMPRESA" << endl; | |
cout << "\n"; | |
cout << left << setw(WINDOW_COL_SIZE) << "SSN" | |
<< setw(WINDOW_COL_SIZE) << "HORAS" | |
<< setw(WINDOW_COL_SIZE) << "SALARIO/HORA" | |
<< setw(WINDOW_COL_SIZE) << "SALARIO/SEMANA" << endl; | |
// This took a lot of work to get right. | |
// So turns out that setfill has to go before setw, and for it to work a character must be printed. | |
cout << setfill('=') << setw(WINDOW_WIDTH) << "" << endl; | |
// Reset fill character for next setw's. | |
cout << setfill(' ') << fixed << setprecision(2) << showpoint; | |
} | |
void printFileTableHeading(ofstream &fileToWrite) | |
{ | |
fileToWrite << setw((FILE_WIDTH / 2) + 7) << "NOMINA DE EMPRESA" << endl; | |
fileToWrite << "\n"; | |
fileToWrite << left << setw(FILE_COL_SIZE) << "PERIODO" | |
<< setw(FILE_COL_SIZE) << "NOMBRE" | |
<< setw(FILE_COL_SIZE) << "SSN" | |
<< setw(FILE_COL_SIZE) << "HORAS" | |
<< setw(FILE_COL_SIZE) << "SALARIO" | |
<< setw(FILE_COL_SIZE) << "BRUTO EXTRA" | |
<< setw(FILE_COL_SIZE) << "TOTAL BRUTO" | |
<< setw(FILE_COL_SIZE) << "DEDUC" | |
<< setw(FILE_COL_SIZE) << "TOTAL NETO" << endl; | |
fileToWrite << setfill('=') << setw(FILE_WIDTH) << "" << endl; | |
fileToWrite << setfill(' ') << fixed << setprecision(2) << showpoint; | |
} | |
void printTermTableRow(Employee e) | |
{ | |
cout << setw(WINDOW_COL_SIZE) << e.ssn; | |
cout << setw(WINDOW_COL_SIZE) << e.hours; | |
cout << setw(WINDOW_COL_SIZE) << e.salary; | |
cout << setw(WINDOW_COL_SIZE) << e.period; | |
cout << endl; | |
} | |
void printFilePersonRowData(ofstream &fileToWrite, Employee e) | |
{ | |
fileToWrite << setw(FILE_COL_SIZE) << e.period; | |
fileToWrite << setw(FILE_COL_SIZE) << e.name; | |
fileToWrite << setw(FILE_COL_SIZE) << e.ssn; | |
} | |
double calculateGross(double salary, double hours, double extra) | |
{ | |
return (salary * hours) + extra; | |
} | |
double calculateExtra(double salary, double hours) | |
{ | |
double extra; | |
double extraDifference = hours - 40; | |
if (extraDifference > 0) | |
{ | |
// double the hourly wage for the difference in hours | |
extra = extraDifference * salary; | |
} | |
else | |
{ | |
extra = 0.0; | |
} | |
return extra; | |
} | |
double calculateDeductions(double gross) | |
{ | |
return gross * 0.18; | |
} | |
double calculateNet(double gross, double deductions) | |
{ | |
return gross - deductions; | |
} | |
void printFileSalaryRowData(ofstream &fileToWrite, Employee e, double &total) | |
{ | |
double extra, gross, deductions, net; | |
extra = calculateExtra(e.salary, e.hours); | |
gross = calculateGross(e.salary, e.hours, extra); | |
deductions = calculateDeductions(gross); | |
net = calculateNet(gross, deductions); | |
// update running total | |
total += net; | |
// print row data | |
fileToWrite << setw(FILE_COL_SIZE) << e.hours; | |
fileToWrite << setw(FILE_COL_SIZE) << e.salary; | |
fileToWrite << setw(FILE_COL_SIZE) << extra; | |
fileToWrite << setw(FILE_COL_SIZE) << gross; | |
fileToWrite << setw(FILE_COL_SIZE) << deductions; | |
fileToWrite << setw(FILE_COL_SIZE) << net; | |
} | |
void printTermTotal(double total) | |
{ | |
cout << "\n"; | |
cout << right << setw(WINDOW_WIDTH - 6) << T_GRN << "Total pagado: " << T_RESET << total << endl; | |
} | |
void printFileTotal(ofstream &fileToWrite, double total) | |
{ | |
fileToWrite << "\n"; | |
fileToWrite << right << setw(FILE_WIDTH - 6) << "Total pagado: " << total; | |
} | |
void askRerun(string &again) | |
{ | |
// note: I used a string type for user experience. | |
// getline handles \n better than using cin, which messes up the stdin buffer | |
// it's a mess | |
cout << endl; | |
cout << T_YEL << "Run again? (y/N) " << T_RESET; | |
getline(cin, again); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment