summaryrefslogtreecommitdiff
path: root/cs162
diff options
context:
space:
mode:
Diffstat (limited to 'cs162')
-rw-r--r--cs162/BUILD14
-rw-r--r--cs162/CMakeLists.txt10
-rw-r--r--cs162/wk1/BUILD33
-rw-r--r--cs162/wk1/CMakeLists.txt3
-rw-r--r--cs162/wk1/quickstop/CMakeLists.txt4
-rw-r--r--cs162/wk1/quickstop/quickstop.cc57
-rw-r--r--cs162/wk1/random2dArrays/CMakeLists.txt4
-rw-r--r--cs162/wk1/random2dArrays/random2dArrays.cc205
-rw-r--r--cs162/wk1/randoms/CMakeLists.txt4
-rw-r--r--cs162/wk1/randoms/randoms.cc71
-rw-r--r--cs162/wk10/BUILD25
-rw-r--r--cs162/wk10/CMakeLists.txt2
-rw-r--r--cs162/wk10/dynamicArray/CMakeLists.txt7
-rw-r--r--cs162/wk10/dynamicArray/dynamicArray.cc65
-rw-r--r--cs162/wk10/pointersOnly/CMakeLists.txt7
-rw-r--r--cs162/wk10/pointersOnly/pointersOnly.cc40
-rw-r--r--cs162/wk2/BUILD26
-rw-r--r--cs162/wk2/CMakeLists.txt2
-rw-r--r--cs162/wk2/dictionaryRead/CMakeLists.txt4
-rw-r--r--cs162/wk2/dictionaryRead/dictionaryRead.cc31
-rw-r--r--cs162/wk2/friendsFile/CMakeLists.txt4
-rw-r--r--cs162/wk2/friendsFile/friendsFile.cc57
-rw-r--r--cs162/wk3/BUILD15
-rw-r--r--cs162/wk3/CMakeLists.txt1
-rw-r--r--cs162/wk3/musicStruct/CMakeLists.txt4
-rw-r--r--cs162/wk3/musicStruct/musicStruct.cc168
-rw-r--r--cs162/wk4/BUILD15
-rw-r--r--cs162/wk4/CMakeLists.txt1
-rw-r--r--cs162/wk4/dateClass/CMakeLists.txt4
-rw-r--r--cs162/wk4/dateClass/date.cc79
-rw-r--r--cs162/wk4/dateClass/date.hh35
-rw-r--r--cs162/wk4/dateClass/testDate.cc58
-rw-r--r--cs162/wk5/BUILD24
-rw-r--r--cs162/wk5/CMakeLists.txt2
-rw-r--r--cs162/wk5/country/CMakeLists.txt4
-rw-r--r--cs162/wk5/country/country.cc22
-rw-r--r--cs162/wk5/country/country.hh54
-rw-r--r--cs162/wk5/country/testCountry.cc103
-rw-r--r--cs162/wk5/gradesHelpers/CMakeLists.txt4
-rw-r--r--cs162/wk5/gradesHelpers/grades.cc64
-rw-r--r--cs162/wk5/gradesHelpers/grades.hh41
-rw-r--r--cs162/wk5/gradesHelpers/testGrades.cc53
-rw-r--r--cs162/wk6/BUILD24
-rw-r--r--cs162/wk6/CMakeLists.txt2
-rw-r--r--cs162/wk6/friends/CMakeLists.txt4
-rw-r--r--cs162/wk6/friends/bankAccount.cc43
-rw-r--r--cs162/wk6/friends/bankAccount.hh42
-rw-r--r--cs162/wk6/friends/testBankAccount.cc39
-rw-r--r--cs162/wk6/overload/CMakeLists.txt4
-rw-r--r--cs162/wk6/overload/shape.cc74
-rw-r--r--cs162/wk6/overload/shape.hh45
-rw-r--r--cs162/wk6/overload/testShape.cc76
-rw-r--r--cs162/wk7/BUILD15
-rw-r--r--cs162/wk7/CMakeLists.txt1
-rw-r--r--cs162/wk7/course/CMakeLists.txt4
-rw-r--r--cs162/wk7/course/course.cc85
-rw-r--r--cs162/wk7/course/course.hh52
-rw-r--r--cs162/wk7/course/student.cc21
-rw-r--r--cs162/wk7/course/student.hh30
-rw-r--r--cs162/wk7/course/testCourse.cc104
-rw-r--r--cs162/wk8/BUILD15
-rw-r--r--cs162/wk8/CMakeLists.txt1
-rw-r--r--cs162/wk8/inherit/CMakeLists.txt10
-rw-r--r--cs162/wk8/inherit/employee.cc25
-rw-r--r--cs162/wk8/inherit/employee.hh49
-rw-r--r--cs162/wk8/inherit/hourlyEmployee.cc7
-rw-r--r--cs162/wk8/inherit/hourlyEmployee.hh31
-rw-r--r--cs162/wk8/inherit/salesperson.cc11
-rw-r--r--cs162/wk8/inherit/salesperson.hh35
-rw-r--r--cs162/wk8/inherit/testEmployeeADTs.cc214
-rw-r--r--cs162/wk9/BUILD15
-rw-r--r--cs162/wk9/CMakeLists.txt1
-rw-r--r--cs162/wk9/vectors/CMakeLists.txt7
-rw-r--r--cs162/wk9/vectors/vectors.cc172
74 files changed, 2684 insertions, 0 deletions
diff --git a/cs162/BUILD b/cs162/BUILD
new file mode 100644
index 0000000..10ccc2e
--- /dev/null
+++ b/cs162/BUILD
@@ -0,0 +1,14 @@
+filegroup(
+ name = "build_all",
+ srcs = [
+ "//cs162/wk1:build_all",
+ "//cs162/wk2:build_all",
+ "//cs162/wk3:build_all",
+ "//cs162/wk4:build_all",
+ "//cs162/wk5:build_all",
+ "//cs162/wk6:build_all",
+ "//cs162/wk7:build_all",
+ "//cs162/wk8:build_all",
+ "//cs162/wk9:build_all",
+ ],
+)
diff --git a/cs162/CMakeLists.txt b/cs162/CMakeLists.txt
new file mode 100644
index 0000000..e5cdfca
--- /dev/null
+++ b/cs162/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_subdirectory(wk1)
+add_subdirectory(wk2)
+add_subdirectory(wk3)
+add_subdirectory(wk4)
+add_subdirectory(wk5)
+add_subdirectory(wk6)
+add_subdirectory(wk7)
+add_subdirectory(wk8)
+add_subdirectory(wk9)
+add_subdirectory(wk10)
diff --git a/cs162/wk1/BUILD b/cs162/wk1/BUILD
new file mode 100644
index 0000000..0e5dde9
--- /dev/null
+++ b/cs162/wk1/BUILD
@@ -0,0 +1,33 @@
+cc_binary(
+ name = "quickstop",
+ srcs = glob([
+ "quickstop/**/*.cc",
+ "quickstop/**/*.hh",
+ ]),
+)
+
+cc_binary(
+ name = "random2dArrays",
+ srcs = glob([
+ "random2dArrays/**/*.cc",
+ "random2dArrays/**/*.hh",
+ ]),
+)
+
+cc_binary(
+ name = "randoms",
+ srcs = glob([
+ "randoms/**/*.cc",
+ "randoms/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "quickstop",
+ "random2dArrays",
+ "randoms",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk1/CMakeLists.txt b/cs162/wk1/CMakeLists.txt
new file mode 100644
index 0000000..b253e2d
--- /dev/null
+++ b/cs162/wk1/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(randoms)
+add_subdirectory(quickstop)
+add_subdirectory(random2dArrays)
diff --git a/cs162/wk1/quickstop/CMakeLists.txt b/cs162/wk1/quickstop/CMakeLists.txt
new file mode 100644
index 0000000..59d03bd
--- /dev/null
+++ b/cs162/wk1/quickstop/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk1_quickstop)
+
+add_executable(wk1_quickstop quickstop.cc)
diff --git a/cs162/wk1/quickstop/quickstop.cc b/cs162/wk1/quickstop/quickstop.cc
new file mode 100644
index 0000000..208ac5c
--- /dev/null
+++ b/cs162/wk1/quickstop/quickstop.cc
@@ -0,0 +1,57 @@
+#include <iostream>
+
+// Print instructions
+void instructions();
+// Get and assign the input
+void getInput(double &, int &);
+// Calculate the adjusted price
+double price(double, int);
+// Output the adjusted price
+void giveOutput(double, int, double);
+
+int main() {
+ // Declare variables
+ double wholesalePrice;
+ int shelfDays;
+ double adjustedPrice;
+
+ instructions();
+ getInput(wholesalePrice, shelfDays);
+ adjustedPrice = price(wholesalePrice, shelfDays);
+ giveOutput(wholesalePrice, shelfDays, adjustedPrice);
+
+ return 0;
+}
+
+void instructions() {
+ // Output instructions
+ std::cout << "Enter the wholesale price and the number of days the item is"
+ "expected to be on shelf, get adjusted price.\n"
+ << std::endl;
+}
+
+void getInput(double &cost, int &turnover) {
+ // Get and assign input
+ std::cout << "Wholesale price: ";
+ std::cin >> cost;
+ std::cout << "Number of days item is expected to be on a shelf: ";
+ std::cin >> turnover;
+}
+
+double price(double cost, int turnover) {
+ // Compare `turnover` to get adjusted price
+ if (turnover <= 7) {
+ return cost + (5.0f / cost);
+ } else if (turnover > 7) {
+ return cost + (10.0f / cost);
+ }
+
+ return 0.0f;
+}
+
+void giveOutput(double cost, int turnover, double price) {
+ // Output adjusted price
+ std::cout << "\nIf an item costing $" << cost
+ << " is expected to be on a shelf for " << turnover
+ << " days, the item will cost $" << price << std::endl;
+}
diff --git a/cs162/wk1/random2dArrays/CMakeLists.txt b/cs162/wk1/random2dArrays/CMakeLists.txt
new file mode 100644
index 0000000..8bf860a
--- /dev/null
+++ b/cs162/wk1/random2dArrays/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk1_random2dArrays)
+
+add_executable(wk1_random2dArrays random2dArrays.cc)
diff --git a/cs162/wk1/random2dArrays/random2dArrays.cc b/cs162/wk1/random2dArrays/random2dArrays.cc
new file mode 100644
index 0000000..db2a8c9
--- /dev/null
+++ b/cs162/wk1/random2dArrays/random2dArrays.cc
@@ -0,0 +1,205 @@
+#include <iomanip>
+#include <iostream>
+#include <random>
+
+// Declare a helper macro for obtaining random numbers
+#define realRand() distribution(mersenneTwister)
+
+// Prints an array
+void printArrayOfSize(int[], int);
+// Prints a two-dimensional array (uses `printArrayOfSize` internally)
+void printTwoDimensionalArray(int[4][5]);
+// Adds two, two-dimensional arrays
+void addTwoDimensionalArrayCells(int[4][5], int[4][5], int[4][5]);
+// Adds two, two-dimensional arrays' rows
+void addTwoDimensionalArrayRows(int[4][5], int[4]);
+// Adds two, two-dimensional arrays' columns
+void addTwoDimensionalArrayColumns(int[4][5], int[5]);
+int addTwoDimensionalArrays(int[4][5], int[4][5]);
+
+int main() {
+ // Declare variables
+ int arrayOne[4][5];
+ int arrayTwo[4][5];
+ int userChoice;
+ // Decided to use C++11 random for sound non-predictable random numbers
+ std::random_device randomDevice;
+ std::mt19937_64 mersenneTwister(randomDevice());
+ std::uniform_real_distribution<double> distribution(10.0, 99.0);
+
+ // Iterate over `arrayOne` and `arrayTwo`
+ for (int i = 0; i < 4; ++i) {
+ // Iterate over `arrayOne` and `arrayTwo`'s rows
+ for (int j = 0; j < 5; ++j) {
+ // Generate and assign a random `int`
+ arrayOne[i][j] =
+ static_cast<int>(realRand()); // arrayOne[i][j] = realRand();
+ arrayTwo[i][j] =
+ static_cast<int>(realRand()); // arrayTwo[i][j] = realRand();
+ }
+ }
+
+ // Output information
+ std::cout << "Choose what to do with two randomly generated 2D arrays\n"
+ "1. Display both 2D arrays\n"
+ "2. Add both 2D arrays\n"
+ "3. Add rows of both 2D arrays\n"
+ "4. Add columns of both 2D arrays\n"
+ "5. Add all values of both arrays\n"
+ << std::endl
+ << "Your choice: ";
+ // Get user's choice
+ std::cin >> userChoice;
+
+ // Run correct branch per user's choice
+ switch (userChoice) {
+ // Output arrays
+ case 1: {
+ std::cout << "\nArray one:\n";
+ printTwoDimensionalArray(arrayOne);
+
+ std::cout << "Array two:\n";
+ printTwoDimensionalArray(arrayTwo);
+ } break;
+
+ // Add and output arrays
+ case 2: {
+ int addArray[4][5];
+
+ addTwoDimensionalArrayCells(arrayOne, arrayTwo, addArray);
+
+ std::cout << "\nArray one:\n";
+ printTwoDimensionalArray(arrayOne);
+
+ std::cout << "Array two:\n";
+ printTwoDimensionalArray(arrayTwo);
+
+ std::cout << '\n';
+
+ std::cout << "Added arrays:\n";
+ printTwoDimensionalArray(addArray);
+ } break;
+
+ // Add and output arrays' rows
+ case 3: {
+ int arrayOneRowsSums[4] = {0};
+ int arrayTwoRowsSums[4] = {0};
+
+ std::cout << "\nArray one:\n";
+ printTwoDimensionalArray(arrayOne);
+
+ std::cout << "Array two:\n";
+ printTwoDimensionalArray(arrayTwo);
+
+ std::cout << '\n';
+
+ addTwoDimensionalArrayRows(arrayOne, arrayOneRowsSums);
+ addTwoDimensionalArrayRows(arrayTwo, arrayTwoRowsSums);
+
+ std::cout << "Array one row sums:\n";
+ printArrayOfSize(arrayOneRowsSums, 4);
+
+ std::cout << '\n';
+
+ std::cout << "Array two row sums:\n";
+ printArrayOfSize(arrayTwoRowsSums, 4);
+ } break;
+
+ // Add and output arrays' columns
+ case 4: {
+ int arrayOneColumnsSums[5] = {0};
+ int arrayTwoColumnsSums[5] = {0};
+
+ std::cout << "\nArray one:\n";
+ printTwoDimensionalArray(arrayOne);
+
+ std::cout << "Array two:\n";
+ printTwoDimensionalArray(arrayTwo);
+
+ std::cout << '\n';
+
+ addTwoDimensionalArrayColumns(arrayOne, arrayOneColumnsSums);
+ addTwoDimensionalArrayColumns(arrayTwo, arrayTwoColumnsSums);
+
+ std::cout << "Array one row columns:\n";
+ printArrayOfSize(arrayOneColumnsSums, 5);
+
+ std::cout << '\n';
+
+ std::cout << "Array two row columns:\n";
+ printArrayOfSize(arrayTwoColumnsSums, 5);
+ } break;
+
+ case 5: {
+ std::cout << "\nAll cells of array one plus array two: "
+ << addTwoDimensionalArrays(arrayOne, arrayTwo) << '\n';
+ } break;
+
+ default: {
+ std::cout << "That is not a valid choice.\n";
+ } break;
+ }
+
+ return 0;
+}
+
+void printArrayOfSize(int array[4], int size) {
+ // Iterate over `array`
+ for (int i = 0; i < size; ++i) {
+ std::cout << std::right << std::setw(3) << " " << array[i];
+ }
+}
+
+void printTwoDimensionalArray(int array[4][5]) {
+ // Iterate over `array`
+ for (int i = 0; i < 4; ++i) {
+ printArrayOfSize(array[i], 5);
+
+ std::cout << '\n';
+ }
+}
+
+void addTwoDimensionalArrayCells(int arrayOne[4][5], int arrayTwo[4][5],
+ int addArray[4][5]) {
+ // Iterate over arrays
+ for (int i = 0; i < 4; ++i) {
+ // Iterate over arrays' rows
+ for (int j = 0; j < 5; ++j) {
+ addArray[i][j] = arrayOne[i][j] + arrayTwo[i][j];
+ }
+ }
+}
+
+void addTwoDimensionalArrayRows(int array[4][5], int sum[4]) {
+ // Iterate over arrays
+ for (int i = 0; i < 4; ++i) {
+ // Iterate over arrays' rows
+ for (int j = 0; j < 5; ++j) {
+ sum[i] += array[i][j];
+ }
+ }
+}
+
+void addTwoDimensionalArrayColumns(int array[4][5], int sum[5]) {
+ // Iterate over arrays
+ for (int i = 0; i < 4; ++i) {
+ // Iterate over arrays' rows
+ for (int j = 0; j < 5; ++j) {
+ sum[j] = array[0][j] + array[1][j] + array[2][j] + array[3][j];
+ }
+ }
+}
+
+int addTwoDimensionalArrays(int arrayOne[4][5], int arrayTwo[4][5]) {
+ int sum = 0;
+
+ // Iterate over arrays
+ for (int i = 0; i < 4; ++i) {
+ // Iterate over arrays' rows
+ for (int j = 0; j < 5; ++j) {
+ sum += arrayOne[i][j] + arrayTwo[i][j];
+ }
+ }
+
+ return sum;
+}
diff --git a/cs162/wk1/randoms/CMakeLists.txt b/cs162/wk1/randoms/CMakeLists.txt
new file mode 100644
index 0000000..85226b3
--- /dev/null
+++ b/cs162/wk1/randoms/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk1_randoms)
+
+add_executable(wk1_randoms randoms.cc)
diff --git a/cs162/wk1/randoms/randoms.cc b/cs162/wk1/randoms/randoms.cc
new file mode 100644
index 0000000..ec7d11c
--- /dev/null
+++ b/cs162/wk1/randoms/randoms.cc
@@ -0,0 +1,71 @@
+#include <iostream>
+
+// Check if there are any duplicates within the array given the array, number
+// to check against, and a reference to a variable which will be used to keep
+// track if the duplicates within the array.
+void checkArrayForDupes(const int[20], int, int &);
+// Print the entire array
+void printArray(const int[20]);
+// Given a variable which may or may not be zero, a reference to a variable
+// which will be assigned to, and the value to assign to the reference; check
+// if the value is zero and assign if the value is zero.
+bool assignIfZero(int &, int &, int);
+
+int main() {
+ int randomNumbers[20];
+
+ // Seed `rand`
+ srand(static_cast<unsigned int>(time(nullptr))); // srand(time(nullptr));
+
+ // Iterate over `random_numbers`
+ for (int &randomNumber : randomNumbers) {
+ // Iterate endlessly until a unique number is found
+ for (;;) {
+ // Generate a random `int`
+ int randomInt = rand() % (20 + 1 - 1) + 1;
+ // Keep track of how many times the random number occurs within the
+ // array
+ int duplicates = 0;
+
+ // Check if the random number already has occurred within the array
+ checkArrayForDupes(randomNumbers, randomInt, duplicates);
+
+ // If the random number has not occurred yet, assign it and break out
+ // of the loop
+ if (assignIfZero(duplicates, randomNumber, randomInt)) {
+ break;
+ }
+ }
+ }
+
+ // Print out array values
+ printArray(randomNumbers);
+
+ return 0;
+}
+
+void checkArrayForDupes(const int numbers[20], int number, int &duplicates) {
+ for (int i = 0; i < 20; ++i) {
+ if (numbers[i] == number) {
+ duplicates += 1;
+ }
+ }
+}
+
+void printArray(const int numbers[20]) {
+ for (int i = 0; i < 20; ++i) {
+ std::cout << numbers[i] << std::endl;
+ }
+}
+
+bool assignIfZero(int &compare, int &assign, int value) {
+ if (compare == 0) {
+ // Assign is a part of the array, so this function makes changes to a
+ // value in the array.
+ assign = value;
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/cs162/wk10/BUILD b/cs162/wk10/BUILD
new file mode 100644
index 0000000..f15d0eb
--- /dev/null
+++ b/cs162/wk10/BUILD
@@ -0,0 +1,25 @@
+cc_binary(
+ name = "pointersOnly",
+ srcs = glob([
+ "pointersOnly/**/*.cc",
+ "pointersOnly/**/*.hh",
+ ]),
+)
+
+cc_binary(
+ name = "dynamicArray",
+ srcs = glob([
+ "dynamicArray/**/*.cc",
+ "dynamicArray/**/*.hh",
+ ]),
+ data = ["//data:dataFile.txt"],
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "pointersOnly",
+ "dynamicArray",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk10/CMakeLists.txt b/cs162/wk10/CMakeLists.txt
new file mode 100644
index 0000000..6ba4ef3
--- /dev/null
+++ b/cs162/wk10/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(pointersOnly)
+add_subdirectory(dynamicArray)
diff --git a/cs162/wk10/dynamicArray/CMakeLists.txt b/cs162/wk10/dynamicArray/CMakeLists.txt
new file mode 100644
index 0000000..d4c4a57
--- /dev/null
+++ b/cs162/wk10/dynamicArray/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk10_dynamicArray)
+
+add_executable(
+ wk10_dynamicArray
+ dynamicArray.cc
+) \ No newline at end of file
diff --git a/cs162/wk10/dynamicArray/dynamicArray.cc b/cs162/wk10/dynamicArray/dynamicArray.cc
new file mode 100644
index 0000000..5fcba9a
--- /dev/null
+++ b/cs162/wk10/dynamicArray/dynamicArray.cc
@@ -0,0 +1,65 @@
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+int main() {
+ std::size_t data_file_size = 0;
+ std::ifstream data_file("data/dataFile.txt");
+ std::string data_item;
+ int lowest = std::numeric_limits<int>::max();
+ int highest = std::numeric_limits<int>::lowest();
+
+ // Make sure the file is open
+ if (!data_file.is_open()) {
+ std::cout << "data file is not open" << std::endl;
+
+ return 0;
+ }
+
+ // Count how many numbers there are in the data file
+ while (data_file >> data_item) {
+ data_file_size += 1;
+ }
+
+ // Seek back the beginning the of the file
+ data_file.clear();
+ data_file.seekg(0, std::ios::beg);
+
+ // auto data = std::make_unique<int[]>(data_file_size);
+ // Set up a dynamic array to hold the exact number of numbers in the data file
+ int *data = new int[data_file_size];
+
+ // Read the values from the data file into the array
+ for (std::size_t i = 0; i < data_file_size; ++i) {
+ data_file >> data[i];
+ }
+
+ // Sort the array using bubble sort
+ for (std::size_t i = 0; i < data_file_size - 1; ++i) {
+ for (std::size_t j = 0; j < data_file_size - 1; ++j) {
+ if (data[j] > data[j + 1]) {
+ std::swap(data[j], data[j + 1]);
+ }
+ }
+ }
+
+ // Find the lowest and highest numbers in the array
+ for (std::size_t i = 0; i < data_file_size; ++i) {
+ if (data[i] < lowest) {
+ lowest = data[i];
+ }
+
+ if (data[i] > highest) {
+ highest = data[i];
+ }
+ }
+
+ // Output the lowest and highest numbers in the array
+ std::cout << "lowest: " << lowest << "\nhighest: " << highest << std::endl;
+
+ // Free the array
+ delete[] data;
+
+ return 0;
+}
diff --git a/cs162/wk10/pointersOnly/CMakeLists.txt b/cs162/wk10/pointersOnly/CMakeLists.txt
new file mode 100644
index 0000000..7aaa73e
--- /dev/null
+++ b/cs162/wk10/pointersOnly/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk10_pointersOnly)
+
+add_executable(
+ wk10_pointersOnly
+ pointersOnly.cc
+) \ No newline at end of file
diff --git a/cs162/wk10/pointersOnly/pointersOnly.cc b/cs162/wk10/pointersOnly/pointersOnly.cc
new file mode 100644
index 0000000..31b6f35
--- /dev/null
+++ b/cs162/wk10/pointersOnly/pointersOnly.cc
@@ -0,0 +1,40 @@
+#include <iostream>
+
+void inputFeetAndInches(double *, double *);
+void feetAndInchesToMeters(const double *, const double *, double *);
+void outputFeetInchesAndMeters(const double *, const double *, const double *);
+
+int main() {
+ auto *feet = new double;
+ auto *inches = new double;
+ auto *meters = new double;
+
+ inputFeetAndInches(feet, inches);
+ feetAndInchesToMeters(feet, inches, meters);
+ outputFeetInchesAndMeters(feet, inches, meters);
+
+ delete feet;
+ delete inches;
+ delete meters;
+
+ return 0;
+}
+
+void inputFeetAndInches(double *feet, double *inches) {
+ std::cout << "feet: ";
+ std::cin >> *feet;
+ std::cout << "inches: ";
+ std::cin >> *inches;
+}
+
+void feetAndInchesToMeters(const double *feet, const double *inches,
+ double *meters) {
+ *meters = ((*feet * 12) + *inches) * 0.0254;
+}
+
+void outputFeetInchesAndMeters(const double *feet, const double *inches,
+ const double *meters) {
+ std::cout << "feet: " << *feet << '\n'
+ << "inches: " << *inches << '\n'
+ << "meters: " << *meters << std::endl;
+}
diff --git a/cs162/wk2/BUILD b/cs162/wk2/BUILD
new file mode 100644
index 0000000..cde7d85
--- /dev/null
+++ b/cs162/wk2/BUILD
@@ -0,0 +1,26 @@
+cc_binary(
+ name = "dictionaryRead",
+ srcs = glob([
+ "dictionaryRead/**/*.cc",
+ "dictionaryRead/**/*.hh",
+ ]),
+ data = ["//data:words.txt"],
+)
+
+cc_binary(
+ name = "friendsFile",
+ srcs = glob([
+ "friendsFile/**/*.cc",
+ "friendsFile/**/*.hh",
+ ]),
+ data = ["//data:nums.txt"],
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "dictionaryRead",
+ "friendsFile",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk2/CMakeLists.txt b/cs162/wk2/CMakeLists.txt
new file mode 100644
index 0000000..da2cb80
--- /dev/null
+++ b/cs162/wk2/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(friendsFile)
+add_subdirectory(dictionaryRead)
diff --git a/cs162/wk2/dictionaryRead/CMakeLists.txt b/cs162/wk2/dictionaryRead/CMakeLists.txt
new file mode 100644
index 0000000..827784a
--- /dev/null
+++ b/cs162/wk2/dictionaryRead/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk2_dictionaryRead)
+
+add_executable(wk2_dictionaryRead dictionaryRead.cc)
diff --git a/cs162/wk2/dictionaryRead/dictionaryRead.cc b/cs162/wk2/dictionaryRead/dictionaryRead.cc
new file mode 100644
index 0000000..e911543
--- /dev/null
+++ b/cs162/wk2/dictionaryRead/dictionaryRead.cc
@@ -0,0 +1,31 @@
+#include <fstream>
+#include <iostream>
+
+int main() {
+ // Declare variables
+ std::string userWord;
+ std::ifstream wordsFile("data/words.txt", std::ifstream::in);
+ std::string currentWord;
+
+ // Get user's word
+ std::cout << "Enter a word: ";
+ std::cin >> userWord;
+
+ // Check lines for word
+ while (!wordsFile.eof()) {
+ wordsFile >> currentWord;
+
+ // Check if line is word
+ if (currentWord == userWord) {
+ std::cout << "That word is spelled correctly." << std::endl;
+
+ wordsFile.close();
+ return 0;
+ }
+ }
+
+ std::cout << "That word is not spelled correctly." << std::endl;
+
+ wordsFile.close();
+ return 0;
+}
diff --git a/cs162/wk2/friendsFile/CMakeLists.txt b/cs162/wk2/friendsFile/CMakeLists.txt
new file mode 100644
index 0000000..4140119
--- /dev/null
+++ b/cs162/wk2/friendsFile/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk2_friendsFile)
+
+add_executable(wk2_friendsFile friendsFile.cc)
diff --git a/cs162/wk2/friendsFile/friendsFile.cc b/cs162/wk2/friendsFile/friendsFile.cc
new file mode 100644
index 0000000..c132165
--- /dev/null
+++ b/cs162/wk2/friendsFile/friendsFile.cc
@@ -0,0 +1,57 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+
+int main() {
+ // Declare variables
+ std::ofstream outputFile("data/nums.txt", std::ofstream::out);
+ std::string userFirstLastName;
+ std::string userAddress;
+ std::string userPhoneNumber;
+ std::string currentFirstLastName;
+ std::string currentAddress;
+ std::string currentPhoneNumber;
+
+ // Output information
+ std::cout << "Enter the names (first and last), phone numbers, and addresses "
+ "of three friends.\n"
+ << std::endl;
+
+ for (int i = 1; i < 4; ++i) {
+ // Get friends' information
+ std::cout << '#' << i << " First and last name: ";
+ std::getline(std::cin, userFirstLastName);
+ std::cout << '#' << i << " Address: ";
+ std::getline(std::cin, userAddress);
+ std::cout << '#' << i << " Phone number: ";
+ std::getline(std::cin, userPhoneNumber);
+
+ // Write friends' data
+ outputFile << userFirstLastName << '\n'
+ << userAddress << '\n'
+ << userPhoneNumber;
+
+ if (i < 3) {
+ outputFile << '\n';
+ }
+ }
+
+ outputFile.close();
+
+ std::ifstream inputFile("data/nums.txt", std::ifstream::in);
+
+ std::cout << "\nRecords: " << std::endl;
+
+ // Read and output user's friends
+ while (!inputFile.eof()) {
+ std::getline(inputFile, currentFirstLastName);
+ std::getline(inputFile, currentAddress);
+ std::getline(inputFile, currentPhoneNumber);
+
+ std::cout << currentFirstLastName << ", " << currentAddress << ", "
+ << currentPhoneNumber << std::endl;
+ }
+
+ inputFile.close();
+ return 0;
+}
diff --git a/cs162/wk3/BUILD b/cs162/wk3/BUILD
new file mode 100644
index 0000000..dfe23a9
--- /dev/null
+++ b/cs162/wk3/BUILD
@@ -0,0 +1,15 @@
+cc_binary(
+ name = "musicStruct",
+ srcs = glob([
+ "musicStruct/**/*.cc",
+ "musicStruct/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "musicStruct",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk3/CMakeLists.txt b/cs162/wk3/CMakeLists.txt
new file mode 100644
index 0000000..9804ee6
--- /dev/null
+++ b/cs162/wk3/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(musicStruct)
diff --git a/cs162/wk3/musicStruct/CMakeLists.txt b/cs162/wk3/musicStruct/CMakeLists.txt
new file mode 100644
index 0000000..80b2d2e
--- /dev/null
+++ b/cs162/wk3/musicStruct/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk3_musicStruct)
+
+add_executable(wk3_musicStruct musicStruct.cc)
diff --git a/cs162/wk3/musicStruct/musicStruct.cc b/cs162/wk3/musicStruct/musicStruct.cc
new file mode 100644
index 0000000..5c17839
--- /dev/null
+++ b/cs162/wk3/musicStruct/musicStruct.cc
@@ -0,0 +1,168 @@
+#include <iostream>
+#include <ranges>
+#include <string>
+#include <vector>
+
+// A structure to hold information about a CD
+struct CD {
+ std::string title;
+ std::vector<std::string> performers;
+ size_t tracks;
+ size_t playtime;
+ char genre;
+};
+
+// Fill a `CD` with information
+void fillCd(CD &);
+// Query a set of CDs based on certain criteria
+std::vector<CD> search(const std::vector<CD> &, int, const std::string &);
+// Display a set of CDs
+void displayCds(const std::vector<CD> &);
+
+int main() {
+ // Declare and initialise variables
+ size_t cdCount = 0;
+ std::vector<CD> cds = {{}, {}, {}, {}};
+ int searchType;
+ std::string searchQuery;
+
+ // Get CD amount
+ do {
+ std::cout << "How many CDs do you have? (Minimum of three) ";
+ std::cin >> cdCount;
+ } while (cdCount < 3);
+ std::cin.ignore(1024, '\n');
+ std::cout << std::endl;
+
+ // Fill CDs
+ for (int i = 0; i < cdCount; ++i) {
+ std::cout << "CD " << i + 1 << " of " << cdCount
+ << ":\n==========" << std::endl;
+
+ fillCd(cds[i]);
+ }
+
+ // Get CD search query type
+ std::cout << "What type of search would you like to perform?\n"
+ "0 = artist\n"
+ "1 = genre\n"
+ "> ";
+ std::cin >> searchType;
+
+ // Get CD search query
+ std::cout << "What would you like to search? ";
+ std::cin.ignore(1024, '\n');
+ std::getline(std::cin, searchQuery);
+ std::cout << std::endl;
+
+ // Filter CDs based ons search criteria
+ std::vector<CD> filtered_cds = search(cds, searchType, searchQuery);
+
+ // Display CDs that matched search criteria
+ displayCds(filtered_cds);
+
+ return 0;
+}
+
+void fillCd(CD &cd) {
+ // Get CD title
+ std::cout << "What is the title of the CD? ";
+ std::getline(std::cin, cd.title);
+
+ // Get CD performers
+
+ // Initialise CD with a maximum of four performers
+ cd.performers = {{}, {}, {}, {}};
+ for (int i = 0; i < 4; ++i) {
+ std::string author;
+
+ // Get CD performer
+ std::cout << "Who is performer " << i + 1
+ << " of 4 of the CD? (0 to cancel) ";
+ std::getline(std::cin, author);
+
+ if (author == "0") {
+ break;
+ } else {
+ cd.performers[i] = author;
+ }
+ }
+
+ // Get CD tracks
+ std::cout << "What is the number of tracks on the CD? ";
+ std::cin >> cd.tracks;
+
+ // Get CD playtime
+ std::cout << "What is the total playtime of the CD? ";
+ std::cin >> cd.playtime;
+
+ // Get CD genre
+ std::cout << "What is the genre of the CD? ";
+ std::cin >> cd.genre;
+
+ std::cin.ignore(1024, '\n');
+
+ std::cout << std::endl;
+}
+
+std::vector<CD> search(const std::vector<CD> &cds, int by,
+ const std::string &query) {
+ std::vector<CD> found_cds;
+
+ // Query based on query type
+ if (by == 0) {
+ // Find CDs where a performer matches the query
+ for (const CD &cd : cds | std::views::filter([&](const CD &cd) -> bool {
+ bool contains = false;
+
+ for (auto performer : cd.performers) {
+ if (query == performer) {
+ contains = true;
+ }
+ }
+
+ return contains;
+ })) {
+ found_cds.emplace_back(cd);
+ }
+ } else {
+ // Find CDs where the genre matches the query
+ for (const CD &cd : cds | std::views::filter([&](const CD &cd) -> bool {
+ return cd.genre == query[0];
+ })) {
+ found_cds.emplace_back(cd);
+ }
+ }
+
+ return found_cds;
+}
+
+void displayCds(const std::vector<CD> &filtered_cds) {
+ if (filtered_cds.empty()) {
+ std::cout << "No CDs where found based on your query!" << std::endl;
+ } else {
+ std::cout << filtered_cds.size()
+ << " CDs where found based on your query:" << std::endl;
+
+ for (int i = 0; i < filtered_cds.size(); ++i) {
+ // Output number and title
+ std::cout << "CD #" << i + 1 << ":\n=====" << std::endl;
+ std::cout << "Title: " << filtered_cds[i].title << std::endl;
+
+ // Output authors
+ for (int j = 0; j < filtered_cds[i].performers.size(); ++j) {
+ std::string performer = filtered_cds[i].performers[j];
+
+ if (!performer.empty()) {
+ std::cout << "Author #" << j + 1 << ": " << performer << std::endl;
+ }
+ }
+
+ // Output tracks, playtime, and genre
+ std::cout << "Tracks: " << filtered_cds[i].tracks << '\n'
+ << "Playtime: " << filtered_cds[i].playtime << '\n'
+ << "Genre: " << filtered_cds[i].genre << '\n'
+ << std::endl;
+ }
+ }
+}
diff --git a/cs162/wk4/BUILD b/cs162/wk4/BUILD
new file mode 100644
index 0000000..7c82b2b
--- /dev/null
+++ b/cs162/wk4/BUILD
@@ -0,0 +1,15 @@
+cc_binary(
+ name = "dateClass",
+ srcs = glob([
+ "dateClass/**/*.cc",
+ "dateClass/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "dateClass",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk4/CMakeLists.txt b/cs162/wk4/CMakeLists.txt
new file mode 100644
index 0000000..c63f514
--- /dev/null
+++ b/cs162/wk4/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(dateClass)
diff --git a/cs162/wk4/dateClass/CMakeLists.txt b/cs162/wk4/dateClass/CMakeLists.txt
new file mode 100644
index 0000000..23dc066
--- /dev/null
+++ b/cs162/wk4/dateClass/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk4_dateClass)
+
+add_executable(wk4_dateClass testDate.cc date.cc)
diff --git a/cs162/wk4/dateClass/date.cc b/cs162/wk4/dateClass/date.cc
new file mode 100644
index 0000000..b3b52b8
--- /dev/null
+++ b/cs162/wk4/dateClass/date.cc
@@ -0,0 +1,79 @@
+#include "date.hh"
+
+// Public constructor to initialise private variables upon construction
+Date::Date(unsigned int _month, unsigned int _day, unsigned int _year) {
+ this->month = _month;
+ this->day = _day;
+ this->year = _year;
+}
+
+// Public getters to get private variables
+unsigned int Date::getMonth() const { return this->month; }
+unsigned int Date::getDay() const { return this->day; }
+unsigned int Date::getYear() const { return this->year; }
+unsigned int Date::getJulian() const {
+ // https://quasar.as.utexas.edu/BillInfo/JulianDatesG.html
+ int A = static_cast<int>(this->year) / 100;
+ int B = A / 4;
+ int C = 2 - A + B;
+ double E = 365.25 * (this->year + 4716);
+ double F = 30.6001 * (this->month + 1);
+
+ // https://www.aavso.org/jd-calculator
+ return static_cast<unsigned int>(C + this->day + E + F - 1524.5);
+}
+
+// Public setters to set private variables
+void Date::setMonth(unsigned int _month) { this->month = _month; }
+void Date::setDay(unsigned int _day) { this->day = _day; }
+void Date::setYear(unsigned int _year) { this->year = _year; }
+void Date::set(unsigned int _month, unsigned int _day, unsigned int _year) {
+ this->month = _month;
+ this->day = _day;
+ this->year = _year;
+}
+
+// Public function which returns `month` as an `std::string`
+std::string Date::monthAsString() const {
+ switch (this->month) {
+ case 1: {
+ return "January";
+ }
+ case 2: {
+ return "February";
+ }
+ case 3: {
+ return "March";
+ }
+ case 4: {
+ return "April";
+ }
+ case 5: {
+ return "May";
+ }
+ case 6: {
+ return "June";
+ }
+ case 7: {
+ return "July";
+ }
+ case 8: {
+ return "August";
+ }
+ case 9: {
+ return "September";
+ }
+ case 10: {
+ return "October";
+ }
+ case 11: {
+ return "November";
+ }
+ case 12: {
+ return "December";
+ }
+ default: {
+ return "Unknown";
+ }
+ }
+}
diff --git a/cs162/wk4/dateClass/date.hh b/cs162/wk4/dateClass/date.hh
new file mode 100644
index 0000000..1aead8f
--- /dev/null
+++ b/cs162/wk4/dateClass/date.hh
@@ -0,0 +1,35 @@
+#ifndef DATE_HH
+#define DATE_HH
+
+#include <string>
+
+// Date class to keep track of a date
+class Date {
+private:
+ // Private variables to keep track of date
+ unsigned int month;
+ unsigned int day;
+ unsigned int year;
+
+public:
+ // Public constructors to initialise private variables upon construction
+ Date() : month(0), day(0), year(0) {}
+ Date(unsigned int _month, unsigned int _day, unsigned int _year);
+
+ // Public getters to get private variables
+ [[nodiscard]] unsigned int getMonth() const;
+ [[nodiscard]] unsigned int getDay() const;
+ [[nodiscard]] unsigned int getYear() const;
+ [[nodiscard]] unsigned int getJulian() const;
+
+ // Public setters to set private variables
+ void setMonth(unsigned int _month);
+ void setDay(unsigned int _day);
+ void setYear(unsigned int _year);
+ void set(unsigned int _month, unsigned int _day, unsigned int _year);
+
+ // Public function which returns `month` as an `std::string`
+ [[nodiscard]] std::string monthAsString() const;
+};
+
+#endif // DATE_HH
diff --git a/cs162/wk4/dateClass/testDate.cc b/cs162/wk4/dateClass/testDate.cc
new file mode 100644
index 0000000..4c80bdf
--- /dev/null
+++ b/cs162/wk4/dateClass/testDate.cc
@@ -0,0 +1,58 @@
+#include <iostream>
+
+#include "date.hh"
+
+int main() {
+ // Test `Date` class with default constructor
+ {
+ Date date;
+
+ std::cout << "date after default constructor:\n"
+ << " month = " << date.getMonth() << '\n'
+ << " day = " << date.getDay() << '\n'
+ << " year = " << date.getYear() << '\n'
+ << std::endl;
+ }
+
+ {
+ // Test `Date` class with overloaded constructor
+ Date date(1, 2, 3);
+
+ std::cout << "date after overloaded constructor:\n"
+ << " month = " << date.getMonth() << '\n'
+ << " day = " << date.getDay() << '\n'
+ << " year = " << date.getYear() << '\n'
+ << std::endl;
+
+ // Test `Date` class with mutator functions
+ date.setMonth(4);
+ date.setDay(5);
+ date.setYear(6);
+
+ std::cout << "date after using mutator functions:\n"
+ << " month = " << date.getMonth() << '\n'
+ << " day = " << date.getDay() << '\n'
+ << " year = " << date.getYear() << '\n'
+ << std::endl;
+
+ date.set(7, 8, 9);
+
+ // Test `Date` class with `set`
+ std::cout << "date after using mutator function set:\n"
+ << " month = " << date.getMonth() << '\n'
+ << " day = " << date.getDay() << '\n'
+ << " year = " << date.getYear() << '\n'
+ << std::endl;
+
+ // Test `Date` class with `monthAsString`
+ std::cout << "date's month after using monthAsString: "
+ << date.monthAsString() << '\n'
+ << std::endl;
+
+ // Test `Date` class with `julian`
+ std::cout << "date's month after using julian: " << date.getJulian()
+ << std::endl;
+ }
+
+ return 0;
+}
diff --git a/cs162/wk5/BUILD b/cs162/wk5/BUILD
new file mode 100644
index 0000000..efcab31
--- /dev/null
+++ b/cs162/wk5/BUILD
@@ -0,0 +1,24 @@
+cc_binary(
+ name = "country",
+ srcs = glob([
+ "country/**/*.cc",
+ "country/**/*.hh",
+ ]),
+)
+
+cc_binary(
+ name = "gradesHelpers",
+ srcs = glob([
+ "gradesHelpers/**/*.cc",
+ "gradesHelpers/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "country",
+ "gradesHelpers",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk5/CMakeLists.txt b/cs162/wk5/CMakeLists.txt
new file mode 100644
index 0000000..7752b0f
--- /dev/null
+++ b/cs162/wk5/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(country)
+add_subdirectory(gradesHelpers)
diff --git a/cs162/wk5/country/CMakeLists.txt b/cs162/wk5/country/CMakeLists.txt
new file mode 100644
index 0000000..57d984b
--- /dev/null
+++ b/cs162/wk5/country/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk5_country)
+
+add_executable(wk5_country country.cc testCountry.cc)
diff --git a/cs162/wk5/country/country.cc b/cs162/wk5/country/country.cc
new file mode 100644
index 0000000..cbc0bc1
--- /dev/null
+++ b/cs162/wk5/country/country.cc
@@ -0,0 +1,22 @@
+#include "country.hh"
+
+float Country::futurePop() const { return this->population * 1.05f * 10.f; }
+
+// Figure out which of the countries have the largest population
+Country Country::largestCountry(Country country2, Country country3) {
+ if ((this->population >= country2.population) &&
+ (this->population >= country3.population)) {
+ return *this;
+ } else if ((country2.population >= this->population) &&
+ (country2.population >= country3.population)) {
+ return country2;
+ } else {
+ return country3;
+ }
+}
+
+void Country::resetValues(const Country &country) {
+ this->name = country.name;
+ this->capital = country.capital;
+ this->population = country.population;
+}
diff --git a/cs162/wk5/country/country.hh b/cs162/wk5/country/country.hh
new file mode 100644
index 0000000..66bdf1f
--- /dev/null
+++ b/cs162/wk5/country/country.hh
@@ -0,0 +1,54 @@
+#ifndef COUNTRY_HH
+#define COUNTRY_HH
+#pragma once
+
+#include <string>
+#include <utility>
+
+class Country {
+private:
+ // Member variables
+ //
+ // I shared this...
+ std::string name;
+ std::string capital;
+ float population;
+
+public:
+ // Constructor
+ //
+ // this...
+ explicit Country(std::string _name = "Unknown",
+ std::string _capital = "Unknown", float _population = 0)
+ : name(std::move(_name)), capital(std::move(_capital)),
+ population(_population) {}
+
+ // Destructor
+ //
+ // and this to my breakout room! Hope they learned from it!
+ ~Country() = default; // Quite literally `{}`
+
+ // Accessors
+ std::string getName() { return this->name; }
+ std::string getCapital() { return this->capital; }
+ [[nodiscard]] float getPopulation() const { return this->population; }
+
+ // Mutators
+ void setName(std::string _name) { this->name = std::move(_name); }
+ void setCapital(std::string _capital) { this->capital = std::move(_capital); }
+ void setPopulation(float _population) { this->population = _population; }
+
+ // Predict the population in ten years
+ [[nodiscard]] float futurePop() const;
+
+ // Return the largest of three populations
+ //
+ // I wish these would have been `const` references, since they are copied for
+ // each invocation but only used as a `const` references.
+ Country largestCountry(Country, Country);
+
+ // Reset the values
+ void resetValues(const Country &);
+};
+
+#endif // COUNTRY_HH
diff --git a/cs162/wk5/country/testCountry.cc b/cs162/wk5/country/testCountry.cc
new file mode 100644
index 0000000..ba061f3
--- /dev/null
+++ b/cs162/wk5/country/testCountry.cc
@@ -0,0 +1,103 @@
+#include <functional>
+#include <iostream>
+
+#include "country.hh"
+
+// Print a countries name, capital, and population
+void printCountry(Country);
+// A test adapter which informs of context and executes a test in the form of a
+// lambda, then, asserts if the test was successful.
+void testContext(const std::string &, const std::function<bool()> &);
+
+int main() {
+ // "populate a Country object with values for name, capital and population"
+ Country country("United States of America", "Washington D.C.",
+ 326.69f); // 326.69
+
+ testContext("\"populate a Country object with values for name, capital and "
+ "population\"",
+ // Separate ... *anonymous* ... functions
+ [&]() -> bool {
+ printCountry(country);
+
+ return country.getName() == "United States of America";
+ });
+ testContext(
+ "\"print the values held in a Country object - in a function in the "
+ "driver file\"",
+ [&]() -> bool {
+ printCountry(country);
+
+ return country.getCapital() == "Washington D.C.";
+ });
+ testContext("\"test resetting the values of a County ( sample function call: "
+ "myCountry."
+ "resetValues(yourCountry); )\"",
+ [&]() -> bool {
+ country.resetValues(
+ Country("Hungary", "Budapest", 9.67f)); // 9.67
+ printCountry(country);
+
+ return country.getName() == "Hungary";
+ });
+ testContext(
+ "\"test the function that returns the population increase of a Country "
+ "specified by the user\"",
+ [&]() -> bool {
+ float futurePop = country.futurePop();
+
+ std::cout << futurePop << std::endl;
+
+ return futurePop == country.getPopulation() * 1.05f * 10.f;
+ });
+ testContext("\"test the function that returns the Country with largest "
+ "population (of "
+ "3)\"",
+ [&]() -> bool {
+ Country country2 =
+ Country("Not the largest", "Not even close", 0);
+ Country country3 = Country("Still not the largest",
+ "Still not even close", 3021);
+ float largest =
+ country.largestCountry(country2, country3).getPopulation();
+
+ std::cout << "Country #1: " << country.getPopulation() << '\n'
+ << "Country #2: " << country2.getPopulation() << '\n'
+ << "Country #3: " << country3.getPopulation() << '\n'
+ << "Largest: " << largest << std::endl;
+
+ return largest == 3021;
+ });
+ testContext("test setters", [&]() -> bool {
+ country.setName("1");
+ country.setCapital("2");
+ country.setPopulation(3);
+
+ printCountry(country);
+
+ return country.getName() == "1";
+ });
+
+ return 0;
+}
+
+void testContext(const std::string &context,
+ const std::function<bool()> &function) {
+ std::cout << context << std::endl;
+
+ bool test_result = function();
+
+ if (test_result) {
+ std::cout << "test was successful" << std::endl;
+ } else {
+ std::cout << "test was unsuccessful" << std::endl;
+ }
+
+ std::cout << std::endl;
+}
+
+void printCountry(Country country) {
+ std::cout << "Name: " << country.getName() << '\n'
+ << "Capital: " << country.getCapital() << '\n'
+ << "Population: " << country.getPopulation() << std::endl;
+} \ No newline at end of file
diff --git a/cs162/wk5/gradesHelpers/CMakeLists.txt b/cs162/wk5/gradesHelpers/CMakeLists.txt
new file mode 100644
index 0000000..ce034f0
--- /dev/null
+++ b/cs162/wk5/gradesHelpers/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk5_gradesHelpers)
+
+add_executable(wk5_gradesHelpers grades.cc testGrades.cc)
diff --git a/cs162/wk5/gradesHelpers/grades.cc b/cs162/wk5/gradesHelpers/grades.cc
new file mode 100644
index 0000000..35bf753
--- /dev/null
+++ b/cs162/wk5/gradesHelpers/grades.cc
@@ -0,0 +1,64 @@
+#include "grades.hh"
+
+Grades::Grades() { defaultTests(); }
+
+void Grades::computeAverage() {
+ int testAccumulated = 0;
+
+ // Total up all test scores
+ for (int &test : this->testScores) {
+ testAccumulated += test;
+ }
+
+ // Find the average by dividing the total test scores by the amount of test
+ // scores
+ this->averageScore =
+ static_cast<float>(testAccumulated) / static_cast<float>(this->tests);
+}
+
+void Grades::checkLowest(int score) {
+ // If the test new `score` is lower than the `lowestScore`, make it the new
+ // lowest score
+ if (score < this->lowestScore) {
+ this->lowestScore = score;
+ }
+}
+
+bool Grades::validScore(int score) {
+ // If the new `score` is within the range 0 - 100, mark it as valid
+ return 0 <= score && score <= 100;
+}
+
+bool Grades::checkNumTests() const {
+ // If the number of tests is less than the max number of test, inform the
+ // caller that they may add a new test score
+ return this->tests < Grades::MAX_TESTS;
+}
+
+void Grades::defaultTests() {
+ // Initialises all test scores to zero
+ for (int &test : this->testScores) {
+ test = 0;
+ }
+}
+
+void Grades::addTest(int newTest) {
+ // If the number of tests is less than the max number of tests...
+ if (this->checkNumTests()) {
+ // and if the `newTest` is within the range 0 - 100...
+ if (this->validScore(newTest)) {
+ // track the `newTest`, ...
+ this->testScores[this->tests] = newTest;
+ // make sure we know that we added a `newTest`, ...
+ this->tests += 1;
+
+ // compute the new average of all test scores, ...
+ this->computeAverage();
+ // and check, possibly assigning, if the new test is the lowest of
+ // all tests scores.
+ this->checkLowest(newTest);
+ }
+ }
+}
+
+float Grades::getAverage() const { return this->averageScore; }
diff --git a/cs162/wk5/gradesHelpers/grades.hh b/cs162/wk5/gradesHelpers/grades.hh
new file mode 100644
index 0000000..89e1022
--- /dev/null
+++ b/cs162/wk5/gradesHelpers/grades.hh
@@ -0,0 +1,41 @@
+#ifndef GRADES_HH
+#define GRADES_HH
+#pragma once
+
+#include <limits>
+
+class Grades {
+private:
+ /// Maximum amount of `testScores`
+ static const size_t MAX_TESTS = 4;
+ /// All test scores
+ int testScores[MAX_TESTS]{};
+ /// The lowest score of all test scores
+ int lowestScore = std::numeric_limits<int>::max();
+ /// The average of all test scores
+ float averageScore = 0.0;
+ /// The amount of tests kept track of
+ size_t tests = 0;
+
+ /// Computes the average every time a new test is added
+ void computeAverage();
+ /// Checks to see if test added has the lowest score.
+ void checkLowest(int);
+ /// Before a test is added to the array, its value is checked to make sure
+ /// the score is in the range 0 - 100, inclusive
+ static bool validScore(int);
+ /// Used to make sure the array is not full before adding a score
+ [[nodiscard]] bool checkNumTests() const;
+ /// Initialises value in the array of tests to zero
+ void defaultTests();
+
+public:
+ Grades();
+
+ /// Add another test score to keep track of
+ void addTest(int);
+ /// Get the average of all test scores
+ [[nodiscard]] float getAverage() const;
+};
+
+#endif // GRADES_HH
diff --git a/cs162/wk5/gradesHelpers/testGrades.cc b/cs162/wk5/gradesHelpers/testGrades.cc
new file mode 100644
index 0000000..04a38cc
--- /dev/null
+++ b/cs162/wk5/gradesHelpers/testGrades.cc
@@ -0,0 +1,53 @@
+#include <functional>
+#include <iostream>
+
+#include "grades.hh"
+
+/// Tests `Grades` given a few grades, an expected average, and if the test
+/// should fail.
+void test(const std::vector<int> &, float, bool);
+
+int main() {
+ {
+ test({80, 70, 90, 10, 10}, 62.5,
+ false); // Test if `checkNumTests` works
+ test({80, 70, 90, 10}, 62.5, false);
+ test({80, 70, 90}, 80, false);
+ test({80, 70, 90}, 70, true);
+ test({80, 70}, 75, false);
+ test({80}, 80, false);
+ test({80}, 70, true);
+ }
+
+ // This works too.
+ {
+ Grades cs162;
+
+ cs162.addTest(80);
+ cs162.addTest(70);
+ cs162.addTest(90);
+ cs162.addTest(10);
+
+ std::cout << cs162.getAverage() << std::endl;
+ }
+
+ return 0;
+}
+
+void test(const std::vector<int> &values, float expect, bool shouldFail) {
+ Grades cs162;
+
+ std::cout << "testing getAverage with [ ";
+
+ for (int grade : values) {
+ std::cout << grade << " ";
+
+ cs162.addTest(grade);
+ }
+
+ std::cout << ((cs162.getAverage() == expect && !shouldFail ||
+ cs162.getAverage() != expect && shouldFail)
+ ? "]: pass"
+ : "]: fail")
+ << std::endl;
+}
diff --git a/cs162/wk6/BUILD b/cs162/wk6/BUILD
new file mode 100644
index 0000000..6442ad9
--- /dev/null
+++ b/cs162/wk6/BUILD
@@ -0,0 +1,24 @@
+cc_binary(
+ name = "friends",
+ srcs = glob([
+ "friends/**/*.cc",
+ "friends/**/*.hh",
+ ]),
+)
+
+cc_binary(
+ name = "overload",
+ srcs = glob([
+ "overload/**/*.cc",
+ "overload/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "friends",
+ "overload",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk6/CMakeLists.txt b/cs162/wk6/CMakeLists.txt
new file mode 100644
index 0000000..4c5a63d
--- /dev/null
+++ b/cs162/wk6/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(friends)
+add_subdirectory(overload)
diff --git a/cs162/wk6/friends/CMakeLists.txt b/cs162/wk6/friends/CMakeLists.txt
new file mode 100644
index 0000000..06eadd6
--- /dev/null
+++ b/cs162/wk6/friends/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk6_friends)
+
+add_executable(wk6_friends bankAccount.cc testBankAccount.cc)
diff --git a/cs162/wk6/friends/bankAccount.cc b/cs162/wk6/friends/bankAccount.cc
new file mode 100644
index 0000000..ede21f8
--- /dev/null
+++ b/cs162/wk6/friends/bankAccount.cc
@@ -0,0 +1,43 @@
+#include "bankAccount.hh"
+
+#include <iostream>
+
+bool BankAccount::withdraw(float amount) {
+ bool canWithdraw = true;
+
+ if (amount <= this->balance) {
+ this->balance -= amount;
+ } else {
+ canWithdraw = false;
+ }
+
+ return canWithdraw;
+}
+
+float BankAccount::computeInterest(float interestRate) const {
+ if (this->balance > 0) {
+ return this->balance * interestRate;
+ } else {
+ return 0;
+ }
+}
+
+std::string BankAccount::greaterBalance(BankAccount &bankAccount) {
+ if (this->balance > bankAccount.balance) {
+ return this->accountNumber;
+ } else {
+ return bankAccount.accountNumber;
+ }
+}
+
+void printAccount(const BankAccount &bankAccount) {
+ std::cout << bankAccount.accountNumber << std::endl;
+ std::cout << bankAccount.balance << std::endl;
+}
+
+BankAccount combineAccounts(const BankAccount &bankAccount1,
+ const BankAccount &bankAccount2) {
+ return BankAccount(std::to_string(std::stoi(bankAccount1.accountNumber) +
+ std::stoi(bankAccount2.accountNumber)),
+ bankAccount1.balance + bankAccount2.balance);
+}
diff --git a/cs162/wk6/friends/bankAccount.hh b/cs162/wk6/friends/bankAccount.hh
new file mode 100644
index 0000000..e85ae47
--- /dev/null
+++ b/cs162/wk6/friends/bankAccount.hh
@@ -0,0 +1,42 @@
+#ifndef BANK_ACCOUNT_HH
+#define BANK_ACCOUNT_HH
+#pragma once
+
+#include <string>
+#include <utility>
+
+class BankAccount {
+private:
+ std::string accountNumber;
+ float balance;
+
+public:
+ // Overloaded default constructor
+ explicit BankAccount(std::string _accountNumber = "", float _balance = 0.0)
+ : accountNumber(std::move(_accountNumber)), balance(_balance) {}
+
+ // Accessors
+ std::string getAccountNumber() { return this->accountNumber; }
+ [[nodiscard]] float getBalance() const { return this->balance; }
+
+ // Mutators
+ void setAccountNumber(std::string _accountNumber) {
+ this->accountNumber = std::move(_accountNumber);
+ }
+ void setBalance(float _balance) { this->balance = _balance; }
+ void deposit(float amount) { this->balance += amount; }
+ bool withdraw(float);
+
+ // Member functions
+ [[nodiscard]] float computeInterest(float) const;
+ std::string greaterBalance(BankAccount &);
+
+ /// Prints out the account number and balance of the parameterized
+ /// `BankAccount`.
+ friend void printAccount(const BankAccount &);
+ /// Combines the balances in two `BankAccount`s into a new `BankAccount`,
+ /// which is returned.
+ friend BankAccount combineAccounts(const BankAccount &, const BankAccount &);
+};
+
+#endif // BANK_ACCOUNT_HH
diff --git a/cs162/wk6/friends/testBankAccount.cc b/cs162/wk6/friends/testBankAccount.cc
new file mode 100644
index 0000000..10943bc
--- /dev/null
+++ b/cs162/wk6/friends/testBankAccount.cc
@@ -0,0 +1,39 @@
+#include <iostream>
+
+#include "bankAccount.hh"
+
+int main() {
+ BankAccount bankAccount("1234", 100.00);
+ bool canWithdraw;
+
+ bankAccount.deposit(25.00);
+
+ canWithdraw = bankAccount.withdraw(10.00);
+
+ if (!canWithdraw) {
+ std::cout << "You cannot withdraw that amount." << std::endl;
+ }
+
+ std::cout << bankAccount.getAccountNumber() << std::endl;
+ std::cout << bankAccount.getBalance() << std::endl;
+
+ BankAccount bankAccount2;
+
+ bankAccount2.setBalance(200.00);
+ bankAccount2.setAccountNumber("4321");
+
+ std::cout << bankAccount2.getAccountNumber() << std::endl;
+ std::cout << bankAccount2.getBalance() << std::endl;
+
+ std::cout << "If the interest rate is 5%, you would earn "
+ << bankAccount2.computeInterest(0.05f) << " in one year.\n"
+ << std::endl;
+
+ std::cout << bankAccount.greaterBalance(bankAccount2)
+ << " has a higher balance." << std::endl;
+
+ printAccount(bankAccount);
+ printAccount(combineAccounts(bankAccount, bankAccount2));
+
+ return 0;
+} \ No newline at end of file
diff --git a/cs162/wk6/overload/CMakeLists.txt b/cs162/wk6/overload/CMakeLists.txt
new file mode 100644
index 0000000..683c7a6
--- /dev/null
+++ b/cs162/wk6/overload/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk6_overload)
+
+add_executable(wk6_overload shape.cc testShape.cc)
diff --git a/cs162/wk6/overload/shape.cc b/cs162/wk6/overload/shape.cc
new file mode 100644
index 0000000..36e5856
--- /dev/null
+++ b/cs162/wk6/overload/shape.cc
@@ -0,0 +1,74 @@
+#define _USE_MATH_DEFINES
+
+#include "shape.hh"
+
+#include <cmath>
+
+char Shape::getType() const { return this->type; }
+
+unsigned int Shape::getDimension() const { return this->dimension; }
+
+float Shape::getArea() const { return this->area; }
+
+void Shape::setType(char _shapeLetter) {
+ if (_shapeLetter == 'c' || _shapeLetter == 's' || _shapeLetter == 'h') {
+ this->type = _shapeLetter;
+ }
+}
+
+void Shape::setDimension(unsigned int _dimension) {
+ // Even though this function takes in an `unsigned int`, we make sure that
+ // the
+ // `_dimension` is greater than zero. This is in case the user is using a
+ // compiler or CXX-flags that do not treat sign mismatches as errors... like
+ // they always should...
+ if (_dimension > 0) {
+ this->dimension = _dimension;
+
+ this->computeArea();
+ }
+}
+
+void Shape::computeArea() {
+ switch (this->type) {
+ case 'c': {
+ this->area = static_cast<float>(M_PI * std::pow(2, this->dimension));
+ } break;
+ case 's': {
+ this->area = static_cast<float>(this->dimension * this->dimension);
+ } break;
+ case 'h': {
+ this->area = static_cast<float>((6 * (this->dimension * this->dimension)) /
+ (4 * std::tan((M_PI / 6))));
+ } break;
+ }
+}
+
+bool Shape::operator==(Shape shape) const {
+ return this->type == shape.type && this->dimension == shape.dimension;
+}
+
+void Shape::operator+=(Shape shape) {
+ if (this->type == shape.type) {
+ this->dimension += shape.dimension;
+
+ this->computeArea();
+ }
+}
+
+bool Shape::operator!=(Shape shape) const { return !(*this == shape); }
+
+Shape Shape::operator+(Shape shape) {
+ if (*this == shape) {
+ Shape newShape;
+
+ newShape.type = this->type;
+ newShape.dimension = this->dimension + shape.dimension;
+
+ newShape.computeArea();
+
+ return newShape;
+ } else {
+ return *this;
+ }
+}
diff --git a/cs162/wk6/overload/shape.hh b/cs162/wk6/overload/shape.hh
new file mode 100644
index 0000000..f12a615
--- /dev/null
+++ b/cs162/wk6/overload/shape.hh
@@ -0,0 +1,45 @@
+#ifndef SHAPE_HH
+#define SHAPE_HH
+
+class Shape {
+private:
+ // c, s, or h
+ char type;
+ unsigned int dimension;
+ float area;
+
+public:
+ // The wording "default values for the private member variables" was a little
+ // of to me knowing that in the past we've been using function overloading
+ // for constructors. I just went ahead and implemented both but kept the one
+ // that made the most sense in terms of how it was worded.
+ Shape() : type('n'), dimension(0), area(0){};
+ /* explicit Shape(char _type = 'n', unsigned int _dimension = 0, float _area
+ = 0) : type(_type), dimension(_dimension), area(_area) {}; */
+
+ // Getters for the three private member variables
+ [[nodiscard]] char getType() const;
+ [[nodiscard]] unsigned int getDimension() const;
+ [[nodiscard]] float getArea() const;
+
+ // Setters for `type` and `dimensions`
+ //
+ // These *should* `throw`, but that's just bad practice.
+ //
+ // These *could* implement C-like error handling, but that's just
+ // overcomplicating things.
+ void setType(char);
+ void setDimension(unsigned int);
+
+ // Operator overloads
+ bool operator==(Shape) const;
+ void operator+=(Shape);
+ bool operator!=(Shape) const;
+ Shape operator+(Shape);
+
+private:
+ // Area computer
+ void computeArea();
+};
+
+#endif // SHAPE_HH
diff --git a/cs162/wk6/overload/testShape.cc b/cs162/wk6/overload/testShape.cc
new file mode 100644
index 0000000..fbc8ca8
--- /dev/null
+++ b/cs162/wk6/overload/testShape.cc
@@ -0,0 +1,76 @@
+#include <iostream>
+
+#include "shape.hh"
+
+/*
+ * # Test Plan
+ *
+ * This test plan uses a test framework.
+ *
+ * The test framework gives accurate context.
+ *
+ * - Test instantiation of `Shape`
+ * - Test all setters of `Shape`
+ * - Test all getters of `Shape`
+ * - Test all valid types: c, s, or h
+ * - Test two different dimensions for each valid type
+ */
+
+#define INIT_TESTS() \
+ int __tested = 0; \
+ int __passed = 0;
+#define TESTED __tested
+#define PASSED __passed
+
+#define TEST(context, shape, type, dimension, expected) \
+ { \
+ if (test(context, shape, type, dimension, expected)) { \
+ __passed += 1; \
+ } \
+ __tested += 1; \
+ }
+
+bool test(const std::string &, Shape, char, unsigned int, float);
+
+int main() {
+ Shape shape;
+
+ INIT_TESTS()
+
+ TEST("circle with radius of two", shape, 'c', 2, 12.566f)
+ TEST("circle with radius of twelve", shape, 'c', 4, 50.27f)
+ TEST("square with side of two", shape, 's', 2, 4)
+ TEST("square with side of twelve", shape, 's', 12, 144)
+ TEST("hexagon with side of two", shape, 'h', 2, 10.392f)
+ TEST("hexagon with side of twelve", shape, 'h', 12, 374.1f)
+ // This should fail
+ TEST("hexagon with side of twelve, should fail", shape, 'h', 12, 376.1f)
+
+ // There should be seven tests with six passing tests (because one was meant
+ // to fail).
+ std::cout << "! results\n"
+ << "> performed " << TESTED << " tests with " << PASSED
+ << " passing" << std::endl;
+
+ return 0;
+}
+
+bool test(const std::string &context, Shape shape, char type,
+ unsigned int dimension, float expected) {
+ shape.setType(type);
+ shape.setDimension(dimension);
+
+ std::cout << "| " << context << std::endl;
+
+ char newType = shape.getType();
+ unsigned int newDimension = shape.getDimension();
+ float area = shape.getArea();
+ // ...
+ bool passed = static_cast<int>(area) == static_cast<int>(expected);
+
+ std::cout << "> " << (passed ? "pass" : "fail") << ": expected " << expected
+ << ", got " << area << " using type \"" << newType
+ << "\" and dimension \"" << newDimension << "\"" << std::endl;
+
+ return passed;
+}
diff --git a/cs162/wk7/BUILD b/cs162/wk7/BUILD
new file mode 100644
index 0000000..6d6d52b
--- /dev/null
+++ b/cs162/wk7/BUILD
@@ -0,0 +1,15 @@
+cc_binary(
+ name = "course",
+ srcs = glob([
+ "course/**/*.cc",
+ "course/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "course",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk7/CMakeLists.txt b/cs162/wk7/CMakeLists.txt
new file mode 100644
index 0000000..1a2e538
--- /dev/null
+++ b/cs162/wk7/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(course)
diff --git a/cs162/wk7/course/CMakeLists.txt b/cs162/wk7/course/CMakeLists.txt
new file mode 100644
index 0000000..d6045de
--- /dev/null
+++ b/cs162/wk7/course/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk7_course)
+
+add_executable(wk7_course course.cc student.cc testCourse.cc)
diff --git a/cs162/wk7/course/course.cc b/cs162/wk7/course/course.cc
new file mode 100644
index 0000000..bce09a4
--- /dev/null
+++ b/cs162/wk7/course/course.cc
@@ -0,0 +1,85 @@
+#include <iostream>
+#include <utility>
+
+#include "course.hh"
+
+[[maybe_unused]] std::string Course::getTitle() { return this->title; }
+
+[[maybe_unused]] std::string Course::getNumber() { return this->number; }
+
+[[maybe_unused]] float Course::getCredits() const { return this->credits; }
+
+void Course::setTitle(std::string _title) { this->title = std::move(_title); }
+
+void Course::setNumber(std::string _number) {
+ this->number = std::move(_number);
+}
+
+void Course::setCredits(float _credits) { this->credits = _credits; }
+
+void Course::displayCourse() const { showCourse(*this); }
+
+bool Course::operator==(const Course &course) const {
+ return this->title == course.title && this->number == course.number &&
+ this->credits == course.credits;
+}
+
+Course &Course::operator+=(const Course &course) {
+ // CBA to implement overflow checks for an already messy C-array, involved
+ // operator that will only ever even add three new items at a time as
+ // expressed in the test file.
+ //
+ // Update: CBA to use C-arrays, just going to use the more versatile and
+ // simple `std::vector` STL container so the previous comment is
+ // non-applicable.
+
+ // if (this->numStudents + course.numStudents > 30) {
+ // return *this;
+ // }
+ //
+ // auto *newStudentsEnrolled = static_cast<float *>(malloc(
+ // (this->numStudents + course.numStudents) * sizeof(sizeof(Student))));
+ //
+ // memcpy(newStudentsEnrolled, this->studentsEnrolled,
+ // this->numStudents * sizeof(Student));
+ // memcpy(newStudentsEnrolled + this->numStudents, course.studentsEnrolled,
+ // course.numStudents * sizeof(Student));
+ //
+ // this->numStudents += course.numStudents;
+
+ for (const Student &student : course.studentsEnrolled) {
+ if (this->numStudents + course.numStudents >= 30) {
+ break;
+ }
+
+ this->studentsEnrolled.emplace_back(student);
+
+ this->numStudents += 1;
+ }
+
+ return *this;
+}
+
+void showCourse(const Course &course) {
+ std::cout << "title: " << course.title << std::endl;
+ std::cout << "number: " << course.number << std::endl;
+ std::cout << "credits: " << course.credits << std::endl;
+ std::cout << "students: " << std::endl;
+
+ for (Student student : course.studentsEnrolled) {
+ std::cout << " last name: " << student.getLastName() << std::endl;
+ std::cout << " first name: " << student.getFirstName() << std::endl;
+ std::cout << " id number: " << student.getIdNum() << '\n' << std::endl;
+ }
+
+ std::cout << "number of students: " << course.numStudents << std::endl;
+}
+
+void Course::addStudents(int studentNum, std::string *firstNames,
+ std::string *lastNames, int *idNums) {
+ for (int i = 0; i < studentNum; ++i) {
+ this->studentsEnrolled.emplace_back(
+ Student(firstNames[i], lastNames[i], idNums[i]));
+ this->numStudents += 1;
+ }
+}
diff --git a/cs162/wk7/course/course.hh b/cs162/wk7/course/course.hh
new file mode 100644
index 0000000..df5f2cb
--- /dev/null
+++ b/cs162/wk7/course/course.hh
@@ -0,0 +1,52 @@
+#ifndef COURSE_HH
+#define COURSE_HH
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "student.hh"
+
+class Course {
+public:
+ static const std::size_t MAX_STUDENTS = 30;
+
+private:
+ std::string title;
+ std::string number;
+ float credits;
+ // Student studentsEnrolled[Course::MAX_STUDENTS];
+ std::vector<Student> studentsEnrolled;
+ std::size_t numStudents{};
+
+public:
+ // Constructor
+ explicit Course(std::string _title = "", std::string _number = "",
+ float _credits = 0)
+ : title(std::move(_title)), number(std::move(_number)),
+ credits(_credits) {}
+
+ // Getters
+ [[maybe_unused]] std::string getTitle();
+ [[maybe_unused]] std::string getNumber();
+ [[maybe_unused]] [[nodiscard]] float getCredits() const;
+
+ // Setters
+ void setTitle(std::string);
+ void setNumber(std::string);
+ void setCredits(float);
+
+ void displayCourse() const;
+ void addStudents(int, std::string[Course::MAX_STUDENTS],
+ std::string[Course::MAX_STUDENTS],
+ int[Course::MAX_STUDENTS]);
+
+ // Operators
+ bool operator==(const Course &) const;
+ Course &operator+=(const Course &);
+
+ // Friends
+ friend void showCourse(const Course &course);
+};
+
+#endif // COURSE_HH
diff --git a/cs162/wk7/course/student.cc b/cs162/wk7/course/student.cc
new file mode 100644
index 0000000..6add4f2
--- /dev/null
+++ b/cs162/wk7/course/student.cc
@@ -0,0 +1,21 @@
+#include <utility>
+
+#include "student.hh"
+
+std::string Student::getLastName() { return this->lastName; }
+
+std::string Student::getFirstName() { return this->firstName; }
+
+std::size_t Student::getIdNum() const { return this->idNum; }
+
+[[maybe_unused]] void Student::setLastName(std::string _lastName) {
+ this->lastName = std::move(_lastName);
+}
+
+[[maybe_unused]] void Student::setFirstName(std::string _firstName) {
+ this->firstName = std::move(_firstName);
+}
+
+[[maybe_unused]] void Student::setIdNum(std::size_t _idNum) {
+ this->idNum = _idNum;
+}
diff --git a/cs162/wk7/course/student.hh b/cs162/wk7/course/student.hh
new file mode 100644
index 0000000..571a5e0
--- /dev/null
+++ b/cs162/wk7/course/student.hh
@@ -0,0 +1,30 @@
+#ifndef STUDENT_HH
+#define STUDENT_HH
+
+#include <string>
+
+class Student {
+private:
+ std::string lastName;
+ std::string firstName;
+ std::size_t idNum;
+
+public:
+ // Constructor
+ explicit Student(std::string _lastName = "", std::string _firstName = "",
+ std::size_t _idNum = 0)
+ : lastName(std::move(_lastName)), firstName(std::move(_firstName)),
+ idNum(_idNum) {}
+
+ // Getters
+ std::string getLastName();
+ std::string getFirstName();
+ [[nodiscard]] std::size_t getIdNum() const;
+
+ // Setters
+ [[maybe_unused]] void setLastName(std::string);
+ [[maybe_unused]] void setFirstName(std::string);
+ [[maybe_unused]] void setIdNum(std::size_t);
+};
+
+#endif // STUDENT_HH
diff --git a/cs162/wk7/course/testCourse.cc b/cs162/wk7/course/testCourse.cc
new file mode 100644
index 0000000..e3e723b
--- /dev/null
+++ b/cs162/wk7/course/testCourse.cc
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Filename: wk7_courseDriver.cpp
+ * Summary: Program to test the Course class (which uses the Student class)
+ * Test program declares 2 Course objects, fills each with values,
+ * uses the += operator to copy the students from one Course into
+ * the other, and prints out the information about the 2 objects.
+ * Author:
+ * Date:
+ *******************************************************************************/
+
+// There were only two instances where I had to replace something in this file
+// to get it to work with my configuration, line 16, 20, and 69. As per my
+// Emacs configuration, this file was also automatically formatted. Other than
+// those changes, everything is 1:1 with the posted file.
+
+#include "course.hh" // Replaced #include "Course.h"
+#include <iostream>
+#include <string>
+using std::cout, std::endl, std::cin;
+using namespace std; // Added
+
+void enterCourseInfo(Course &);
+// Prompts user to enter course title, designator, and credits
+void enterStudents(Course &);
+// Prompts user to enter up to 3 students
+
+const int MAX_STUDENTS = 3;
+
+int main() {
+ Course c1;
+ Course c2("Data Structures", "CS260", 4); // title, number, credits
+
+ cout << "Testing the showCourse friend function\n";
+ showCourse(c2);
+ cout << endl;
+
+ cout << "Testing mutator functions\n";
+ enterCourseInfo(c1);
+ showCourse(c1);
+ cout << endl;
+
+ cout << "Testing the += operator\n";
+ enterStudents(c2);
+ cout << "Before the += operator\n";
+ showCourse(c1);
+ showCourse(c2);
+ c1 += c2;
+ cout << "After the += operator\n";
+ showCourse(c1);
+ cout << endl;
+
+ return 0;
+}
+
+void enterCourseInfo(Course &crs) {
+ string userInput;
+ int creditIn;
+
+ cout << "What is the course title? ";
+ getline(cin, userInput);
+ crs.setTitle(userInput);
+
+ cout << "What is the course identifier? ";
+ getline(cin, userInput);
+ crs.setNumber(userInput);
+
+ cout << "How many credits? ";
+ cin >> creditIn;
+ crs.setCredits(static_cast<float>(creditIn));
+
+ enterStudents(crs);
+
+ crs.displayCourse();
+
+ return;
+}
+
+void enterStudents(Course &crs) {
+ string firstNames[MAX_STUDENTS];
+ string lastNames[MAX_STUDENTS];
+ int idNums[MAX_STUDENTS];
+
+ int studentNum;
+
+ cout << "How many students are in the class? (up to " << MAX_STUDENTS
+ << ")\n";
+ cin >> studentNum;
+ cin.ignore(80, '\n');
+
+ cout << "Enter the information about " << studentNum << " students:\n";
+ for (int i = 0; i < studentNum; i++) {
+ cout << "First name: ";
+ getline(cin, firstNames[i]);
+ cout << "Last name: ";
+ getline(cin, lastNames[i]);
+ cout << "ID number: ";
+ cin >> idNums[i];
+ cin.ignore(80, '\n');
+ }
+
+ crs.addStudents(studentNum, firstNames, lastNames, idNums);
+
+ return;
+}
diff --git a/cs162/wk8/BUILD b/cs162/wk8/BUILD
new file mode 100644
index 0000000..a2e6835
--- /dev/null
+++ b/cs162/wk8/BUILD
@@ -0,0 +1,15 @@
+cc_binary(
+ name = "inherit",
+ srcs = glob([
+ "inherit/**/*.cc",
+ "inherit/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "inherit",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk8/CMakeLists.txt b/cs162/wk8/CMakeLists.txt
new file mode 100644
index 0000000..fe529a4
--- /dev/null
+++ b/cs162/wk8/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(inherit)
diff --git a/cs162/wk8/inherit/CMakeLists.txt b/cs162/wk8/inherit/CMakeLists.txt
new file mode 100644
index 0000000..7df8cdc
--- /dev/null
+++ b/cs162/wk8/inherit/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk8_inherit)
+
+add_executable(
+ wk8_inherit
+ employee.cc
+ hourlyEmployee.cc
+ salesperson.cc
+ testEmployeeADTs.cc
+) \ No newline at end of file
diff --git a/cs162/wk8/inherit/employee.cc b/cs162/wk8/inherit/employee.cc
new file mode 100644
index 0000000..3d72686
--- /dev/null
+++ b/cs162/wk8/inherit/employee.cc
@@ -0,0 +1,25 @@
+#include <utility>
+
+#include "employee.hh"
+
+int Employee::getIDNo() const { return this->idNo; }
+
+std::string Employee::getFName() { return this->fName; }
+
+std::string Employee::getLName() { return this->lName; }
+
+std::string Employee::getPosition() { return this->position; }
+
+int Employee::getDeptNo() const { return deptno; }
+
+void Employee::setIDNo(int _idNo) { this->idNo = _idNo; }
+
+void Employee::setFName(std::string _fName) { this->fName = std::move(_fName); }
+
+void Employee::setLName(std::string _lName) { this->lName = std::move(_lName); }
+
+void Employee::setPos(std::string _position) {
+ this->position = std::move(_position);
+}
+
+void Employee::setDeptNo(int _deptNo) { this->deptno = _deptNo; }
diff --git a/cs162/wk8/inherit/employee.hh b/cs162/wk8/inherit/employee.hh
new file mode 100644
index 0000000..df4067f
--- /dev/null
+++ b/cs162/wk8/inherit/employee.hh
@@ -0,0 +1,49 @@
+#ifndef EMPLOYEE_HH
+#define EMPLOYEE_HH
+
+#include <string>
+#include <utility>
+
+class Employee {
+private:
+ // Members
+ /// employee ID number
+ int idNo;
+ /// first name
+ std::string fName;
+ /// last name
+ std::string lName;
+ /// position title
+ std::string position;
+ /// department number
+ int deptno;
+
+public:
+ // Constructor
+ explicit Employee(int _idNo = 0, std::string _fName = "",
+ std::string _lName = "", std::string _position = "",
+ int _deptno = 0)
+ : idNo(_idNo), fName(std::move(_fName)), lName(std::move(_lName)),
+ position(std::move(_position)), deptno(_deptno) {}
+
+ // Getters
+ /// returns ID number
+ [[nodiscard]] int getIDNo() const;
+ /// returns first name
+ std::string getFName();
+ /// returns last name
+ std::string getLName();
+ /// returns position title
+ std::string getPosition();
+ /// returns department #
+ [[nodiscard]] int getDeptNo() const;
+
+ // Setters
+ void setIDNo(int);
+ void setFName(std::string);
+ void setLName(std::string);
+ void setPos(std::string);
+ void setDeptNo(int);
+};
+
+#endif // EMPLOYEE_HH
diff --git a/cs162/wk8/inherit/hourlyEmployee.cc b/cs162/wk8/inherit/hourlyEmployee.cc
new file mode 100644
index 0000000..f89bcc8
--- /dev/null
+++ b/cs162/wk8/inherit/hourlyEmployee.cc
@@ -0,0 +1,7 @@
+#include "hourlyEmployee.hh"
+
+float HourlyEmployee::getHourlyRate() const { return this->hourlyRate; }
+
+void HourlyEmployee::setHourlyRate(float _hourlyRate) {
+ this->hourlyRate = _hourlyRate;
+}
diff --git a/cs162/wk8/inherit/hourlyEmployee.hh b/cs162/wk8/inherit/hourlyEmployee.hh
new file mode 100644
index 0000000..f555b2a
--- /dev/null
+++ b/cs162/wk8/inherit/hourlyEmployee.hh
@@ -0,0 +1,31 @@
+#ifndef HOURLY_EMPLOYEE_HH
+#define HOURLY_EMPLOYEE_HH
+
+#include <utility>
+
+#include "employee.hh"
+
+class HourlyEmployee : public Employee {
+private:
+ // Member
+ /// hourly rate of pay
+ float hourlyRate;
+
+public:
+ // Constructor
+ explicit HourlyEmployee(float _hourlyRate = 0, int _idNo = 0,
+ std::string _fName = "", std::string _lName = "",
+ std::string _position = "", int _deptno = 0)
+ : hourlyRate(_hourlyRate),
+ Employee(_idNo, std::move(_fName), std::move(_lName),
+ std::move(_position), _deptno) {}
+
+ // Getter
+ /// returns hourly rate
+ [[nodiscard]] float getHourlyRate() const;
+
+ // Setter
+ void setHourlyRate(float);
+};
+
+#endif // HOURLY_EMPLOYEE_HH
diff --git a/cs162/wk8/inherit/salesperson.cc b/cs162/wk8/inherit/salesperson.cc
new file mode 100644
index 0000000..a4d484a
--- /dev/null
+++ b/cs162/wk8/inherit/salesperson.cc
@@ -0,0 +1,11 @@
+#include "salesperson.hh"
+
+float Salesperson::getFlatIncome() const { return this->flatIncome; }
+
+float Salesperson::getCommRate() const { return this->commRate; }
+
+void Salesperson::setFlatIncome(float _flatIncome) {
+ this->flatIncome = _flatIncome;
+}
+
+void Salesperson::setCommRate(float _commRate) { this->commRate = _commRate; }
diff --git a/cs162/wk8/inherit/salesperson.hh b/cs162/wk8/inherit/salesperson.hh
new file mode 100644
index 0000000..4a9c358
--- /dev/null
+++ b/cs162/wk8/inherit/salesperson.hh
@@ -0,0 +1,35 @@
+#ifndef SALESPERSON_HH
+#define SALESPERSON_HH
+
+#include "employee.hh"
+
+class Salesperson : public Employee {
+private:
+ // Members
+ /// monthly flat income
+ float flatIncome;
+ /// commission rate
+ float commRate;
+
+public:
+ // Constructor
+ explicit Salesperson(float _flatIncome = 0, float _commRate = 0,
+ int _idNo = 0, std::string _fName = "",
+ std::string _lName = "", std::string _position = "",
+ int _deptno = 0)
+ : flatIncome(_flatIncome), commRate(_commRate),
+ Employee(_idNo, std::move(_fName), std::move(_lName),
+ std::move(_position), _deptno) {}
+
+ // Getters
+ /// returns flat income
+ [[nodiscard]] float getFlatIncome() const;
+ /// returns commission rate
+ [[nodiscard]] float getCommRate() const;
+
+ // Setters
+ void setFlatIncome(float);
+ void setCommRate(float);
+};
+
+#endif // SALESPERSON_HH
diff --git a/cs162/wk8/inherit/testEmployeeADTs.cc b/cs162/wk8/inherit/testEmployeeADTs.cc
new file mode 100644
index 0000000..8500b5b
--- /dev/null
+++ b/cs162/wk8/inherit/testEmployeeADTs.cc
@@ -0,0 +1,214 @@
+#include <chrono>
+#include <iostream>
+
+#include "employee.hh"
+#include "hourlyEmployee.hh"
+#include "salesperson.hh"
+
+#define INIT_TESTS() \
+ int __test_tested = 0; \
+ int __test_passed = 0; \
+ auto __test_clock = std::chrono::high_resolution_clock::now();
+
+#define TESTS_TESTED __test_tested
+#define TESTS_PASSED __test_passed
+#define TEST_TIME \
+ std::chrono::duration_cast<std::chrono::milliseconds>( \
+ std::chrono::high_resolution_clock::now() - __test_clock) \
+ .count()
+
+#define TEST(context, from, field, value) \
+ { \
+ if (test(context, from, field, value)) { \
+ __test_passed += 1; \
+ } \
+ __test_tested += 1; \
+ }
+
+template <class C, typename K, typename V>
+bool test(const std::string &, C, K, V);
+
+int main() {
+ INIT_TESTS()
+
+ // Test everything on `Employee` using a full constructor
+ {
+ Employee employee(1, "2", "3", "4", 5);
+
+ TEST(".getIDNo()", employee, employee.getIDNo(), 1)
+ TEST(".getFName()", employee, employee.getFName(), "2")
+ TEST(".getLName()", employee, employee.getLName(), "3")
+ TEST(".getPosition()", employee, employee.getPosition(), "4")
+ TEST(".getDeptNo()", employee, employee.getDeptNo(), 5)
+
+ employee.setIDNo(6);
+ employee.setFName("7");
+ employee.setLName("8");
+ employee.setPos("9");
+ employee.setDeptNo(10);
+
+ TEST(".setIDNo()", employee, employee.getIDNo(), 6)
+ TEST(".setFName()", employee, employee.getFName(), "7")
+ TEST(".setLName()", employee, employee.getLName(), "8")
+ TEST(".setPos()", employee, employee.getPosition(), "9")
+ TEST(".setDeptNo()", employee, employee.getDeptNo(), 10)
+ }
+
+ // Test everything on `Employee` using an empty constructor
+ {
+ Employee employee;
+
+ TEST(".getIDNo()", employee, employee.getIDNo(), 0)
+ TEST(".getFName()", employee, employee.getFName(), "")
+ TEST(".getLName()", employee, employee.getLName(), "")
+ TEST(".getPosition()", employee, employee.getPosition(), "")
+ TEST(".getDeptNo()", employee, employee.getDeptNo(), 0)
+
+ employee.setIDNo(6);
+ employee.setFName("7");
+ employee.setLName("8");
+ employee.setPos("9");
+ employee.setDeptNo(10);
+
+ TEST(".setIDNo()", employee, employee.getIDNo(), 6)
+ TEST(".setFName()", employee, employee.getFName(), "7")
+ TEST(".setLName()", employee, employee.getLName(), "8")
+ TEST(".setPos()", employee, employee.getPosition(), "9")
+ TEST(".setDeptNo()", employee, employee.getDeptNo(), 10)
+ }
+
+ // Test everything on `HourlyEmployee` using a full constructor
+ {
+ HourlyEmployee employee(0, 1, "2", "3", "4", 5);
+
+ TEST(".getHourlyRate()", employee, employee.getHourlyRate(), 0)
+ TEST(".getIDNo()", employee, employee.getIDNo(), 1)
+ TEST(".getFName()", employee, employee.getFName(), "2")
+ TEST(".getLName()", employee, employee.getLName(), "3")
+ TEST(".getPosition()", employee, employee.getPosition(), "4")
+ TEST(".getDeptNo()", employee, employee.getDeptNo(), 5)
+
+ employee.setIDNo(6);
+ employee.setFName("7");
+ employee.setLName("8");
+ employee.setPos("9");
+ employee.setDeptNo(10);
+ employee.setHourlyRate(11);
+
+ TEST(".setIDNo()", employee, employee.getIDNo(), 6)
+ TEST(".setFName()", employee, employee.getFName(), "7")
+ TEST(".setLName()", employee, employee.getLName(), "8")
+ TEST(".setPos()", employee, employee.getPosition(), "9")
+ TEST(".setDeptNo()", employee, employee.getDeptNo(), 10)
+ TEST(".setHourlyRate()", employee, employee.getHourlyRate(), 11)
+ }
+
+ // Test everything on `HourlyEmployee` using an empty constructor
+ {
+ HourlyEmployee employee;
+
+ TEST(".getHourlyRate()", employee, employee.getHourlyRate(), 0)
+ TEST(".getIDNo()", employee, employee.getIDNo(), 0)
+ TEST(".getFName()", employee, employee.getFName(), "")
+ TEST(".getLName()", employee, employee.getLName(), "")
+ TEST(".getPosition()", employee, employee.getPosition(), "")
+ TEST(".getDeptNo()", employee, employee.getDeptNo(), 0)
+
+ employee.setIDNo(6);
+ employee.setFName("7");
+ employee.setLName("8");
+ employee.setPos("9");
+ employee.setDeptNo(10);
+ employee.setHourlyRate(11);
+
+ TEST(".setIDNo()", employee, employee.getIDNo(), 6)
+ TEST(".setFName()", employee, employee.getFName(), "7")
+ TEST(".setLName()", employee, employee.getLName(), "8")
+ TEST(".setPos()", employee, employee.getPosition(), "9")
+ TEST(".setDeptNo()", employee, employee.getDeptNo(), 10)
+ TEST(".setHourlyRate()", employee, employee.getHourlyRate(), 11)
+ }
+
+ // Test everything on `Salesperson` using a full constructor
+ {
+ Salesperson employee(-1, 0, 1, "2", "3", "4", 5);
+
+ TEST(".getFlatIncome()", employee, employee.getFlatIncome(), -1)
+ TEST(".getCommRate()", employee, employee.getCommRate(), 0)
+ TEST(".getIDNo()", employee, employee.getIDNo(), 1)
+ TEST(".getFName()", employee, employee.getFName(), "2")
+ TEST(".getLName()", employee, employee.getLName(), "3")
+ TEST(".getPosition()", employee, employee.getPosition(), "4")
+ TEST(".getDeptNo()", employee, employee.getDeptNo(), 5)
+
+ employee.setIDNo(6);
+ employee.setFName("7");
+ employee.setLName("8");
+ employee.setPos("9");
+ employee.setDeptNo(10);
+ employee.setFlatIncome(11);
+ employee.setCommRate(12);
+
+ TEST(".setIDNo()", employee, employee.getIDNo(), 6)
+ TEST(".setFName()", employee, employee.getFName(), "7")
+ TEST(".setLName()", employee, employee.getLName(), "8")
+ TEST(".setPos()", employee, employee.getPosition(), "9")
+ TEST(".setDeptNo()", employee, employee.getDeptNo(), 10)
+ TEST(".setFlatIncome()", employee, employee.getFlatIncome(), 11)
+ TEST(".setCommRate()", employee, employee.getCommRate(), 12)
+ }
+
+ // Test everything on `Salesperson` using an empty constructor
+ {
+ Salesperson employee;
+
+ TEST(".getFlatIncome()", employee, employee.getFlatIncome(), 0)
+ TEST(".getCommRate()", employee, employee.getCommRate(), 0)
+ TEST(".getIDNo()", employee, employee.getIDNo(), 0)
+ TEST(".getFName()", employee, employee.getFName(), "")
+ TEST(".getLName()", employee, employee.getLName(), "")
+ TEST(".getPosition()", employee, employee.getPosition(), "")
+ TEST(".getDeptNo()", employee, employee.getDeptNo(), 0)
+
+ employee.setIDNo(6);
+ employee.setFName("7");
+ employee.setLName("8");
+ employee.setPos("9");
+ employee.setDeptNo(10);
+ employee.setFlatIncome(11);
+ employee.setCommRate(12);
+
+ TEST(".setIDNo()", employee, employee.getIDNo(), 6)
+ TEST(".setFName()", employee, employee.getFName(), "7")
+ TEST(".setLName()", employee, employee.getLName(), "8")
+ TEST(".setPos()", employee, employee.getPosition(), "9")
+ TEST(".setDeptNo()", employee, employee.getDeptNo(), 10)
+ TEST(".setFlatIncome()", employee, employee.getFlatIncome(), 11)
+ TEST(".setCommRate()", employee, employee.getCommRate(), 12)
+ }
+
+ TEST(": this **should** fail to prove that the test harness works",
+ Employee(), true, false)
+
+ std::cout << "! results: performed " << TESTS_TESTED << " tests in "
+ << TEST_TIME << "ms with " << TESTS_PASSED << " passing and "
+ << TESTS_TESTED - TESTS_PASSED << " failing" << std::endl;
+
+ return 0;
+}
+
+// I didn't want to overcomplicate things and mess with function pointers in
+// maps, symbol resolution, etc. to get the name of a function from its
+// function pointer, so I just pass it as the context. :)
+template <class C, typename K, typename V>
+bool test(const std::string &context, C _from, K field, V expected) {
+ bool passed = field == expected;
+
+ std::cout << "| " << std::string(typeid(_from).name()).substr(6) << context
+ << ": ";
+
+ std::cout << (passed ? "pass" : "fail") << ": expected " << expected
+ << ", got " << field << std::endl;
+
+ return passed;
+}
diff --git a/cs162/wk9/BUILD b/cs162/wk9/BUILD
new file mode 100644
index 0000000..4bb86d3
--- /dev/null
+++ b/cs162/wk9/BUILD
@@ -0,0 +1,15 @@
+cc_binary(
+ name = "vectors",
+ srcs = glob([
+ "vectors/**/*.cc",
+ "vectors/**/*.hh",
+ ]),
+)
+
+filegroup(
+ name = "build_all",
+ srcs = [
+ "vectors",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/cs162/wk9/CMakeLists.txt b/cs162/wk9/CMakeLists.txt
new file mode 100644
index 0000000..9c5fae2
--- /dev/null
+++ b/cs162/wk9/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(vectors)
diff --git a/cs162/wk9/vectors/CMakeLists.txt b/cs162/wk9/vectors/CMakeLists.txt
new file mode 100644
index 0000000..d476693
--- /dev/null
+++ b/cs162/wk9/vectors/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.21)
+project(wk9_vectors)
+
+add_executable(
+ wk9_vectors
+ vectors.cc
+) \ No newline at end of file
diff --git a/cs162/wk9/vectors/vectors.cc b/cs162/wk9/vectors/vectors.cc
new file mode 100644
index 0000000..8aad0fe
--- /dev/null
+++ b/cs162/wk9/vectors/vectors.cc
@@ -0,0 +1,172 @@
+#include <iomanip>
+#include <iostream>
+#include <numeric>
+#include <random>
+
+#define DEBUG
+#define FINITE
+
+/**
+ * @brief vector related operations and types
+ * @see std::vector
+ */
+namespace vectors {
+
+/**
+ * @brief A generic "real" number type
+ * @see double
+ */
+typedef double real_type;
+
+/**
+ * @brief Get the largest value of a vector.
+ * @return real_type
+ * @see real_type
+ * @see std::vector
+ */
+real_type largest_vector_value(const std::vector<real_type> &);
+/**
+ * @brief Get the smallest value of a vector.
+ * @return real_type
+ * @see real_type
+ * @see std::vector
+ */
+real_type smallest_vector_value(const std::vector<real_type> &);
+/**
+ * @brief Get the average value of a vector.
+ * @return real_type
+ * @see real_type
+ * @see std::vector
+ */
+real_type average_vector_value(const std::vector<real_type> &);
+
+} // namespace vectors
+
+int main() {
+ // Settings and RNG-related producers and criteria
+ int user_choice;
+ int value_precision = 2;
+ vectors::real_type minimum_value = 0;
+ vectors::real_type maximum_value = 1000;
+ std::size_t random_values_size;
+ const std::string &rt = typeid(vectors::real_type).name();
+ const std::string &st = typeid(std::size_t).name();
+ std::vector<vectors::real_type> random_values;
+ std::random_device random_device;
+ std::default_random_engine random_engine{random_device()};
+
+ // Get the users input for settings and RNG criteria
+#ifdef FINITE
+ std::cout << "minimum random value(" + rt + "): ";
+ std::cin >> minimum_value;
+ std::cout << "maximum random value(" + rt + "): ";
+ std::cin >> maximum_value;
+#endif
+ std::cout << "number of initial random values(" + st + "): ";
+ std::cin >> random_values_size;
+#ifdef FINITE
+ std::cout << "value precision(" + st + "): ";
+ std::cin >> value_precision;
+#endif
+ // Set the precision of random number output based on the users choice.
+ std::cout << std::fixed << std::setprecision(value_precision);
+
+ // Set up the RNG producer based on the user's criteria
+ std::uniform_real_distribution<vectors::real_type> uniform_distribution{
+ minimum_value, maximum_value};
+
+ // Append the user's preference of maximum random values to the random value
+ // pool
+ for (std::size_t i = 0; i < random_values_size; ++i) {
+ random_values.push_back(uniform_distribution(random_engine));
+ }
+
+ std::cout << "what operation would you like to perform?\n"
+ " 1. find the largest value\n"
+ " 2. find the smallest value\n"
+ " 3. compute the average value\n"
+ " 4. emplace more random values into the value pool\n"
+#ifdef DEBUG
+ " 5. number of random values in the value pool\n"
+#endif
+ " 0. quit"
+ << std::endl;
+
+ // Keep performing until the user would like
+ do {
+ // Get the user's operation choice
+ std::cout << "your choice(" + std::string(typeid(int).name()) + "): ";
+ std::cin >> user_choice;
+
+ // Perform the user's operation choice
+ switch (user_choice) {
+ case 0: {
+ // Say "goodbye." and free up any used resources.
+ std::cout << "goodbye." << std::endl;
+
+ return 0;
+ } // break;
+ case 1: {
+ // Output the largest value of the vector and run again.
+ std::cout << "largest value: "
+ << vectors::largest_vector_value(random_values) << std::endl;
+ } break;
+ case 2: {
+ // Output the smallest value of the vector and run again.
+ std::cout << "smallest value: "
+ << vectors::smallest_vector_value(random_values) << std::endl;
+ } break;
+ case 3: {
+ // Output the average value of the vector and run again.
+ std::cout << "average value: "
+ << vectors::average_vector_value(random_values) << std::endl;
+ } break;
+ case 4: {
+ std::size_t append_maximum_random_values;
+
+ // Get the number of random values to append to the random value pool from
+ // the user.
+ std::cout
+ << "number of random values to append to the random value pool: ";
+ std::cin >> append_maximum_random_values;
+
+ // Append the user's choice of extra random values to the random value
+ // pool
+ for (std::size_t i = 0; i < append_maximum_random_values; ++i) {
+ random_values.push_back(uniform_distribution(random_engine));
+ }
+ } break;
+#ifdef DEBUG
+ case 5: {
+ // Output the number of values in the random value pool and run again.
+ std::cout << "number of values in the random value pool: "
+ << random_values.size() << std::endl;
+ } break;
+#endif
+ default: {
+ // Inform the user the operation is invalid and run gain.
+ std::cout << "you chose an invalid choice. please choice a valid choice "
+ "the next time around."
+ << std::endl;
+ } break;
+ }
+ } while (user_choice != 0);
+
+ return 0;
+}
+
+namespace vectors {
+
+real_type largest_vector_value(const std::vector<real_type> &v) {
+ return *std::max_element(v.begin(), v.end());
+}
+
+real_type smallest_vector_value(const std::vector<real_type> &v) {
+ return *std::min_element(v.begin(), v.end());
+}
+
+real_type average_vector_value(const std::vector<real_type> &v) {
+ return std::reduce(v.begin(), v.end()) / v.size();
+}
+
+} // namespace vectors