Class and Functions help

Hi, for class i was given an assignment to create a program using a class called student and various methods within it. The purpose is too calculate a grade based on points earned within the class, and to create 4 already created objects and to try and match the output given, which is:
The first Student object

Rando
Program Average: 84.75
Exam + Quiz Average: 95.63
Course Average: 92.36
Letter Grade: A


The second Student object

Pat Jones
Program Average: 52.38
Exam + Quiz Average: 67.88
Course Average: 63.23
Letter Grade: F


The third Student object

Chris Wilson
Program Average: 100.00
Exam + Quiz Average: 100.00
Course Average: 100.00
Letter Grade: A


The fourth Student object

Jarret Jack
Program Average: 0.00
Exam + Quiz Average: 0.00
Course Average: 0.00
Letter Grade: F

Jarret Jack
Program Average: 70.61
Exam + Quiz Average: 77.63
Course Average: 75.52
Letter Grade: C

but when i compile my output looks extremely different. I have been trying to slowly find a solution, but after making lots of simple fixes iam now stuck and don't know how proceed any help would be appreciated. If you need to see the output i see just ask and ill post it, thanks.

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
#include <iostream>
#include <iomanip>
#include <string.h>

using namespace std;
const int PGM_POINTS = 905;
const int QUIZ_POINTS = 120;
const int MAX_SUM = 20;
const double EXAM_POINTS = 300;

class student{
	public:
		student (const char [], int, int, int, double);
		void setPgmPts (int newPgmPts);
		void setQuizPts (int newQuizPts);
		void setSum2Low (int newSum2Low);
		void setExamPts (double newExamPts);
		double calcPgmAverage ();
		double calcExamAndQuizAverage();
		double calcCourseAverage ();
		char letterGrade ();
		void printStudent ();
	private:
		char name [50];
		int pgmPts;
		int quizPts;
		int sum2Low;
		double examPts;
		
			
};
int main(){

	student s1 = student ("Rando", 767 , 106, 10, 286.50);
	student s2 = student ("Pat Jones", 474, 53, 0, 218.50);
	student s3 = student ("Chris Wilson", 905, 120, 20, 300.00);
	student s4 = student ("Jarret Jack", 906, 121, 21, 301);
	cout << "The First Student" << endl;
	s1.printStudent();
	cout << "The Second Student" << endl;
	s2.printStudent();
	cout << "The Third Student" << endl;
	s3.printStudent();
	cout << "The Fourth Student" << endl;
	s4.printStudent();
	s4 = student ("Jarret Jack", 639, 107, 8, 211.50);
	s4.printStudent();
	return 0;
}

void student::setPgmPts(int newPgmPts){
	if (pgmPts < 0 or pgmPts > PGM_POINTS){
		newPgmPts = 0;
		cout << "Errror in setPgmPts: argument is invalid" << endl;;
	}
	else {
	
	newPgmPts = pgmPts;
	}	
}

void student::setQuizPts(int newQuizPts){
	if (quizPts < 0 && quizPts > QUIZ_POINTS){
		newQuizPts = 0;
		cout << "Error in setQuizPts: argument is invalid" << endl;
	}
	else {
		newQuizPts = quizPts;
	}
}

void student::setSum2Low(int newSum2Low){
	if (sum2Low < 0 && sum2Low > MAX_SUM){
		newSum2Low = 0;
		cout << "Error in setSum2Low: argument is invalid" << endl;
	}
	else {
		newSum2Low = sum2Low;
	}
}

void student::setExamPts(double newExamPts){
	if (examPts < 0 && examPts > EXAM_POINTS){
		newExamPts = 0;
		cout << "Error in setExamPts: argument is invlid" << endl;
	}
	else {
		newExamPts = examPts;
	}
}

double student::calcPgmAverage(){
	double i;
	i = (pgmPts / PGM_POINTS) * 100;
	return i;
}

double student::calcExamAndQuizAverage(){
	double i;
	i = (examPts+quizPts-sum2Low)/(EXAM_POINTS+QUIZ_POINTS-MAX_SUM) * 100;
	return i;
}
double student::calcCourseAverage(){
	double i;
	i = (.30 *((pgmPts / PGM_POINTS) * 100)) + (.70 *((examPts+quizPts-sum2Low)/(EXAM_POINTS+QUIZ_POINTS-MAX_SUM) * 100));
	return i;
}

char student::letterGrade(){
	double i;
	char f;
	i = (.30 *((pgmPts / PGM_POINTS) * 100))+ (.70*((examPts+quizPts-sum2Low)/(EXAM_POINTS+QUIZ_POINTS-MAX_SUM) * 100));
	
	if (i >= 90 && i <= 100){
		f = 'A';
	}
	else if (i >= 80 && i <=90){
		f = 'B';
	}
	else if (i >= 70 && i<= 80){
		f = 'C';
	}
	else if (i >= 60 && i <= 70){
		f = 'D';
	}
	else {
		f = 'F';
	}
	return f;
}
void student::printStudent(){
	for (int i = 0; i < strlen(name); i++){
		cout << name[i];
	}
	cout << endl << "	Program Average:	  " << calcPgmAverage () << endl;
	cout << "	Exam + Quiz Average:      " << calcExamAndQuizAverage() << endl;
	cout << "	Course Average:		  " << calcCourseAverage() << endl;
	cout << "	Letter Grade:		  " << letterGrade() << endl;
	
	
}
student::student(const char [], int pgmPts, int quizPts, int sum2Low, double examPts){
	strcpy (name, "Rando");
	setPgmPts(pgmPts);
	setQuizPts(quizPts);
	setSum2Low(sum2Low);
	setExamPts(examPts);
}
Last edited on
Line 143: You're setting every student name to "Rando".

Line 142: Your first argument is unnamed. This is what you want to copy to the member variable name.

Line 132-134: There is no need to output name character by character. As long as name has a terminating null, you can just cout name. Using a std::string would be better.

Lines 114-123: Your if statements are multiply inclusive. i.e. 90 satisfies both line 114 and line 117. This won't cause a problem because of the else if, but it's poor style.

lines 34-37: No reason to invoke an unnecessary copy operation. Just call the object's constructor directly:
1
2
3
4
    student s1 ("Rando", 767 , 106, 10, 286.50);
    student s2 ("Pat Jones", 474, 53, 0, 218.50);
    student s3 ("Chris Wilson", 905, 120, 20, 300.00);
    student s4 ("Jarret Jack", 906, 121, 21, 301);


line 52-58: You've reversed the argument and the member variable. i.e. You're testing the member variable, which hasn't been set yet. Then you're assigning the member variable to the argument. That's ass backwards.

Line 62-70: ditto
Line 72-80: ditto
Line 82-90: ditto

Last edited on
If I could add some thing extra:

I don't see the need for a member function to call another member function to get a member variable. Member functions have direct access to member variables.

With the printStudent(), you could avoid calling functions as well, but would need to have some more member variables to hold the values calculated by the statistics functions. Actually, then you could have the body of the constructor call all your functions. Those functions could even be private. Then the printStudent() could just std::cout the member variables directly. This strategy would work as long as one didn't want to change any member variables after creating the object.

Line 94 and in many other places does integer division before it is multiplied by another int (100), then cast to double. Try this:

1
2
3
4
5
void student::calcPgmAverage() {
	// make double ProgramAverage a member variable
	ProgramAverage = (static_cast<double>(pgmPts) / PGM_POINTS) * 100.0; // 100.0 is a double, 100 is int
	
}


Alternatively, it might be easier to make all your member variables double.

Try to avoid magic numbers like 0.30 throughout your code: make them const variables instead. I always put numbers before and after the decimal point for floating point literals. So not .3 or 100. .

With variables names, I find pgmPts and PGM_POINTS potentially confusing. One of them is ALLCAPS because it is a constant, that's ok, but I would prefer the 2 variables names not to be so similar. PGM_POINTS is really the maximum points, and pgmPts is the actual points attained by the student.

Good variable and function names make code self documenting and read like a story. Here is a comical version of what I mean :+)
http://www.cplusplus.com/forum/lounge/176684/#msg872881

Good Luck !!
> I don't see the need for a member function to call another member function to get a member variable.
> Member functions have direct access to member variables.

Yes, they do. But localising dependencies makes the code more maintainable (less brittle).

Original:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template < typename T > struct foo
{
      // ...

     std::size_t size() const { return sz ; } 
     bool empty() const { return size() == 0 ; } // this is self-maintaining

     // ...

      private: 
          T* buffer ;
          std::size_t sz ;
          std::size_t capacity ; 
};


Modified later:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template < typename T > struct foo
{
      // ...
      
     std::size_t size() const { return buffer_begin == nullptr ? 0 :  elements_end - buffer_begin ;  } // ***
     bool empty() const { return size() == 0 ; } // this is self-maintaining

     // ...

      private: 
          T* buffer_begin ;
          T* elements_end ;
          T* buffer_end ; 
};
@JLBorges

Right oh! Thank you :+)
Topic archived. No new replies allowed.