commit bd329151ff09ea9a14a7d2eec3b266ee1e03cbee
parent bddf7e7c68e459a357547059e5f363fa77dd8fa2
Author: Evan Alba <evanalba@protonmail.com>
Date: Wed, 28 Dec 2022 23:41:25 -0800
feat: Added C++ directory.
Diffstat:
13 files changed, 1571 insertions(+), 0 deletions(-)
diff --git a/c++/3c/CinReader.cpp b/c++/3c/CinReader.cpp
@@ -0,0 +1,406 @@
+#include "CinReader.h"
+
+CinReader::CinReader ()
+{
+ intErrors = true;
+ charRangeErrors = true;
+
+ boolMsg = "Please enter \"true\" or \"false\": ";
+ charMsg = "Please enter a single character: ";
+ charRangeMsg = "is not valid. Re-enter: ";
+ intMsg = "Re-enter number: ";
+ doubleMsg = "Input is not a double. Re-enter: ";
+ floatMsg = "Input is not a float. Re-enter: ";
+ stringMsg = "Input cannot be blank--enter text: ";
+}
+
+CinReader::~CinReader ()
+{
+}
+
+int CinReader::readInt (int lower, int upper)
+{
+ string input = "";
+ string msg = "";
+ getline (cin, input);
+ input = stripCommas(input);
+ if (lower > upper)
+ {
+ int temp = upper;
+ lower = upper;
+ upper = temp;
+ }
+
+ while (!testIntInput(input, msg, lower, upper))
+ {
+ if (intErrors)
+ cout << "[ ERROR: " << msg << " ]\n";
+ cout << intMsg;
+ getline (cin, input);
+ }
+
+ return (atoi(input.c_str()));
+}
+
+int CinReader::readInt (bool userLimit, int lower, int upper)
+{
+ if (userLimit)
+ return (readInt(lower, upper));
+ else
+ return (readInt());
+}
+
+double CinReader::readDouble ()
+{
+ string input = "";
+ getline(cin, input);
+ input = stripCommas(input);
+ while (!testDoubleInput(input))
+ {
+ cout << doubleMsg;
+ getline(cin, input);
+ }
+
+ return (atof(input.c_str()));
+}
+
+float CinReader::readFloat ()
+{
+ string input = "";
+ getline(cin, input);
+ input = stripCommas(input);
+ while (!testDoubleInput(input))
+ {
+ cout << floatMsg;
+ getline(cin, input);
+ }
+
+ return (atof(input.c_str()));
+}
+
+char CinReader::readChar (string range)
+{
+ bool valid = false;
+ string input = "";
+ getline(cin, input);
+
+ if (range.length() > 0)
+ {
+ do
+ {
+ while (input.length() != 1)
+ {
+ cout << charMsg;
+ getline(cin, input);
+ }
+ if (!testCharInput(input[0], range))
+ {
+ if (charRangeErrors)
+ cout << "[" << input[0] << "] " << charRangeMsg;
+ input = "";
+ }
+ else
+ valid = true;
+ } while (!valid);
+ }
+ else
+ {
+ while (input.length() != 1)
+ {
+ cout << charMsg;
+ getline(cin, input);
+ }
+ }
+
+ return (input[0]);
+}
+
+bool CinReader::readBool ()
+{
+ string input = "";
+ getline(cin, input);
+ while (!testBoolInput(input))
+ {
+ cout << boolMsg;
+ getline(cin, input);
+ }
+
+ return (getBoolValue(input));
+}
+
+string CinReader::readString (bool allowEmpty, unsigned int limitTo)
+{
+ string input = "";
+ getline(cin, input);
+ if (!allowEmpty)
+ {
+ while (input.length() == 0)
+ {
+ cout << stringMsg;
+ getline(cin, input);
+ }
+ }
+ if (limitTo > 0)
+ {
+ if (input.length() > limitTo)
+ input = input.substr(0, limitTo);
+ }
+ return input;
+}
+
+void CinReader::showIntErrors (bool show)
+{
+ intErrors = show;
+}
+
+void CinReader::showCharRangeErrors (bool show)
+{
+ charRangeErrors = show;
+}
+
+void CinReader::setBoolMessage (string newMessage)
+{
+ boolMsg = newMessage;
+ if (boolMsg.length() > 0 && boolMsg[boolMsg.length()-1] != ' ')
+ boolMsg += ' ';
+}
+
+void CinReader::setCharMessage (string newMessage)
+{
+ charMsg = newMessage;
+ if (charMsg.length() > 0 && charMsg[charMsg.length()-1] != ' ')
+ charMsg += ' ';
+}
+
+void CinReader::setCharRangeMessage (string newMessage)
+{
+ charRangeMsg = newMessage;
+ if (charRangeMsg.length() > 0 && charRangeMsg[charRangeMsg.length()-1] != ' ')
+ charRangeMsg += ' ';
+}
+
+void CinReader::setIntMessage (string newMessage)
+{
+ intMsg = newMessage;
+ if (intMsg.length() > 0 && intMsg[intMsg.length()-1] != ' ')
+ intMsg += ' ';
+}
+
+void CinReader::setDoubleMessage (string newMessage)
+{
+ doubleMsg = newMessage;
+ if (doubleMsg.length() > 0 && doubleMsg[doubleMsg.length()-1] != ' ')
+ doubleMsg += ' ';
+}
+
+void CinReader::setFloatMessage (string newMessage)
+{
+ floatMsg = newMessage;
+ if (floatMsg.length() > 0 && floatMsg[floatMsg.length()-1] != ' ')
+ floatMsg += ' ';
+}
+
+void CinReader::setStringMessage (string newMessage)
+{
+ stringMsg = newMessage;
+ if (stringMsg.length() > 0 && stringMsg[stringMsg.length()-1] != ' ')
+ stringMsg += ' ';
+}
+
+string CinReader::stripCommas (string input)
+{
+ string outs = "";
+ for (unsigned int i=0; i<input.length(); i++)
+ {
+ if (input[i] != ',')
+ outs += input[i];
+ }
+ return outs;
+}
+
+bool CinReader::testIntInput (string input, string& msg, int lowerLimit, int upperLimit)
+{
+ int upperMarker = -1;
+ int lowerMarker = -1;
+ if (upperLimit == INT_MAX)
+ upperMarker = 47;
+ if (lowerLimit == INT_MIN)
+ lowerMarker = 48;
+
+ long linput = strtol(input.c_str(), NULL, 10);
+ stringstream ssinput;
+ ssinput << linput;
+ if (ssinput.str() != input)
+ {
+ msg = "integer input out-of-range";
+ return false;
+ }
+
+ else
+ {
+ if (input.length() > 0)
+ {
+ if (input[0] != '-' && (!isdigit(input[0])))
+ {
+ msg = "not an integer";
+ return false;
+ }
+ for (unsigned int i=1; i<input.length(); i++)
+ {
+ if (!isdigit(input[i]))
+ {
+ msg = "not an integer";
+ return false;
+ }
+ }
+
+ int tmp = strtol(input.c_str(), NULL, 10);
+ if (tmp >= upperLimit)
+ {
+ if (upperMarker != -1)
+ {
+ string ts = "";
+ ts += input[input.length()-2];
+ ts += input[input.length()-1];
+ int ti = atoi(ts.c_str());
+ if (ti > upperMarker)
+ {
+ msg = "larger than 32-bit integer";
+ return false;
+ }
+ else
+ return true;
+ }
+ else
+ {
+ if (tmp == upperLimit)
+ return true;
+ else
+ {
+ msg = "larger than upper limit";
+ return false;
+ }
+ }
+ }
+ else if (tmp <= lowerLimit)
+ {
+ if (lowerMarker != -1)
+ {
+ string ts = "";
+ ts += input[input.length()-2];
+ ts += input[input.length()-1];
+ int ti = atoi(ts.c_str());
+ if (ti > lowerMarker)
+ {
+ msg = "smaller than 32-bit integer";
+ return false;
+ }
+ else
+ return true;
+ }
+ else
+ {
+ if (tmp == lowerLimit)
+ return true;
+ else
+ {
+ msg = "smaller than lower limit";
+ return false;
+ }
+ }
+ }
+ else
+ return true;
+ }
+ msg = "no input";
+ return false;
+ }
+}
+
+bool CinReader::testDoubleInput (string input)
+{
+ int dotCount = 0;
+ if (input.length() > 0)
+ {
+ if (input[0] != '-' && (!isdigit(input[0])) && input[0] != '.')
+ return false;
+ if (input[0] == '.')
+ dotCount = 1;
+ for (unsigned int i=1; i<input.length(); i++)
+ {
+ if (input[i] == '.')
+ {
+ if (dotCount != 0)
+ return false;
+ else
+ ++dotCount;
+ }
+ else if (!isdigit(input[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool CinReader::testCharInput (char c, string range)
+{
+ bool valid = false;
+ for (unsigned int i=0; i<range.length(); i++)
+ {
+ if (range[i] == c)
+ {
+ valid = true;
+ break;
+ }
+ }
+ return valid;
+}
+
+bool CinReader::testBoolInput (string input)
+{
+ if (input.length() > 0)
+ {
+ if (input.length() == 1)
+ {
+ if (toupper(input[0]) == 'T' || toupper(input[0]) == 'F')
+ return true;
+ else
+ return false;
+ }
+ else
+ {
+ if (ignoreCaseCompare(input, "TRUE") ||
+ ignoreCaseCompare(input, "FALSE"))
+ return true;
+ else
+ return false;
+ }
+ }
+ else
+ return false;
+}
+
+bool CinReader::getBoolValue (string input)
+{
+ if (toupper(input[0]) == 'T')
+ return true;
+ else
+ return false;
+}
+
+bool CinReader::ignoreCaseCompare (string input, string comp)
+{
+ toUpperCase(input);
+ if (input == comp)
+ return true;
+ else
+ return false;
+}
+
+void CinReader::toUpperCase (string& s)
+{
+ transform(s.begin(), s.end(), s.begin(), ::toupper);
+}
diff --git a/c++/3c/CinReader.h b/c++/3c/CinReader.h
@@ -0,0 +1,244 @@
+/*
+Copyright (c) 2008, J Boyd Trolinger
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this list
+of conditions and the following disclaimer in the documentation and/or other materials
+provided with the distribution.
+
+Neither the name of the Butte College Department of Computer Science nor the names of its
+contributors may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma once
+
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <climits>
+#include <sstream>
+
+using namespace std;
+
+/**
+ * A class for handling keyboard input. CinReader provides
+ * functions for reading all of the C++ primitive data types
+ * and C++ strings, and performs error checking on the input.
+ * @author J Boyd Trolinger
+ * @version 1.1
+ */
+ class CinReader
+{
+ public:
+
+ /**
+ * Constructor.
+ * Initializes data members to the following values:
+ * <ul>
+ * <li>intErrors = true;</li>
+ * <li>charRangeErrors = true;</li>
+ * <li>boolMsg = "Please enter \"true\" or \"false\": "</li>
+ * <li>charMsg = "Please enter a single character: "</li>
+ * <li>charRangeMsg = "is not valid. Re-enter: "</li>
+ * <li>intMsg = "Re-enter number: "</li>
+ * <li>doubleMsg = "Input is not a double. Re-enter: "</li>
+ * <li>floatMsg = "Input is not a float. Re-enter: "</li>
+ * <li>stringMsg = "Input cannot be blank--enter text: "</li>
+ * </ul>
+ */
+ CinReader ();
+
+ /**
+ * Destructor.
+ * CinReader performs no dynamic memory allocation. Destructor
+ * is provided for thoroughness and to reinforce good OO/C++
+ * programming practices.
+ */
+ ~CinReader ();
+
+ /**
+ * Read integer input from the keyboard.
+ * Used with no arguments, the function will return an integer between
+ * INT_MIN and INT_MAX. Optionally the function can be called
+ * with caller-specified upper and lower limits. If lower>upper, valid return
+ * value is not guaranteed. Uses intMsg for error prompt.
+ * @param lower caller-specified lower limit of the input, defaults to INT_MIN
+ * @param upper caller-specified upper limit of the input, defaults to INT_MAX
+ * @return an integer between INT_MIN and INT_MAX if called with
+ * no arguments, or between lower and upper (inclusive)
+ */
+ int readInt (int lower=INT_MIN, int upper=INT_MAX);
+
+ /**
+ * Read integer input from the keyboard.
+ * Provided for backward compatibility with the version 1.0 CinReader API. Calls
+ * readInt(lower,upper) if userLimit==true, else calls readInt().
+ * @param userLimit if true, limit keyboard input to caller-specified range
+ * @param lower caller-specified lower limit of the input
+ * @param upper caller-specified upper limit of the input
+ * @return an integer between lower and upper (inclusive)
+ */
+ int readInt (bool userLimit, int lower, int upper);
+
+ /**
+ * Read double input from the keyboard.
+ * Unlike readInt, this function does not limit the range of the
+ * input value. Uses doubleMsg for error prompt.
+ * @return a double
+ */
+ double readDouble ();
+
+ /**
+ * Read float input from the keyboard.
+ * Unlike readInt, this function does not limit the range of the
+ * input value. Uses floatMsg for error prompt.
+ * @return a float
+ */
+ float readFloat ();
+
+ /**
+ * Read input from the keyboard as a boolean value.
+ * Will accept "T", "F" or "TRUE", "FALSE" as input and will
+ * return a corresponding boolean value. The function is NOT
+ * case sensitive, it will accept input as any combination of
+ * uppercase and lowercase characters. Uses boolMsg for error prompt.
+ * @return a bool
+ */
+ bool readBool ();
+
+ /**
+ * Read char input from the keyboard.
+ * Used with no arguments, the function will return the char entered at
+ * the keyboard. Optionally, a range of acceptable inputs can
+ * be specified. The range must be written as a list of chars, such as
+ * "abcdef". Uses charMsg for error prompt. If charRangeErrors==true, and
+ * range.length() > 0, also uses charRangeMsg for error prompt.
+ * @param range the range of acceptable inputs
+ * @return a char that is a member of range if specified, or
+ * any single char if no range is provided
+ */
+ char readChar (string range="");
+
+ /**
+ * Read string input from the keyboard.
+ * Used with no arguments, the function will return the string
+ * entered at the keyboard, which can include an empty string.
+ * Uses stringMsg for error prompt.
+ * @param allowEmpty if true, allow empty string as input, else
+ * require at least one character of input
+ * @param limitTo if 0, do not limit the number of characters of
+ * input; if not 0, return only "limitTo" number of
+ * characters
+ * @return a string
+ */
+ string readString (bool allowEmpty = true, unsigned int limitTo = 0);
+
+ /**
+ * Enable or disable more verbose error messages for invalid integer inputs.
+ * Defaults to true.
+ * @param show if true, show additional ERROR output on invalid input; if false,
+ * display only intMsg as error prompt.
+ */
+ void showIntErrors (bool show);
+
+ /**
+ * Enable or disable more verbose error messages for invalid character inputs when
+ * limiting to a caller-specified range.
+ * Defaults to true.
+ * @param show if true, show additional ERROR output on invalid input; if false,
+ * display only charMsg as error prompt.
+ */
+ void showCharRangeErrors (bool show);
+
+ /**
+ * Set the prompt string for invalid bool inputs.
+ * Default boolMsg is "Please enter \"true\" or \"false\": "
+ * @param newMessage a prompt string for invalid bool inputs
+ */
+ void setBoolMessage (string newMessage);
+
+ /**
+ * Set the prompt string for invalid char inputs.
+ * Default charMsg is "Please enter a single character: "
+ * @param newMessage a prompt string for invalid char inputs
+ */
+ void setCharMessage (string newMessage);
+
+ /**
+ * Set the prompt string for invalid char inputs when limiting to a caller-specified
+ * range.
+ * Default charRangeMsg is "[CHAR] is not valid. Re-enter: " (CHAR is the user's invalid
+ * input.) "[CHAR]" is always appended to the beginning of the char range error prompt string.
+ * @param newMessage a prompt string for invalid char inputs
+ */
+ void setCharRangeMessage (string newMessage);
+
+ /**
+ * Set the prompt string for invalid int inputs.
+ * Default intMsg is "Re-enter number: "
+ * @param newMessage a prompt string for invalid int inputs
+ */
+ void setIntMessage (string newMessage);
+
+ /**
+ * Set the prompt string for invalid double inputs.
+ * Default doubleMsg is "Input is not a double. Re-enter: "
+ * @param newMessage a prompt string for invalid double inputs
+ */
+ void setDoubleMessage (string newMessage);
+
+ /**
+ * Set the prompt string for invalid float inputs.
+ * Default floatMsg is "Input is not a float. Re-enter: "
+ * @param newMessage a prompt string for invalid float inputs
+ */
+ void setFloatMessage (string newMessage);
+
+ /**
+ * Set the prompt string for invalid string inputs.
+ * Default stringMsg is "Input cannot be blank--enter text: "
+ * @param newMessage a prompt string for invalid string inputs
+ */
+ void setStringMessage (string newMessage);
+
+ private:
+
+ bool intErrors;
+ bool charRangeErrors;
+ string boolMsg;
+ string charMsg;
+ string charRangeMsg;
+ string intMsg;
+ string doubleMsg;
+ string floatMsg;
+ string stringMsg;
+
+ string stripCommas (string input);
+ bool testIntInput (string, string&, int l=-1, int u=-1);
+ bool testDoubleInput (string);
+ bool testCharInput (char, string);
+ bool testBoolInput (string);
+ bool getBoolValue (string);
+ void toUpperCase (string&);
+ bool ignoreCaseCompare (string, string);
+};
diff --git a/c++/3c/assignment_3.dSYM/Contents/Info.plist b/c++/3c/assignment_3.dSYM/Contents/Info.plist
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.xcode.dsym.assignment_3</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>dSYM</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ </dict>
+</plist>
diff --git a/c++/3c/assignment_3.dSYM/Contents/Resources/DWARF/assignment_3 b/c++/3c/assignment_3.dSYM/Contents/Resources/DWARF/assignment_3
Binary files differ.
diff --git a/c++/3c/assignment_3_unit_test.cpp b/c++/3c/assignment_3_unit_test.cpp
@@ -0,0 +1,337 @@
+/*
+ * Name : assignment_3_unit_test.cpp
+ * Author : Luke Sathrum
+ * Description : Unit Test for class TodoItem and TodoList.
+ * THIS FILE SHOUD NOT BE ALTERED, UNLESS DEBUGGING IN MAIN
+ */
+
+#include <iostream>
+#include <sstream>
+#include <streambuf>
+#include "todo_list.h"
+#include "todo_item.h"
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+// For testing (DO NOT ALTER)
+#include <cctype>
+#include <vector>
+void UnitTest();
+template <typename T>
+void Test(bool test, string more_info = "", T yours = T(),
+ T expected = T());
+void OutputFailedTests();
+unsigned int ut_passed = 0, ut_failed = 0, ut_total = 0, num_of_tests = 53;
+std::vector<int> failed_tests;
+
+// Program Execution Starts Here
+int main() {
+ // START DEBUGGING CODE
+
+ // END DEBUGINH CODE
+ // To test your code (DO NOT ALTER)
+ UnitTest();
+ // This ends program execution
+ return 0;
+}
+
+
+// For testing (DO NOT ALTER)
+void UnitTest() {
+ cout << string(40, '-') << endl;
+ cout << "UNIT TEST:\n" << string(40, '-') << endl;
+ if (num_of_tests != 0)
+ cout << "Total Number of Tests: " << num_of_tests << endl;
+
+ // Tests
+ string desc1 = "Go to Store";
+ string desc2 = "Brush Teeth @ 8PM";
+ string expected, yours;
+ string to_file;
+
+ cout << "*****TodoItem(\"Go to Store\")*****\n";
+ TodoItem item(desc1);
+ Test(item.description() == desc1, "description()", item.description(), desc1);
+ Test(item.priority() == 1, "priority()", item.priority(), 1);
+ Test(item.completed() == false, "completed()", item.completed(), false);
+ to_file = "Go to Store@1@0";
+ Test(item.ToFile() == to_file, "ToFile()", item.ToFile(), to_file);
+
+ cout << "\n*****TodoItem(\"Go to Store\", 3)*****\n";
+ TodoItem item2(desc1, 3);
+ Test(item2.description() == desc1, "description()", item2.description(),
+ desc1);
+ Test(item2.priority() == 3, "priority()", item2.priority(), 3);
+ Test(item2.completed() == false, "completed()", item2.completed(), false);
+ to_file = "Go to Store@3@0";
+ Test(item2.ToFile() == to_file, "ToFile()", item2.ToFile(), to_file);
+
+ cout << "\n*****TodoItem(\"Go to Store\", 2, true)*****\n";
+ TodoItem item3(desc1, 2, true);
+ Test(item3.description() == desc1, "description()", item3.description(),
+ desc1);
+ Test(item3.priority() == 2, "priority()", item3.priority(), 2);
+ Test(item3.completed() == true, "completed()", item3.completed(), true);
+ to_file = "Go to Store@2@1";
+ Test(item3.ToFile() == to_file, "ToFile()", item3.ToFile(), to_file);
+
+ cout << "\n*****TodoItem Mutators*****\n";
+ item.set_description(desc2);
+ Test(item.description() == desc2,
+ "set_description(\"Brush Teeth @ 8PM\") / description()",
+ item.description(), desc2);
+ item.set_priority(4);
+ Test(item.priority() == 4, "set_priority(4) / priority()", item.priority(),
+ 4);
+ item.set_priority(0);
+ Test(item.priority() == 5, "set_priority(0) / priority()", item.priority(),
+ 5);
+ item.set_priority(6);
+ Test(item.priority() == 5, "set_priority(6) / priority()", item.priority(),
+ 5);
+ item.set_completed(true);
+ Test(item.completed() == true, "set_completed(true) / completed()",
+ item.completed(), true);
+ to_file = "Brush Teeth ` 8PM@5@1";
+ Test(item.ToFile() == to_file, "ToFile()", item.ToFile(), to_file);
+
+ cout << "\n*****TodoList Constructor*****\n";
+ TodoList list;
+ Test(list.GetSize() == 0, "GetSize()", list.GetSize(),
+ static_cast<unsigned int>(0));
+ Test(list.GetCapacity() == 25, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(25));
+ Test(list.ToFile() == "", "ToFile()", list.ToFile(), string(""));
+
+ cout << "\n*****TodoList Member Functions with 1 Item*****\n";
+ list.AddItem(new TodoItem(desc1));
+ Test(list.GetSize() == 1, "AddItem(TodoItem(\"Go to Store\")) / GetSize()",
+ list.GetSize(), static_cast<unsigned int>(1));
+ Test(list.GetCapacity() == 25, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(25));
+ Test(list.GetItem(1)->ToFile() == string("Go to Store@1@0"),
+ "GetItem(1)->ToFile()", list.GetItem(1)->ToFile(),
+ string("Go to Store@1@0"));
+ Test(list.ToFile() == "Go to Store@1@0\n", "ToFile()", list.ToFile(),
+ string("Go to Store@1@0\n"));
+ cout << "Testing Overloaded <<:\n" << list << endl;
+
+ cout << "\n*****TodoList Member Functions with 2 Items*****\n";
+ list.AddItem(new TodoItem(desc1, 2, true));
+ Test(list.GetSize() == 2,
+ "AddItem(TodoItem(\"Go to Store\", 2, true)) / GetSize()",
+ list.GetSize(), static_cast<unsigned int>(2));
+ Test(list.GetCapacity() == 25, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(25));
+ yours = list.GetItem(1)->ToFile();
+ expected = "Go to Store@1@0";
+ Test(yours == expected, "GetItem(1)->ToFile()", yours, expected);
+ yours = list.GetItem(2)->ToFile();
+ expected = "Go to Store@2@1";
+ Test(yours == expected, "GetItem(2)->ToFile()", yours, expected);
+ yours = list.ToFile();
+ expected = "Go to Store@1@0\nGo to Store@2@1\n";
+ Test(yours == expected, "ToFile()", yours, expected);
+ list.DeleteItem(1);
+ Test(list.GetSize() == 1, "DeleteItem(1) / GetSize()", list.GetSize(),
+ static_cast<unsigned int>(1));
+ Test(list.GetCapacity() == 25, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(25));
+ cout << "Testing Overloaded <<:\n" << list << endl;
+
+ cout << "\n*****TodoList Member Functions with 25 Items*****\n";
+ list.AddItem(new TodoItem(desc2, 4, true));
+ stringstream ss;
+ for (int i = 0; i < 23; i++) {
+ ss << "Description #" << i + 3;
+ list.AddItem(new TodoItem(ss.str(), i % 5 + 1));
+ ss.str("");
+ }
+ Test(list.GetSize() == 25, "AddItem(Adding 24 More Items) / GetSize()",
+ list.GetSize(), static_cast<unsigned int>(25));
+ Test(list.GetCapacity() == 25, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(25));
+ yours = list.GetItem(17)->ToFile();
+ expected = "Description #17@5@0";
+ Test(yours == expected, "GetItem(17)->ToFile()", yours, expected);
+ yours = list.GetItem(25)->ToFile();
+ expected = "Description #25@3@0";
+ Test(yours == expected, "GetItem(25)->ToFile()", yours, expected);
+ yours = list.ToFile();
+ expected =
+ "Go to Store@2@1\nBrush Teeth ` 8PM@4@1\nDescription #3@1@0\n"
+ "Description #4@2@0\nDescription #5@3@0\nDescription #6@4@0\n"
+ "Description #7@5@0\nDescription #8@1@0\nDescription #9@2@0\n"
+ "Description #10@3@0\nDescription #11@4@0\nDescription #12@5@0\n"
+ "Description #13@1@0\nDescription #14@2@0\nDescription #15@3@0\n"
+ "Description #16@4@0\nDescription #17@5@0\nDescription #18@1@0\n"
+ "Description #19@2@0\nDescription #20@3@0\nDescription #21@4@0\n"
+ "Description #22@5@0\nDescription #23@1@0\nDescription #24@2@0\n"
+ "Description #25@3@0\n";
+ Test(yours == expected, "ToFile()", yours, expected);
+ cout << "Testing Overloaded <<:\n" << list << endl;
+
+ list.DeleteItem(15);
+ Test(list.GetSize() == 24, "DeleteItem(15) / GetSize()", list.GetSize(),
+ static_cast<unsigned int>(24));
+ Test(list.GetCapacity() == 25, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(25));
+ yours = list.GetItem(10)->ToFile();
+ expected = "Description #10@3@0";
+ Test(yours == expected, "GetItem(10)->ToFile()", yours, expected);
+ yours = list.GetItem(20)->ToFile();
+ expected = "Description #21@4@0";
+ Test(yours == expected, "GetItem(20)->ToFile()", yours, expected);
+ yours = list.ToFile();
+ expected = "Go to Store@2@1\nBrush Teeth ` 8PM@4@1\nDescription #3@1@0\n"
+ "Description #4@2@0\nDescription #5@3@0\nDescription #6@4@0\n"
+ "Description #7@5@0\nDescription #8@1@0\nDescription #9@2@0\n"
+ "Description #10@3@0\nDescription #11@4@0\nDescription #12@5@0\n"
+ "Description #13@1@0\nDescription #14@2@0\n"
+ "Description #16@4@0\nDescription #17@5@0\nDescription #18@1@0\n"
+ "Description #19@2@0\nDescription #20@3@0\nDescription #21@4@0\n"
+ "Description #22@5@0\nDescription #23@1@0\nDescription #24@2@0\n"
+ "Description #25@3@0\n";
+ Test(yours == expected, "ToFile()", yours, expected);
+ cout << "Testing Overloaded <<:\n" << list << endl;
+
+ cout << "\n*****TodoList Member Functions with 30 Items*****\n";
+ for (int i = 25; i <= 30; i++) {
+ ss << "New Description #" << i;
+ list.AddItem(new TodoItem(ss.str(), i % 5 + 1, true));
+ ss.str("");
+ }
+ Test(list.GetSize() == 30, "AddItem(Adding 6 More Items) / GetSize()",
+ list.GetSize(), static_cast<unsigned int>(30));
+ Test(list.GetCapacity() == 35, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(35));
+ yours = list.GetItem(11)->ToFile();
+ expected = "Description #11@4@0";
+ Test(yours == expected, "GetItem(11)->ToFile()", yours, expected);
+ yours = list.GetItem(30)->ToFile();
+ expected = "New Description #30@1@1";
+ Test(yours == expected, "GetItem(30)->ToFile()", yours, expected);
+ yours = list.ToFile();
+ expected = "Go to Store@2@1\nBrush Teeth ` 8PM@4@1\nDescription #3@1@0\n"
+ "Description #4@2@0\nDescription #5@3@0\nDescription #6@4@0\n"
+ "Description #7@5@0\nDescription #8@1@0\nDescription #9@2@0\n"
+ "Description #10@3@0\nDescription #11@4@0\nDescription #12@5@0\n"
+ "Description #13@1@0\nDescription #14@2@0\n"
+ "Description #16@4@0\nDescription #17@5@0\nDescription #18@1@0\n"
+ "Description #19@2@0\nDescription #20@3@0\nDescription #21@4@0\n"
+ "Description #22@5@0\nDescription #23@1@0\nDescription #24@2@0\n"
+ "Description #25@3@0\nNew Description #25@1@1\nNew Description #26@2@1\n"
+ "New Description #27@3@1\nNew Description #28@4@1\n"
+ "New Description #29@5@1\nNew Description #30@1@1\n";
+ Test(yours == expected, "ToFile()", yours, expected);
+ cout << "Testing Overloaded <<:\n" << list << endl;
+
+ cout << "\n*****Sorting TodoList with 30 Items*****\n";
+ list.Sort();
+ bool sorted = true;
+ for (int i = 1; i <= 30; i++) {
+ if ((i <= 7) && (list.GetItem(i)->priority()) != 1)
+ sorted = false;
+ else if ((i > 7 && i <= 14) && (list.GetItem(i)->priority()) != 2)
+ sorted = false;
+ else if ((i > 14 && i <= 19) && (list.GetItem(i)->priority()) != 3)
+ sorted = false;
+ else if ((i > 19 && i <= 25) && (list.GetItem(i)->priority()) != 4)
+ sorted = false;
+ else if ((i > 25 && i <= 30) && (list.GetItem(i)->priority()) != 5)
+ sorted = false;
+ }
+ yours = list.ToFile();
+ expected = "Description #3@1@0\nDescription #8@1@0\n"
+ "Description #13@1@0\nDescription #18@1@0\n"
+ "Description #23@1@0\nNew Description #25@1@1\n"
+ "New Description #30@1@1\nGo to Store@2@1\n"
+ "Description #4@2@0\nDescription #9@2@0\n"
+ "Description #14@2@0\nDescription #19@2@0\n"
+ "Description #24@2@0\nNew Description #26@2@1\n"
+ "Description #5@3@0\nDescription #10@3@0\n"
+ "Description #20@3@0\nDescription #25@3@0\n"
+ "New Description #27@3@1\nBrush Teeth ` 8PM@4@1\n"
+ "Description #6@4@0\nDescription #11@4@0\n"
+ "Description #16@4@0\nDescription #21@4@0\n"
+ "New Description #28@4@1\nDescription #7@5@0\n"
+ "Description #12@5@0\nDescription #17@5@0\n"
+ "Description #22@5@0\nNew Description #29@5@1\n";
+
+ Test(sorted && yours == expected, "Sort()", yours, expected);
+ cout << "Testing Overloaded <<:\n" << list << endl;
+
+ cout << "\n*****TodoList Member Functions with 1000 Items*****\n";
+ for (int i = 0; i < 970; i++)
+ list.AddItem(new TodoItem("A", 1, true));
+ Test(list.GetSize() == 1000, "AddItem(Adding 970 More Items) / GetSize()",
+ list.GetSize(), static_cast<unsigned int>(1000));
+ Test(list.GetCapacity() == 1005, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(1005));
+ cout << "**Deleting All Items**\n";
+ for (int i = 1000; i >= 1; i--)
+ list.DeleteItem(i);
+ Test(list.GetSize() == 0, "DeleteItem() / GetSize()", list.GetSize(),
+ static_cast<unsigned int>(0));
+ Test(list.GetCapacity() == 1005, "GetCapacity()", list.GetCapacity(),
+ static_cast<unsigned int>(1005));
+
+ // Testing Destructors
+ cout << "\n*****Testing Destructors*****" << endl
+ << "If the next line is the \"END Testing Destructors\" then you passed!"
+ << endl;
+ TodoItem *dynamic_item = new TodoItem("testing");
+ delete dynamic_item;
+ dynamic_item = new TodoItem("testing2", 5);
+ delete dynamic_item;
+ dynamic_item = new TodoItem("Testing3", 3, true);
+ TodoList *dynamic_list = new TodoList();
+ delete dynamic_list;
+ dynamic_list = new TodoList();
+ for (int i = 0; i < 50; i++)
+ dynamic_list->AddItem(new TodoItem("testing"));
+ delete dynamic_list;
+ cout << "*****END Testing Destructors*****" << endl;
+ Test(true, "Destructors", 0, 0);
+
+ cout << string(40, '-') << endl;
+ cout << "Passed: " << ut_passed << " / " << ut_total << endl;
+ OutputFailedTests();
+ cout << string(40, '-') << endl;
+ cout << "END OF UNIT TEST!\n";
+ cout << string(40, '-') << endl;
+ cout << "Be sure to run 'make style' to check for any style errors.\n"
+ << "Please note that 'make style' does NOT check variable names or"
+ << " indentation" << endl << endl;
+}
+
+// For testing (DO NOT ALTER)
+template <typename T>
+void Test(bool test, string more_info, T yours, T expected) {
+ ut_total++;
+ if (test) {
+ cout << "PASSED TEST ";
+ ut_passed++;
+ } else {
+ cout << "FAILED TEST ";
+ ut_failed++;
+ failed_tests.push_back(ut_total);
+ }
+ cout << ut_total << " " << more_info << "!" << endl;
+ if (!test && yours != T()) {
+ cout << "Expected: " << std::boolalpha << expected << endl;
+ cout << "Yours : " << std::boolalpha << yours << endl << endl;
+ }
+}
+
+void OutputFailedTests() {
+ if (failed_tests.size()) {
+ cout << "Failed test number(s): ";
+ for (unsigned int i = 0; i < failed_tests.size() - 1; i++)
+ cout << failed_tests.at(i) << ", ";
+ cout << failed_tests.at(failed_tests.size() - 1) << endl;
+ }
+}
+
diff --git a/c++/3c/driver.cpp b/c++/3c/driver.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+#include "todo_ui.h"
+
+/* Create a new object using the TodoUI class
+and then call the object to display the menu */
+int main() {
+ TodoUI obj;
+ obj.menu();
+ return 0;
+}
+
diff --git a/c++/3c/makefile b/c++/3c/makefile
@@ -0,0 +1,43 @@
+# Makefile for Assignment 3
+CXX = g++
+ASSIGNMENT = 3
+ASSIGNMENT_NAME = assignment_${ASSIGNMENT}
+MAIN = ${ASSIGNMENT_NAME}_unit_test
+CPP_FILES = todo_item.cpp todo_list.cpp todo_ui.cpp
+H_FILES = todo_item.h todo_list.h todo_ui.h
+CXXFLAGS = -Wall -Wextra -pedantic -g
+
+options:
+ @echo
+ @echo Options
+ @echo ----------------------------------------
+ @echo 'make - View these options'
+ @echo 'make todo_list - Compiles the unit test for TodoList'
+ @echo 'make todo_ui - Compiles the UI Application'
+ @echo 'make style - Runs the class style check'
+ @echo 'make clean - Deletes your executable'
+ @echo
+ @echo
+ @echo "Once you've created your executable use the following to test"
+ @echo './${ASSIGNMENT_NAME} - Run the Interactive Unit Test'
+ @echo
+ @echo
+
+# Type 'make todo_ui' to create the executable
+todo_ui: driver.cpp ${H_FILES} CinReader.h ${CPP_FILES} CinReader.cpp
+ ${CXX} ${CXXFLAGS} driver.cpp ${CPP_FILES} CinReader.cpp -o ${ASSIGNMENT_NAME}
+ @echo
+ @echo 'Compiled! (Fix any warnings above)'
+
+todo_list: ${MAIN}.cpp todo_list.h todo_list.cpp todo_item.h todo_item.cpp
+ ${CXX} ${CXXFLAGS} ${MAIN}.cpp todo_list.cpp todo_item.cpp -o ${ASSIGNMENT_NAME}
+ @echo
+ @echo 'Compiled! (Fix any warnings above)'
+
+# Type 'make style' to check your code style
+s style: ../../helpful_files/cpplint.py
+ python2 $< --filter=-runtime/references,-legal/copyright,-readability/streams,-runtime/explicit,-build/header_guard,-build/include ${H_FILES} ${CPP_FILES} driver.cpp
+
+# Type 'make clean' to remove the executable
+c clean:
+ rm -rf ${ASSIGNMENT_NAME}
diff --git a/c++/3c/todo_item.cpp b/c++/3c/todo_item.cpp
@@ -0,0 +1,34 @@
+/*
+ * Name : todo_item.cpp
+ * Author : Evan Alba
+ * Description : CPP File for class TodoItem.
+ */
+
+#include "todo_item.h"
+
+void TodoItem::set_description(std::string info) {
+ description_ = info;
+}
+
+void TodoItem::set_priority(int rank) {
+ if ((rank >= 1) && (rank <= 5)) {
+ priority_ = rank;
+ } else {
+ priority_ = 5;
+ }
+}
+
+void TodoItem::set_completed(bool state) {
+ completed_ = state;
+}
+
+std::string TodoItem::ToFile() {
+ return scrub(description_) + "@" + std::to_string(priority_) + "@"
+ + std::to_string(completed_);
+}
+
+/* PRIVATE FUNCTION BELLOW */
+std::string TodoItem::scrub(std::string edit) {
+ std::replace(edit.begin(), edit.end(), '@', '`');
+ return edit;
+}
diff --git a/c++/3c/todo_item.h b/c++/3c/todo_item.h
@@ -0,0 +1,63 @@
+/*
+ * Name : todo_item.h
+ * Author : Evan Alba
+ * Description : Header File for class TodoItem.
+ */
+
+#ifndef TODO_ITEM
+#define TODO_ITEM
+#include <algorithm>
+#include <iostream>
+#include <string>
+
+class TodoItem {
+ public:
+ /* Create Item on the Todo list. */
+ TodoItem(std::string info, int rank = 1, bool done = false) {
+ description_ = info;
+ priority_ = rank;
+ completed_ = done;
+ }
+
+ /* Get the Description. */
+ std::string description() const {
+ return description_;
+ }
+
+ /* Get the Priority ranking of item on the Todo List. */
+ int priority() const {
+ return priority_;
+ }
+
+ /* Get back if the item on the Todo List has been completed. */
+ bool completed() const {
+ return completed_;
+ }
+
+ /* PUBLIC Setters Prototypes for Todo Item Class */
+ /* Set the description of the item. */
+ void set_description(std::string text);
+
+ /* Check if priority number of item given is a number of 1 - 5.
+ If TRUE, set priority number.
+ If the priority number invalid, set to 5. */
+ void set_priority(int rank);
+
+ /* State if the item on the Todo List has been completed. */
+ void set_completed(bool state);
+
+ /* Returns a string containing the description,
+ priority, and completed status, separated by the @ symbol. */
+ std::string ToFile();
+
+ private:
+ /* PRIVATE Data for Todo Item Class */
+ std::string description_;
+ int priority_;
+ bool completed_;
+
+ /* PRIVATE Prototype for Scrub Function */
+ /* Replace @ in the description with ` symbol. */
+ std::string scrub(std::string edit);
+};
+#endif
diff --git a/c++/3c/todo_list.cpp b/c++/3c/todo_list.cpp
@@ -0,0 +1,119 @@
+/*
+ * Name : todo_list.cpp
+ * Author : Evan Alba
+ * Description : CPP File for class TodoList.
+ */
+#include "todo_list.h"
+
+TodoList::TodoList() {
+ size_ = 0;
+ cap_ = 25;
+ list_ = new TodoItem*[cap_];
+ for (unsigned int i = 0; i < cap_; i++) {
+ list_[i] = nullptr;
+ }
+}
+
+TodoList::~TodoList() {
+ for (unsigned int i = 0; i < size_; i++) {
+ delete list_[i];
+ }
+ delete[] list_;
+}
+
+void TodoList::AddItem(TodoItem* add) {
+ if (size_ == cap_) {
+ IncreaseCap();
+ }
+ list_[size_] = add;
+ size_ += 1;
+}
+
+void TodoList::DeleteItem(unsigned int location) {
+ if ((location > 0) && (location <= size_)) {
+ delete list_[location - 1];
+ list_[location - 1] = nullptr;
+ size_ -= 1;
+ TightenArray(location - 1);
+ }
+}
+
+TodoItem* TodoList::GetItem(int location) {
+ if ((size_ > 0) && (size_ <= cap_) && (list_[location-1] != nullptr)) {
+ return list_[location - 1];
+ }
+ return nullptr;
+}
+
+unsigned int TodoList::GetSize() const {
+ return size_;
+}
+
+unsigned int TodoList::GetCapacity() const {
+ return cap_;
+}
+
+void TodoList::Sort() {
+ for (unsigned int i = 0; i <= (size_ - 1); i++) {
+ int j = i;
+ while ((j > 0) && (list_[j]->priority() < list_[j - 1]->priority())) {
+ std::swap(list_[j], list_[j - 1]);
+ j -= 1;
+ }
+ }
+}
+
+/*
+ Returns a string containing all TodoItems in the list.
+ Uses the TodoItems ToFile function to create. Each item should be
+ on its own line.
+*/
+std::string TodoList::ToFile() {
+ if ((size_ > 0) && (size_ <= cap_)) {
+ std::stringstream all;
+ for (unsigned int i = 0; i < size_; i++) {
+ all << list_[i]->ToFile() << std::endl;
+ }
+ return all.str();
+ }
+ return "";
+}
+
+/* Outputs a numbered list of all TodoItem present in the list. */
+std::ostream &operator << (std::ostream &out, const TodoList &obj) {
+ for (unsigned int i = 0; i < obj.size_; i++) {
+ out << obj.list_[i]->description() << obj.list_[i]->priority()
+ << obj.list_[i]->completed() << std::endl;
+ }
+ return out;
+}
+
+/* PRIVATE */
+/*
+ Increases the capacity of the array by 10. Should be called by
+ AddItem at the appropriate time.
+*/
+void TodoList::IncreaseCap() {
+ cap_ += 10;
+ TodoItem** extend = new TodoItem*[cap_];
+ for (unsigned int i = 0; i < size_; i++) {
+ extend[i] = list_[i];
+ }
+ for (unsigned int i = size_; i < cap_; i++) {
+ extend[i] = nullptr;
+ }
+ delete[] list_;
+ list_ = extend;
+}
+
+/*
+ Compacts the array to get rid of an empty spot in the array.
+ Should be called by DeleteItem at the appropriate time.
+*/
+void TodoList::TightenArray(int start) {
+ for (unsigned int i = start; i < size_; i++) {
+ if (list_[i + 1] != nullptr) {
+ list_[i] = list_[i + 1];
+ }
+ }
+}
diff --git a/c++/3c/todo_list.h b/c++/3c/todo_list.h
@@ -0,0 +1,87 @@
+/*
+ * Name : todo_list.h
+ * Author : Evan Alba
+ * Description : Header File for class TodoList.
+ */
+#ifndef TODO_LIST
+#define TODO_LIST
+#include "todo_item.h"
+#include <algorithm>
+#include <iostream>
+#include <string>
+#include <sstream>
+
+class TodoList {
+ public:
+ /*
+ Creates a dynamic array of 25 elements and initializes the elements
+ to NULL.
+ */
+ TodoList();
+
+ /*
+ Frees the memory for all TodoItems
+ Frees the memory for the dynamic TodoItem* array
+ */
+ ~TodoList();
+
+ /*
+ Add an item to the list.
+ If there is room in the array add the new
+ dynamic instance to the first available spot (i.e. the current size). If
+ the array is full, increase capacity by 10 and then add the item.
+ */
+ void AddItem(TodoItem* add);
+
+ /*
+ Delete a item from the list given the location.
+ Checks first if location valid to delete item from list.
+ Please note the location (area) is in human-readable form, i.e.
+ location 1 is really array index 0. After you delete the item you will
+ need to pack your array (shift all items "down" so there are no
+ empty slots between items).
+ */
+ void DeleteItem(unsigned int location);
+
+ /*
+ Gets an item from the list given the location.
+ Checks first if location valid to get an item from the list.
+ Please note the location is in human-
+ readable form, i.e. location 1 is really array index 0. This function
+ will return a pointer to the TodoItem requested. If that location
+ doesn't exist it returns NULL.
+ */
+ TodoItem* GetItem(int location);
+
+ /*
+ Returns an unsigned integer containing the
+ current size of the list (number of items present).
+ */
+ unsigned int GetSize() const;
+
+ /*
+ Returns an unsigned integer containing the
+ current maximum capacity of the list (number of slots).
+ */
+ unsigned int GetCapacity() const;
+
+ /*
+ Sorts the array by the priorities of the items. (1 is
+ highest priority, 5 is lowest).
+ */
+ void Sort();
+
+
+ std::string ToFile();
+ friend std::ostream& operator << (std::ostream &out, const TodoList &obj);
+
+ private:
+ /* PRIVATE Data for Todo List Class */
+ unsigned int size_; /* Current size of your list. */
+ unsigned int cap_; /* Max capacity of your list. */
+ TodoItem** list_; /* Pointer to TodoItem*. */
+ /* PRIVATE Prototypes for Todo List Class */
+ void IncreaseCap();
+ void TightenArray(int start);
+};
+#endif
diff --git a/c++/3c/todo_ui.cpp b/c++/3c/todo_ui.cpp
@@ -0,0 +1,146 @@
+/*
+* Name : todo_ui.cpp
+* Author : Evan Alba
+* Description : CPP File for class TodoUI.
+*/
+
+#include "todo_ui.h"
+
+TodoUI::TodoUI() {
+ interface_ = new TodoList;
+}
+
+TodoUI::~TodoUI() {
+ delete interface_;
+}
+
+void TodoUI::menu() {
+ std::cout << "Welcome to the console-based Todo List.\n\nPlease type any " <<
+ "integer number to start." << std::endl;
+ reader.readInt();
+ int choice = -1;
+ while (choice != 0) {
+ std::cout <<
+ "Please type a number to select one of the following options below:\n\n"
+ << "0. Exit the program.\n" << "1. Create a new item.\n"
+ << "2. Edit an item.\n" << "3. Delete an item.\n"
+ << "4. Delete all items.\n" << "5. View a specific item.\n"
+ << "6. View all items.\n" << std::endl;
+ choice = reader.readInt();
+ switch (choice) {
+ case 0:
+ choice = 0;
+ break;
+ case 1:
+ NewItem();
+ break;
+ case 2:
+ EditItem();
+ break;
+ case 3:
+ DeleteItem();
+ break;
+ case 4:
+ DeleteItems();
+ break;
+ case 5:
+ ViewItem();
+ break;
+ case 6:
+ ViewItems();
+ break;
+ }
+ }
+}
+
+/* PRIVATE */
+void TodoUI::NewItem() {
+ std::cout << "Please type a description for your item:" << std::endl;
+ std::string desc = reader.readString();
+ std::cout <<
+ "Please type the number from 1-5 (1 = Highest) for your item's priority:"
+ << std::endl;
+ int num = reader.readInt(1, 5);
+ std::cout <<
+ "Has the item been completed?" <<
+ " Please type the word true if the item is completed." <<
+ "If the item is not completed, please type the word false: "
+ << std::endl;
+ bool status = reader.readBool();
+ interface_->AddItem(new TodoItem(desc, num, status));
+}
+
+void TodoUI::EditItem() {
+ if (interface_->GetSize() == 0) {
+ std::cout << "No items on the Todo List to edit.\n" << std::endl;
+ return;
+ }
+ std::cout <<
+ "Please type the number corresponding to the location" <<
+ " of the item you want to edit:"
+ << std::endl;
+ int location = reader.readInt(1, interface_->GetSize());
+ std::cout << "Please type the number corresponding on what part " <<
+ "you want to edit of the item you have chosen. (1 = Description" <<
+ " | 2 = Priority | 3 = Completion Status)\n\n" << std::endl;
+ int option = reader.readInt(1, 3);
+ if (option == 1) {
+ std::cout << "Please type new description you want to set:" << std::endl;
+ std::string desc = reader.readString();
+ interface_->GetItem(location)->set_description(desc);
+ } else if (option == 2) {
+ std::cout << "Please type a new number from 1 to 5 to set the new " <<
+ "priority of the item:" << std::endl;
+ int num = reader.readInt(1, 5);
+ interface_->GetItem(location)->set_priority(num);
+ } else if (option == 3) {
+ std::cout << "Has the item been completed? Please type the word " <<
+ "true if the item is completed. If the item is not completed, " <<
+ "please type the word false:" << std::endl;
+ bool status = reader.readBool();
+ interface_->GetItem(location)->set_completed(status);
+ }
+}
+
+void TodoUI::DeleteItem() {
+ if (interface_->GetSize() == 0) {
+ std::cout << "No items on the Todo List to delete.\n" << std::endl;
+ return;
+ }
+ std::cout << "Please type the location of the item you want to " <<
+ "remove from the Todo List:" << std::endl;
+ int num = reader.readInt(1, interface_->GetSize());
+ interface_->DeleteItem(num);
+}
+
+void TodoUI::DeleteItems() {
+ if (interface_->GetSize() == 0) {
+ std::cout << "No items on the Todo List to delete.\n" << std::endl;
+ return;
+ }
+ std::cout << "All items on the Todo List have been deleted.\n" << std::endl;
+ while (interface_->GetItem(1) != nullptr) {
+ interface_->DeleteItem(1);
+ }
+}
+
+void TodoUI::ViewItem() {
+ std::cout << "Please type the number corresponding to the location " <<
+ "of the item you want to view:" << std::endl;
+ int location = reader.readInt();
+ std::cout << "\nDescription:\n" <<
+ interface_->GetItem(location)->description()
+ << "\nPriority:\n" << interface_->GetItem(location)->priority() <<
+ "\nIs it completed? (1 = True | 2 = False)\n" <<
+ interface_->GetItem(location)->completed() <<
+ "\n\n" << std::endl;
+}
+
+void TodoUI::ViewItems() {
+ if (interface_->GetSize() == 0) {
+ std::cout << "No items on the Todo List to view.\n" << std::endl;
+ return;
+ }
+ std::cout << *interface_ << std::endl;
+}
+
diff --git a/c++/3c/todo_ui.h b/c++/3c/todo_ui.h
@@ -0,0 +1,61 @@
+/*
+* Name : todo_ui.h
+* Author : Evan Alba
+* Description : Header File for class TodoUI.
+*/
+#ifndef TODO_UI
+#define TODO_UI
+#include "CinReader.h"
+#include "todo_item.h"
+#include "todo_list.h"
+#include <iostream>
+#include <string>
+#include <unistd.h>
+#include <term.h>
+class TodoUI {
+ public:
+ /* Create a new Todo List */
+ TodoUI();
+
+ /* Delete the dynamic TodoList and set the pointer to the List to NULL */
+ ~TodoUI();
+
+ /* Display the menu ui to the user and give them the options of:
+ 1. Exiting the program
+ 2. Create a new item
+ 3. Edit an Item
+ 4, Delete all items
+ 5. View a specific item
+ 6. View all items
+ */
+ void menu();
+
+ private:
+ /* Initialize CinReader */
+ CinReader reader;
+ TodoList* interface_;
+
+ /* Create a new item by asking the user the
+ description of the item todo, priority, and
+ if the item on the list has been completed. */
+ void NewItem();
+
+ /* Ask the user what they want to edit a specific item's of the following:
+ Description, Priority, and if it was completed.
+ After that edit the part of the item they want to edit out. */
+ void EditItem();
+
+ /* Allows user to delete a specific item in the Todo List */
+ void DeleteItem();
+
+ /* Deletes all the items in the Todo List. */
+ void DeleteItems();
+
+ /* Prints out a specific item in the Todo List */
+ void ViewItem();
+
+ /* Prints out all the items in the Todo List */
+ void ViewItems();
+};
+#endif
+