Adding exam part 1/4
This commit is contained in:
49
Exam/part1/CMakeLists.txt
Normal file
49
Exam/part1/CMakeLists.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
project(part1)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# "ON" = build Option 1, "OFF" = build Option 2.
|
||||
option(BUILD_ASSIGNMENT_01_OPTION_1 "Build Assignment Option 1 (Standard)" ON)
|
||||
|
||||
add_executable(Assignment-01
|
||||
main.cpp
|
||||
option1.cpp
|
||||
option2.cpp
|
||||
Song.h
|
||||
TDoublyLinkedList.cpp
|
||||
TDoublyLinkedList.h
|
||||
TStack.cpp
|
||||
TStack.h
|
||||
TQueue.cpp
|
||||
TQueue.h
|
||||
Utils.cpp
|
||||
Utils.h
|
||||
)
|
||||
|
||||
# Conditionally add the correct source file
|
||||
if(BUILD_ASSIGNMENT_01_OPTION_1)
|
||||
# If ON, add option1.cpp and define 'ASSIGNMENT_OPTION=1' for C++
|
||||
target_sources(Assignment-01
|
||||
PRIVATE
|
||||
option1.cpp
|
||||
option1.h
|
||||
)
|
||||
target_compile_definitions(Assignment-01 PRIVATE "ASSIGNMENT_01_OPTION=1")
|
||||
else()
|
||||
# If OFF, add option2.cpp and define 'ASSIGNMENT_OPTION=2' for C++
|
||||
target_sources(Assignment-01
|
||||
PRIVATE
|
||||
option2.cpp
|
||||
option2.h
|
||||
)
|
||||
target_compile_definitions(Assignment-01 PRIVATE "ASSIGNMENT_01_OPTION=2")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
add_custom_command(TARGET Assignment-01 POST_BUILD
|
||||
# Add a custom command here if needed
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Assignment-01 post-build step"
|
||||
)
|
||||
100
Exam/part1/SharedLib.h
Normal file
100
Exam/part1/SharedLib.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
#ifndef SHARED_LIB_H
|
||||
#define SHARED_LIB_H
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type for processing a name read from a file.
|
||||
/// </summary>
|
||||
/// <param name="aIndex">The index of the name (0-based).</param>
|
||||
/// <param name="aTotalCount">The total number of names.</param>
|
||||
/// <param name="aFirstName">The first name read from the file.</param>
|
||||
/// <param name="aLastName">The last name read from the file.</param>
|
||||
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||
typedef bool (*FNameRead)(
|
||||
const int aIndex,
|
||||
const int aTotalCount,
|
||||
const std::string& aFirstName,
|
||||
const std::string& aLastName
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Use this function to read names from a specified file and process them using a callback function.
|
||||
/// </summary>
|
||||
/// <function>readNamesFromFile</function>
|
||||
/// <description>Reads names from a specified file and invokes a callback for each name read.</description>
|
||||
/// <param name="aFilename">The path to the file containing names.</param>
|
||||
/// <param name="aOnNameRead">A callback function that is called for each name read. It takes two parameters: firstName and lastName. If the callback returns false, the reading process stops.</param>
|
||||
/// <param name="firstName">The first name read from the file.</param>
|
||||
/// <param name="lastName">The last name read from the file.</param>
|
||||
/// <returns>None.</returns>
|
||||
void readNamesFromFile(const std::string& aFilename, FNameRead aOnNameRead);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type for processing a node read from the file.
|
||||
/// </summary>
|
||||
/// <description>Function pointer type for a callback that processes nodes read from a file.</description>
|
||||
/// <param name="aIndex">The index of the node (0-based).</param>
|
||||
/// <param name="aTotalCount">The total number of nodes.</param>
|
||||
/// <param name="aNode">The node std::string.</param>
|
||||
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||
typedef bool (*FNodeRead)(const int aIndex, const int aTotalCount, const std::string& aNode);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type for processing an edge read from the file.
|
||||
/// </summary>
|
||||
/// <description>Function pointer type for a callback that processes edges read from a file.</description>
|
||||
/// <param name="aIndex">The index of the edge (0-based).</param>
|
||||
/// <param name="aTotalCount">The total number of edges.</param>
|
||||
/// <param name="aFromNode">The from node std::string.</param>
|
||||
/// <param name="aToNode">The to node std::string.</param>
|
||||
/// <param name="aWeight">The weight of the edge.</param>
|
||||
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||
typedef bool (*FEdgeRead)(const int aIndex, const int aTotalCount, const std::string& aFromNode, const std::string& aToNode, float aWeight);
|
||||
|
||||
/// </summary>
|
||||
/// Use this function to read a graph from a specified file and process its nodes and edges using callback functions.
|
||||
/// </summary>
|
||||
/// <function>readGraphFromFile</function>
|
||||
/// <description>
|
||||
/// Reads a graph from a specified file and invokes callbacks for each node and edge read.
|
||||
/// All nodes are read first, followed by edges.
|
||||
/// </description>
|
||||
/// <param name="aFilename">The path to the file containing the graph data.</param>
|
||||
/// <param name="aOnNodeRead">A callback function that is called for each node read. It takes one parameter: the node std::string. If the callback returns false, the reading process stops.</param>
|
||||
/// <param name="aOnEdgeRead">A callback function that is called for each edge read. It takes three parameters: the fromNode std::string, the toNode std::string, and the weight float. If the callback returns false, the reading process stops.</param>
|
||||
void readGraphFromFile(const std::string& aFilename, FNodeRead aOnNodeRead, FEdgeRead aOnEdgeRead);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Delegate type for processing a song read from the file.
|
||||
/// </summary>
|
||||
/// <param name="aIndex">The index of the song (0-based).</param>
|
||||
/// <param name="aTotalCount">The total number of songs.</param>
|
||||
/// <param name="aArtist">The artist.</param>
|
||||
/// <param name="aTitle">The title.</param>
|
||||
/// <param name="aYear">The release year (as a std::string).</param>
|
||||
/// <param name="aGenre">The genre.</param>
|
||||
/// <param name="aSource">The source.</param>
|
||||
/// <returns>Returns true to continue reading, false to stop.</returns>
|
||||
typedef bool (*FSongRead)(
|
||||
const int aIndex,
|
||||
const int aTotalCount,
|
||||
const std::string& aArtist,
|
||||
const std::string& aTitle,
|
||||
const std::string& aYear,
|
||||
const std::string& aGenre,
|
||||
const std::string& aSource
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Reads song data from a file and processes them using a callback.
|
||||
/// This function automatically skips the "records:=" header.
|
||||
/// </summary>
|
||||
/// <param name="aFilename">The path to the file (e.g., "songs.txt").</param>
|
||||
/// <param name="aOnSongRead">The callback function called for each song.</param>
|
||||
void ReadSongsFromFile(const std::string& aFilename, FSongRead aOnSongRead);
|
||||
|
||||
|
||||
#endif // SHARED_LIB_H
|
||||
41
Exam/part1/Song.h
Normal file
41
Exam/part1/Song.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
struct TSong
|
||||
{
|
||||
std::string title;
|
||||
std::string artist;
|
||||
|
||||
TSong(std::string aTitle, std::string aArtist)
|
||||
: title(aTitle), artist(aArtist) {
|
||||
}
|
||||
};
|
||||
|
||||
// TMusicPlayerApp.h
|
||||
#pragma once
|
||||
#include "TLinkedList.hpp"
|
||||
#include "TQueue.hpp"
|
||||
#include "TStack.hpp"
|
||||
#include "TSong.h"
|
||||
#include <string>
|
||||
|
||||
class TMusicPlayerApp
|
||||
{
|
||||
private:
|
||||
// Attributes
|
||||
TLinkedList<TSong*> mSongLibrary;
|
||||
TQueue<TSong*> mMainQueue;
|
||||
TQueue<TSong*> mWishQueue;
|
||||
TStack<TSong*> mHistoryStack;
|
||||
|
||||
// Private helper for loading
|
||||
void LoadLibrary(const std::string& aFilename);
|
||||
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
TMusicPlayerApp(const std::string& aSongFilename);
|
||||
~TMusicPlayerApp(); // Will be empty, destructors of attributes handle it
|
||||
|
||||
// Public API for RunApp() to call
|
||||
// ... (we will define these next)
|
||||
};
|
||||
112
Exam/part1/TDoublyLinkedList.cpp
Normal file
112
Exam/part1/TDoublyLinkedList.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "TDoublyLinkedList.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void TDoublyLinkedList::Append(const std::string& line)
|
||||
{
|
||||
auto* newNode = new Node(line);
|
||||
if (size == 0)
|
||||
head = tail = newNode;
|
||||
else {
|
||||
newNode->SetPrev(tail);
|
||||
tail->SetNext(newNode);
|
||||
tail = newNode;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
|
||||
void TDoublyLinkedList::Prepend(const std::string& line)
|
||||
{
|
||||
auto* newNode = new Node(line);
|
||||
if (size == 0)
|
||||
head = tail = newNode;
|
||||
else {
|
||||
newNode->SetNext(head);
|
||||
head->SetPrev(newNode);
|
||||
head = newNode;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
|
||||
TDoublyLinkedList::Node* TDoublyLinkedList::NavigateToNode(const int index) const
|
||||
{
|
||||
if (index < 0 || index >= size)
|
||||
return nullptr;
|
||||
|
||||
auto* node = head;
|
||||
|
||||
for (int i = 0; i < index; i++)
|
||||
node = node->GetNext();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void TDoublyLinkedList::Remove(const int index)
|
||||
{
|
||||
auto* node = NavigateToNode(index);
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
if (node->GetPrev())
|
||||
node->GetPrev()->SetNext(node->GetNext());
|
||||
else
|
||||
head = node->GetNext();
|
||||
if (node->GetNext())
|
||||
node->GetNext()->SetPrev(node->GetPrev());
|
||||
else
|
||||
tail = node->GetPrev();
|
||||
|
||||
delete node;
|
||||
size--;
|
||||
}
|
||||
|
||||
std::string TDoublyLinkedList::GetAtIndex(const int index) const
|
||||
{
|
||||
const auto* node = NavigateToNode(index);
|
||||
return node ? node->GetLine() : "Error, line does not exist\n";
|
||||
}
|
||||
|
||||
void TDoublyLinkedList::InsertAtIndex(const int index, const std::string &line)
|
||||
{
|
||||
if (index < 0 || index > size) {
|
||||
std::cout << "========\nIndex doesn't exist\n========\n" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (index == 0)
|
||||
{
|
||||
Prepend(line);
|
||||
return;
|
||||
}
|
||||
if (index == size)
|
||||
{
|
||||
Append(line);
|
||||
return;
|
||||
}
|
||||
Node* cur = head;
|
||||
for (int i = 0; i < index; i++)
|
||||
cur = cur->GetNext();
|
||||
Node* newNode = new Node(line);
|
||||
Node* prev = cur->GetPrev();
|
||||
|
||||
newNode->SetPrev(prev);
|
||||
newNode->SetNext(cur);
|
||||
|
||||
prev->SetNext(newNode);
|
||||
cur->SetPrev(newNode);
|
||||
|
||||
size++;
|
||||
}
|
||||
|
||||
|
||||
int TDoublyLinkedList::GetSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
67
Exam/part1/TDoublyLinkedList.h
Normal file
67
Exam/part1/TDoublyLinkedList.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef PART1_TDOUBLYLINKEDLIST_H
|
||||
#define PART1_TDOUBLYLINKEDLIST_H
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
|
||||
class TDoublyLinkedList {
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
std::string line;
|
||||
Node* next;
|
||||
Node* prev;
|
||||
explicit Node(std::string text) : line(std::move(text)), next(nullptr), prev(nullptr) {}
|
||||
|
||||
void SetNext(Node* node)
|
||||
{
|
||||
this->next = node;
|
||||
}
|
||||
void SetPrev(Node* node)
|
||||
{
|
||||
this->prev = node;
|
||||
}
|
||||
[[nodiscard]] Node* GetPrev() const
|
||||
{
|
||||
return this->prev;
|
||||
}
|
||||
[[nodiscard]] Node* GetNext() const
|
||||
{
|
||||
return this->next;
|
||||
}
|
||||
[[nodiscard]] std::string GetLine() const
|
||||
{
|
||||
return line;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Node* head;
|
||||
Node* tail;
|
||||
int size;
|
||||
|
||||
|
||||
public:
|
||||
TDoublyLinkedList() : head(nullptr), tail(nullptr), size(0) {}
|
||||
~TDoublyLinkedList() = default;
|
||||
|
||||
void Append(const std::string &line);
|
||||
void Prepend(const std::string& line);
|
||||
[[nodiscard]] Node* NavigateToNode(int index) const;
|
||||
void Remove(int index);
|
||||
[[nodiscard]] std::string GetAtIndex(int index) const;
|
||||
void InsertAtIndex(int index, const std::string &line);
|
||||
[[nodiscard]] int GetSize() const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PART1_TDOUBLYLINKEDLIST_H
|
||||
47
Exam/part1/TQueue.cpp
Normal file
47
Exam/part1/TQueue.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "TQueue.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
void TQueue::Enqueue(const std::string& text)
|
||||
{
|
||||
if (IsFull())
|
||||
throw std::overflow_error("Queue Overflow");
|
||||
queue[tail] = text;
|
||||
tail = (tail + 1) % MAX_SIZE;
|
||||
count++;
|
||||
}
|
||||
|
||||
std::string TQueue::Dequeue()
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::underflow_error("Empty Queue");
|
||||
const std::string item = queue[head];
|
||||
head = (head + 1) % MAX_SIZE;
|
||||
count--;
|
||||
return item;
|
||||
}
|
||||
|
||||
std::string TQueue::Peek() const
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::underflow_error("Empty Queue");
|
||||
return queue[head];
|
||||
}
|
||||
|
||||
bool TQueue::IsEmpty() const
|
||||
{
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
bool TQueue::IsFull() const
|
||||
{
|
||||
return count == MAX_SIZE;
|
||||
}
|
||||
|
||||
int TQueue::GetTail() const
|
||||
{
|
||||
if (IsEmpty())
|
||||
throw std::underflow_error("Empty Queue");
|
||||
return tail;
|
||||
}
|
||||
28
Exam/part1/TQueue.h
Normal file
28
Exam/part1/TQueue.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef PART1_TQUEUE_H
|
||||
#define PART1_TQUEUE_H
|
||||
#define MAX_SIZE 100
|
||||
|
||||
#include "TDoublyLinkedList.h"
|
||||
|
||||
|
||||
class TQueue {
|
||||
private:
|
||||
std::string queue[MAX_SIZE];
|
||||
int head = 0;
|
||||
int tail = 0;
|
||||
int count = 0;
|
||||
|
||||
public:
|
||||
TQueue() = default;
|
||||
~TQueue() = default;
|
||||
|
||||
void Enqueue(const std::string& text);
|
||||
std::string Dequeue();
|
||||
[[nodiscard]] int GetTail() const;
|
||||
[[nodiscard]] std::string Peek() const;
|
||||
[[nodiscard]] bool IsEmpty() const;
|
||||
[[nodiscard]] bool IsFull() const;
|
||||
};
|
||||
|
||||
|
||||
#endif //PART1_TQUEUE_H
|
||||
36
Exam/part1/TStack.cpp
Normal file
36
Exam/part1/TStack.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "TStack.h"
|
||||
#include <stdexcept>
|
||||
|
||||
void TStack::Push(const TAction& action)
|
||||
{
|
||||
if (top >= STACK_MAX_SIZE)
|
||||
throw std::overflow_error("Stack overflow");
|
||||
event[top++] = action;
|
||||
}
|
||||
|
||||
TStack::TAction TStack::Pop()
|
||||
{
|
||||
if (top == 0)
|
||||
throw std::underflow_error("Stack empty");
|
||||
return event[--top];
|
||||
}
|
||||
|
||||
TStack::TAction TStack::Peek() const
|
||||
{
|
||||
if (top == 0)
|
||||
throw std::underflow_error("Stack empty");
|
||||
return event[top - 1];
|
||||
}
|
||||
|
||||
bool TStack::IsEmpty() const
|
||||
{
|
||||
return top == 0;
|
||||
}
|
||||
|
||||
void TStack::Clear()
|
||||
{
|
||||
for (int i = 0; i < top; i++) {
|
||||
this->Pop();
|
||||
}
|
||||
}
|
||||
|
||||
37
Exam/part1/TStack.h
Normal file
37
Exam/part1/TStack.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef PART1_TSTACK_H
|
||||
#define PART1_TSTACK_H
|
||||
|
||||
#define STACK_MAX_SIZE 100
|
||||
#include <string>
|
||||
|
||||
|
||||
enum EnumActionType {
|
||||
INSERT,
|
||||
DELETE
|
||||
};
|
||||
|
||||
class TStack {
|
||||
private:
|
||||
struct TAction {
|
||||
EnumActionType action;
|
||||
std::string text;
|
||||
int index;
|
||||
};
|
||||
|
||||
TAction event[STACK_MAX_SIZE]{};
|
||||
int top = 0;
|
||||
|
||||
public:
|
||||
TStack() = default;
|
||||
~TStack() = default;
|
||||
|
||||
void Push(const TAction& action);
|
||||
TAction Pop();
|
||||
[[nodiscard]] TAction Peek() const;
|
||||
[[nodiscard]] bool IsEmpty() const;
|
||||
void Clear();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PART1_TSTACK_H
|
||||
78
Exam/part1/Utils.cpp
Normal file
78
Exam/part1/Utils.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "Utils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
#include "TDoublyLinkedList.h"
|
||||
#include "TStack.h"
|
||||
|
||||
|
||||
int Utils::Choice()
|
||||
{
|
||||
std::cout << "========\n1. Add line\n2. Remove line\n3. Print current document\n4. Print queue\n5. Undo\n6. Redo\n0. Exit"
|
||||
"\n\nChoice: ";
|
||||
int choice;
|
||||
std::cin >> choice;
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
//std::cout << "\n=====================\n";
|
||||
return choice;
|
||||
}
|
||||
|
||||
int Utils::Insert(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index)
|
||||
{
|
||||
for (int i = 0; i < document.GetSize(); i++) {
|
||||
std::cout << i + 1 << ". " << document.GetAtIndex(i) << std::endl;
|
||||
}
|
||||
if (document.GetSize() > 0)
|
||||
{
|
||||
std::cout << "Enter the line number where you want to insert the line" <<std::endl;
|
||||
if (!(std::cin >> index)) {
|
||||
std::cin.clear();
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
std::cout << "========\nIndex must be a number\n========\n\n" << std::endl;
|
||||
return index;
|
||||
}
|
||||
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
}
|
||||
if (document.GetSize() < 1)
|
||||
index = 1;
|
||||
|
||||
std::cout << "Enter the text" <<std::endl;
|
||||
std::string line;
|
||||
std::getline(std::cin, line);
|
||||
|
||||
|
||||
document.InsertAtIndex(index - 1, line);
|
||||
undoStack.Push({INSERT, line, index - 1});
|
||||
if (!redoStack.IsEmpty()) {
|
||||
redoStack.Clear();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void Utils::PrintList(const TDoublyLinkedList &document)
|
||||
{
|
||||
for (int i = 0; i < document.GetSize(); i++) {
|
||||
std::cout << i + 1 << ". " << document.GetAtIndex(i) << std::endl;
|
||||
}
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
|
||||
int Utils::RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index)
|
||||
{
|
||||
std::cout << "Enter the number of the line you want to remove" <<std::endl;
|
||||
if (!(std::cin >> index)) {
|
||||
std::cin.clear();
|
||||
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
std::cout << "========\nIndex must be a number\n========\n\n" << std::endl;
|
||||
return index;
|
||||
} std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
const std::string deletedLine = document.GetAtIndex(index-1);
|
||||
document.Remove(index-1);
|
||||
undoStack.Push({DELETE, deletedLine, index-1});
|
||||
if (!redoStack.IsEmpty()) {
|
||||
redoStack.Clear();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
26
Exam/part1/Utils.h
Normal file
26
Exam/part1/Utils.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef PART1_UTILS_H
|
||||
#define PART1_UTILS_H
|
||||
#include "TDoublyLinkedList.h"
|
||||
#include "TStack.h"
|
||||
|
||||
|
||||
class Utils {
|
||||
public:
|
||||
static int Choice();
|
||||
static int Insert(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
||||
static void PrintList(const TDoublyLinkedList &document);
|
||||
static int RemoveLine(TDoublyLinkedList &document, TStack &undoStack, TStack &redoStack, int index);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PART1_UTILS_H
|
||||
57
Exam/part1/main.cpp
Normal file
57
Exam/part1/main.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Mandatory-02.cpp : Defines the entry point for the application.
|
||||
//
|
||||
|
||||
/*
|
||||
Dear Student,
|
||||
|
||||
Remember to follow the coding standards and best practices discussed
|
||||
in the portfolio assignment document.
|
||||
Good luck with your portfolio!
|
||||
|
||||
NB: Do not delete the code below that prints the assignment and option info!
|
||||
|
||||
---------------------------------------------------------------------
|
||||
*** HOW TO SWITCH BETWEEN OPTION 1 AND OPTION 2 ***
|
||||
---------------------------------------------------------------------
|
||||
You CANNOT switch options by changing this file.
|
||||
|
||||
1. Go to the 'CMakeLists.txt' file for this assignment.
|
||||
2. Find the line:
|
||||
option(BUILD_ASSIGNMENT_OPTION_1 "..." ON)
|
||||
3. Change 'ON' (for Option 1) to 'OFF' (for Option 2).
|
||||
|
||||
*** VERY IMPORTANT: After changing the option ***
|
||||
Your project will NOT update until you re-run the CMake configuration.
|
||||
|
||||
To force an update (e.g., in Visual Studio):
|
||||
- Right-click the 'CMakeLists.txt' file and select 'Configure Cache'.
|
||||
- OR, simply delete the 'out' / 'build' folder and rebuild the project.
|
||||
---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
|
||||
static constexpr std::string_view AssignmentName = "Category 1: Lists, Stacks, & Queues";
|
||||
|
||||
#if ASSIGNMENT_01_OPTION == 1
|
||||
#include "option1.h"
|
||||
static constexpr std::string_view AssignmentOption = "Option 1 (Standard): Console Text Editor.";
|
||||
#elif ASSIGNMENT_01_OPTION == 2
|
||||
#include "option2.h"
|
||||
static constexpr std::string_view AssignmentOption = "Option 2 (Advanced): Console Music Player.";
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int appStatus = 0;
|
||||
std::cout << AssignmentName << std::endl;
|
||||
std::cout << AssignmentOption << std::endl;
|
||||
|
||||
// Create only core or common code in main.cpp
|
||||
// Use the option header files to implement the specific assignment option logic
|
||||
appStatus = RunApp();
|
||||
return appStatus;
|
||||
}
|
||||
114
Exam/part1/option1.cpp
Normal file
114
Exam/part1/option1.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
// Option 1 (Standard): Console Text Editor.
|
||||
//
|
||||
|
||||
#include "option1.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
|
||||
#include "TDoublyLinkedList.h"
|
||||
#include "TQueue.h"
|
||||
#include "TStack.h"
|
||||
#include "Utils.h"
|
||||
|
||||
TDoublyLinkedList document;
|
||||
TQueue printQueue;
|
||||
TStack undoStack, redoStack;
|
||||
|
||||
bool running = true;
|
||||
int lastIndex = 0;
|
||||
std::string deletedLine;
|
||||
|
||||
void Undo()
|
||||
{
|
||||
if (!undoStack.IsEmpty()) {
|
||||
const auto action = undoStack.Pop();
|
||||
if (action.action == INSERT){
|
||||
document.Remove(action.index);
|
||||
}
|
||||
else{
|
||||
document.InsertAtIndex(action.index, action.text);
|
||||
}
|
||||
redoStack.Push(action);
|
||||
}
|
||||
}
|
||||
void Redo()
|
||||
{
|
||||
if (!redoStack.IsEmpty()) {
|
||||
const auto action = redoStack.Pop();
|
||||
if (action.action == INSERT) {
|
||||
document.InsertAtIndex(action.index, action.text);
|
||||
}
|
||||
else {
|
||||
document.Remove(action.index);
|
||||
}
|
||||
undoStack.Push(action);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int RunApp()
|
||||
{
|
||||
// Implement the Console Text Editor application logic here
|
||||
while (running) {
|
||||
switch (Utils::Choice()) {
|
||||
case 1: {
|
||||
std::cout << "----------Add line----------" << std::endl;
|
||||
lastIndex = Utils::Insert(document, undoStack, redoStack, lastIndex);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::cout << "----------Remove line----------" << std::endl;
|
||||
Utils::PrintList(document);
|
||||
lastIndex = Utils::RemoveLine(document, undoStack, redoStack, lastIndex);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
std::cout << "----------Current document----------" << std::endl;
|
||||
for (int i = 0; i < document.GetSize(); i++)
|
||||
std::cout << i + 1 << ". " << document.GetAtIndex(i) << std::endl;
|
||||
std::cout << "------------------------------------\n\n";
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: {
|
||||
for (int i = 0; i < document.GetSize(); ++i)
|
||||
printQueue.Enqueue(document.GetAtIndex(i));
|
||||
|
||||
std::cout << "----------Printing queue-----------" << std::endl;
|
||||
|
||||
while (!printQueue.IsEmpty())
|
||||
std::cout << printQueue.Dequeue() << std::endl;
|
||||
std::cout << "------------------------------------\n\n";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
std::cout << "----------UNDO----------" <<std::endl;
|
||||
Undo();
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
std::cout << "----------REDO----------" <<std::endl;
|
||||
Redo();
|
||||
break;
|
||||
}
|
||||
|
||||
case 0: {
|
||||
std::cout << "----------Exiting...----------" << std::endl;
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
std::cout << "Invalid input, please pick a number..." << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
17
Exam/part1/option1.h
Normal file
17
Exam/part1/option1.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// option1.h : Option 1 (Standard): Console Text Editor.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef OPTION1_H
|
||||
#define OPTION1_H
|
||||
|
||||
int RunApp();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // OPTION1_H
|
||||
20
Exam/part1/option2.cpp
Normal file
20
Exam/part1/option2.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Option 2 (Advanced): Console Music Player.
|
||||
|
||||
#include <iostream>
|
||||
#include "option2.h"
|
||||
#include "SharedLib.h"
|
||||
|
||||
static bool SongReadCallback(const int aIndex, const int aTotalCount, const std::string& aArtist, const std::string& aTitle, const std::string& aYear, const std::string& aGenre, const std::string& aSource) {
|
||||
// Implement the logic to process each song read from the file
|
||||
// For example, print the song details to the console
|
||||
std::cout << "Song " << (aIndex + 1) << " of " << aTotalCount << ":\n";
|
||||
std::cout << " Artist: " << aArtist << "\n";
|
||||
std::cout << " Title: " << aTitle << "\n";
|
||||
std::cout << " Year: " << aYear << "\n";
|
||||
std::cout << " Genre: " << aGenre << "\n";
|
||||
std::cout << " Source: " << aSource << "\n\n";
|
||||
// Return true to continue reading more songs
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
10
Exam/part1/option2.h
Normal file
10
Exam/part1/option2.h
Normal file
@@ -0,0 +1,10 @@
|
||||
// option1.h : Option 2 (Advanced): Console Music Player.
|
||||
#pragma once
|
||||
|
||||
#ifndef OPTION2_H
|
||||
#define OPTION2_H
|
||||
|
||||
//int RunApp();
|
||||
|
||||
|
||||
#endif // OPTION2_H
|
||||
Reference in New Issue
Block a user