Commit 778aea04 authored by Stojcheska Teodora's avatar Stojcheska Teodora
Browse files

Add task modified - delete not functional and exception not functional

parent ee501bb9
......@@ -7,28 +7,26 @@ public class Calendar
{
public List<Day> days { get; set; }
// make an indexer for tasks ind day
public List<Task> allTasks { get; set; }
public DateTime currentDate { get; set; }
public int defaultWorkingHoursInterval { get; set; }
public (int, int) defaultWorkingHoursInterval { get; set; }
public int defaultWorkingHours { get; set; }
public Calendar()
{
this.days = new List<Day>();
this.allTasks = new List<Task>();
this.currentDate = DateTime.Now; // format dd.mm.yyyy hh:mm:ss
}
public Calendar(List<Day> days, List<Task> allTasks)
public Calendar(List<Day> days)
{
this.days = days;
this.allTasks = allTasks;
this.currentDate = DateTime.Now; // format dd.mm.yyyy hh:mm:ss
}
// TODO: Check the case when we add a task for today since this function will be returning 0
private int numberOfDaysInRange(DateTime startingDate, DateTime endDate) => (endDate.Date - startingDate.Date).Days + 1;
private bool isDateValid(DateTime startingDate, DateTime endDate) => numberOfDaysInRange(startingDate, endDate) >= 0;
private bool isDateValid(DateTime startingDate, DateTime endDate) => numberOfDaysInRange(startingDate, endDate) > 0;
private bool shouldAddDay(Task task) => days[days.Count - 1].hoursToShift * -1 < task.duration;
......@@ -38,15 +36,17 @@ public class Calendar
// TODO: don't add just one day, but add days according to the duration of the task
Day newDay;
if (days.Count == 0) {
newDay = new Day(currentDate, new List<Task>(), defaultWorkingHoursInterval, defaultWorkingHoursInterval);
if (days.Count == 0)
{
newDay = new Day(currentDate, new List<Task>(), defaultWorkingHoursInterval, defaultWorkingHours);
days.Add(newDay);
validDays.Add(newDay);
return validDays;
}
if (shouldAddDay(task)) {
newDay = new Day(days[days.Count - 1].date.AddDays(1), new List<Task>(), defaultWorkingHoursInterval, defaultWorkingHoursInterval);
if (shouldAddDay(task))
{
newDay = new Day(days[days.Count - 1].date.AddDays(1), new List<Task>(), defaultWorkingHoursInterval, defaultWorkingHours);
newDay.prevDay = days[days.Count - 1];
days[days.Count - 1].nextDay = newDay;
days.Add(newDay);
......@@ -54,7 +54,7 @@ public class Calendar
int numberOfValidDaysInRange = numberOfDaysInRange(currentDate, task.deadline);
if(numberOfValidDaysInRange == 0)
if (numberOfValidDaysInRange == 0)
{
WriteLine("The date is not valid!");
}
......@@ -71,27 +71,156 @@ public class Calendar
return validDays;
}
public bool isThereEnoughSpace(List<Day> validDays, Task task) {
// check how much hours are left in the day
int hoursLeft = validDays[validDays.Count - 1].workingHours - validDays[validDays.Count - 1].totalHoursTasks();
int hours = task.duration - hoursLeft;
if (hours <= 0) { return true; }
for(int i = validDays.Count - 1; i >= 0; --i) {
for(int j = validDays[i].tasks.Count - 1; j >= 0; --j) {
// start date end date
if(numberOfDaysInRange(task.deadline, validDays[i].tasks[j].deadline) > 0) {
hours -= task.duration;
public void handleException(Day day, Task task)
{
WriteLine("There is no space to add the task with there parameters and these working hours. Do you want make some changes to the task?");
if (ReadLine() == "Y")
{
WriteLine("Which parameters do you wish to change?" +
"1. Working hours -> automatically more working hours will be added from today till the task's deadline so that you have enough time to finish it" +
"2. The deadline of the task" +
"3. The duration of the task");
string answer = ReadLine();
if (answer == "1")
{
// make a function that will take care of this.
}
else if (answer == "2")
{
WriteLine("Enter new deadline");
modifyTask(day, task, "deadline", ReadLine());
}
else if (answer == "3")
{
WriteLine("Enter new duration");
modifyTask(day, task, "duration", ReadLine());
}
else
{
WriteLine("Wrong input");
}
}
else
{
// remove task
}
}
// we add tasks to day and remove them from nextDay
public List<Task> updateDays(Day day, int hours)
{
Day nextDay = day.nextDay;
List<Task> tasks = new List<Task>();
while (nextDay != null)
{
if(day.tasks.Count == 0)
{
nextDay = nextDay.nextDay;
}
// from nextDay I remove and add tasks to day
for(int i = 0; i < nextDay.tasks.Count; ++i)
{
if(hours == 0){ break; }
Task curTask = nextDay.tasks[i];
// take care of exception if date is not valid
if (curTask.duration > hours)
{
int additionalHours = 0;
if (curTask.isSplit)
{
additionalHours = curTask.splitTaskPtr.duration;
// TODO: take care of the case when the task would be split into multiple days/tasks
nextDay.nextDay.removeTask(curTask.splitTaskPtr);
curTask.mergeTasks(curTask, curTask.splitTaskPtr);
}
int[] splitHours = { curTask.duration - hours - additionalHours, hours + additionalHours };
curTask.splitTask(splitHours, 0, curTask, day);
hours = 0;
// day.nextDay.addTask(curTask.splitTaskPtr, 0);
// add currentTask to day and currentTask.splitTaskPtr to nextDay
tasks.Add(curTask);
nextDay.removeTask(curTask);
nextDay.addTask(curTask.splitTaskPtr, 0);
}
else {
break;
else
{
int curTaskHours = curTask.duration;
if (curTask.isSplit)
{
curTask.splitTaskPtr.duration += curTask.duration;
nextDay.nextDay.removeTask(curTask.splitTaskPtr);
// TODO: Get back to the above case
}
else
{
tasks.Add(curTask);
//day.nextDay.addTask(curTask, 0);
}
hours -= curTaskHours;
nextDay.removeTask(curTask);
}
}
}
// delete empty days
return tasks;
}
public void modifyWorkingHours(int hours)
{
int hoursPerDay = hours / days.Count;
// make the oneMore give more hours as we're approaching the dealine?
int oneMore = hours - hoursPerDay * days.Count - 1; // to start counter i from 0
for (int i = 0; i < days.Count; ++i)
{
days[i].workingHours += hoursPerDay;
if (i <= oneMore)
{
days[i].workingHours++;
}
}
return hours <= 0;
// now reorganize the tasks
// use reorderCalendar somehow?
// should iterate though the days resusivelt
// it should start iterating through the days from days[0] and add x hours of tasks then as we iterate through the days we add i * x amount of tasks to the days
// and if we gat to a point when for ex 16 hours need to be shifter we must recursively access the days to get the tasks
}
public void addTask(Task task)
{
try
{
_addTask(task);
}
catch (NoSpaceForTaskExeption exception)
{
WriteLine(task.name);
Day day = findTaskInDay(task);
day.removeTask(task);
reorderCalendar(exception.day, task.duration, false, day);
// from day in the addTask from when I thorow the exeption until the day that I have here from which I remove the task
/*
Options:
-Modify task
-Add hours to the day
-Delete task
-Add hours equally to each day from the current date up until the deadline of the task
*/
}
}
public bool temp(Task task, List<Day> validDays, ref Day d)
public void temp(Task task, List<Day> validDays, ref Day d)
{
for (int i = 0; i < validDays.Count; ++i)
{
......@@ -113,36 +242,30 @@ public class Calendar
if (hours < task.duration)
{
WriteLine("No space to add task");
return false;
throw new NoSpaceForTaskExeption("There is no space to add the task which needs to be added as the last task in the calendar", d, task, hours - task.duration);
}
return true;
}
public void addTask(Task task)
public void _addTask(Task task)
{
List<Day> validDays = getRangeOfDaysForTask(task);
if(!isThereEnoughSpace(validDays, task)) {
WriteLine("Not enough space");
return;
}
// Insert task
foreach (Day day in validDays)
{
// TODO: Handle it in a different way
//if (day.tasks.Count != 0) {
for (int i = 0; i < day.tasks.Count; ++i) {
// TODO: If equality optimize according to duration
if (numberOfDaysInRange(day.tasks[i].deadline, task.deadline) <= 0 && day.tasks[i].type != Type.FIXED) {
for (int i = 0; i < day.tasks.Count; ++i)
{
if (numberOfDaysInRange(day.tasks[i].deadline, task.deadline) <= 0 && day.tasks[i].type != Type.FIXED)
{
day.addTask(task, i);
if (day.isDayFull(0)) {
reorderCalendar(day, day.hoursToShift);
if (day.isDayFull(0))
{
reorderCalendar(day, day.hoursToShift, true, null);
}
return;
}
}
}
//}
/*else {
day.addTask(task, 0);
......@@ -150,6 +273,7 @@ public class Calendar
}*/
}
// Add task at the end
Day d = validDays[0];
temp(task, validDays, ref d);
......@@ -157,16 +281,25 @@ public class Calendar
d.addTask(task, d.tasks.Count);
if (d.isDayFull(0))
{
reorderCalendar(d, d.hoursToShift);
reorderCalendar(d, d.hoursToShift, true, null);
}
}
// TODO: Check every implementation of reorderCalendar and check if the next and returnPoint parameters are sent correctly
// TODO: Split reorderCalendar into two functions: one that will return a list of tasks given hours and day
// and one that will do the work of reordering the calendar
// when reordering the calendar take care of the dates and if you are sending a task to a date
// when the deadline would be finished, then send an error
void reorderCalendar(Day day, int hours)
void reorderCalendar(Day day, int hours, bool next, Day returnPoint)
{
Day nextDay = day.nextDay;
if (nextDay == null) { return; }
Day dirDay;
int indexDir;
dirDay = (next ? day.nextDay : day.prevDay);
indexDir = (next ? day.tasks.Count - 1 : 0);
// Equals
if (dirDay == null || dirDay.Equals(returnPoint)) { return; }
List<Task> tasks = new List<Task>();
for (int i = day.tasks.Count - 1; i >= 0; --i)
......@@ -177,6 +310,25 @@ public class Calendar
Task curTask = day.tasks[i];
// if the date of where I need to shift the task is not compatible throw an exception
// curTask in in day an I want to shift it to dirDay
// the question is can I shift curTask in dirDay
// I have not yet shifted the curTask anywhere
if (!isDateValid(dirDay.date, curTask.deadline))
{
// TODO: Should I remove the task since -> the exception
// day.removeTask(curTask);
// call reorderCalendar
// now reverse all action done so far
/* for (int j = tasks.Count - 1; j >= 0; --j)
{
day.addTask(tasks[j], day.tasks.Count);
hours += tasks[j].duration;
} */
throw new NoSpaceForTaskExeption("There is no space to add the task, error occured during shifting the tasks", day, curTask, hours);
}
// add split tasks to "tasks" so that I can handle it during the exception
if (curTask.duration > hours)
{
int additionalHours = 0;
......@@ -185,18 +337,13 @@ public class Calendar
{
additionalHours = curTask.splitTaskPtr.duration;
// TODO: take care of the case when the task would be split into multiple days/tasks
day.nextDay.removeTask(curTask.splitTaskPtr);
dirDay.removeTask(curTask.splitTaskPtr);
curTask.mergeTasks(curTask, curTask.splitTaskPtr);
}
int[] splitHours = { curTask.duration - hours - additionalHours, hours + additionalHours};
// TODO: should I pass day or day.nextDay to splitTask as a parameter
int[] splitHours = { curTask.duration - hours - additionalHours, hours + additionalHours };
curTask.splitTask(splitHours, 0, curTask, day);
if (!isDateValid(day.nextDay.date, curTask.splitTaskPtr.deadline))
{
WriteLine("There is no space to add task");
return;
}
hours = 0;
//day.nextDay.addTask(curTask.splitTaskPtr, 0);
tasks.Add(curTask.splitTaskPtr);
......@@ -204,7 +351,8 @@ public class Calendar
else
{
int curTaskHours = curTask.duration;
if (curTask.isSplit) {
if (curTask.isSplit)
{
curTask.splitTaskPtr.duration += curTask.duration;
}
else
......@@ -219,51 +367,61 @@ public class Calendar
}
}
foreach(Task task in tasks)
foreach (Task task in tasks) { dirDay.addTask(task, 0); }
reorderCalendar(dirDay, dirDay.hoursToShift, next, null);
}
private Day findTaskInDay(Task task)
{
foreach (Day day in days)
{
if (!isDateValid(day.nextDay.date, task.deadline))
for (int i = 0; i < day.tasks.Count; ++i)
{
WriteLine("There is no space to shift the tasks");
// TODO: Throw exeption
// then there is no space to add the task we are adding
/*
Options:
-Modify task
-Add hours to the day
-Add hours equally to each day from the current date up until the deadline of the task
*/
return;
if (day.tasks[i] == task)
{
return day;
}
}
nextDay.addTask(task, 0);
}
reorderCalendar(nextDay, nextDay.hoursToShift);
WriteLine("Task doesn't exist");
return null;
}
void deleteTask(Day day, Task task)
// NOTE: Helper function until I make the interface
public void deleteTask(Day day, Task task)
{
// use findTaskInDay to find the day when you're given only the task
for (int i = 0; i < day.tasks.Count; ++i)
{
if (day.tasks[i] == task)
{
day.removeTask(task);
// Iterate the calendar backwards and remove tasks from day x and add them to day x - 1
// until we have reached day "day"
// Idea
// First - instaead of a "linked list" make the data structure a doubly linked list
// Second - pass the "directon" of reordering the calendar as a parameter and use it both ways
// i.e. modify reorder calendar
reorderCalendar(days[days.Count - 1], task.duration, false, day);
}
}
}
public void deleteTaskRunHelper(Task task)
{
foreach (Day day in days)
{
for (int i = 0; i < day.tasks.Count; ++i)
{
if (day.tasks[i] == task)
{
deleteTask(day, task);
}
}
}
}
void modifyTask<T>(Day day, Task task, string parameterType, string parameter)
public void modifyTask(Day day, Task task, string parameterType, string parameter)
{
// TODO: Ask Bane => if I iterate with foreach will the changes be saved?
// TODO: How to compare two tasks, should I overwrite compareTo method?
for(int i = 0; i < day.tasks.Count; ++i)
// TODO: compare two tasks, overwrite compareTo method
for (int i = 0; i < day.tasks.Count; ++i)
{
if(day.tasks[i] == task)
if (day.tasks[i] == task)
{
if (parameterType == "deadline")
{
......@@ -274,8 +432,16 @@ public class Calendar
else if (parameterType == "duration")
{
// Option 1
task.duration = int.Parse(parameter);
reorderCalendar(day, int.Parse(parameter));
if (task.duration > int.Parse(parameter))
{
task.duration = int.Parse(parameter);
reorderCalendar(day, int.Parse(parameter), true, null);
}
else if (task.duration < int.Parse(parameter))
{
task.duration = int.Parse(parameter);
reorderCalendar(day, int.Parse(parameter), false, day);
}
// Option 2
day.removeTask(task);
......@@ -288,7 +454,6 @@ public class Calendar
}
}
}
}
void loadFile()
......@@ -301,12 +466,15 @@ public class Calendar
}
public void print() {
foreach(Day day in days) {
public void print()
{
foreach (Day day in days)
{
WriteLine(day.date.ToString());
foreach(Task task in day.tasks) {
WriteLine($" Name: {task.name} Deadline: {task.deadline} Duration: {task.duration}");
foreach (Task task in day.tasks)
{
WriteLine($"\tName: {task.name} Deadline: {task.deadline} Duration: {task.duration}");
}
}
}
......
......@@ -8,12 +8,14 @@ public class Day
public DateTime date { get; set; }
public List<Task> tasks { get; set; }
// format xx:yy
public int workingHoursInterval { get; set; }
public (int, int) workingHoursInterval { get; set; }
public int workingHours { get; set; }
public Day nextDay { get; set; }
public Day prevDay { get; set; }
public Day(DateTime date, List<Task> tasks, int workingHoursInterval, int workingHours)
public bool dir { get; set; }
public Day(DateTime date, List<Task> tasks, (int, int) workingHoursInterval, int workingHours)
{
this.date = date;
this.tasks = tasks;
......@@ -23,6 +25,30 @@ public class Day
this.prevDay = null;
}
public override bool Equals(Object obj)
{
if ((obj == null) || !this.GetType().Equals(obj.GetType()))
{
return false;
}
else
{
Day d = (Day)obj;
return d.date == date;
}
}
public override int GetHashCode()
{
long hash = 0;
foreach (char c in date.ToString())
{
hash = hash * 1000003 + c.GetHashCode();
}
return (int)hash;
}
public int totalHoursTasks() {
int totalHours = 0;
foreach (Task task in tasks) {
......
using System;
class NoSpaceForTaskExeption: Exception
{
public Day day { get; set; }
public Task task { get; set; }
public int hours { get; set; }
public NoSpaceForTaskExeption() : base() { }
public NoSpaceForTaskExeption(string message) : base(message) { }
public NoSpaceForTaskExeption(string message, Day day, Task task, int hours): base(message)
{
this.day = day;
this.task = task;
this.hours = hours;
}
}
......@@ -6,25 +6,39 @@ static class Program
static void Main()
{
Calendar calendar = new Calendar();
calendar.defaultWorkingHoursInterval = 12;
Task task = new Task("kdb", new DateTime(2021, 07, 08), 5, Type.NORMAL, false);
calendar.defaultWorkingHours = 12;
/*Task task = new Task("kdb", new DateTime(2021, 07, 08), 5, Type.NORMAL, false);
Task t = new Task("Test", new DateTime(2021, 07, 07), 3, Type.NORMAL, false);
Task t1 = new Task("Test1", new DateTime(2021, 06, 14), 5, Type.NORMAL, false);
Task t2 = new Task("Test2", new DateTime(2021, 06, 15), 2, Type.NORMAL, false);
Task t1 = new Task("Test1", new DateTime(2021, 06, 15), 5, Type.NORMAL, false);
Task t2 = new Task("Test2", new DateTime(2021, 06, 16), 7, Type.NORMAL, false);
Task t3 = new Task("Test3", new DateTime(2021, 06, 15), 6, Type.NORMAL, false);
Task t4 = new Task("Test4", new DateTime(2021, 06, 15), 2, Type.NORMAL, false);
Task t5 = new Task("Test5", new DateTime(2021, 06, 15), 3, Type.NORMAL, false);
Task t6 = new Task("Test6", new DateTime(2021, 06, 14), 10, Type.NORMAL, false);
Task t4 = new Task("Test4", new DateTime(2021, 06, 16), 3, Type.NORMAL, false);
Task t5 = new Task("Test5", new DateTime(2021, 06, 16), 5, Type.NORMAL, false);
Task t6 = new Task("Test6", new DateTime(2021, 06, 15), 3, Type.NORMAL, false);*/
Task task = new Task("kdb", new DateTime(2021, 07, 08), 5, Type.NORMAL, false);
Task t = new Task("Test", new DateTime(2021, 07, 07), 3, Type.NORMAL, false);
Task t1 = new Task("Test1", new DateTime(2021, 06, 17), 5, Type.NORMAL, false<