From b2e75e6a2a84939c48269edf5e3b39cdc0dc3e74 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 10:19:47 +0100 Subject: [PATCH 01/27] feat: display menu options --- Todo-Challenge/Todo-Challenge/Menu.cs | 24 ++++++++++++++++++++++++ Todo-Challenge/Todo-Challenge/Program.cs | 7 +++++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 Todo-Challenge/Todo-Challenge/Menu.cs diff --git a/Todo-Challenge/Todo-Challenge/Menu.cs b/Todo-Challenge/Todo-Challenge/Menu.cs new file mode 100644 index 0000000..022f67f --- /dev/null +++ b/Todo-Challenge/Todo-Challenge/Menu.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Todo_Challenge +{ + class Menu + { + public static void DisplayOptions() + { + Console.WriteLine("Your current todo list is:"); + Console.WriteLine(); + Console.WriteLine("To edit it, use the options below"); + Console.WriteLine(); + Console.WriteLine("OPTIONS"); + Console.WriteLine("input: action:"); + Console.WriteLine("1 create a new todo"); + Console.WriteLine("2 delete a todo"); + Console.WriteLine("3 set a todo's completion status to true or false"); + } + } +} diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index 3751555..560cbaf 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -1,2 +1,5 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +using System.Text; +using Todo_Challenge; + +new Menu(); +Menu.DisplayOptions(); \ No newline at end of file From 245cd7bbaf057afedbabfdf9e8dc02aee9b0979b Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 10:20:05 +0100 Subject: [PATCH 02/27] feat: TodoItem class --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Todo-Challenge/Todo-Challenge/TodoItem.cs diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs new file mode 100644 index 0000000..e6847ed --- /dev/null +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Todo_Challenge +{ + internal class TodoItem + { + public int Id { get; set; } + public string? Name { get; set; } + public bool Completed { get; set; } = false; + + public TodoItem? NextTodoItem { get; set; } = null; + + public TodoItem(int id, string name) + { + Id = id; + Name = name ?? string.Empty; + Completed = false; + } + } +} From 9e8f6f17273eb7b5ae1083d959bbf1688b1b4096 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 10:20:20 +0100 Subject: [PATCH 03/27] feat: TodoList class --- Todo-Challenge/Todo-Challenge/TodoList.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Todo-Challenge/Todo-Challenge/TodoList.cs diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs new file mode 100644 index 0000000..4619ab2 --- /dev/null +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Todo_Challenge +{ + internal class TodoList + { + public string Name; + public TodoItem? FirstTodoItem { get; set; } = null; + public int NextId { get; set; } = 1; + + public TodoList(string name) + { + Name = name; + } + + } +} From 1efeb7dc80cc50b6429100f849bc584d0a01c1d8 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 10:23:20 +0100 Subject: [PATCH 04/27] fix: remove irrelevant properties from constructor --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index e6847ed..1dd4259 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -14,11 +14,9 @@ internal class TodoItem public TodoItem? NextTodoItem { get; set; } = null; - public TodoItem(int id, string name) + public TodoItem(string name) { - Id = id; - Name = name ?? string.Empty; - Completed = false; + Name = name; } } } From 78ad50e6e13cc5dd6cb6567b5f51a11b0a33b380 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 10:43:52 +0100 Subject: [PATCH 05/27] feat: implement incremental id --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 5 ++++- Todo-Challenge/Todo-Challenge/TodoList.cs | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index 1dd4259..0a63a2c 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -14,9 +15,11 @@ internal class TodoItem public TodoItem? NextTodoItem { get; set; } = null; - public TodoItem(string name) + public TodoItem(string name, TodoList todoList) { + Id = todoList.NextId; Name = name; + todoList.IncreaseId(); } } } diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 4619ab2..40686f3 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -17,5 +17,9 @@ public TodoList(string name) Name = name; } + public void IncreaseId() + { + NextId++; + } } } From cafb9e47a566c46a37640d3987e1304db101b68b Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 11:25:31 +0100 Subject: [PATCH 06/27] feat: link todoItem instances --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 17 ++++++++++++++++- Todo-Challenge/Todo-Challenge/TodoList.cs | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index 0a63a2c..8c6feee 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -12,14 +12,29 @@ internal class TodoItem public int Id { get; set; } public string? Name { get; set; } public bool Completed { get; set; } = false; - public TodoItem? NextTodoItem { get; set; } = null; + private readonly TodoList _list; + private void LinkToPreviousItem() + { + if (_list.DoesNotContainFirstTodoItem()) + { + _list.FirstTodoItem = this; + } + if (_list.LastTodoItem != null) + { + _list.LastTodoItem.NextTodoItem = this; + } + } + public TodoItem(string name, TodoList todoList) { Id = todoList.NextId; Name = name; + _list = todoList; todoList.IncreaseId(); + LinkToPreviousItem(); + todoList.LastTodoItem = this; } } } diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 40686f3..50db838 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -10,6 +10,8 @@ internal class TodoList { public string Name; public TodoItem? FirstTodoItem { get; set; } = null; + + public TodoItem? LastTodoItem { get; set; } = null; public int NextId { get; set; } = 1; public TodoList(string name) @@ -21,5 +23,7 @@ public void IncreaseId() { NextId++; } + + public bool DoesNotContainFirstTodoItem() { return FirstTodoItem == null; } } } From e33afeb8a07a6bd70459d7f0fc4fec705cc2fd60 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 11:43:29 +0100 Subject: [PATCH 07/27] feat: view list --- Todo-Challenge/Todo-Challenge/TodoList.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 50db838..5347429 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -25,5 +25,15 @@ public void IncreaseId() } public bool DoesNotContainFirstTodoItem() { return FirstTodoItem == null; } + public void ViewList() + { + var item = FirstTodoItem; + while(item != null) + { + Console.WriteLine(item.Name + " completion status: "); + item = item.NextTodoItem; + + } + } } } From c085aa3fc1dabc800525e2c4bdc87c088ef2e9ce Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 11:48:25 +0100 Subject: [PATCH 08/27] feat: read completion status --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index 8c6feee..9796de9 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -27,6 +27,11 @@ private void LinkToPreviousItem() } } + public string ReadCompletionStatus() + { + return Completed ? "done" : "to do"; + } + public TodoItem(string name, TodoList todoList) { Id = todoList.NextId; From c9f23de0fe07a08bbd7b10c484fbe19c52333a6f Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 11:49:52 +0100 Subject: [PATCH 09/27] feat: log completion status --- Todo-Challenge/Todo-Challenge/TodoList.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 5347429..995bc49 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -28,9 +28,10 @@ public void IncreaseId() public void ViewList() { var item = FirstTodoItem; + var isComplete = item.ReadCompletionStatus(); while(item != null) { - Console.WriteLine(item.Name + " completion status: "); + Console.WriteLine(item.Name + " completion status: " + isComplete); item = item.NextTodoItem; } From 7c3f50b502453e567e83c7bdf04ee41d9888d098 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 11:51:41 +0100 Subject: [PATCH 10/27] fix: prevent reading of property on potentially null object --- Todo-Challenge/Todo-Challenge/TodoList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 995bc49..3e9a894 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -28,9 +28,9 @@ public void IncreaseId() public void ViewList() { var item = FirstTodoItem; - var isComplete = item.ReadCompletionStatus(); while(item != null) { + var isComplete = item.ReadCompletionStatus(); Console.WriteLine(item.Name + " completion status: " + isComplete); item = item.NextTodoItem; From 4a3550f8ae687b0f92452e05907c6fb2a172ba30 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 12:20:24 +0100 Subject: [PATCH 11/27] feat: log exit option on menu --- Todo-Challenge/Todo-Challenge/Menu.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Todo-Challenge/Todo-Challenge/Menu.cs b/Todo-Challenge/Todo-Challenge/Menu.cs index 022f67f..855ac43 100644 --- a/Todo-Challenge/Todo-Challenge/Menu.cs +++ b/Todo-Challenge/Todo-Challenge/Menu.cs @@ -15,10 +15,11 @@ public static void DisplayOptions() Console.WriteLine("To edit it, use the options below"); Console.WriteLine(); Console.WriteLine("OPTIONS"); - Console.WriteLine("input: action:"); - Console.WriteLine("1 create a new todo"); - Console.WriteLine("2 delete a todo"); - Console.WriteLine("3 set a todo's completion status to true or false"); + Console.WriteLine("input: action:"); + Console.WriteLine(" 1 -> create a new todo"); + Console.WriteLine(" 2 -> delete a todo"); + Console.WriteLine(" 3 -> set a todo's completion status to true or false"); + Console.WriteLine(" exit -> stop running this app"); } } } From 5b43bc7255866b735f4d53844c2869cd04fb338c Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 12:22:00 +0100 Subject: [PATCH 12/27] feat: app listens to input --- Todo-Challenge/Todo-Challenge/Program.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index 560cbaf..a469613 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -2,4 +2,20 @@ using Todo_Challenge; new Menu(); -Menu.DisplayOptions(); \ No newline at end of file +Menu.DisplayOptions(); + +string? line = Console.ReadLine(); + +while (line != "exit") +{ + switch (line) + { + case "1": + break; + case "2": + break; + case "3": + break; + } + line = Console.ReadLine(); +} From 8c4c737d9ff9dacac83c293cc448210c72117b26 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 12:46:15 +0100 Subject: [PATCH 13/27] feat: get command reference number --- Todo-Challenge/Todo-Challenge/CommandHandler.cs | 16 ++++++++++++++++ Todo-Challenge/Todo-Challenge/Program.cs | 10 ++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 Todo-Challenge/Todo-Challenge/CommandHandler.cs diff --git a/Todo-Challenge/Todo-Challenge/CommandHandler.cs b/Todo-Challenge/Todo-Challenge/CommandHandler.cs new file mode 100644 index 0000000..d2e6b3d --- /dev/null +++ b/Todo-Challenge/Todo-Challenge/CommandHandler.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Todo_Challenge +{ + internal class CommandHandler + { + public static char GetCommandRefNum(string line) + { + return line[0]; + } + } +} diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index a469613..3c344a8 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -8,13 +8,15 @@ while (line != "exit") { - switch (line) + if (line == null) break; + char refNum = CommandHandler.GetCommandRefNum(line); + switch (refNum) { - case "1": + case '1': break; - case "2": + case '2': break; - case "3": + case '3': break; } line = Console.ReadLine(); From 9c1bfe465cb378446abee602b53a154345db60e0 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 12:55:34 +0100 Subject: [PATCH 14/27] feat: get inputed todo item name --- Todo-Challenge/Todo-Challenge/CommandHandler.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/CommandHandler.cs b/Todo-Challenge/Todo-Challenge/CommandHandler.cs index d2e6b3d..6d330bc 100644 --- a/Todo-Challenge/Todo-Challenge/CommandHandler.cs +++ b/Todo-Challenge/Todo-Challenge/CommandHandler.cs @@ -11,6 +11,13 @@ internal class CommandHandler public static char GetCommandRefNum(string line) { return line[0]; - } + } + public static string GetTodoItemName(string line) + { + + string lineWithoutRefNum = line.Remove(0, 1); + string name = lineWithoutRefNum.Trim(); + return name; + } } } From 5e2be2d15c26d2b2f3abd67bc075d9ca0acdbc84 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 12:56:03 +0100 Subject: [PATCH 15/27] feat: new todos can be created from the command line --- Todo-Challenge/Todo-Challenge/Program.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index 3c344a8..e38023e 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -6,6 +6,8 @@ string? line = Console.ReadLine(); +var list = new TodoList("Todo list"); + while (line != "exit") { if (line == null) break; @@ -13,11 +15,14 @@ switch (refNum) { case '1': + string itemName = CommandHandler.GetTodoItemName(line); + new TodoItem(itemName, list); break; case '2': break; case '3': break; } + list.ViewList(); line = Console.ReadLine(); } From ec2eae6620ed575f4a342ad133f0b4923329570b Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 17:39:38 +0100 Subject: [PATCH 16/27] feat: delete item --- Todo-Challenge/Todo-Challenge/TodoList.cs | 51 ++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 3e9a894..fa2c13d 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -10,7 +11,6 @@ internal class TodoList { public string Name; public TodoItem? FirstTodoItem { get; set; } = null; - public TodoItem? LastTodoItem { get; set; } = null; public int NextId { get; set; } = 1; @@ -27,8 +27,11 @@ public void IncreaseId() public bool DoesNotContainFirstTodoItem() { return FirstTodoItem == null; } public void ViewList() { + Console.WriteLine(); + Console.WriteLine("TODO LIST"); + Console.WriteLine(); var item = FirstTodoItem; - while(item != null) + while (item != null) { var isComplete = item.ReadCompletionStatus(); Console.WriteLine(item.Name + " completion status: " + isComplete); @@ -36,5 +39,49 @@ public void ViewList() } } + + private TodoItem GetTodoItemByName(string name) + { + var item = FirstTodoItem; + while (item != null && item.Name != name) + { + item = item.NextTodoItem; + continue; + } + return item; + } + + private TodoItem? GetPreviousTodoItemByName(string name) + { + var item = FirstTodoItem; + if (FirstTodoItem != null && FirstTodoItem.Name == name) + { + return null; + } + + while (item != null && item.NextTodoItem != null && item.NextTodoItem.Name != name) + { + item = item.NextTodoItem; + continue; + } + return item; + } + + public void DeleteItemWhereNameIs(string name) + { + var item = GetTodoItemByName(name); + var previousItem = GetPreviousTodoItemByName(name); + if (previousItem == null) + { + FirstTodoItem = item.NextTodoItem; + return; + } + else + { + // if I got this right redirecting the pointer is enough to remove + // any references to said item, and set it up for garbage collection (since it becomes unreachable) + previousItem.NextTodoItem = item.NextTodoItem; + } + } } } From 5a1d610b51dcadad336f5f446868f75ceec8992e Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 17:40:17 +0100 Subject: [PATCH 17/27] feat: option 2 triggers item deletion --- Todo-Challenge/Todo-Challenge/Program.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index e38023e..7d04916 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -12,13 +12,14 @@ { if (line == null) break; char refNum = CommandHandler.GetCommandRefNum(line); + string itemName = CommandHandler.GetTodoItemName(line); switch (refNum) { case '1': - string itemName = CommandHandler.GetTodoItemName(line); new TodoItem(itemName, list); break; case '2': + list.DeleteItemWhereNameIs(itemName); break; case '3': break; From f5dbd62e86366401162278314a49c94dacbdb0b4 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 17:45:43 +0100 Subject: [PATCH 18/27] feat: update option 3 action description --- Todo-Challenge/Todo-Challenge/Menu.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/Menu.cs b/Todo-Challenge/Todo-Challenge/Menu.cs index 855ac43..9990bea 100644 --- a/Todo-Challenge/Todo-Challenge/Menu.cs +++ b/Todo-Challenge/Todo-Challenge/Menu.cs @@ -18,7 +18,7 @@ public static void DisplayOptions() Console.WriteLine("input: action:"); Console.WriteLine(" 1 -> create a new todo"); Console.WriteLine(" 2 -> delete a todo"); - Console.WriteLine(" 3 -> set a todo's completion status to true or false"); + Console.WriteLine(" 3 -> toggle an item's completion status"); Console.WriteLine(" exit -> stop running this app"); } } From b1f71b9b3b1e5e7fb502c5dc3528a00ddafbda9c Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 17:46:05 +0100 Subject: [PATCH 19/27] feat: toggle item completion status --- Todo-Challenge/Todo-Challenge/TodoList.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index fa2c13d..3732de9 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -83,5 +83,10 @@ public void DeleteItemWhereNameIs(string name) previousItem.NextTodoItem = item.NextTodoItem; } } + public void ToggleItemCompletionStatusWhereNameIs(string name) + { + var item = GetTodoItemByName(name); + item.Completed = !item.Completed; + } } } From 02072c7a1989de903a80013cc032abd457220668 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Wed, 22 May 2024 17:46:25 +0100 Subject: [PATCH 20/27] feat: option 3 triggers item completion status toggle --- Todo-Challenge/Todo-Challenge/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index 7d04916..ab5abf6 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -22,6 +22,7 @@ list.DeleteItemWhereNameIs(itemName); break; case '3': + list.ToggleItemCompletionStatusWhereNameIs(itemName); break; } list.ViewList(); From b2ff1e2443f341061f3bf72a2f9a8d7494e52364 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Thu, 23 May 2024 10:06:58 +0100 Subject: [PATCH 21/27] refactor: rename method for clarity --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 2 +- Todo-Challenge/Todo-Challenge/TodoList.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index 9796de9..41d82c8 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -37,7 +37,7 @@ public TodoItem(string name, TodoList todoList) Id = todoList.NextId; Name = name; _list = todoList; - todoList.IncreaseId(); + todoList.IncreaseNextIdByOne(); LinkToPreviousItem(); todoList.LastTodoItem = this; } diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 3732de9..bbfc99c 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -19,7 +19,7 @@ public TodoList(string name) Name = name; } - public void IncreaseId() + public void IncreaseNextIdByOne() { NextId++; } From f04cf672a6bdb92220a7f95d212e1a562ef2a48b Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Thu, 23 May 2024 10:07:36 +0100 Subject: [PATCH 22/27] fix: amend return type for GetTodoItemByName --- Todo-Challenge/Todo-Challenge/TodoList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index bbfc99c..ff27d4c 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -40,7 +40,7 @@ public void ViewList() } } - private TodoItem GetTodoItemByName(string name) + private TodoItem? GetTodoItemByName(string name) { var item = FirstTodoItem; while (item != null && item.Name != name) From 2ba3dc920307c62c497afec73c8afe2375450cad Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Thu, 23 May 2024 10:13:56 +0100 Subject: [PATCH 23/27] feat: handle incorrect names passed as input --- Todo-Challenge/Todo-Challenge/TodoList.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index ff27d4c..c4f27ab 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -70,6 +70,11 @@ public void ViewList() public void DeleteItemWhereNameIs(string name) { var item = GetTodoItemByName(name); + if (item == null) + { + Console.WriteLine($"failed to delete ${name}, no such item found"); + return; + } var previousItem = GetPreviousTodoItemByName(name); if (previousItem == null) { @@ -86,6 +91,11 @@ public void DeleteItemWhereNameIs(string name) public void ToggleItemCompletionStatusWhereNameIs(string name) { var item = GetTodoItemByName(name); + if (item == null) + { + Console.WriteLine($"failed to toggle completion status of {name}, no such item found"); + return; + } item.Completed = !item.Completed; } } From eb30b1756ea4c4bdd01279c9bf1f57cbb49fd2b8 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Thu, 23 May 2024 10:20:06 +0100 Subject: [PATCH 24/27] docs: comment to categorise todo list methods --- Todo-Challenge/Todo-Challenge/TodoList.cs | 61 +++++++++++++---------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index c4f27ab..25592bf 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -14,32 +14,7 @@ internal class TodoList public TodoItem? LastTodoItem { get; set; } = null; public int NextId { get; set; } = 1; - public TodoList(string name) - { - Name = name; - } - - public void IncreaseNextIdByOne() - { - NextId++; - } - - public bool DoesNotContainFirstTodoItem() { return FirstTodoItem == null; } - public void ViewList() - { - Console.WriteLine(); - Console.WriteLine("TODO LIST"); - Console.WriteLine(); - var item = FirstTodoItem; - while (item != null) - { - var isComplete = item.ReadCompletionStatus(); - Console.WriteLine(item.Name + " completion status: " + isComplete); - item = item.NextTodoItem; - - } - } - + // private retrieval operations executed prior to modifying the list private TodoItem? GetTodoItemByName(string name) { var item = FirstTodoItem; @@ -54,7 +29,7 @@ public void ViewList() private TodoItem? GetPreviousTodoItemByName(string name) { var item = FirstTodoItem; - if (FirstTodoItem != null && FirstTodoItem.Name == name) + if (FirstTodoItem != null && FirstTodoItem.Name == name) { return null; } @@ -67,6 +42,37 @@ public void ViewList() return item; } + // is ran upon the start of the application + public TodoList(string name) + { + Name = name; + } + + // methods ran when a todo item is created + public void IncreaseNextIdByOne() + { + NextId++; + } + + public bool DoesNotContainFirstTodoItem() { return FirstTodoItem == null; } + + // method ran after each list modification so the user may visualise the result + public void ViewList() + { + Console.WriteLine(); + Console.WriteLine("TODO LIST"); + Console.WriteLine(); + var item = FirstTodoItem; + while (item != null) + { + var isComplete = item.ReadCompletionStatus(); + Console.WriteLine(item.Name + " completion status: " + isComplete); + item = item.NextTodoItem; + + } + } + + // list modification operations triggered by commands public void DeleteItemWhereNameIs(string name) { var item = GetTodoItemByName(name); @@ -88,6 +94,7 @@ public void DeleteItemWhereNameIs(string name) previousItem.NextTodoItem = item.NextTodoItem; } } + public void ToggleItemCompletionStatusWhereNameIs(string name) { var item = GetTodoItemByName(name); From bda67b395281feba9545b3f57d86b19d950ff93b Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Thu, 23 May 2024 10:25:05 +0100 Subject: [PATCH 25/27] feat: return if first check failed --- Todo-Challenge/Todo-Challenge/TodoItem.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index 41d82c8..8625d46 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -15,11 +15,13 @@ internal class TodoItem public TodoItem? NextTodoItem { get; set; } = null; private readonly TodoList _list; + private void LinkToPreviousItem() { if (_list.DoesNotContainFirstTodoItem()) { _list.FirstTodoItem = this; + return; } if (_list.LastTodoItem != null) { From b3e3f4090cf0bfa04ff144fd139c78918f209b3b Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Thu, 23 May 2024 10:26:47 +0100 Subject: [PATCH 26/27] style: remove empty line --- Todo-Challenge/Todo-Challenge/CommandHandler.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Todo-Challenge/Todo-Challenge/CommandHandler.cs b/Todo-Challenge/Todo-Challenge/CommandHandler.cs index 6d330bc..8bcd8aa 100644 --- a/Todo-Challenge/Todo-Challenge/CommandHandler.cs +++ b/Todo-Challenge/Todo-Challenge/CommandHandler.cs @@ -14,7 +14,6 @@ public static char GetCommandRefNum(string line) } public static string GetTodoItemName(string line) { - string lineWithoutRefNum = line.Remove(0, 1); string name = lineWithoutRefNum.Trim(); return name; From f4479babafc31d4b9aadd03f2e8263de850c3373 Mon Sep 17 00:00:00 2001 From: Chloe Zermatten Date: Tue, 28 May 2024 17:03:14 +0100 Subject: [PATCH 27/27] refactor: TodoList implements IEnumerable --- Todo-Challenge/Todo-Challenge/Program.cs | 6 +- Todo-Challenge/Todo-Challenge/TodoItem.cs | 9 +-- Todo-Challenge/Todo-Challenge/TodoList.cs | 78 ++++++++++++++--------- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/Todo-Challenge/Todo-Challenge/Program.cs b/Todo-Challenge/Todo-Challenge/Program.cs index ab5abf6..e6e78cf 100644 --- a/Todo-Challenge/Todo-Challenge/Program.cs +++ b/Todo-Challenge/Todo-Challenge/Program.cs @@ -19,12 +19,12 @@ new TodoItem(itemName, list); break; case '2': - list.DeleteItemWhereNameIs(itemName); + TodoList.DeleteItemWhereNameIs(itemName, list); break; case '3': - list.ToggleItemCompletionStatusWhereNameIs(itemName); + TodoList.ToggleItemCompletionStatusWhereNameIs(itemName, list); break; } - list.ViewList(); + TodoList.View(list); line = Console.ReadLine(); } diff --git a/Todo-Challenge/Todo-Challenge/TodoItem.cs b/Todo-Challenge/Todo-Challenge/TodoItem.cs index 8625d46..c227ad7 100644 --- a/Todo-Challenge/Todo-Challenge/TodoItem.cs +++ b/Todo-Challenge/Todo-Challenge/TodoItem.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; @@ -20,12 +21,12 @@ private void LinkToPreviousItem() { if (_list.DoesNotContainFirstTodoItem()) { - _list.FirstTodoItem = this; + _list.Head = this; return; } - if (_list.LastTodoItem != null) + if (_list.Tail != null) { - _list.LastTodoItem.NextTodoItem = this; + _list.Tail.NextTodoItem = this; } } @@ -41,7 +42,7 @@ public TodoItem(string name, TodoList todoList) _list = todoList; todoList.IncreaseNextIdByOne(); LinkToPreviousItem(); - todoList.LastTodoItem = this; + todoList.Tail = this; } } } diff --git a/Todo-Challenge/Todo-Challenge/TodoList.cs b/Todo-Challenge/Todo-Challenge/TodoList.cs index 25592bf..b208084 100644 --- a/Todo-Challenge/Todo-Challenge/TodoList.cs +++ b/Todo-Challenge/Todo-Challenge/TodoList.cs @@ -1,51 +1,72 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; +using System.Xml.Linq; namespace Todo_Challenge { - internal class TodoList + internal class TodoList : IEnumerable { public string Name; - public TodoItem? FirstTodoItem { get; set; } = null; - public TodoItem? LastTodoItem { get; set; } = null; - public int NextId { get; set; } = 1; + public TodoItem? Head { get; set; } + public TodoItem? Tail { get; set; } + public TodoItem? Current { get; set; } + public int NextId { get; set; } + + IEnumerator IEnumerable.GetEnumerator() + { + Current = Head; + + while (Current != null) + { + yield return Current; + Current = Current.NextTodoItem; + } + } + // private retrieval operations executed prior to modifying the list - private TodoItem? GetTodoItemByName(string name) + private static TodoItem? GetTodoItemByName(string name, TodoList todoList) { - var item = FirstTodoItem; - while (item != null && item.Name != name) + foreach (TodoItem item in todoList) { - item = item.NextTodoItem; - continue; + if (item != null && item.Name == name) + { + return item; + } } - return item; + return null; } - private TodoItem? GetPreviousTodoItemByName(string name) + private static TodoItem? GetPreviousTodoItemByName(string name, TodoList todoList) { - var item = FirstTodoItem; - if (FirstTodoItem != null && FirstTodoItem.Name == name) + if (todoList.Head != null && todoList.Head.Name == name) { return null; } - while (item != null && item.NextTodoItem != null && item.NextTodoItem.Name != name) + foreach (TodoItem item in todoList) { - item = item.NextTodoItem; - continue; + if (item != null && item.NextTodoItem != null && item.NextTodoItem.Name == name) + { + return item; + } } - return item; + return null; } // is ran upon the start of the application public TodoList(string name) { Name = name; + Head = null; + Tail = null; + Current = null; + NextId = 1; } // methods ran when a todo item is created @@ -54,37 +75,35 @@ public void IncreaseNextIdByOne() NextId++; } - public bool DoesNotContainFirstTodoItem() { return FirstTodoItem == null; } + public bool DoesNotContainFirstTodoItem() { return Head == null; } // method ran after each list modification so the user may visualise the result - public void ViewList() + public static void View(TodoList todoList) { Console.WriteLine(); Console.WriteLine("TODO LIST"); Console.WriteLine(); - var item = FirstTodoItem; - while (item != null) + + foreach (TodoItem item in todoList) { var isComplete = item.ReadCompletionStatus(); Console.WriteLine(item.Name + " completion status: " + isComplete); - item = item.NextTodoItem; - } } // list modification operations triggered by commands - public void DeleteItemWhereNameIs(string name) + public static void DeleteItemWhereNameIs(string name, TodoList todoList) { - var item = GetTodoItemByName(name); + var item = GetTodoItemByName(name, todoList); if (item == null) { Console.WriteLine($"failed to delete ${name}, no such item found"); return; } - var previousItem = GetPreviousTodoItemByName(name); + var previousItem = GetPreviousTodoItemByName(name, todoList); if (previousItem == null) { - FirstTodoItem = item.NextTodoItem; + todoList.Head = item.NextTodoItem; return; } else @@ -95,9 +114,9 @@ public void DeleteItemWhereNameIs(string name) } } - public void ToggleItemCompletionStatusWhereNameIs(string name) + public static void ToggleItemCompletionStatusWhereNameIs(string name, TodoList todoList) { - var item = GetTodoItemByName(name); + var item = GetTodoItemByName(name, todoList); if (item == null) { Console.WriteLine($"failed to toggle completion status of {name}, no such item found"); @@ -105,5 +124,6 @@ public void ToggleItemCompletionStatusWhereNameIs(string name) } item.Completed = !item.Completed; } + } }