SENECA OOP WORKSHOP 244200 DIY MARK CLASS
DIY (50%)
Note that you can (and probably should) add additional methods to make the DIY part work. <br/ >Also, when developing the operator overloads, remember that many operator overloads can reuse the other operators by calling them. For example "less than" is the same as "not greater than or equal"
Create a C++ Module for a class called Mark to encapsulate a mark between 0 and 100.
MarkGradeScale 4 mark0 <= Mark < 50
F0.050 <= Mark < 60
D1.060 <= Mark < 70
C2.070 <= Mark < 80
B3.080 <= Mark <= 100
A4.0
Important: No values are allowed to be kept in a mark out of the range of 0 to 100. In any circumstance and during any function if the value goes below 0 or above 100, the mark is set to an invalid empty state. This rule is to be followed during the workshop and applies to all the functions and operators of class Mark
Construction
A Mark object can be created using an integer value (one argument constructor)that sets the value of the mark. If this value is not provided (no argument constructor), the value of the mark will be zero.
Mark m, n(25), k(200), p(-10);
// value of m is 0
// value of n is 25
// k is invalid
// p is invalid
Type conversion Operators:
- A Mark object can be casted to an integer (int type); the result would be the value of the mark or zero if the mark is in an invalid state.
Mark m, n(25), k(200), p(-10);
cout << int(m) << endl;
cout << int(n) << endl;
cout << int(k) << endl;
cout << int(p) << endl;
Ouptut:
0
25
0
0
- A Mark object can be casted to a double; the result would be the GPA equivalent of the integer value. See the table of mark values above. Casting an invalid mark will result in a zero value.
Mark m(50), n(80), k(120);
cout << double(m) << endl;
cout << double(n) << endl;
cout << double(k) << endl;
Output:
1
4
0
- A Mark object can be casted to a character (char type); the result would be the grade letter value of the mark. See the table of mark values above. Casting an invalid mark will result in an 'X' value.
Mark m(50), n(80), k(120);
cout << char(m) << endl;
cout << char(n) << endl;
cout << char(k) << endl;
Output:
D
A
X
- A Mark can be casted to a boolean (bool type); the result would be if the mark in a valid state(true) or not (false).
Mark n(80), k(120);
cout << bool(n) << endl;
cout << bool(k) << endl;
Output:
1
0
Comparison operator overloads
- A Mark can be compared with other Marks using
==, !=, <, >, <=
and>=
returning a boolean in result.
Comparison results involving invalid marks are undefined
Mark m(40), n(80);
cout << (m > n) << endl;
cout << (m < n) << endl;
cout << (m >= n) << endl;
cout << (m <= n) << endl;
cout << (m == m) << endl;
cout << (m != n) << endl;
Output:
0
1
0
1
1
1
Unary operators:
- The
++ and --
operators (postfix and prefix) work with a mark exactly as they do with an integer, except that they don't take any action if the mark is invalid.
Mark m, n(25), k(200);
cout << int(++m) << endl;
cout << int(--n) << endl;
cout << int(n--) << endl;
cout << int(m++) << endl;
cout << int(n) << endl;
cout << int(m) << endl;
Ouptut:
1
24
24
1
23
2
-
~
operator returns true if the mark is a pass.
Mark m(40), n(80), k(120);
cout << ~m << endl;
cout << ~n << endl;
cout << ~k << endl;
Output:
0
1
0
Binary Operators
- A Mark object can be set to an integer using the assignment operator. If the mark is in an invalid state, the invalid value can be corrected by the assignment.
Mark m, n(25), k(200);
cout << int(m = 80) << endl;
cout << int(n = 120) << endl;
cout << int(k = 70) << endl;
cout << int(n = m = 90) << endl;
Output:
80
0
70
90
- An integer can be added to the value or deducted from the value of the mark using += and -= operator; if the mark is invalid, the action is omitted. A reference of the mark is returned after the operation.
Mark m, n(25), k(200);
cout << int(m += 20) << endl;
cout << int(n += 20) << endl;
cout << int(k += 20) << endl;
cout << int(n += 60) << endl;
cout << int(m -= 10) << endl;
cout << int(m -= 20) << endl;
Output:
20
45
0
0
10
0
- A mark's value can be added to an integer or deducted from an integer, returning the integer after the operation. Invalid marks will not have any effect on the value of the integer.
int val = 60;
Mark n(80), k(120);
cout << (val += n) << endl;
cout << (val += k) << endl;
cout << (val -= n) << endl;
cout << (val -= k) << endl;
Output:
140
140
60
60
- The sum of a Mark and an integer or another Mark will return a Mark with the sum of the two values as a result.
int val = 15;
Mark m(10), n(80);
cout << int(n + val) << endl;
cout << int(m + n ) << endl;
cout << int(m + n + val) << endl;
Output:
95
90
0
-
<<
and>>
operators move and add the mark value from one mark (source) to another (destination) leaving the source as zero.
int val = 15;
Mark m(70), n(80), p(20);
m << p;
cout << int(m) << endl;
cout << int(p) << endl;
m >> p;
cout << int(m) << endl;
cout << int(p) << endl;
p << n;
cout << int(p) << endl;
Output:
90
0
0
90
0
##Tester program:
/***********************************************************************
// OOP244 Workshop 5 p2: tester program
//
// File main.cpp
// Version 1.0
// Date 2022/10/10
// Author Fardad Soleimanloo
//
// Revision History
// -----------------------------------------------------------
// Name Date Reason
//
/////////////////////////////////////////////////////////////////
***********************************************************************/
#include <iostream>
#include <iomanip>
#include "Mark.h"
using namespace std;
using namespace sdds;
ostream& prn(const Mark& m, int mode = 0, ostream& ostr = cout);
ostream& operator<<(ostream& ostr, const Mark& M);
void testComparison(const Mark& L, const Mark& E, const Mark& H);
void unaryOpTest();
void constructorAndConversion();
void binaryTest(const Mark& I);
int main() {
Mark L = 49, E = 50, H = 51, I = 20;
constructorAndConversion();
testComparison(L, E, H);
unaryOpTest();
binaryTest(I);
return 0;
}
void testComparison(const Mark& L, const Mark& E, const Mark& H) {
cout << "Testing Comparision!" << endl;
cout << L << " < " << E << ": " << (L < E ? "T" : "F") << endl;
cout << L << " > " << E << ": " << (L > E ? "T" : "F") << endl;
cout << L << " <= " << E << ": " << (L <= E ? "T" : "F") << endl;
cout << L << " >= " << E << ": " << (L >= E ? "T" : "F") << endl;
cout << L << " == " << E << ": " << (L == E ? "T" : "F") << endl;
cout << L << " != " << E << ": " << (L != E ? "T" : "F") << endl;
cout << "----------------" << endl;
cout << E << " < " << E << ": " << (E < E ? "T" : "F") << endl;
cout << E << " > " << E << ": " << (E > E ? "T" : "F") << endl;
cout << E << " <= " << E << ": " << (E <= E ? "T" : "F") << endl;
cout << E << " >= " << E << ": " << (E >= E ? "T" : "F") << endl;
cout << E << " == " << E << ": " << (E == E ? "T" : "F") << endl;
cout << E << " != " << E << ": " << (E != E ? "T" : "F") << endl;
cout << "----------------" << endl;
cout << E << " < " << H << ": " << (E < H ? "T" : "F") << endl;
cout << E << " > " << H << ": " << (E > H ? "T" : "F") << endl;
cout << E << " <= " << H << ": " << (E <= H ? "T" : "F") << endl;
cout << E << " >= " << H << ": " << (E >= H ? "T" : "F") << endl;
cout << E << " == " << H << ": " << (E == H ? "T" : "F") << endl;
cout << E << " != " << H << ": " << (E != H ? "T" : "F") << endl;
cout << "----------------" << endl;
}
void unaryOpTest() {
Mark m, n(51), p(100), R;
cout << "Testing Unary operators!" << endl;
cout << "m: " << m << endl;
R = m--;
cout << "R = m--, R: " << R << ", m: " << m << endl;
R = --m;
cout << "R = --m, R: " << R << ", m: " << m << endl;
R = m++;
cout << "R = m++, R: " << R << ", m: " << m << endl;
R = ++m;
cout << "R = ++m, R: " << R << ", m: " << m << endl;
cout << "-----------------------------------------" << endl;
cout << "n: " << n << endl;
R = --n;
cout << "R = --n, R: " << R << ", n: " << n << (~n ? " Passed!" : " Failed!") << endl;
R = n--;
cout << "R = n--, R: " << R << ", n: " << n << (~n ? " Passed!" : " Failed!") << endl;
R = ++n;
cout << "R = ++n, R: " << R << ", n: " << n << (~n ? " Passed!" : " Failed!") << endl;
R = n++;
cout << "R = n++, R: " << R << ", n: " << n << (~n ? " Passed!" : " Failed!") << endl;
cout << "-----------------------------------------" << endl;
cout << "p: " << p << endl;
R = p++;
cout << "R = p++, R: " << R << ", p: " << p << endl;
R = ++p;
cout << "R = ++p, R: " << R << ", p: " << p << endl;
R = p--;
cout << "R = p--, R: " << R << ", p: " << p << endl;
R = --p;
cout << "R = --p, R: " << R << ", p: " << p << endl;
}
void constructorAndConversion() {
Mark m, n(30), k(75), p(300);
cout << "Constructors and" << endl;
cout << "and conversion" << endl;
prn(m) << ", ";
prn(n, 1) << ", ";
prn(k, 2) << ", ";
prn(p) << endl;
}
void binaryTest(const Mark& C) {
Mark m, n = 90;
cout << "Testing Member Binaries!" << endl;
cout << "m: " << m << endl;
cout << "m = 75, m: " << (m = 75) << endl;
cout << "m = -1, m: " << (m = -1) << endl;
cout << "m = 100, m: " << (m = 100) << endl;
cout << "m = 101, m: " << (m = 101) << endl;
cout << "-----------------------------------------" << endl;
cout << "m += 65: " << (m += 65) << endl;
cout << "m -= 10: " << (m -= 10) << endl;
cout << "m = 10: " << (m = 10) << endl;
cout << "m += 65: " << (m += 65) << endl;
cout << "m -= 55: " << (m -= 10) << endl;
cout << "-----------------------------------------" << endl;
cout << "m = 5" << endl;
m = 5;
cout << "m: " << m << ", n: " << n << endl;
cout << "m << n: " << (m << n) << endl;
cout << "m: " << m << ", n: " << n << endl;
cout << "m >> n: " << (m >> n) << endl;
cout << "m: " << m << ", n: " << n << endl;
cout << "-----------------------------------------" << endl;
cout << "C: " << C << endl;
cout << "C + 30: " << (C + 30) << endl;
cout << "C + -90: " << (C + -90) << endl;
cout << "C + 100: " << (C + 100) << endl;
cout << "C + C: " << (C + C) << endl;
cout << "n = 90" << endl;
n = 90;
cout << "n: " << n << endl;
cout << "C + n: " << (C + n) << endl;
cout << "-----------------------------------------" << endl;
cout << "Testing Helper Binaries!" << endl;
int v = 50;
cout << "v: " << v << ", C: " << C << endl;
cout << "v += C: " << (v += C) << endl;
cout << "v: " << v << ", C: " << C << endl;
cout << "v -= C: " << (v -= C) << endl;
cout << "v: " << v << ", C: " << C << endl;
cout << "v + C: " << (v + C) << endl;
cout << "v: " << v << ", C: " << C << endl;
}
ostream& prn(const Mark& m, int mode, ostream& ostr) {
ostr << "[";
if(bool(m)) {
if(mode == 1) {
ostr << char(m);
} else if(mode == 2) {
ostr << fixed << setprecision(1) << setw(3) << double(m);
} else {
ostr << setw(3) << right << int(m);
}
} else {
ostr << "Invalid!";
}
return ostr << "]";
}
ostream& operator<<(ostream& ostr, const Mark& M) {
return prn(M, 0, ostr);
}
Here is the execution sample for the tester program
Constructors and
and conversion
[ 0], [F], [3.0], [Invalid!]
Testing Comparision!
[ 49] < [ 50]: T
[ 49] > [ 50]: F
[ 49] <= [ 50]: T
[ 49] >= [ 50]: F
[ 49] == [ 50]: F
[ 49] != [ 50]: T
----------------
[ 50] < [ 50]: F
[ 50] > [ 50]: F
[ 50] <= [ 50]: T
[ 50] >= [ 50]: T
[ 50] == [ 50]: T
[ 50] != [ 50]: F
----------------
[ 50] < [ 51]: T
[ 50] > [ 51]: F
[ 50] <= [ 51]: T
[ 50] >= [ 51]: F
[ 50] == [ 51]: F
[ 50] != [ 51]: T
----------------
Testing Unary operators!
m: [ 0]
R = m--, R: [ 0], m: [Invalid!]
R = --m, R: [Invalid!], m: [Invalid!]
R = m++, R: [Invalid!], m: [Invalid!]
R = ++m, R: [Invalid!], m: [Invalid!]
-----------------------------------------
n: [ 51]
R = --n, R: [ 50], n: [ 50] Passed!
R = n--, R: [ 50], n: [ 49] Failed!
R = ++n, R: [ 50], n: [ 50] Passed!
R = n++, R: [ 50], n: [ 51] Passed!
-----------------------------------------
p: [100]
R = p++, R: [100], p: [Invalid!]
R = ++p, R: [Invalid!], p: [Invalid!]
R = p--, R: [Invalid!], p: [Invalid!]
R = --p, R: [Invalid!], p: [Invalid!]
Testing Member Binaries!
m: [ 0]
m = 75, m: [ 75]
m = -1, m: [Invalid!]
m = 100, m: [100]
m = 101, m: [Invalid!]
-----------------------------------------
m += 65: [Invalid!]
m -= 10: [Invalid!]
m = 10: [ 10]
m += 65: [ 75]
m -= 55: [ 65]
-----------------------------------------
m = 5
m: [ 5], n: [ 90]
m << n: [ 95]
m: [ 95], n: [ 0]
m >> n: [ 0]
m: [ 0], n: [ 95]
-----------------------------------------
C: [ 20]
C + 30: [ 50]
C + -90: [Invalid!]
C + 100: [Invalid!]
C + C: [ 40]
n = 90
n: [ 90]
C + n: [Invalid!]
-----------------------------------------
Testing Helper Binaries!
v: 50, C: [ 20]
v += C: 70
v: 70, C: [ 20]
v -= C: 50
v: 50, C: [ 20]
v + C: 70
v: 50, C: [ 20]
Modify the tester program to test all the different circumstances/cases of the application if desired and note that the professor's tester may have many more samples than the tester program here.
Reflection
Study your final solutions for each deliverable of the workshop, reread the related parts of the course notes, and make sure that you have understood the concepts covered by this workshop. This should take no less than 30 minutes of your time and the result is suggested to be at least 150 words in length.
Create a file named reflect.txt
that contains your detailed description of the topics that you have learned in completing this workshop and mention any issues that caused you difficulty.
You may be asked to talk about your reflection (as a presentation) in class.
Part 2 Submission (DIY)
Files to submit:
reflect.txt
and:
Mark.h
Mark.cpp
main.cpp
Data Entry
??? explain what data will be used for submission and testing
Submission Process:
Upload the files listed above to your matrix
account. Compile and run your code using the g++
compiler as shown in Compiling and Testing Your Program and make sure that everything works properly.
Then, run the following command from your account
- replace
profname.proflastname
with your professor’s Seneca userid - replace ?? with your subject code (200 or 244)
- replace # with the workshop number
- replace X with the workshop part number (1 or 2)
~profname.proflastname/submit 2??/w#/pX
and follow the instructions.
Submitting Utils Module
To have your custom Utils module compiled with your workshop and submitted, add a u to the part number of your workshop (i.e up1 for part one and up2 for part two) and issue the following submission command instead of the above:
~profname.proflastname/submit 2??/w#/upX
See Custom Code Submission section for more detail
Important: Please note that a successful submission does not guarantee full credit for this workshop. If the professor is not satisfied with your implementation, your professor may ask you to resubmit. Re-submissions will attract a penalty.