Example - C++ Library#
An example for an exam, where the interface is defined in the .h
file and the student implements the .cpp
file.
Exercise:
For a given non-zero whole number N return the factorial of N (1 * 2 * 3 * ... N)
Example .h
file:
#ifndef Q_H
#define Q_H
// DO NOT MODIFY THIS FILE!
// THIS FILE DEFINES THE STRUCTURE OF THE FUNCTIONS WHICH WILL BE TESTED
// IF YOU MODIFY THE STRUCUTRE OF THE FUNCTION, YOUR RESULTS WILL NOT BE VALID
// API: For a given non-zero whole number N return the factorial of N (1 * 2 * 3 * ... N)
// if N is 0, return 1
// Params:
// N - the number to calculate factorial for (n <= 20)
// Returns:
// The factorial of the number
// Example:
// N - 5, return - 120
unsigned long long factorial(int N);
#endif // Q_H
Example empty .cpp
file:
#include "Maths.h"
// import any required libraries here
unsigned long long factorial(int N){
}
Example solved .cpp
file:
#include "Maths.h"
// import any required libraries here
unsigned long long factorial(int N){
if(N <= 1){
return 1;
}
return N * factorial(N - 1);
}
Example tester:
#include "Maths.h"
#include "cpp_eval_util.h"
#include <string>
#include <iostream>
#include <exception>
using namespace std;
#define TEST_CASE_COUNT 8
class FactorialEvaluator : public Evaluator<unsigned long long> // Change this type to the type returned by the evaluated function
{
public:
// Test cases
unsigned long long test_cases[TEST_CASE_COUNT][2] = {
{0, 1},
{1, 1},
{2, 2},
{5, 120},
{10, 3628800},
{12, 479001600},
{15, 1307674368000},
{20, 2432902008176640000}
};
// Constructor
FactorialEvaluator(int argc, char** argv):Evaluator(argc, argv){}
// Return the name of the exam. Evaluator will start at i = 0 until "" is returned, which marks the number of questions.
string GetName(int i){
if(i >= TEST_CASE_COUNT) { return ""; }
return "factorial(" + to_string(test_cases[i][0]) + ")";
}
// For a given question run some code. Return value must match Evaluator<> templated type
unsigned long long GetResult(int i){
return factorial(test_cases[i][0]);
}
// For a given result, return a score between 0 and 1. Second parameter type must match Evaluator<> templated type
float GetScore(int i, unsigned long long result){
return result == test_cases[i][1] ? 1.0f : 0.0f;
}
// For a given result and score, return some feedback. Second parameter type must match Evaluator<> templated type
string GetFeedback(int i, unsigned long long result, float score){
return "Returned " + to_string(result) + ", expecting " + to_string(test_cases[i][1]) + (score >= 1 ? " : PASS!" : " : FAIL!");
}
};
int main(int argc, char **argv) {
FactorialEvaluator evaluator(argc, argv);
return evaluator.Run();
}
Example config file:
{
"tests": [
{
"type": "replace_files",
"files": [
"C++/2_Advanced/02_Maths/Maths.h"
]
},
{
"type": "compile",
"max_score": 10.0,
"number": "1",
"tags": [],
"visibility": "visible"
},
{
"type": "functionality",
"max_score": 60.0,
"number": "2",
"tags": [],
"visibility": "visible",
"tester_file": "path/to/factorial_tester.cpp"
},
{
"type": "static",
"max_score": 10.0,
"number": "3",
"tags": [],
"visibility": "visible"
},
{
"type": "comments",
"max_score": 10.0,
"number": "4",
"tags": [],
"visibility": "visible"
},
{
"type": "style",
"max_score": 10.0,
"number": "5",
"tags": [],
"visibility": "visible",
"style": "google"
}
]
}
More than one tester can be used to test multiple functions