Reputation: 211
I posted a question on this topic earlier when I was beginning the problem. Since then, I have worked on the source code and filled in a lot of blanks. I have experiencing some troubles now, because there are a lot of discrepancies and problems with my source code.
Please ignore the comments. I include them for my own personal benefit as they help remind me of what I am doing or what is going on especially when I am checking my own work.
First, it has 9 function prototypes that are categorized into 3 groups with 3 methods each that do the same thing but for different variables. For example, int getFirstLowest(StudentData[])
int getFirstHighest(StudentData[])
, and double getAverage1(StudentData[], int)
. I want a different method to find the lowest, highest and average of each exam and the lowest, highest and average value of the totals of each. An idea that I had was to create an array of size 3 for each statistic I need to calculate (lowest, highest, average and standard deviation), but I don't know how to do it.
Next, I am curious if I should just combine my getTotal
function and getGrades
function to be more efficient. The getTotal
method just adds up all the exam scores while the getGrades
is just filled with if else statements to categorize the scores and determine their grades.
In addition, I also need some help with the print
function. My output needs to look similar to the image I attached below, but it doesn't. The count for each student turns out wrong and starts at 0 and messes up my alignment which is why I did not include it.
Here is an image of how my output should look like:
Here is an image of my current output:
I printed the lowest, highest, and average data at the top to check if my calculations were correct for each aspect as I am still unsure how to place the data into an array to print it out more smoothly. In addition, please note that some of the data in both images are the same and are different, because the first image is a sample from a previous semester. My numbers are correct in the exam columns.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
struct StudentData
{
int studentID;
string first_name;
string last_name;
int exam1;
int exam2;
int exam3;
int total;
char ch;
};
istream& operator >> (istream& in, StudentData& st)
{
return (in >> st.studentID
>> st.first_name
>> st.last_name
>> st.exam1
>> st.exam2
>> st.exam3);
}
const int SIZE = 9;
// Function prototypes
void openInputFile(ifstream &, string);
int getFirstLowest(StudentData[]);
int getSecondLowest(StudentData[]);
int getThirdLowest(StudentData[]);
int getFirstHighest(StudentData[]);
int getSecondHighest(StudentData[]);
int getThirdHighest(StudentData[]);
double getAverage1(StudentData[], int);
double getAverage2(StudentData[], int);
double getAverage3(StudentData[], int);
void getTotal(StudentData arr[]);
void getGrade(StudentData arr[]);
void print(StudentData[]);
int main()
{
// Variables
//standardDeviation;
StudentData arr[SIZE];
int x, y, z, w; // Stores lowest exam scores
int i, j, k, l; // Holds highest exam scores
double average1, average2, average3, average4; // Represents average of each exam
int lowest[3];
int highest[3];
double average[3];
ifstream inFile;
string inFileName = "C:\\Users\\Lisa\\Desktop\\scores.txt";
// Call function to read data in file
openInputFile(inFile, inFileName);
// Read data into an array of structs
size_t numItems = 0;
while (inFile >> arr[numItems])
{
++numItems;
}
// Close input file
inFile.close();
// Get lowest exam scores from each exam
x = getFirstLowest(arr);
y = getSecondLowest(arr);
z = getThirdLowest(arr);
// Get highest exam scores from each exam
i = getFirstHighest(arr);
j = getSecondHighest(arr);
k = getThirdHighest(arr);
cout << "\nLowest exam scores (in order): " << x << " " << y << " " << z << endl;
cout << "\nHighest exam scores (in order): " << i << " " << j << " " << k << endl;
cout << "\n";
// Get average score of each exam
average1 = getAverage1(arr, SIZE);
average2 = getAverage2(arr, SIZE);
average3 = getAverage3(arr, SIZE);
cout << "Exam 1 Average: " << setprecision(2) << fixed << average1 << endl;
cout << "Exam 2 Average: " << setprecision(2) << fixed << average2 << endl;
cout << "Exam 3 Average: " << setprecision(2) << fixed << average3 << endl;
cout << "\n";
getTotal(arr);
getGrade(arr);
print(arr);
system("PAUSE");
return 0;
}
/**
* Pre-condition:
* Post-condition:
*/
void openInputFile(ifstream &inFile, string inFileName)
{
//Open the file
inFile.open(inFileName);
//Input validation
if (!inFile)
{
cout << "Error to open file." << endl;
cout << endl;
return;
}
}
/**
* Pre-condition:
* Post-condition:
*/
int getFirstLowest(StudentData arr[])
{
int lowest = 0;
int num = arr[0].exam1;
for (int i = 0; i<SIZE; i++)
{
if (num > arr[i].exam1)
{
num = arr[i].exam1;
lowest = i;
}
}
return num;
}
/**
* Pre-condition:
* Post-condition:
*/
int getSecondLowest(StudentData arr[])
{
int lowest = 0;
int num = arr[0].exam2;
for (int i = 0; i<SIZE; i++)
{
if (num > arr[i].exam2)
{
num = arr[i].exam2;
lowest = i;
}
}
return num;
}
/**
* Pre-condition:
* Post-condition:
*/
int getThirdLowest(StudentData arr[])
{
int lowest = 0;
int num = arr[0].exam3;
for (int i = 0; i<SIZE; i++)
{
if (num > arr[i].exam3)
{
num = arr[i].exam3;
lowest = i;
}
}
return num;
}
/**
* Pre-condition:
* Post-condition:
*/
int getFirstHighest(StudentData arr[])
{
int highest = 0;
int num = arr[0].exam1;
for (int i = 0; i<SIZE; i++)
{
if (num < arr[i].exam1)
{
num = arr[i].exam1;
highest = i;
}
}
return num;
}
/**
* Pre-condition:
* Post-condition:
*/
int getSecondHighest(StudentData arr[])
{
int highest = 0;
int num = arr[0].exam2;
for (int i = 0; i<SIZE; i++)
{
if (num < arr[i].exam2)
{
num = arr[i].exam2;
highest = i;
}
}
return num;
}
/**
* Pre-condition:
* Post-condition:
*/
int getThirdHighest(StudentData arr[])
{
int highest = 0;
int num = arr[0].exam3;
for (int i = 0; i<SIZE; i++)
{
if (num < arr[i].exam3)
{
num = arr[i].exam3;
highest = i;
}
}
return num;
}
/**
* Pre-condition:
* Post-condition:
*/
double getAverage1(StudentData arr[], int size)
{
int sum = 0;
double average = 0;
for(int i = 0; i < SIZE; i++)
{
sum += arr[i].exam1;
}
average += static_cast<double>(sum)/size;
return average;
}
/**
* Pre-condition:
* Post-condition:
*/
double getAverage2(StudentData arr[], int size)
{
int sum = 0;
double average = 0;
for(int i = 0; i < SIZE; i++)
{
sum += arr[i].exam2;
}
average += static_cast<double>(sum)/size;
return average;
}
/**
* Pre-condition:
* Post-condition:
*/
double getAverage3(StudentData arr[], int size)
{
int sum = 0;
double average = 0;
for(int i = 0; i < SIZE; i++)
{
sum += arr[i].exam3;
}
average += static_cast<double>(sum)/size;
return average;
}
/**
* Pre-condition:
* Post-condition:
*/
void getTotal(StudentData arr[])
{
for(int i = 0; i < SIZE; i++)
{
arr[i].total = arr[i].exam1 + arr[i].exam2 + arr[i].exam3;
}
}
/**
* Pre-condition:
* Post-condition:
*/
void getGrade(StudentData arr[])
{
for(int i = 0; i < SIZE; i++)
{
if(arr[i].total >= 270)
arr[i].ch = 'A';
else if(arr[i].total >= 240)
arr[i].ch = 'B';
else if(arr[i].total >= 210)
arr[i].ch = 'C';
else if(arr[i].total >= 180)
arr[i].ch = 'D';
else
arr[i].ch = 'F';
}
}
/**
* Pre-condition:
* Post-condition:
*/
void print(StudentData arr[])
{
cout << "ID First Name Last Name Exam1 Exam2 Exam3 Total Grade" << endl;
for(int i = 0; i < SIZE; i++)
{
cout << left << arr[i].studentID << "\t" << setw(10) << arr[i].first_name << "\t" << setw(5) << arr[i].last_name << "\t\t"
<< arr[i].exam1 << "\t" << arr[i].exam2 << "\t" << arr[i].exam3 << "\t" << arr[i].total << "\t" << arr[i].ch << endl;
}
}
Upvotes: 1
Views: 4445
Reputation: 9602
First, it has 9 function prototypes that are categorized into 3 groups with 3 methods each that do the same thing but for different variables.
This is not very extensible (i.e., because of all the work involved, meaning code changes, when new exam scores and/or students are add). Perhaps you're already aware of this since you made the following statement.
I want a different method to find the lowest, highest and average of each exam and the lowest, highest and average value of the totals of each.
Since this is a learning assignment I can show you my output, my main, and my skeleton implementation. If it looks like something you were trying to do then you can finish implementing the skeleton code. Note, I didn't try to get the formatting exact since it should be easy enough for you.
1234 David Dalton 82 86 80 248
9138 Shirley Gross 90 98 94 282
3124 Cynthia Morley 87 84 82 253
4532 Albert Roberts 56 89 78 223
5678 Amelia Pauls 90 87 65 242
6134 Samson Smith 29 65 33 127
7874 Michael Garett 91 92 92 275
8026 Melissa Downey 74 75 89 238
9893 Gabe Yu 69 66 68 203
Lowest: 29 65 33 127
Higest: 91 98 94 283
Avg: 74.2222 82.4444 75.6667 232.333
The implementation is pretty straight-forward/simple.
int main()
{
Students students;
Exams exams;
// Read data from file and populate all student and exam data structures
if (!initialize(students, exams))
{
return -1;
}
// Compute all the exam statistics
exams.computeStatistics();
// Print all the student information
for (const auto& student : students)
{
std::cout << student << "\n";
}
// Print the exam information
std::cout << "\n";
std::cout << exams << "\n";
return 0;
}
Here is a skeleton of the code I used which may be helpful to you.
// A class to represent a single exam
class Exam
{
public:
// Computes min, max, and avg (later can be extended to compute
// additional statistics)
void computeStatistics()
{
// TODO
}
int min() const { return mMin; }
int max() const { return mMax; }
double avg() const { return mAvg; }
// Adds a score earned by a student (i.e., keeps track of all scores
// which are used by the 'computeStatistics' function)
void addScore(int score)
{
// TODO
}
private:
std::vector<int> mScores; // All scores for this exam
// Values computed for all available scores
int mMin;
int mMax;
double mAvg;
};
// A class to represent all exams (this is helpful since there are some
// statistics that need to be computed for all exams)
class Exams
{
public:
// Get the exam associated with the specified exam numer
Exam& operator[](std::size_t examNumber)
{
return mExams[examNumber];
}
// Compute min total, max total, average average, store all exam min
// scores, store all exam max scores, store all exam avg scores
void computeStatistics()
{
// TODO
}
// Prints the exam information (e.g., Lowest, Highest, Average)
friend std::ostream& operator<<(std::ostream& stream, const Exams& exams)
{
// TODO
}
private:
// Mapping from 'exam number' to the exam data type
std::map<int, Exam> mExams;
// Stores all min, max, and avg exam scores (for printing later)
std::vector<int> mMinScores;
std::vector<int> mMaxScores;
std::vector<double> mAvgScores;
// Values computed for all available exams
int mMinTotal;
int mMaxTotal;
double mAvgAvg;
};
// Class to represent a student
class Student
{
public:
Student() :
mTotalScore(0)
{
// Do nothing
}
// Records a student's score on a particular exam (this is also used
// to keep a running total of all exam scores for this student, which
// can be printed later)
void addScore(int examNumber, int score)
{
// TODO
}
// Each exam score for this student is added to 'exams'
void updateExams(Exams& exams) const
{
// TODO
}
int mId;
std::string mFirstName;
std::string mLastName;
// Mapping from 'exam number' to exam score
std::map<int, int> mExams;
int mTotalScore; // Total of all exam scores for this student
};
// Reads a student from a stream (hint: uses the 'addScore' function)
std::istream& operator>>(std::istream& stream, Student& student)
{
// TODO
}
// Prints out a student (i.e., id, fist, last, exam1, exam2, exam3, examTotal)
std::ostream& operator<<(std::ostream& stream, const Student& student)
{
// TODO
}
// Just an alias so that you don't have to type 'std::vector<Student>' all over
using Students = std::vector<Student>;
// Reads all the data from the text file and adds each student to 'students'
// and each exam to 'exams' (hint: after each student is read it can be
// used to update all the exams)
bool initialize(Students& students, Exams& exams)
{
// TODO
}
Upvotes: 1