languages

A collection of programs made with different programming languages.
git clone git://evanalba.com/languages
Log | Files | Refs

commit bd329151ff09ea9a14a7d2eec3b266ee1e03cbee
parent bddf7e7c68e459a357547059e5f363fa77dd8fa2
Author: Evan Alba <evanalba@protonmail.com>
Date:   Wed, 28 Dec 2022 23:41:25 -0800

feat: Added C++ directory.

Diffstat:
Ac++/3c/CinReader.cpp | 406+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/CinReader.h | 244+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/assignment_3.dSYM/Contents/Info.plist | 20++++++++++++++++++++
Ac++/3c/assignment_3.dSYM/Contents/Resources/DWARF/assignment_3 | 0
Ac++/3c/assignment_3_unit_test.cpp | 337+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/driver.cpp | 11+++++++++++
Ac++/3c/makefile | 43+++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/todo_item.cpp | 34++++++++++++++++++++++++++++++++++
Ac++/3c/todo_item.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/todo_list.cpp | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/todo_list.h | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/todo_ui.cpp | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ac++/3c/todo_ui.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 +