calculate avg from input file
angrybeaver76 (9)
Dec 6, 2012 at 5:34pm UTC
Hi. I have this program I'm writing that I'm stuck on. The first part needs to read in a list of student ID's and a corresponding test score (example input file below). Scores are int values between 1-10. A student that did not take the test will have a -1 score and should not be counted towards the average.
Example input file:
1234 1
3456 3
3453 5
4365 9
3456 -1
I was able to figure out this code to calculate the average from reading in a file. See below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
ifstream inputFile;
int score, avg, numofstudents = 0, totalgrade = 0;
string id, grade;
inputFile.open("TestScores.txt" );
//get the average
while (!inputFile.eof())
{
inputFile >> id;
cout << left << setw(10) << id;
inputFile >> score;
cout << left << setw(10) << score << endl;
if (score >= 0 && score <= 10)
{
totalgrade = totalgrade + score;
numofstudents++;
}
}
avg = totalgrade/numofstudents;
cout << "The avg score is " << avg << endl << endl;
Where I'm stuck is the next part of the program. I need to create a new output file that has a new column with the converted letter grade. So I need to take the average from the first part above and generate the letter grade. (-1 gets no grade, average or the average + 1 = B, average + 2 or average + 3 = A-, +4 ( or 10 if average is 7 or more ) = A, average -1 = C and average – 2 or less = F.)
Needed output file:
1234 1 F
3456 3 C
3453 5 B
4365 9 A
3456 -1
I started with this... but then I stopped short cause I don't think a switch is the way to go. I can't figure out the best way to go about this. Any suggestions?
1 2 3 4 5 6 7 8 9 10 11
inputFile.open("TestScores.txt" );
while (!inputFile.eof())
{
inputFile >> id;
inputFile >> score;
if (score >= 0 && score <= 10)
{
switch (score)
case
toum (169)
Dec 6, 2012 at 8:56pm UTC
You can't compute the letter grade inside the loop because you need the average grade to compute them, and you don't have it yet.
What you need to do is store the ids and scores of all the students into arrays when you read the file.
Once you've computed the average grade, use the stored data to compute the letter grade for each student and put the 3 values (id, grade, letter grade) into the output file.
angrybeaver76 (9)
Dec 8, 2012 at 3:07am UTC
Ok I think I'm headed in the right direction. I just can't get the right data to save into the arrays for some reason. I was able to calculate the correct letter grade and output to new file, but I want to then read all 3 rows into arrays. When I try to run the menu options 2 and 3, the data it outputs is not right. :( why why why?
Sample "TestScores_Grades.txt" to read from:
10214 8 A-
19285 3 F
11753 5 B
11261 3 F
13893 -1 F
17611 7 A-
10587 3 F
15568 10 A
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
const char FILENAME[30] = "TestScores.txt" ;
ifstream inFile;
int id, score, avg, s = 0, numofstudents = 0, totalgrade = 0;
inFile.open(FILENAME);
while (!inFile.eof())
{
inFile >> id;
inFile >> score;
if (score >= 0 && score <= 10)
{
totalgrade = totalgrade + score;
numofstudents++;
s = s + 1;
}
}
avg = totalgrade/numofstudents;
inFile.close();
ifstream inFile2;
ofstream outFile1;
int idx;
string grade;
inFile2.open(FILENAME);
outFile1.open("TestScores_Grades.txt" );
for (idx = 0; idx < s; idx++)
{
inFile2 >> id >> score;
if (score == avg || score == avg +1)
grade = "B" ;
else if (score == avg + 2 || score == avg + 3)
grade = "A-" ;
else if (score == avg +4 || score == 10 )
grade = "A" ;
else if (score == avg - 1)
grade = "C" ;
else if (score <= (avg - 2))
grade = "F" ;
outFile1 << id << " " << score << " " << grade << endl;
}
inFile2.close();
ifstream inFile3;
int num, ids[idx], scores[idx];
char grades[idx];
inFile3.open("TestScores_Grades.txt" );
idx = 0;
while (idx <= s && !inFile3.eof())
{
inFile3 >> ids[idx] >> scores[idx] >> grades[idx];
idx++;
}
inFile3.close();
do
{
cout << setw(30) << "QUIZ RESULTS MENU " << endl;
cout << setw(30) << "***************************" << endl << endl;
cout << " 1. " << left << setw(30) << "List by Student ID" << endl;
cout << " 2. " << setw(30) << "List by Student ID and Grades" << endl;
cout << " 3. " << setw(30) << "List by Letter Grade" << endl;
cout << " 4. " << setw(30) << "List by Numeric Grade" << endl;
cout << " 5. " << setw(30) << "List Grades by Percentage" << endl << endl;
cout << right << "Enter an option: " ;
cin >> num;
cout << endl;
if (num == 1)
cout << "This option sorts the student list by ID and writes it to a file." ;
if (num == 2)
{
//Read the new file and search for the target ID that the user enters.
ifstream inFile4;
inFile4.open("TestScores_Grades.txt" );
int target;
for (idx = 0; idx < s; idx++)
{
cout << "Enter a student ID: " ;
cin >> target;
if (ids[idx] = target)
{
cout << "Result: " << ids[idx] << " " << scores[idx] << " " << grades[idx] << endl;
}
}
}
else if (num == 3)
//cout << "This option searches for students with a particular letter grade." << endl << endl;
{
//Read the file again and search for the target letter grade that the user enters.
ifstream inFile4;
inFile4.open("TestScores_Grades.txt" );
char targetGrade;
for (idx = 0; idx < s; idx++)
{
cout << "Enter a letter grade: " ;
cin >> targetGrade;
if (grades[idx] = targetGrade)
cout << "Result: " << ids[idx] << " " << scores[idx] << " " << grades[idx];
}
}
else if (num == 4)
cout << "This option sorts the list by numeric grade." ;
else if (num == 5)
cout << "This option calculates the % of students with a particular grade." ;
else if (num < 1 || num > 5)
cout << "This is an invalid entry. Please rerun the program." ;
cout << endl << endl << endl;
}
while (num > 0 && num <= 5);
system("PAUSE" );
return EXIT_SUCCESS;
}
Last edited on Dec 8, 2012 at 3:11am UTC
toum (169)
Dec 8, 2012 at 7:05pm UTC
Line 26, incrementation of "s" should be outside the "if".
Line 61, grades should be a string array, not a char array.
Lines 100 and 119, it should be "==" and not "=".
Lines 98-99 and 117-118, this code should be outside the loop.
angrybeaver76 (9)
Dec 9, 2012 at 3:37pm UTC
thanks toum.
I'm getting this error now: no match for 'operator==' in 'grades[idx]==targetGrade'
I don't understand that one. Match for ==?
angrybeaver76 (9)
Dec 9, 2012 at 4:05pm UTC
Nvm. I figured out the error. The error was for the variable 'targetGrade'. Hadn't changed it to string also.
angrybeaver76 (9)
Dec 9, 2012 at 4:09pm UTC
Ok. I got menu options 2 and 3 to run. But when I run 5, it gives me results the first time, but I can't run 5 again. It crashes. What am I missing?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
const char FILENAME[30] = "TestScores.txt" ;
ifstream inFile;
int id, score, avg, s = 0, numofstudents = 0, totalgrade = 0;
inFile.open(FILENAME);
while (!inFile.eof())
{
inFile >> id;
inFile >> score;
if (score >= 0 && score <= 10)
{
totalgrade = totalgrade + score;
numofstudents++;
//s = s + 1;
}
s = s + 1;
}
avg = totalgrade/numofstudents;
inFile.close();
ifstream inFile2;
ofstream outFile1;
int idx;
string grade;
inFile2.open(FILENAME);
outFile1.open("TestScores_Grades.txt" );
for (idx = 0; idx < s; idx++)
{
inFile2 >> id >> score;
if (score == avg || score == avg +1)
grade = "B" ;
else if (score == avg + 2 || score == avg + 3)
grade = "A-" ;
else if (score == avg +4 || score == 10 )
grade = "A" ;
else if (score == avg - 1)
grade = "C" ;
else if (score <= (avg - 2))
grade = "F" ;
outFile1 << id << " " << score << " " << grade << endl;
}
inFile2.close();
ifstream inFile3;
int num, ids[idx], scores[idx];
string grades[idx];
inFile3.open("TestScores_Grades.txt" );
idx = 0;
while (idx <= s && !inFile3.eof())
{
inFile3 >> ids[idx] >> scores[idx] >> grades[idx];
idx++;
}
inFile3.close();
do
{
cout << setw(30) << "QUIZ RESULTS MENU " << endl;
cout << setw(30) << "***************************" << endl << endl;
cout << " 1. " << left << setw(30) << "List by Student ID" << endl;
cout << " 2. " << setw(30) << "List by Student ID and Grades" << endl;
cout << " 3. " << setw(30) << "List by Letter Grade" << endl;
cout << " 4. " << setw(30) << "List by Numeric Grade" << endl;
cout << " 5. " << setw(30) << "List Grades by Percentage" << endl << endl;
cout << right << "Enter an option: " ;
cin >> num;
cout << endl;
if (num == 1)
cout << "This option sorts the student list by ID and writes it to a file." ;
if (num == 2)
{
ifstream inFile4;
inFile4.open("TestScores_Grades.txt" );
int target;
cout << "Enter a student ID: " ;
cin >> target;
for (idx = 0; idx < s; idx++)
{
inFile4 >> ids[idx] >> scores[idx] >> grades[idx];
if (ids[idx] == target)
cout << "Result: " << ids[idx] << " " << scores[idx] << " " << grades[idx] << endl;
}
inFile4.close();
}
else if (num == 3)
{
ifstream inFile5;
inFile5.open("TestScores_Grades.txt" );
string targetGrade;
idx = 0;
while (idx <= s && !inFile5.eof())
{
inFile5 >> ids[idx] >> scores[idx] >> grades[idx];
idx++;
}
cout << "Enter a grade: " ;
cin >> targetGrade;
for (idx = 0; idx < s; idx++)
{
if (grades[idx] == targetGrade)
cout << "Result: " << ids[idx] << " " << grades[idx] << endl;
}
inFile5.close();
}
else if (num == 4)
cout << "This option sorts the list by numeric grade." ;
else if (num == 5)
{
ifstream inFile6;
inFile6.open("TestScores_Grades.txt" );
string targetLetter;
int p = 0, percent;
while (idx <= s && !inFile6.eof())
{
inFile6>> ids[idx] >> scores[idx] >> grades[idx];
idx++;
}
cout << "Enter the letter grade to calculate %: " ;
cin >> targetLetter;
for (idx = 0; idx < s; idx++)
{
if (grades[idx] == targetLetter)
{
p = p + 1;
percent = (p * 100)/s;
}
}
cout << percent << " % of the students received a " << targetLetter << "." << endl;
inFile6.close();
}
else if (num < 1 || num > 5)
cout << "This is an invalid entry. Please rerun the program." ;
cout << endl << endl << endl;
}
while (num > 0 && num <= 5);
system("PAUSE" );
return EXIT_SUCCESS;
}
toum (169)
Dec 9, 2012 at 9:15pm UTC
I tried to run your program and there was no crash. What was your input ?
I noticed a small bug: you should reinitialize idx to 0 before doing the loop line 141.
angrybeaver76 (9)
Dec 10, 2012 at 3:46am UTC
It's not crashing for me now either. Hmm. I must've fixed something without knowing it.
I added the idx=0. Thanks!