summaryrefslogtreecommitdiffstats
path: root/C++/Midterm/Midterm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'C++/Midterm/Midterm.cpp')
-rw-r--r--C++/Midterm/Midterm.cpp280
1 files changed, 280 insertions, 0 deletions
diff --git a/C++/Midterm/Midterm.cpp b/C++/Midterm/Midterm.cpp
new file mode 100644
index 0000000..e79f58e
--- /dev/null
+++ b/C++/Midterm/Midterm.cpp
@@ -0,0 +1,280 @@
+// Name: msglm
+// Date: Oct 3rd, 2022
+// Program Name: Midterm
+// Description: Read in a file, sanitize said file of html tags, output the contents in a format sorted that the user chooses.
+
+//90% of this is self-plagiarism, or as I like to call it, recycled
+//and think, some people get really angry about reuse!
+//I never understood that mentality, it's just absurd to me:
+//just never transfer your copyrights and also put your code
+//under a free software license and this won't be a problem.
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <array>
+#include <iomanip>
+using namespace std;
+
+//Structures
+// Use a struct to:
+// Create an array or vector variable to store a person’s favorite movie
+// Create an array or vector variable to store when the year that movie was released
+// Create an array or vector variable to store the box office gross (total amount of money) it made
+//
+struct Person {
+ vector<string> favMov;
+ vector<string> yearReleased;
+ vector<string> gross;
+};
+
+struct Movie {
+ string favMov;
+ string yearReleased;
+ string gross;
+};
+
+
+//initalizes the file
+
+//with the amount of times I used this function, I have to wonder
+//why I don't end up making my own standard library
+//or code processorsor to catconate some standard stuff
+void initalize(string location, ifstream & fileVar) {
+ fileVar.open(location);
+
+ if (!fileVar) {
+ cout << "ERROR! " << location << " failed to open!";
+ exit(1);
+ }
+}
+
+
+//borrowed code from another assignment
+//
+//it's great that I made this not have any side effects
+//I can just slap this down anywhere I please
+string sanitize(string userInput) {
+ bool insideATag = false;
+ bool metTheTagTerminator = false;
+ int beginBracketPos;
+ int endBracketPos;
+ int tagLength;
+
+ for (int charPos=0; charPos<=userInput.length();charPos++) {
+ if (insideATag && metTheTagTerminator) {
+
+ //Tag length only exists because std::String.erase() doesn't accept
+ //a range, but rather a start and the chars to go. it's accursed.
+ tagLength = (endBracketPos-beginBracketPos)+1;
+ userInput.erase(beginBracketPos, tagLength);
+ charPos = 0;
+ insideATag = false;
+ metTheTagTerminator = false;
+ }
+ if (userInput[charPos] == '<') {
+ insideATag = true;
+ beginBracketPos = charPos;
+ }
+
+ if (userInput[charPos] == '>' && insideATag) {
+ metTheTagTerminator = true;
+ endBracketPos = charPos;
+ }
+
+
+ }
+ return userInput;
+}
+
+
+//takes a file as input and, for every 3 lines, puts it into the movieDataContainer's vectors
+//Will only run if the next line after a set of 3 is not EOF
+//there is no error checking
+Person orderAndAssociateIntoStruct(ifstream & fileVar) {
+ Person movieDataContainer;
+ string temp;
+ int oscillate = 0;
+ int epoch = 0;
+
+ while(getline(fileVar, temp)) {
+ switch (oscillate) {
+ case 0:
+ movieDataContainer.favMov.push_back(sanitize(temp));
+ oscillate++;
+ break;
+ case 1:
+ movieDataContainer.yearReleased.push_back(sanitize(temp));
+ oscillate++;
+ break;
+ case 2:
+ movieDataContainer.gross.push_back(sanitize(temp));
+ epoch++;
+ oscillate = 0;
+ break;
+ if (fileVar.peek() != EOF) {
+ break;
+ }
+ }
+ }
+ return movieDataContainer;
+}
+
+
+//Prints out all the data in a tabular format
+void output(vector<Movie> movieDataContainer) {
+
+ cout << left << setw(16) << "Movie Name" << " ";
+ cout << left << setw(16) << "Year Published" << " ";
+ cout << left << setw(16) << "Gross Box Office" << " ";
+
+ for (Movie movie : movieDataContainer) {
+ cout << endl;
+ cout << left << setw(16) << movie.favMov;
+ cout << left << setw(16) << movie.yearReleased;
+ cout << left << setw(16) << movie.gross;
+ }
+ cout << endl;
+ }
+
+
+//Bubble sort implementations
+//
+//depending on the menu option selected, this will sort by different values
+//The movieList is read for all the movie structs in it, those struct's values
+//are what are read when sorting happens. Depending on if the sorting deemes the values
+//greater or lesser, the swapping of the movie struct itself will happen
+//
+//It took many hours in gdb to discover that this function had a bug due to
+//movieList.size() returning 5 instead of 4 if 4 movie structs are in movieList
+//
+//The experience of debugging C++ seg faults is only comparable to one thing: passing a kidney stone;
+//It takes 3 hours of your life away, it's painful, and by the end of it, you'll be bleeding out of places
+//you never thought you could bleed out of.
+//
+//The only upside to debugging C++ code is that it doesn't bill your insurance...
+//well, it does end up billing it later on when the blood pressure problems start setting in, but right now that's not my problem.
+vector<Movie> sort(vector<Movie> movieList, int menuOption) {
+ Movie temp;
+ switch(menuOption) {
+ case 1:
+ for (int pos = 0; pos < movieList.size() - 1; pos++) {
+ for (int comparePos = 0; comparePos < ((movieList.size() - 1) - pos); comparePos++) {
+ if(movieList[comparePos].favMov > movieList[comparePos + 1].favMov) {
+ temp = movieList[comparePos];
+ movieList[comparePos] = movieList[comparePos + 1];
+ movieList[comparePos + 1] = temp;
+ }
+ }
+ }
+ break;
+ case 2:
+ for (int pos = 0; pos < movieList.size() - 1; pos++) {
+ for (int comparePos = 0; comparePos < ((movieList.size() - 1) - pos); comparePos++) {
+ if(stof(movieList[comparePos].yearReleased) > stof(movieList[comparePos + 1].yearReleased)) {
+ temp = movieList[comparePos];
+ movieList[comparePos] = movieList[comparePos + 1];
+ movieList[comparePos + 1] = temp;
+ }
+ }
+ }
+ break;
+ case 3:
+ for (int pos = 0; pos < movieList.size() - 1; pos++) {
+ for (int comparePos = 0; comparePos < ((movieList.size() - 1) - pos); comparePos++) {
+ if(stof(movieList[comparePos].gross) > stof(movieList[comparePos + 1].gross)) {
+ temp = movieList[comparePos];
+ movieList[comparePos] = movieList[comparePos + 1];
+ movieList[comparePos + 1] = temp;
+ }
+ }
+ }
+ break;
+ }
+ return movieList;
+}
+
+//just a simple menu. returns a number because I don't feel like dealing with flags
+int menuOption() {
+ int choice;
+ //No input validation here since the rubric doesn't call for it.
+ cout << "1. Sort by Movie Name\n";
+ cout << "2. Sort by Year Released\n";
+ cout << "3. Sort by Box office gross\n";
+ cout << "Enter Selection: ";
+ cin >> choice;
+ return choice;
+}
+
+//effectively inverts the person struct
+//instead of being a struct with vectors in it, it's a vector with structs in it
+//and those structs hold data about an individual movie
+//
+//This is achieved using a similar algorithm to reading in the file
+vector<Movie> person2MovieList(Person person) {
+
+ vector<Movie> personsMovieList;
+ int oscillate = 0;
+ string tempfavMov;
+ string tempyearReleased;
+ string tempGross;
+
+ int moviePos = 0;
+ //Since gross and year release are associated with movie, we can assume
+ //that for every movie, there should be a gross and year release.
+ //
+ //If this was in production, some type of check would be ran to ensure this
+ while(moviePos < person.favMov.size()) {
+ switch (oscillate){
+ case 0:
+ tempfavMov = person.favMov[moviePos];
+ oscillate++;
+ break;
+ case 1:
+ tempyearReleased = person.yearReleased[moviePos];
+ oscillate++;
+ break;
+ case 2:
+ tempGross = person.gross[moviePos];
+ oscillate = 0;
+ personsMovieList.push_back( Movie() );
+ personsMovieList[moviePos].favMov = tempfavMov;
+ personsMovieList[moviePos].yearReleased = tempyearReleased;
+ personsMovieList[moviePos].gross = tempGross;
+ moviePos++;
+ break;
+ }
+ }
+ return personsMovieList;
+
+}
+
+int main() {
+ //Variable declaration
+ ifstream data;
+
+ initalize("input.txt", data);
+ Person organizedMovieData = orderAndAssociateIntoStruct(data);
+ //This current data structure makes the sorting section a nightmare.
+ //this is due to the lack of a hard associations between the movie's name, year of release, and gross profit
+ //
+ //I somehow must associate those three variables despite them being in an array
+ //Instead of using an accursed flag system to accomplish this, I will instead opt to
+ //just convert the data in the Person struct into a vector of Movie Structs
+ //this way, the order of the struct may be managed much more simply
+
+ vector<Movie> personsMovieList = person2MovieList(organizedMovieData);
+ output(sort(personsMovieList, menuOption()));
+
+ data.close();
+
+}
+
+/*
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 ONLY as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */