Skip to content

Instantly share code, notes, and snippets.

@matteing
Created November 30, 2019 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matteing/7ee440e15f8d1232c0de58f1cd0cf3d2 to your computer and use it in GitHub Desktop.
Save matteing/7ee440e15f8d1232c0de58f1cd0cf3d2 to your computer and use it in GitHub Desktop.
/*
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>
#include <vector>
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;
double extra;
double gross;
double deductions;
double net;
};
// 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 calculateAllSalaryData(Employee &);
void printTermTableHeading();
void printTermTableRow(Employee);
void printTermTotal(double);
void printFileTableHeading(ofstream &);
void printFilePersonRowData(ofstream &, Employee);
void printFileSalaryRowData(ofstream &, Employee);
void printFileTotal(ofstream &, double);
void parseEmployeeFile(ifstream &, double &, vector<Employee> &);
void printRowsToFile(ofstream &, vector<Employee> &);
void sortEmployeesByName(vector<Employee> &);
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
vector<Employee> employees;
// parse file && add to employee vector
double total = 0.0; // set running total
parseEmployeeFile(fileToRead, total, employees);
printRowsToFile(fileToWrite, employees);
// 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.net;
cout << endl;
}
void calculateAllSalaryData(Employee &e) {
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);
e.extra = extra;
e.gross = gross;
e.deductions = deductions;
e.net = net;
}
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)
{
// print row data
fileToWrite << setw(FILE_COL_SIZE) << e.hours;
fileToWrite << setw(FILE_COL_SIZE) << e.salary;
fileToWrite << setw(FILE_COL_SIZE) << e.extra;
fileToWrite << setw(FILE_COL_SIZE) << e.gross;
fileToWrite << setw(FILE_COL_SIZE) << e.deductions;
fileToWrite << setw(FILE_COL_SIZE) << e.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);
}
void parseEmployeeFile(ifstream &file, double &total, vector<Employee> &employees) {
int index = 0;
string period, name, ssn;
double net = 0.0, gross = 0.0, deductions = 0.0, extra = 0.0, hours = 0.0, salary = 0.0;
while (file >> period >> name >> ssn >> hours >> salary)
{
Employee e = {
index, name, period, ssn, hours, salary};
calculateAllSalaryData(e);
total += e.net;
employees.push_back(e);
index++; // update ID counter
}
sortEmployeesByName(employees);
}
void printRowsToFile(ofstream &file, vector<Employee> &employees) {
for (Employee e : employees) {
// Write terminal row
printTermTableRow(e);
// Write row data (file)
printFilePersonRowData(file, e);
printFileSalaryRowData(file, e);
// end row...
file << endl;
}
}
void sortEmployeesByName(vector<Employee> &employees) {
for (int start = 0; start < size - 1; start++) {
min = arre[start];
minInd = start;
for (int i = start; i < size; i++) {
if (arre[i].name < min.name) {
min = arre[i];
minInd = i;
}
}
arre[minInd] = arre[start];
arre[start] = min;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment