Subtracting a minimum score out of an average

I have written a c++ program to calculate student grades. I have confirmed my code is correct for a main.cpp, a student.h file , and a student.cpp file but I am missing one element from the main.cpp file: I need to add something that removes the lowest homework score. First, find the minimum homework assignment score (min). Then you add all the homework assignment scores (sum). After you get the sum, you can calculate the average homework scores in the formula
(sum - min)/(n-1) n is the number of homework assignments. And i have to replace lowest exam score by final exam if final exam is higher. How would I do this? The TA has approved my code below so no need to make any changes to it besides these score dropping elements

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
#include "Student.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <iomanip>
#include <random>
#include <algorithm>
#include <fstream>
#include <cstring>
using namespace std;


vector<int> process_line(string line){
	vector<int> entries;
	string built_int = "";
	for(int i = 0; i < line.size(); i++){
		if (line[i] == ' '){
			entries.push_back(stoi(built_int));
			built_int = "";
		} else {

			built_int = built_int + line[i];
		}
	}
	entries.push_back(stoi(built_int));
	return entries;
}


int main(int argc, char *argv[]){
	if (argc == 1){
		cout << "You did not enter any file names!" << endl;
		return 0;
	}
	ifstream input_file;
	input_file.clear();
	input_file.open("student_data.dat");
	if (! input_file.is_open() ){
		cout << "The file could not be opened!" << endl;
		return 0;
	}
	int linenum=1;
	vector<string> names;
	vector<vector<int>> hw;
	vector<vector<int>> e;
	vector<int> f;
	string line;
	
	while(getline(input_file, line)){
		if (line=="")
			linenum=0;
		
		switch (linenum){
			case 0: 
			linenum++;
			break;
			
			case 1:
			names.push_back(line);
			linenum++;
			break;

			case 2:
			hw.push_back(process_line(line));
			linenum++;
			break;
			
			case 3:
			e.push_back(process_line(line));
			linenum++;
			break;
			
			case 4:
			f.push_back(stoi(line));
			linenum++;
			break;
		}
	}
	input_file.close();
	for (int i=0; i<hw[i].size();i++){
		sort (hw[i].begin(), hw[i].end());
	}
	vector<int> hw_tot;
	vector<int> e_tot;
	int row_sum;
	for (int i=0; i<hw.size();i++){
		row_sum=0;
		for(int j=1; j<hw[i].size();j++){
			row_sum+=hw[i][j];
		}
		hw_tot.push_back(row_sum);

	}
	for (int i=0; i<e.size();i++){
		row_sum=0;
		for(int j=0; j<e[i].size();j++){
			row_sum+=e[i][j];
		}
		e_tot.push_back(row_sum);
	}
	
	vector<string> f_names;
	vector<string> l_names;

	for (int i=0;i<names.size();i++){
		size_t pos= names[i].find(" ");
		f_names.push_back(names[i].substr(0,pos));
		l_names.push_back(names[i].substr(pos+1));
	}
	

	vector<double> finalgrades;
	for (int i=0;i<names.size();i++){
		Student current_student= {hw_tot[i],e_tot[i],f[i]};
		finalgrades.push_back(current_student.grade());
	}

	vector<int> order;
	for (int i=0; i < l_names.size(); i++){ 
		order.push_back(i);
	}

	auto comparator = [&l_names](int a, int b){
		return (l_names[a] < l_names[b]);
	};

	sort(order.begin(), order.end(), comparator);
	int k;

	for (int i=0;i<l_names.size();i++){
		k=order[i];
		cout<<l_names[k]<<", "<<f_names[k]<<" "<<finalgrades[k]<<endl;
	}
		

	
	return 0;
}
If I understand your code
- you’ve created a class “Student”.
- You read Student’s data from a file into std::vectors which are not members of Student.
- You need to perform some basic calculation on those data.

For what I can see, there could be a misunderstanding: all the data you’re dealing with were probably supposed to be managed from inside your class Student - otherwise I can’t see the point of writing that class.
Let’s assume the data you need to manage are (for each Student):
a) first and last name;
b) list of homework marks;
c) list of exam score;
d) final exam score.
It seams you’re putting those data into:
a) vector<string> names; --> a std::vector for all Students names
b) vector<vector<int>> hw; --> a std::vector of std::vectors for all Students lists of homework marks
c) vector<vector<int>> e; --> a std::vector of std::vectors for all Students lists of exam scores
d) vector<int> f; --> a std::vector for all Students final exam scores
While it is possible the assignment asks you to use your class more or less this way:
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef SHIMSHIM96_STUDENT_H
#define SHIMSHIM96_STUDENT_H

class Student {
    std::string fname, lname;
    std::vector<int> hws;
    std::vector<int> exams;
    int fscore;
    double average;
};

#endif // SHIMSHIM96_STUDENT_H 


Maybe I’m wrong, of course, but I’d read the assignment again to be sure.

Anyway, about your question
I need to add something that removes the lowest homework score
Once you’ve sorted your std::vector, the lowest homework mark is the first one, i.e. the one at position 0.

I think your "student_data.dat" file is somewhat like:

Ann Anderson
13 666 679
51 34 47
18

Barbara Brown
14 667 681
52 74 16
44

Carl Carter
56 28 45
63 11 26
85


Let’s reduce it to:

Ann
13 666 679

Barbara
14 667 681

Carl
56 28 45

to deal only with homework marks.
An example of code similar to yours could be:
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
#include <algorithm>
#include <fstream>
#include <iostream>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>

std::vector<int> process_line(const std::string& line);
double getAverage(std::vector<int>& hws);
int getRowSum(const std::vector<int>& hws);

int main()
{
    std::ifstream input_file("student_data.dat");
    if (! input_file) {
        std::cout << "The file could not be opened!\n";
        return 0;
    }

    std::vector<std::string> names;
    std::vector<std::vector<int>> hw;
    int linenum { 1 };
    for(std::string line; std::getline(input_file, line); ++linenum) {
        if(line.empty()) { linenum = 0; }
        switch (linenum) {
        case 0:
            break;
        case 1:
            names.push_back(line);
            break;
        case 2:
            hw.push_back(process_line(line));
            break;
        }
    }
    input_file.close();
    std::vector<double> averages(names.size());
    for(size_t i{}; i<hw.size(); ++i) { averages.at(i) = getAverage(hw.at(i)); }
    for (size_t i=0; i<names.size(); ++i) {
        std::cout << names.at(i) << " average is " << averages.at(i) << '\n';
    }
    return 0;
}

std::vector<int> process_line(const std::string& line)
{
    std::istringstream iss(line);
    std::vector<int> entries;
    for(int i{}; iss >> i; /**/) { entries.push_back(i); }
    return entries;
}

double getAverage(std::vector<int>& hws)
{
    std::sort(hws.begin(), hws.end());
    return static_cast<double>(getRowSum(hws) - hws.at(0)) / (hws.size() - 1);
}

int getRowSum(const std::vector<int>& hws)
{
    return std::accumulate(hws.begin(), hws.end(), 0);
}

Output:
Ann average is 672.5
Barbara average is 674
Carl average is 50.5

Registered users can post here. Sign in or register to post.