From e1c1b428c213eafb5e829bf502983a482c2318b0 Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Fri, 5 May 2023 15:23:18 +0200 Subject: [PATCH 1/8] start #33, test some functions --- MCTG/ConsoleApp/IResearchMenuRecipe.cs | 13 ++ MCTG/ConsoleApp/Program.cs | 48 ++++++- MCTG/ConsoleApp/ResearchMenu.cs | 71 ++++++++++ MCTG/Model/IReasearch.cs | 13 ++ MCTG/Model/Recipe.cs | 178 ++++++++++++------------- MCTG/Model/RecipeCollection.cs | 7 +- MCTG/SAE-2.01.sln | 84 ++++++------ 7 files changed, 276 insertions(+), 138 deletions(-) create mode 100644 MCTG/ConsoleApp/IResearchMenuRecipe.cs create mode 100644 MCTG/ConsoleApp/ResearchMenu.cs create mode 100644 MCTG/Model/IReasearch.cs diff --git a/MCTG/ConsoleApp/IResearchMenuRecipe.cs b/MCTG/ConsoleApp/IResearchMenuRecipe.cs new file mode 100644 index 0000000..a1b3da8 --- /dev/null +++ b/MCTG/ConsoleApp/IResearchMenuRecipe.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleApp +{ + public interface IResearchMenu + { + void updateDisplay(string researchStr, T[] researchResult); + } +} diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs index 773f61b..b746e54 100644 --- a/MCTG/ConsoleApp/Program.cs +++ b/MCTG/ConsoleApp/Program.cs @@ -2,7 +2,7 @@ using ConsoleApp; using Model; - +using System.Text; Console.WriteLine("Hello, World!\n\n"); @@ -14,8 +14,44 @@ Stub stub = new Stub(); List recipes = stub.LoadRecipes(); List recipeCollections = stub.LoadRecipeCollection(); -foreach (Recipe r in recipes) - Console.WriteLine(r); - -foreach (RecipeCollection r in recipeCollections) - Console.WriteLine(r); +RecipeCollection? allRecipe = recipeCollections.Find(x => x.Description.Equals("All")); +if (allRecipe == null) + throw new ArgumentException("Load AllRecipe in stub: can't find 'All'."); + +StringBuilder sb = new StringBuilder(); +ResearchMenuRecipe researchMenu = new ResearchMenuRecipe(); +Recipe[] result = allRecipe.ResearchByName(sb.ToString()); +researchMenu.UpdateDisplay(sb.ToString(), result); + +ConsoleKeyInfo cki; + +do +{ + cki = Console.ReadKey(true); + + switch (cki.Key) + { + case ConsoleKey.UpArrow: + researchMenu.SelectPrevioustLine(); + break; + case ConsoleKey.DownArrow: + researchMenu.SelectNextLine(); + break; + case ConsoleKey.Backspace: + if (sb.Length > 0) + { + sb.Remove(sb.Length - 1, 1); + result = allRecipe.ResearchByName(sb.ToString()); + } + break; + default: + sb.Append(cki.KeyChar); + result = allRecipe.ResearchByName(sb.ToString()); + break; + } + + researchMenu.UpdateDisplay(sb.ToString(), result); + +} while (cki.Key != ConsoleKey.Enter); + +Console.WriteLine(researchMenu.ReturnSelected()); \ No newline at end of file diff --git a/MCTG/ConsoleApp/ResearchMenu.cs b/MCTG/ConsoleApp/ResearchMenu.cs new file mode 100644 index 0000000..f16cb02 --- /dev/null +++ b/MCTG/ConsoleApp/ResearchMenu.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Model; + +namespace ConsoleApp +{ + internal class ResearchMenuRecipe + { + internal string displayText = ""; + public int CurrentLine + { + get => currentLine; + set + { + currentLine = value; + if (currentLine > maxLines) + { + currentLine = maxLines; + } + if (currentLine < 0) + { + currentLine = 0; + } + return; + } + } + private int currentLine = 0; + private int maxLines = 0; + private Recipe? currentSelected; + + public void UpdateDisplay(string researchStr, Recipe[] researchResult) + { + maxLines = researchResult.Length - 1; + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("---------------------------------------------------------"); + sb.AppendLine($" Research: {researchStr}"); + sb.AppendLine("---------------------------------------------------------"); + for (int i = 0; i < researchResult.Length; i++) + { + if (i == CurrentLine) + { + currentSelected = researchResult[i]; + sb.Append($">"); + } + sb.AppendLine($" [ {researchResult[i].Id} ]: {researchResult[i].Title} "); + } + Console.Clear(); + Console.WriteLine(sb); + } + + public int SelectNextLine() + { + return ++CurrentLine; + } + + public int SelectPrevioustLine() + { + return --CurrentLine; + } + + public Recipe? ReturnSelected() + { + return currentSelected; + } + } +} diff --git a/MCTG/Model/IReasearch.cs b/MCTG/Model/IReasearch.cs new file mode 100644 index 0000000..74314a1 --- /dev/null +++ b/MCTG/Model/IReasearch.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Model +{ + public interface IReasearch + { + public T ResearchByName(string str); + } +} diff --git a/MCTG/Model/Recipe.cs b/MCTG/Model/Recipe.cs index 9d65bf9..341383c 100644 --- a/MCTG/Model/Recipe.cs +++ b/MCTG/Model/Recipe.cs @@ -1,101 +1,101 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Security.Cryptography; -using System.Text; - -namespace Model -{ - /// - /// Define a Recipe for the preparation of a meal. - /// - public class Recipe : IEquatable - { - #region Attributes - private string _title = ""; - #endregion +using System.Text; - #region Properties - /// - /// The ID of the recipe - allows you to compare and/or get this item in an easier way. - /// - public int Id { get; init; } - - /// - /// The Title of the recipe.
- /// Set to "No title." when the value passed is null, empty or contain white spaces. - ///
- public string Title - { - get => _title; - set - { - if (string.IsNullOrWhiteSpace(value)) - _title = "No title."; - else - _title = value; - } - } - - /// - /// The steps of the preparation. See: . - /// - public List PreparationSteps { get; set; } - #endregion - - #region Constructors - /// - /// Construct a new recipe. - /// - /// The title of the recipe - /// The id of the recipe. If not given, get a new id. - /// The steps of the preparation of the meal - public Recipe(string title = "", int? id = null, - params PreparationStep[] preparationSteps) - { - Title = title; - PreparationSteps = new List(preparationSteps); +namespace Model +{ + /// + /// Define a Recipe for the preparation of a meal. + /// + public class Recipe : IEquatable + { + #region Attributes + private string _title = ""; + #endregion + + #region Properties + /// + /// The ID of the recipe - allows you to compare and/or get this item in an easier way. + /// + public int Id { get; init; } + + /// + /// The Title of the recipe.
+ /// Set to "No title." when the value passed is null, empty or contain white spaces. + ///
+ public string Title + { + get => _title; + set + { + if (string.IsNullOrWhiteSpace(value)) + _title = "No title."; + else + _title = value; + } + } + + /// + /// The steps of the preparation. See: . + /// + public List PreparationSteps { get; set; } + #endregion + + #region Constructors + /// + /// Construct a new recipe. + /// + /// The title of the recipe + /// The id of the recipe. If not given, get a new id. + /// The steps of the preparation of the meal + public Recipe(string title = "", int? id = null, + params PreparationStep[] preparationSteps) + { + Title = title; + PreparationSteps = new List(preparationSteps); if (id == null) { var randomGenerator = RandomNumberGenerator.Create(); byte[] data = new byte[16]; - randomGenerator.GetBytes(data); - Id = Math.Abs(BitConverter.ToInt16(data)); - } - else Id = (int)id; - } - #endregion - - #region Methods - public virtual bool Equals(Recipe? other) - { - if (other == null) return false; - if (other == this) return true; - return Title.Equals(other.Title) && PreparationSteps.Equals(other.PreparationSteps); - } - + randomGenerator.GetBytes(data); + Id = Math.Abs(BitConverter.ToInt16(data)); + } + else Id = (int)id; + } + #endregion + + #region Methods + public virtual bool Equals(Recipe? other) + { + if (other == null) return false; + if (other == this) return true; + return Title.Equals(other.Title) && PreparationSteps.Equals(other.PreparationSteps); + } + public override bool Equals(object? obj) { var item = obj as Recipe; if (item == null) return false; return Equals(obj); - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder($"[Recipe n°{Id}] - {Title}\n"); - foreach (PreparationStep ps in PreparationSteps) - { - sb.AppendFormat("\t* {0}\n", ps.ToString()); - } - return sb.ToString(); - } - #endregion - } -} + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder($"[Recipe n°{Id}] - {Title}\n"); + foreach (PreparationStep ps in PreparationSteps) + { + sb.AppendFormat("\t* {0}\n", ps.ToString()); + } + return sb.ToString(); + } + #endregion + } +} diff --git a/MCTG/Model/RecipeCollection.cs b/MCTG/Model/RecipeCollection.cs index 3592bb8..3da7d6d 100644 --- a/MCTG/Model/RecipeCollection.cs +++ b/MCTG/Model/RecipeCollection.cs @@ -148,7 +148,12 @@ namespace Model sb.AppendFormat("\t - {0}\n", r.ToString()); } return sb.ToString(); - } + } + + public Recipe[] ResearchByName(string str) + { + return _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray(); + } #endregion } } diff --git a/MCTG/SAE-2.01.sln b/MCTG/SAE-2.01.sln index 81242a9..4e7f013 100644 --- a/MCTG/SAE-2.01.sln +++ b/MCTG/SAE-2.01.sln @@ -1,42 +1,42 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.33516.290 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{666C2211-8EBB-4FC8-9484-CB93BC854153}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{42FF86BD-92F9-4A32-A938-68515905378F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model_UnitTests", "Tests\Model_UnitTests\Model_UnitTests.csproj", "{45AB746A-194B-4E43-81EB-83B06F35AA33}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{08B80CE8-A01D-4D86-8989-AF225D5DA48C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {666C2211-8EBB-4FC8-9484-CB93BC854153}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {666C2211-8EBB-4FC8-9484-CB93BC854153}.Debug|Any CPU.Build.0 = Debug|Any CPU - {666C2211-8EBB-4FC8-9484-CB93BC854153}.Release|Any CPU.ActiveCfg = Release|Any CPU - {666C2211-8EBB-4FC8-9484-CB93BC854153}.Release|Any CPU.Build.0 = Release|Any CPU - {42FF86BD-92F9-4A32-A938-68515905378F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {42FF86BD-92F9-4A32-A938-68515905378F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {42FF86BD-92F9-4A32-A938-68515905378F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {42FF86BD-92F9-4A32-A938-68515905378F}.Release|Any CPU.Build.0 = Release|Any CPU - {45AB746A-194B-4E43-81EB-83B06F35AA33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {45AB746A-194B-4E43-81EB-83B06F35AA33}.Debug|Any CPU.Build.0 = Debug|Any CPU - {45AB746A-194B-4E43-81EB-83B06F35AA33}.Release|Any CPU.ActiveCfg = Release|Any CPU - {45AB746A-194B-4E43-81EB-83B06F35AA33}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {45AB746A-194B-4E43-81EB-83B06F35AA33} = {08B80CE8-A01D-4D86-8989-AF225D5DA48C} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {ADEA5603-1EF6-4D43-9493-7D6D9DE7FA3F} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33516.290 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{666C2211-8EBB-4FC8-9484-CB93BC854153}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model", "Model\Model.csproj", "{42FF86BD-92F9-4A32-A938-68515905378F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Model_UnitTests", "Tests\Model_UnitTests\Model_UnitTests.csproj", "{45AB746A-194B-4E43-81EB-83B06F35AA33}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{08B80CE8-A01D-4D86-8989-AF225D5DA48C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {666C2211-8EBB-4FC8-9484-CB93BC854153}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {666C2211-8EBB-4FC8-9484-CB93BC854153}.Debug|Any CPU.Build.0 = Debug|Any CPU + {666C2211-8EBB-4FC8-9484-CB93BC854153}.Release|Any CPU.ActiveCfg = Release|Any CPU + {666C2211-8EBB-4FC8-9484-CB93BC854153}.Release|Any CPU.Build.0 = Release|Any CPU + {42FF86BD-92F9-4A32-A938-68515905378F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42FF86BD-92F9-4A32-A938-68515905378F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42FF86BD-92F9-4A32-A938-68515905378F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42FF86BD-92F9-4A32-A938-68515905378F}.Release|Any CPU.Build.0 = Release|Any CPU + {45AB746A-194B-4E43-81EB-83B06F35AA33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {45AB746A-194B-4E43-81EB-83B06F35AA33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {45AB746A-194B-4E43-81EB-83B06F35AA33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {45AB746A-194B-4E43-81EB-83B06F35AA33}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {45AB746A-194B-4E43-81EB-83B06F35AA33} = {08B80CE8-A01D-4D86-8989-AF225D5DA48C} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {ADEA5603-1EF6-4D43-9493-7D6D9DE7FA3F} + EndGlobalSection +EndGlobal From 5e9a7f68604f13ef31ccdd0d07e6dd1cbcd2fa3f Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sat, 6 May 2023 17:36:08 +0200 Subject: [PATCH 2/8] :recycle: refactor classes --- MCTG/ConsoleApp/ConsoleApp.csproj | 2 +- MCTG/ConsoleApp/ConsoleMenu.cs | 60 ++++ MCTG/ConsoleApp/IResearchMenuRecipe.cs | 13 - MCTG/ConsoleApp/Program.cs | 82 ++--- .../{ResearchMenu.cs => SearcherRecipe.cs} | 139 ++++---- MCTG/Model/IReasearch.cs | 13 - MCTG/Model/Manager.cs | 25 ++ MCTG/Model/RecipeCollection.cs | 320 +++++++++--------- 8 files changed, 341 insertions(+), 313 deletions(-) create mode 100644 MCTG/ConsoleApp/ConsoleMenu.cs delete mode 100644 MCTG/ConsoleApp/IResearchMenuRecipe.cs rename MCTG/ConsoleApp/{ResearchMenu.cs => SearcherRecipe.cs} (58%) delete mode 100644 MCTG/Model/IReasearch.cs create mode 100644 MCTG/Model/Manager.cs diff --git a/MCTG/ConsoleApp/ConsoleApp.csproj b/MCTG/ConsoleApp/ConsoleApp.csproj index c7f3ecd..7e8ef62 100644 --- a/MCTG/ConsoleApp/ConsoleApp.csproj +++ b/MCTG/ConsoleApp/ConsoleApp.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/MCTG/ConsoleApp/ConsoleMenu.cs b/MCTG/ConsoleApp/ConsoleMenu.cs new file mode 100644 index 0000000..5b561ee --- /dev/null +++ b/MCTG/ConsoleApp/ConsoleMenu.cs @@ -0,0 +1,60 @@ +using ConsoleApp; +using Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace ConsoleApp +{ + public class ConsoleMenu : Manager + { + public ConsoleMenu(Manager manager) + { + AllRecipes = manager.AllRecipes; + } + + public Recipe? ResearchOnRecipe() + { + StringBuilder sb = new StringBuilder(); + SearcherRecipe searcherRecipe = new SearcherRecipe(); + RecipeCollection result = AllRecipes.ResearchByName(sb.ToString()); + searcherRecipe.UpdateDisplay(sb.ToString(), result); + + ConsoleKeyInfo cki; + + do + { + cki = Console.ReadKey(true); + + switch (cki.Key) + { + case ConsoleKey.UpArrow: + searcherRecipe.SelectPrevioustLine(); + break; + case ConsoleKey.DownArrow: + searcherRecipe.SelectNextLine(); + break; + case ConsoleKey.Backspace: + if (sb.Length > 0) + { + sb.Remove(sb.Length - 1, 1); + result = AllRecipes.ResearchByName(sb.ToString()); + } + break; + default: + sb.Append(cki.KeyChar); + result = AllRecipes.ResearchByName(sb.ToString()); + break; + } + + searcherRecipe.UpdateDisplay(sb.ToString(), result); + + } while (cki.Key != ConsoleKey.Enter); + + return searcherRecipe.CurrentSelected; + } + } +} diff --git a/MCTG/ConsoleApp/IResearchMenuRecipe.cs b/MCTG/ConsoleApp/IResearchMenuRecipe.cs deleted file mode 100644 index a1b3da8..0000000 --- a/MCTG/ConsoleApp/IResearchMenuRecipe.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ConsoleApp -{ - public interface IResearchMenu - { - void updateDisplay(string researchStr, T[] researchResult); - } -} diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs index b746e54..909395f 100644 --- a/MCTG/ConsoleApp/Program.cs +++ b/MCTG/ConsoleApp/Program.cs @@ -1,57 +1,27 @@ -// See https://aka.ms/new-console-template for more information - +// See https://aka.ms/new-console-template for more information + using ConsoleApp; -using Model; -using System.Text; - -Console.WriteLine("Hello, World!\n\n"); - - -// TESTS: - -Stub stub = new Stub(); - -List recipes = stub.LoadRecipes(); -List recipeCollections = stub.LoadRecipeCollection(); - -RecipeCollection? allRecipe = recipeCollections.Find(x => x.Description.Equals("All")); -if (allRecipe == null) - throw new ArgumentException("Load AllRecipe in stub: can't find 'All'."); - -StringBuilder sb = new StringBuilder(); -ResearchMenuRecipe researchMenu = new ResearchMenuRecipe(); -Recipe[] result = allRecipe.ResearchByName(sb.ToString()); -researchMenu.UpdateDisplay(sb.ToString(), result); - -ConsoleKeyInfo cki; - -do -{ - cki = Console.ReadKey(true); - - switch (cki.Key) - { - case ConsoleKey.UpArrow: - researchMenu.SelectPrevioustLine(); - break; - case ConsoleKey.DownArrow: - researchMenu.SelectNextLine(); - break; - case ConsoleKey.Backspace: - if (sb.Length > 0) - { - sb.Remove(sb.Length - 1, 1); - result = allRecipe.ResearchByName(sb.ToString()); - } - break; - default: - sb.Append(cki.KeyChar); - result = allRecipe.ResearchByName(sb.ToString()); - break; - } - - researchMenu.UpdateDisplay(sb.ToString(), result); - -} while (cki.Key != ConsoleKey.Enter); - -Console.WriteLine(researchMenu.ReturnSelected()); \ No newline at end of file +using Model; + +using System.Text; + +Console.WriteLine("Hello, World!\n\n"); + + +// TESTS: + +Stub stub = new Stub(); + +List recipes = stub.LoadRecipes(); +List recipeCollections = stub.LoadRecipeCollection(); + +RecipeCollection? allRecipe = recipeCollections.Find(x => x.Description.Equals("All")); +if (allRecipe == null) + throw new ArgumentException("Load AllRecipe in stub: can't find 'All'."); + +Manager manager = new Manager(allRecipe); +ConsoleMenu menu = new ConsoleMenu(manager); + +Recipe? recipeRetSearchMenu = menu.ResearchOnRecipe(); + +Console.WriteLine(recipeRetSearchMenu); diff --git a/MCTG/ConsoleApp/ResearchMenu.cs b/MCTG/ConsoleApp/SearcherRecipe.cs similarity index 58% rename from MCTG/ConsoleApp/ResearchMenu.cs rename to MCTG/ConsoleApp/SearcherRecipe.cs index f16cb02..321c14c 100644 --- a/MCTG/ConsoleApp/ResearchMenu.cs +++ b/MCTG/ConsoleApp/SearcherRecipe.cs @@ -1,71 +1,68 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Model; - -namespace ConsoleApp -{ - internal class ResearchMenuRecipe - { - internal string displayText = ""; - public int CurrentLine - { - get => currentLine; - set - { - currentLine = value; - if (currentLine > maxLines) - { - currentLine = maxLines; - } - if (currentLine < 0) - { - currentLine = 0; - } - return; - } - } - private int currentLine = 0; - private int maxLines = 0; - private Recipe? currentSelected; - - public void UpdateDisplay(string researchStr, Recipe[] researchResult) - { - maxLines = researchResult.Length - 1; - - StringBuilder sb = new StringBuilder(); - sb.AppendLine("---------------------------------------------------------"); - sb.AppendLine($" Research: {researchStr}"); - sb.AppendLine("---------------------------------------------------------"); - for (int i = 0; i < researchResult.Length; i++) - { - if (i == CurrentLine) - { - currentSelected = researchResult[i]; - sb.Append($">"); - } - sb.AppendLine($" [ {researchResult[i].Id} ]: {researchResult[i].Title} "); - } - Console.Clear(); - Console.WriteLine(sb); - } - - public int SelectNextLine() - { - return ++CurrentLine; - } - - public int SelectPrevioustLine() - { - return --CurrentLine; - } - - public Recipe? ReturnSelected() - { - return currentSelected; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Model; + +namespace ConsoleApp +{ + internal class SearcherRecipe + { + public int CurrentLine + { + get => _currentLine; + set + { + _currentLine = value; + if (_currentLine > _maxLines) + { + _currentLine = _maxLines; + } + if (_currentLine < 0) + { + _currentLine = 0; + } + return; + } + } + + public Recipe? CurrentSelected { get; private set; } + + private int _currentLine = 0; + private int _maxLines = 0; + + + public void UpdateDisplay(string researchStr, RecipeCollection researchResult) + { + _maxLines = researchResult.Count - 1; + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("---------------------------------------------------------"); + sb.AppendLine($" Research: {researchStr}"); + sb.AppendLine("---------------------------------------------------------"); + for (int i = 0; i < researchResult.Count; i++) + { + if (i == CurrentLine) + { + CurrentSelected = researchResult[i]; + sb.Append($">"); + } + sb.AppendLine($" [ {researchResult[i].Id} ]: {researchResult[i].Title} "); + } + Console.Clear(); + Console.WriteLine(sb); + } + + public int SelectNextLine() + { + return ++CurrentLine; + } + + public int SelectPrevioustLine() + { + return --CurrentLine; + } + } +} diff --git a/MCTG/Model/IReasearch.cs b/MCTG/Model/IReasearch.cs deleted file mode 100644 index 74314a1..0000000 --- a/MCTG/Model/IReasearch.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Model -{ - public interface IReasearch - { - public T ResearchByName(string str); - } -} diff --git a/MCTG/Model/Manager.cs b/MCTG/Model/Manager.cs new file mode 100644 index 0000000..0a233eb --- /dev/null +++ b/MCTG/Model/Manager.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Model +{ + public partial class Manager + { + public RecipeCollection AllRecipes { get; protected set; } + + public Manager() + { + AllRecipes = new RecipeCollection(description: "All Recipes"); + } + + public Manager(RecipeCollection allRecipes) + { + AllRecipes = new RecipeCollection( + description: "All Recipes", + recipes: allRecipes.ToArray()); + } + } +} diff --git a/MCTG/Model/RecipeCollection.cs b/MCTG/Model/RecipeCollection.cs index 3da7d6d..3108a35 100644 --- a/MCTG/Model/RecipeCollection.cs +++ b/MCTG/Model/RecipeCollection.cs @@ -1,159 +1,161 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Text; - -namespace Model -{ - /// - /// Define a collection of . - ///
This class implement and . - ///
- public class RecipeCollection : IList, IEquatable - { - #region Attributes - private readonly List _recipes; - private string _description = ""; - #endregion - - #region Properties - /// - /// A short description of what this collection contain.
- /// Set to "No description." when the value passed is null, empty or contain white spaces. - ///
- public string Description - { - get => _description; - set - { - if (string.IsNullOrWhiteSpace(value)) - _description = "No description."; - else - _description = value; - } - } - - #region IList Prperties - public int Count => _recipes.Count; - public bool IsReadOnly => false; - public Recipe this[int index] { get => _recipes[index]; set => _recipes[index] = value; } - #endregion - #endregion - - #region Constructors - /// - /// Construct a new collection of _recipes. - /// - /// A short description of what this list will contain - /// Recipes to add in this new collection - public RecipeCollection(string description, params Recipe[] recipes) - { - _recipes = new List(recipes); - Description = description; - } - #endregion - - #region Methods - /// - /// Find a recipe in this list by giving the id. - /// - /// The id of the list we are looking for - /// The recipe of the id given - /// - public Recipe? GetRecipeById(int id) - { - Recipe? recipe = _recipes.Find(r => r.Id == id); - if (recipe == null) throw new ArgumentException("No _recipes match the given id."); - return recipe; - } - - #region IList Methods - public int IndexOf(Recipe item) - { - return _recipes.IndexOf(item); - } - - public void Insert(int index, Recipe item) - { - _recipes.Insert(index, item); - } - - public void RemoveAt(int index) - { - _recipes.RemoveAt(index); - } - - public void Add(Recipe item) - { - _recipes.Add(item); - } - - public void Clear() - { - _recipes.Clear(); - } - - public bool Contains(Recipe item) - { - return _recipes.Contains(item); - } - - public void CopyTo(Recipe[] array, int arrayIndex) - { - _recipes.CopyTo(array, arrayIndex); - } - - public bool Remove(Recipe item) - { - return _recipes.Remove(item); - } - - public IEnumerator GetEnumerator() - { - return _recipes.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _recipes.GetEnumerator(); - } - #endregion - - public virtual bool Equals(RecipeCollection? other) - { - - if (other == null) return false; - if (other == this) return true; - return _description.Equals(other.Description) && _recipes.Equals(other._recipes); - } - - public override bool Equals(object? obj) - { - var item = obj as RecipeCollection; - if (item == null) return false; - return Equals(obj); - } - - public override int GetHashCode() - { - return _recipes.GetHashCode(); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder($"[RecipeCollection] - {Description}:\n"); - foreach (Recipe r in _recipes) - { - sb.AppendFormat("\t - {0}\n", r.ToString()); - } - return sb.ToString(); - } - - public Recipe[] ResearchByName(string str) - { - return _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray(); - } - #endregion - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; + +namespace Model +{ + /// + /// Define a collection of . + ///
This class implement and . + ///
+ public class RecipeCollection : IList, IEquatable + { + #region Attributes + private readonly List _recipes; + private string _description = ""; + #endregion + + #region Properties + /// + /// A short description of what this collection contain.
+ /// Set to "No description." when the value passed is null, empty or contain white spaces. + ///
+ public string Description + { + get => _description; + set + { + if (string.IsNullOrWhiteSpace(value)) + _description = "No description."; + else + _description = value; + } + } + + #region IList Prperties + public int Count => _recipes.Count; + public bool IsReadOnly => false; + public Recipe this[int index] { get => _recipes[index]; set => _recipes[index] = value; } + #endregion + #endregion + + #region Constructors + /// + /// Construct a new collection of _recipes. + /// + /// A short description of what this list will contain + /// Recipes to add in this new collection + public RecipeCollection(string description, params Recipe[] recipes) + { + _recipes = new List(recipes); + Description = description; + } + #endregion + + #region Methods + /// + /// Find a recipe in this list by giving the id. + /// + /// The id of the list we are looking for + /// The recipe of the id given + /// + public Recipe? GetRecipeById(int id) + { + Recipe? recipe = _recipes.Find(r => r.Id == id); + if (recipe == null) throw new ArgumentException("No _recipes match the given id."); + return recipe; + } + + public RecipeCollection ResearchByName(string str) + { + return new RecipeCollection( + description: $"Results of the research: {str}", + recipes: _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray()); + } + + #region IList Methods + public int IndexOf(Recipe item) + { + return _recipes.IndexOf(item); + } + + public void Insert(int index, Recipe item) + { + _recipes.Insert(index, item); + } + + public void RemoveAt(int index) + { + _recipes.RemoveAt(index); + } + + public void Add(Recipe item) + { + _recipes.Add(item); + } + + public void Clear() + { + _recipes.Clear(); + } + + public bool Contains(Recipe item) + { + return _recipes.Contains(item); + } + + public void CopyTo(Recipe[] array, int arrayIndex) + { + _recipes.CopyTo(array, arrayIndex); + } + + public bool Remove(Recipe item) + { + return _recipes.Remove(item); + } + + public IEnumerator GetEnumerator() + { + return _recipes.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _recipes.GetEnumerator(); + } + #endregion + + public virtual bool Equals(RecipeCollection? other) + { + + if (other == null) return false; + if (other == this) return true; + return _description.Equals(other.Description) && _recipes.Equals(other._recipes); + } + + public override bool Equals(object? obj) + { + var item = obj as RecipeCollection; + if (item == null) return false; + return Equals(obj); + } + + public override int GetHashCode() + { + return _recipes.GetHashCode(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder($"[RecipeCollection] - {Description}:\n"); + foreach (Recipe r in _recipes) + { + sb.AppendFormat("\t - {0}\n", r.ToString()); + } + return sb.ToString(); + } + #endregion + } +} From 473d2c7fd2630181c45446ae2e7239e3ef23f071 Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sat, 6 May 2023 18:03:57 +0200 Subject: [PATCH 3/8] add some recipes stubs --- MCTG/ConsoleApp/Stub.cs | 58 ++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/MCTG/ConsoleApp/Stub.cs b/MCTG/ConsoleApp/Stub.cs index a6fc02a..ec885c3 100644 --- a/MCTG/ConsoleApp/Stub.cs +++ b/MCTG/ConsoleApp/Stub.cs @@ -1,5 +1,6 @@ using Model; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; @@ -15,16 +16,53 @@ namespace ConsoleApp stub.AddRange(new[] { new Recipe(), - new Recipe("Cookies"), - new Recipe("Cookies", 23), - new Recipe("Cookies", null), - new Recipe("", null), - new Recipe("", 24), - new Recipe("Cookies", 24, - new PreparationStep(1)), - new Recipe("Cookies", 26, - new PreparationStep(1), - new PreparationStep(2, "Faire cuire.")) + new Recipe( + title: "Cookies"), + new Recipe( + title: "Cookies", id: 23), + new Recipe( + title: "Cookies au chocolat", id: null), + new Recipe( + title: "", id: null), + new Recipe( + title: "", id: 24), + new Recipe( + title: "Cookies", id: 24, + preparationSteps: new[]{ + new PreparationStep(1) + }), + new Recipe( + title: "Cookies", id: 26, + preparationSteps: new[]{ + new PreparationStep(1), + new PreparationStep(2, "Faire cuire.") + }), + new Recipe( + title: "Gateau à la crème", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 1h10 au four traditionnel.") + }), + new Recipe( + title: "Gateau au chocolat", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(2, "Ajouter 100g de chocolat fondu."), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 45h au four traditionnel.") + }), + new Recipe( + title: "Gateau aux cerises", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(2, "Ajouter des morceaux de fraises découpées en petits carré"), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 30min au four traditionnel.") + }), }); return stub; } From 1671bb6b8fba300891c6074ce6377cf6fc72d17b Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sat, 6 May 2023 18:44:56 +0200 Subject: [PATCH 4/8] :recycle: add interface and clean code --- MCTG/ConsoleApp/ConsoleMenu.cs | 12 +++++----- MCTG/ConsoleApp/IMenuDisplay.cs | 15 ++++++++++++ MCTG/ConsoleApp/SearcherRecipe.cs | 39 ++++++++++++++++++++++++------- 3 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 MCTG/ConsoleApp/IMenuDisplay.cs diff --git a/MCTG/ConsoleApp/ConsoleMenu.cs b/MCTG/ConsoleApp/ConsoleMenu.cs index 5b561ee..37279c4 100644 --- a/MCTG/ConsoleApp/ConsoleMenu.cs +++ b/MCTG/ConsoleApp/ConsoleMenu.cs @@ -19,9 +19,9 @@ namespace ConsoleApp public Recipe? ResearchOnRecipe() { StringBuilder sb = new StringBuilder(); - SearcherRecipe searcherRecipe = new SearcherRecipe(); - RecipeCollection result = AllRecipes.ResearchByName(sb.ToString()); - searcherRecipe.UpdateDisplay(sb.ToString(), result); + SearcherRecipe searcherRecipe = new SearcherRecipe(AllRecipes); + searcherRecipe.ComputeSearch(); + searcherRecipe.UpdateDisplay(); ConsoleKeyInfo cki; @@ -41,16 +41,16 @@ namespace ConsoleApp if (sb.Length > 0) { sb.Remove(sb.Length - 1, 1); - result = AllRecipes.ResearchByName(sb.ToString()); + searcherRecipe.ComputeSearch(sb.ToString()); } break; default: sb.Append(cki.KeyChar); - result = AllRecipes.ResearchByName(sb.ToString()); + searcherRecipe.ComputeSearch(sb.ToString()); break; } - searcherRecipe.UpdateDisplay(sb.ToString(), result); + searcherRecipe.UpdateDisplay(); } while (cki.Key != ConsoleKey.Enter); diff --git a/MCTG/ConsoleApp/IMenuDisplay.cs b/MCTG/ConsoleApp/IMenuDisplay.cs new file mode 100644 index 0000000..11622df --- /dev/null +++ b/MCTG/ConsoleApp/IMenuDisplay.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleApp +{ + internal interface IMenuDisplay + { + void UpdateDisplay(); + int SelectNextLine(); + int SelectPrevioustLine(); + } +} diff --git a/MCTG/ConsoleApp/SearcherRecipe.cs b/MCTG/ConsoleApp/SearcherRecipe.cs index 321c14c..771f47d 100644 --- a/MCTG/ConsoleApp/SearcherRecipe.cs +++ b/MCTG/ConsoleApp/SearcherRecipe.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; @@ -8,12 +9,12 @@ using Model; namespace ConsoleApp { - internal class SearcherRecipe + internal class SearcherRecipe : IMenuDisplay { public int CurrentLine { get => _currentLine; - set + private set { _currentLine = value; if (_currentLine > _maxLines) @@ -28,28 +29,48 @@ namespace ConsoleApp } } + public RecipeCollection SearchResult { get; private set; } + public Recipe? CurrentSelected { get; private set; } + public string ResearchStr { get; set; } + private RecipeCollection _allRecipes; + private string _researchStr = ""; private int _currentLine = 0; private int _maxLines = 0; - - public void UpdateDisplay(string researchStr, RecipeCollection researchResult) + + public SearcherRecipe(RecipeCollection recipes) + { + _allRecipes = recipes; + SearchResult = recipes; + ResearchStr = ""; + } + + public bool ComputeSearch(string researchStr = "") { - _maxLines = researchResult.Count - 1; + ResearchStr = researchStr; + SearchResult = _allRecipes.ResearchByName(ResearchStr.ToLower()); + _maxLines = SearchResult.Count - 1; + return SearchResult.Count > 0; + } + + + public void UpdateDisplay() + { StringBuilder sb = new StringBuilder(); sb.AppendLine("---------------------------------------------------------"); - sb.AppendLine($" Research: {researchStr}"); + sb.AppendLine($" Research: {ResearchStr}"); sb.AppendLine("---------------------------------------------------------"); - for (int i = 0; i < researchResult.Count; i++) + for (int i = 0; i < SearchResult.Count; i++) { if (i == CurrentLine) { - CurrentSelected = researchResult[i]; + CurrentSelected = SearchResult[i]; sb.Append($">"); } - sb.AppendLine($" [ {researchResult[i].Id} ]: {researchResult[i].Title} "); + sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} "); } Console.Clear(); Console.WriteLine(sb); From 9249306ad351264585bd3d525829d3871c40ad8e Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sun, 7 May 2023 00:20:29 +0200 Subject: [PATCH 5/8] :art: nested menu classes --- .gitignore | 1 + MCTG/ConsoleApp/ConsoleMenu.cs | 60 ++++++-------- MCTG/ConsoleApp/Program.cs | 9 +- MCTG/ConsoleApp/SearcherRecipe.cs | 131 ++++++++++++++++-------------- 4 files changed, 100 insertions(+), 101 deletions(-) diff --git a/.gitignore b/.gitignore index 6c1ac87..07fac84 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ # User-spacific editor config .editorconfig +.vscode # User-specific files *.rsuser diff --git a/MCTG/ConsoleApp/ConsoleMenu.cs b/MCTG/ConsoleApp/ConsoleMenu.cs index 37279c4..6cd551d 100644 --- a/MCTG/ConsoleApp/ConsoleMenu.cs +++ b/MCTG/ConsoleApp/ConsoleMenu.cs @@ -9,52 +9,38 @@ using System.Threading.Tasks; namespace ConsoleApp { - public class ConsoleMenu : Manager + public partial class ConsoleMenu : Manager { - public ConsoleMenu(Manager manager) + public abstract class SelectMenu : IMenuDisplay { - AllRecipes = manager.AllRecipes; - } - - public Recipe? ResearchOnRecipe() - { - StringBuilder sb = new StringBuilder(); - SearcherRecipe searcherRecipe = new SearcherRecipe(AllRecipes); - searcherRecipe.ComputeSearch(); - searcherRecipe.UpdateDisplay(); + protected int _currentLine = 0; + protected int _maxLines = 0; - ConsoleKeyInfo cki; + public T? CurrentSelected { get; protected set; } - do + public int CurrentLine { - cki = Console.ReadKey(true); - - switch (cki.Key) + get => _currentLine; + protected set { - case ConsoleKey.UpArrow: - searcherRecipe.SelectPrevioustLine(); - break; - case ConsoleKey.DownArrow: - searcherRecipe.SelectNextLine(); - break; - case ConsoleKey.Backspace: - if (sb.Length > 0) - { - sb.Remove(sb.Length - 1, 1); - searcherRecipe.ComputeSearch(sb.ToString()); - } - break; - default: - sb.Append(cki.KeyChar); - searcherRecipe.ComputeSearch(sb.ToString()); - break; + _currentLine = value; + if (_currentLine > _maxLines) + { + _currentLine = _maxLines; + } + if (_currentLine < 0) + { + _currentLine = 0; + } + return; } + } - searcherRecipe.UpdateDisplay(); - - } while (cki.Key != ConsoleKey.Enter); + public int SelectNextLine() { return ++CurrentLine; } + public int SelectPrevioustLine() { return --CurrentLine; } - return searcherRecipe.CurrentSelected; + public abstract void UpdateDisplay(); } + } } diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs index 909395f..00ea4d1 100644 --- a/MCTG/ConsoleApp/Program.cs +++ b/MCTG/ConsoleApp/Program.cs @@ -20,8 +20,11 @@ if (allRecipe == null) throw new ArgumentException("Load AllRecipe in stub: can't find 'All'."); Manager manager = new Manager(allRecipe); -ConsoleMenu menu = new ConsoleMenu(manager); -Recipe? recipeRetSearchMenu = menu.ResearchOnRecipe(); +Console.WriteLine(ConsoleMenu.SearcherRecipe.ResearchOn(manager.AllRecipes)); -Console.WriteLine(recipeRetSearchMenu); + + + +// press any key to quit +Console.ReadKey(); \ No newline at end of file diff --git a/MCTG/ConsoleApp/SearcherRecipe.cs b/MCTG/ConsoleApp/SearcherRecipe.cs index 771f47d..5a8e5c9 100644 --- a/MCTG/ConsoleApp/SearcherRecipe.cs +++ b/MCTG/ConsoleApp/SearcherRecipe.cs @@ -9,81 +9,90 @@ using Model; namespace ConsoleApp { - internal class SearcherRecipe : IMenuDisplay + public partial class ConsoleMenu : Manager { - public int CurrentLine + public class SearcherRecipe : SelectMenu { - get => _currentLine; - private set + public RecipeCollection SearchResult { get; private set; } + public string ResearchStr { get; set; } + private RecipeCollection _recipeOnSearch; + + + public SearcherRecipe(RecipeCollection recipeOnSearch) { - _currentLine = value; - if (_currentLine > _maxLines) - { - _currentLine = _maxLines; - } - if (_currentLine < 0) - { - _currentLine = 0; - } - return; + _recipeOnSearch = recipeOnSearch; + SearchResult = _recipeOnSearch; + ResearchStr = ""; } - } - - public RecipeCollection SearchResult { get; private set; } - public Recipe? CurrentSelected { get; private set; } - public string ResearchStr { get; set; } + public bool ComputeSearch(string researchStr = "") + { + ResearchStr = researchStr; + SearchResult = _recipeOnSearch.ResearchByName(ResearchStr.ToLower()); + _maxLines = SearchResult.Count - 1; - private RecipeCollection _allRecipes; - private string _researchStr = ""; - private int _currentLine = 0; - private int _maxLines = 0; + return SearchResult.Count > 0; + } + public override void UpdateDisplay() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("---------------------------------------------------------"); + sb.AppendLine($" Research: {ResearchStr}"); + sb.AppendLine("---------------------------------------------------------"); + for (int i = 0; i < SearchResult.Count; i++) + { + if (i == CurrentLine) + { + CurrentSelected = SearchResult[i]; + sb.Append($">"); + } + sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} "); + } + Console.Clear(); + Console.WriteLine(sb); + } - public SearcherRecipe(RecipeCollection recipes) - { - _allRecipes = recipes; - SearchResult = recipes; - ResearchStr = ""; - } + public static Recipe? ResearchOn(RecipeCollection recipeOnSearch) + { + SearcherRecipe sr = new SearcherRecipe(recipeOnSearch); + StringBuilder sb = new StringBuilder(); + sr.ComputeSearch(); + sr.UpdateDisplay(); - public bool ComputeSearch(string researchStr = "") - { - ResearchStr = researchStr; - SearchResult = _allRecipes.ResearchByName(ResearchStr.ToLower()); - _maxLines = SearchResult.Count - 1; + ConsoleKeyInfo cki; - return SearchResult.Count > 0; - } + do + { + cki = Console.ReadKey(true); + switch (cki.Key) + { + case ConsoleKey.UpArrow: + sr.SelectPrevioustLine(); + break; + case ConsoleKey.DownArrow: + sr.SelectNextLine(); + break; + case ConsoleKey.Backspace: + if (sb.Length > 0) + { + sb.Remove(sb.Length - 1, 1); + sr.ComputeSearch(sb.ToString()); + } + break; + default: + sb.Append(cki.KeyChar); + sr.ComputeSearch(sb.ToString()); + break; + } - public void UpdateDisplay() - { - StringBuilder sb = new StringBuilder(); - sb.AppendLine("---------------------------------------------------------"); - sb.AppendLine($" Research: {ResearchStr}"); - sb.AppendLine("---------------------------------------------------------"); - for (int i = 0; i < SearchResult.Count; i++) - { - if (i == CurrentLine) - { - CurrentSelected = SearchResult[i]; - sb.Append($">"); - } - sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} "); - } - Console.Clear(); - Console.WriteLine(sb); - } + sr.UpdateDisplay(); - public int SelectNextLine() - { - return ++CurrentLine; - } + } while (cki.Key != ConsoleKey.Enter); - public int SelectPrevioustLine() - { - return --CurrentLine; + return sr.CurrentSelected; + } } } } From 2143f0637ec64294e26dcd78d76437eb29d204f8 Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sun, 7 May 2023 01:00:34 +0200 Subject: [PATCH 6/8] :memo: new documentation + new file organisation --- MCTG/ConsoleApp/IMenuDisplay.cs | 15 - MCTG/ConsoleApp/{ => Menu}/ConsoleMenu.cs | 16 + MCTG/ConsoleApp/Menu/IMenuDisplay.cs | 28 ++ MCTG/ConsoleApp/{ => Menu}/SearcherRecipe.cs | 34 +- MCTG/ConsoleApp/Program.cs | 4 +- MCTG/ConsoleApp/{ => Stubs}/Stub.cs | 166 +++++----- MCTG/Model/{ => Manager}/Manager.cs | 15 +- MCTG/Model/Model.csproj | 2 +- MCTG/Model/{ => Recipes}/PreparationStep.cs | 0 MCTG/Model/{ => Recipes}/Recipe.cs | 202 ++++++------ MCTG/Model/{ => Recipes}/RecipeCollection.cs | 327 ++++++++++--------- 11 files changed, 442 insertions(+), 367 deletions(-) delete mode 100644 MCTG/ConsoleApp/IMenuDisplay.cs rename MCTG/ConsoleApp/{ => Menu}/ConsoleMenu.cs (65%) create mode 100644 MCTG/ConsoleApp/Menu/IMenuDisplay.cs rename MCTG/ConsoleApp/{ => Menu}/SearcherRecipe.cs (72%) rename MCTG/ConsoleApp/{ => Stubs}/Stub.cs (97%) rename MCTG/Model/{ => Manager}/Manager.cs (52%) rename MCTG/Model/{ => Recipes}/PreparationStep.cs (100%) rename MCTG/Model/{ => Recipes}/Recipe.cs (96%) rename MCTG/Model/{ => Recipes}/RecipeCollection.cs (94%) diff --git a/MCTG/ConsoleApp/IMenuDisplay.cs b/MCTG/ConsoleApp/IMenuDisplay.cs deleted file mode 100644 index 11622df..0000000 --- a/MCTG/ConsoleApp/IMenuDisplay.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ConsoleApp -{ - internal interface IMenuDisplay - { - void UpdateDisplay(); - int SelectNextLine(); - int SelectPrevioustLine(); - } -} diff --git a/MCTG/ConsoleApp/ConsoleMenu.cs b/MCTG/ConsoleApp/Menu/ConsoleMenu.cs similarity index 65% rename from MCTG/ConsoleApp/ConsoleMenu.cs rename to MCTG/ConsoleApp/Menu/ConsoleMenu.cs index 6cd551d..5e91b27 100644 --- a/MCTG/ConsoleApp/ConsoleMenu.cs +++ b/MCTG/ConsoleApp/Menu/ConsoleMenu.cs @@ -9,15 +9,31 @@ using System.Threading.Tasks; namespace ConsoleApp { + /// + /// Define multiple type of menu + ///
See: + ///
- + ///
- + ///
public partial class ConsoleMenu : Manager { + /// + /// An abstract class that define the components of a selection-type menu. + /// + /// The return type of the currently selected item public abstract class SelectMenu : IMenuDisplay { protected int _currentLine = 0; protected int _maxLines = 0; + /// + /// The currently selected item. + /// public T? CurrentSelected { get; protected set; } + /// + /// The current line selected in the menu. + /// public int CurrentLine { get => _currentLine; diff --git a/MCTG/ConsoleApp/Menu/IMenuDisplay.cs b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs new file mode 100644 index 0000000..44341aa --- /dev/null +++ b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleApp +{ + internal interface IMenuDisplay + { + /// + /// Update the menu display in the Console. + /// + void UpdateDisplay(); + + /// + /// Select the next line in the menu + /// + /// The current number of the new selected line + int SelectNextLine(); + + /// + /// Select the previous line in the menu + /// + /// The current number of the new selected line + int SelectPrevioustLine(); + } +} diff --git a/MCTG/ConsoleApp/SearcherRecipe.cs b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs similarity index 72% rename from MCTG/ConsoleApp/SearcherRecipe.cs rename to MCTG/ConsoleApp/Menu/SearcherRecipe.cs index 5a8e5c9..97f5162 100644 --- a/MCTG/ConsoleApp/SearcherRecipe.cs +++ b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs @@ -11,13 +11,31 @@ namespace ConsoleApp { public partial class ConsoleMenu : Manager { + /// + /// An utility to find a recipe. + /// public class SearcherRecipe : SelectMenu { - public RecipeCollection SearchResult { get; private set; } - public string ResearchStr { get; set; } + #region Attribute private RecipeCollection _recipeOnSearch; + #endregion + #region Properties + /// + /// A collection of recipe where the title contain the search string + /// + public RecipeCollection SearchResult { get; private set; } + + /// + /// The search string + /// + public string ResearchStr { get; set; } + #endregion + /// + /// Constructor of the SearcherRecipe utility. + /// + /// The collection of recipe where to search public SearcherRecipe(RecipeCollection recipeOnSearch) { _recipeOnSearch = recipeOnSearch; @@ -25,6 +43,12 @@ namespace ConsoleApp ResearchStr = ""; } + #region Methodes + /// + /// Launch a search by name request in the collection of Recipe with with a string. + /// + /// The string for search + /// True if the result of the search gave at least 1 element. False otherwise. public bool ComputeSearch(string researchStr = "") { ResearchStr = researchStr; @@ -53,6 +77,11 @@ namespace ConsoleApp Console.WriteLine(sb); } + /// + /// Launch and pilot the search menu. + /// + /// The collection of recipe where to search + /// The recipe selected public static Recipe? ResearchOn(RecipeCollection recipeOnSearch) { SearcherRecipe sr = new SearcherRecipe(recipeOnSearch); @@ -93,6 +122,7 @@ namespace ConsoleApp return sr.CurrentSelected; } + #endregion } } } diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs index 00ea4d1..f3bccbd 100644 --- a/MCTG/ConsoleApp/Program.cs +++ b/MCTG/ConsoleApp/Program.cs @@ -24,7 +24,5 @@ Manager manager = new Manager(allRecipe); Console.WriteLine(ConsoleMenu.SearcherRecipe.ResearchOn(manager.AllRecipes)); - - // press any key to quit -Console.ReadKey(); \ No newline at end of file +Console.ReadKey(); diff --git a/MCTG/ConsoleApp/Stub.cs b/MCTG/ConsoleApp/Stubs/Stub.cs similarity index 97% rename from MCTG/ConsoleApp/Stub.cs rename to MCTG/ConsoleApp/Stubs/Stub.cs index ec885c3..7a0805b 100644 --- a/MCTG/ConsoleApp/Stub.cs +++ b/MCTG/ConsoleApp/Stubs/Stub.cs @@ -1,83 +1,83 @@ -using Model; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ConsoleApp -{ - internal struct Stub - { - public List LoadRecipes() - { - List stub = new List(); - stub.AddRange(new[] - { - new Recipe(), - new Recipe( - title: "Cookies"), - new Recipe( - title: "Cookies", id: 23), - new Recipe( - title: "Cookies au chocolat", id: null), - new Recipe( - title: "", id: null), - new Recipe( - title: "", id: 24), - new Recipe( - title: "Cookies", id: 24, - preparationSteps: new[]{ - new PreparationStep(1) - }), - new Recipe( - title: "Cookies", id: 26, - preparationSteps: new[]{ - new PreparationStep(1), - new PreparationStep(2, "Faire cuire.") - }), - new Recipe( - title: "Gateau à la crème", - preparationSteps: new[]{ - new PreparationStep(1, "Ajouter les oeufs."), - new PreparationStep(2, "Ajouter la farine."), - new PreparationStep(3, "Mélanger le tout."), - new PreparationStep(4, "Faire cuire 1h10 au four traditionnel.") - }), - new Recipe( - title: "Gateau au chocolat", - preparationSteps: new[]{ - new PreparationStep(1, "Ajouter les oeufs."), - new PreparationStep(2, "Ajouter la farine."), - new PreparationStep(2, "Ajouter 100g de chocolat fondu."), - new PreparationStep(3, "Mélanger le tout."), - new PreparationStep(4, "Faire cuire 45h au four traditionnel.") - }), - new Recipe( - title: "Gateau aux cerises", - preparationSteps: new[]{ - new PreparationStep(1, "Ajouter les oeufs."), - new PreparationStep(2, "Ajouter la farine."), - new PreparationStep(2, "Ajouter des morceaux de fraises découpées en petits carré"), - new PreparationStep(3, "Mélanger le tout."), - new PreparationStep(4, "Faire cuire 30min au four traditionnel.") - }), - }); - return stub; - } - - public List LoadRecipeCollection() - { - List stub = new List(); - stub.AddRange(new[] - { - new RecipeCollection("All", LoadRecipes().ToArray()), - new RecipeCollection("Starters", LoadRecipes().FindAll(x => x.Id.Equals(23)).ToArray()), - new RecipeCollection("Dishies", LoadRecipes().FindAll(x => x.Id.Equals(24)).ToArray()), - new RecipeCollection("Desserts", LoadRecipes().FindAll(x => x.Id.Equals(26)).ToArray()), - }); - return stub; - } - } -} +using Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConsoleApp +{ + internal struct Stub + { + public List LoadRecipes() + { + List stub = new List(); + stub.AddRange(new[] + { + new Recipe(), + new Recipe( + title: "Cookies"), + new Recipe( + title: "Cookies", id: 23), + new Recipe( + title: "Cookies au chocolat", id: null), + new Recipe( + title: "", id: null), + new Recipe( + title: "", id: 24), + new Recipe( + title: "Cookies", id: 24, + preparationSteps: new[]{ + new PreparationStep(1) + }), + new Recipe( + title: "Cookies", id: 26, + preparationSteps: new[]{ + new PreparationStep(1), + new PreparationStep(2, "Faire cuire.") + }), + new Recipe( + title: "Gateau à la crème", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 1h10 au four traditionnel.") + }), + new Recipe( + title: "Gateau au chocolat", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(2, "Ajouter 100g de chocolat fondu."), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 45h au four traditionnel.") + }), + new Recipe( + title: "Gateau aux cerises", + preparationSteps: new[]{ + new PreparationStep(1, "Ajouter les oeufs."), + new PreparationStep(2, "Ajouter la farine."), + new PreparationStep(2, "Ajouter des morceaux de fraises découpées en petits carré"), + new PreparationStep(3, "Mélanger le tout."), + new PreparationStep(4, "Faire cuire 30min au four traditionnel.") + }), + }); + return stub; + } + + public List LoadRecipeCollection() + { + List stub = new List(); + stub.AddRange(new[] + { + new RecipeCollection("All", LoadRecipes().ToArray()), + new RecipeCollection("Starters", LoadRecipes().FindAll(x => x.Id.Equals(23)).ToArray()), + new RecipeCollection("Dishies", LoadRecipes().FindAll(x => x.Id.Equals(24)).ToArray()), + new RecipeCollection("Desserts", LoadRecipes().FindAll(x => x.Id.Equals(26)).ToArray()), + }); + return stub; + } + } +} diff --git a/MCTG/Model/Manager.cs b/MCTG/Model/Manager/Manager.cs similarity index 52% rename from MCTG/Model/Manager.cs rename to MCTG/Model/Manager/Manager.cs index 0a233eb..5c4a6a7 100644 --- a/MCTG/Model/Manager.cs +++ b/MCTG/Model/Manager/Manager.cs @@ -6,15 +6,28 @@ using System.Threading.Tasks; namespace Model { - public partial class Manager + /// + /// Manager of the model. Here is stoked all the recipes, the users, etc... + /// + public class Manager { + /// + /// A collection of all the recipe loaded in the app. + /// public RecipeCollection AllRecipes { get; protected set; } + /// + /// The constructor of the manager. + /// public Manager() { AllRecipes = new RecipeCollection(description: "All Recipes"); } + /// + /// The constructor of the manager. + /// + /// A list of loaded recipes public Manager(RecipeCollection allRecipes) { AllRecipes = new RecipeCollection( diff --git a/MCTG/Model/Model.csproj b/MCTG/Model/Model.csproj index cfadb03..a1ed5b3 100644 --- a/MCTG/Model/Model.csproj +++ b/MCTG/Model/Model.csproj @@ -1,4 +1,4 @@ - + net7.0 diff --git a/MCTG/Model/PreparationStep.cs b/MCTG/Model/Recipes/PreparationStep.cs similarity index 100% rename from MCTG/Model/PreparationStep.cs rename to MCTG/Model/Recipes/PreparationStep.cs diff --git a/MCTG/Model/Recipe.cs b/MCTG/Model/Recipes/Recipe.cs similarity index 96% rename from MCTG/Model/Recipe.cs rename to MCTG/Model/Recipes/Recipe.cs index 341383c..6048fdf 100644 --- a/MCTG/Model/Recipe.cs +++ b/MCTG/Model/Recipes/Recipe.cs @@ -1,101 +1,101 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Security.Cryptography; -using System.Text; - -namespace Model -{ - /// - /// Define a Recipe for the preparation of a meal. - /// - public class Recipe : IEquatable - { - #region Attributes - private string _title = ""; - #endregion - - #region Properties - /// - /// The ID of the recipe - allows you to compare and/or get this item in an easier way. - /// - public int Id { get; init; } - - /// - /// The Title of the recipe.
- /// Set to "No title." when the value passed is null, empty or contain white spaces. - ///
- public string Title - { - get => _title; - set - { - if (string.IsNullOrWhiteSpace(value)) - _title = "No title."; - else - _title = value; - } - } - - /// - /// The steps of the preparation. See: . - /// - public List PreparationSteps { get; set; } - #endregion - - #region Constructors - /// - /// Construct a new recipe. - /// - /// The title of the recipe - /// The id of the recipe. If not given, get a new id. - /// The steps of the preparation of the meal - public Recipe(string title = "", int? id = null, - params PreparationStep[] preparationSteps) - { - Title = title; - PreparationSteps = new List(preparationSteps); - - if (id == null) - { - var randomGenerator = RandomNumberGenerator.Create(); - byte[] data = new byte[16]; - randomGenerator.GetBytes(data); - Id = Math.Abs(BitConverter.ToInt16(data)); - } - else Id = (int)id; - } - #endregion - - #region Methods - public virtual bool Equals(Recipe? other) - { - if (other == null) return false; - if (other == this) return true; - return Title.Equals(other.Title) && PreparationSteps.Equals(other.PreparationSteps); - } - - public override bool Equals(object? obj) - { - var item = obj as Recipe; - if (item == null) return false; - return Equals(obj); - } - - public override int GetHashCode() - { - return Id.GetHashCode(); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder($"[Recipe n°{Id}] - {Title}\n"); - foreach (PreparationStep ps in PreparationSteps) - { - sb.AppendFormat("\t* {0}\n", ps.ToString()); - } - return sb.ToString(); - } - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Text; + +namespace Model +{ + /// + /// Define a Recipe for the preparation of a meal. + /// + public class Recipe : IEquatable + { + #region Attributes + private string _title = ""; + #endregion + + #region Properties + /// + /// The ID of the recipe - allows you to compare and/or get this item in an easier way. + /// + public int Id { get; init; } + + /// + /// The Title of the recipe.
+ /// Set to "No title." when the value passed is null, empty or contain white spaces. + ///
+ public string Title + { + get => _title; + set + { + if (string.IsNullOrWhiteSpace(value)) + _title = "No title."; + else + _title = value; + } + } + + /// + /// The steps of the preparation. See: . + /// + public List PreparationSteps { get; set; } + #endregion + + #region Constructors + /// + /// Construct a new recipe. + /// + /// The title of the recipe + /// The id of the recipe. If not given, get a new id. + /// The steps of the preparation of the meal + public Recipe(string title = "", int? id = null, + params PreparationStep[] preparationSteps) + { + Title = title; + PreparationSteps = new List(preparationSteps); + + if (id == null) + { + var randomGenerator = RandomNumberGenerator.Create(); + byte[] data = new byte[16]; + randomGenerator.GetBytes(data); + Id = Math.Abs(BitConverter.ToInt16(data)); + } + else Id = (int)id; + } + #endregion + + #region Methods + public virtual bool Equals(Recipe? other) + { + if (other == null) return false; + if (other == this) return true; + return Title.Equals(other.Title) && PreparationSteps.Equals(other.PreparationSteps); + } + + public override bool Equals(object? obj) + { + var item = obj as Recipe; + if (item == null) return false; + return Equals(obj); + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder($"[Recipe n°{Id}] - {Title}\n"); + foreach (PreparationStep ps in PreparationSteps) + { + sb.AppendFormat("\t* {0}\n", ps.ToString()); + } + return sb.ToString(); + } + #endregion + } +} diff --git a/MCTG/Model/RecipeCollection.cs b/MCTG/Model/Recipes/RecipeCollection.cs similarity index 94% rename from MCTG/Model/RecipeCollection.cs rename to MCTG/Model/Recipes/RecipeCollection.cs index 3108a35..42ff5d8 100644 --- a/MCTG/Model/RecipeCollection.cs +++ b/MCTG/Model/Recipes/RecipeCollection.cs @@ -1,161 +1,166 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Text; - -namespace Model -{ - /// - /// Define a collection of . - ///
This class implement and . - ///
- public class RecipeCollection : IList, IEquatable - { - #region Attributes - private readonly List _recipes; - private string _description = ""; - #endregion - - #region Properties - /// - /// A short description of what this collection contain.
- /// Set to "No description." when the value passed is null, empty or contain white spaces. - ///
- public string Description - { - get => _description; - set - { - if (string.IsNullOrWhiteSpace(value)) - _description = "No description."; - else - _description = value; - } - } - - #region IList Prperties - public int Count => _recipes.Count; - public bool IsReadOnly => false; - public Recipe this[int index] { get => _recipes[index]; set => _recipes[index] = value; } - #endregion - #endregion - - #region Constructors - /// - /// Construct a new collection of _recipes. - /// - /// A short description of what this list will contain - /// Recipes to add in this new collection - public RecipeCollection(string description, params Recipe[] recipes) - { - _recipes = new List(recipes); - Description = description; - } - #endregion - - #region Methods - /// - /// Find a recipe in this list by giving the id. - /// - /// The id of the list we are looking for - /// The recipe of the id given - /// - public Recipe? GetRecipeById(int id) - { - Recipe? recipe = _recipes.Find(r => r.Id == id); - if (recipe == null) throw new ArgumentException("No _recipes match the given id."); - return recipe; - } - - public RecipeCollection ResearchByName(string str) - { - return new RecipeCollection( - description: $"Results of the research: {str}", - recipes: _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray()); - } - - #region IList Methods - public int IndexOf(Recipe item) - { - return _recipes.IndexOf(item); - } - - public void Insert(int index, Recipe item) - { - _recipes.Insert(index, item); - } - - public void RemoveAt(int index) - { - _recipes.RemoveAt(index); - } - - public void Add(Recipe item) - { - _recipes.Add(item); - } - - public void Clear() - { - _recipes.Clear(); - } - - public bool Contains(Recipe item) - { - return _recipes.Contains(item); - } - - public void CopyTo(Recipe[] array, int arrayIndex) - { - _recipes.CopyTo(array, arrayIndex); - } - - public bool Remove(Recipe item) - { - return _recipes.Remove(item); - } - - public IEnumerator GetEnumerator() - { - return _recipes.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _recipes.GetEnumerator(); - } - #endregion - - public virtual bool Equals(RecipeCollection? other) - { - - if (other == null) return false; - if (other == this) return true; - return _description.Equals(other.Description) && _recipes.Equals(other._recipes); - } - - public override bool Equals(object? obj) - { - var item = obj as RecipeCollection; - if (item == null) return false; - return Equals(obj); - } - - public override int GetHashCode() - { - return _recipes.GetHashCode(); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder($"[RecipeCollection] - {Description}:\n"); - foreach (Recipe r in _recipes) - { - sb.AppendFormat("\t - {0}\n", r.ToString()); - } - return sb.ToString(); - } - #endregion - } -} +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; + +namespace Model +{ + /// + /// Define a collection of . + ///
This class implement and . + ///
+ public class RecipeCollection : IList, IEquatable + { + #region Attributes + private readonly List _recipes; + private string _description = ""; + #endregion + + #region Properties + /// + /// A short description of what this collection contain.
+ /// Set to "No description." when the value passed is null, empty or contain white spaces. + ///
+ public string Description + { + get => _description; + set + { + if (string.IsNullOrWhiteSpace(value)) + _description = "No description."; + else + _description = value; + } + } + + #region IList Prperties + public int Count => _recipes.Count; + public bool IsReadOnly => false; + public Recipe this[int index] { get => _recipes[index]; set => _recipes[index] = value; } + #endregion + #endregion + + #region Constructors + /// + /// Construct a new collection of _recipes. + /// + /// A short description of what this list will contain + /// Recipes to add in this new collection + public RecipeCollection(string description, params Recipe[] recipes) + { + _recipes = new List(recipes); + Description = description; + } + #endregion + + #region Methods + /// + /// Find a recipe in this list by giving the id. + /// + /// The id of the list we are looking for + /// The recipe of the id given + /// + public Recipe? GetRecipeById(int id) + { + Recipe? recipe = _recipes.Find(r => r.Id == id); + if (recipe == null) throw new ArgumentException("No _recipes match the given id."); + return recipe; + } + + /// + /// Utility to find a recipe by his name. + /// + /// The string for the search + /// A collection of Recipe where their Title contain the string. + public RecipeCollection ResearchByName(string str) + { + return new RecipeCollection( + description: $"Results of the research: {str}", + recipes: _recipes.FindAll(x => x.Title.ToLower().Contains(str.ToLower())).ToArray()); + } + + #region IList Methods + public int IndexOf(Recipe item) + { + return _recipes.IndexOf(item); + } + + public void Insert(int index, Recipe item) + { + _recipes.Insert(index, item); + } + + public void RemoveAt(int index) + { + _recipes.RemoveAt(index); + } + + public void Add(Recipe item) + { + _recipes.Add(item); + } + + public void Clear() + { + _recipes.Clear(); + } + + public bool Contains(Recipe item) + { + return _recipes.Contains(item); + } + + public void CopyTo(Recipe[] array, int arrayIndex) + { + _recipes.CopyTo(array, arrayIndex); + } + + public bool Remove(Recipe item) + { + return _recipes.Remove(item); + } + + public IEnumerator GetEnumerator() + { + return _recipes.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _recipes.GetEnumerator(); + } + #endregion + + public virtual bool Equals(RecipeCollection? other) + { + + if (other == null) return false; + if (other == this) return true; + return _description.Equals(other.Description) && _recipes.Equals(other._recipes); + } + + public override bool Equals(object? obj) + { + var item = obj as RecipeCollection; + if (item == null) return false; + return Equals(obj); + } + + public override int GetHashCode() + { + return _recipes.GetHashCode(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder($"[RecipeCollection] - {Description}:\n"); + foreach (Recipe r in _recipes) + { + sb.AppendFormat("\t - {0}\n", r.ToString()); + } + return sb.ToString(); + } + #endregion + } +} From b2e6217d103eb7b49c99969d1efd09797007e456 Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sun, 7 May 2023 01:12:16 +0200 Subject: [PATCH 7/8] :white_check_mark: make sure test work + add a test for RecipeCollection.ResearchByName --- .../Model_UnitTests/RecipeCollection_UT.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs diff --git a/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs b/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs new file mode 100644 index 0000000..36008b1 --- /dev/null +++ b/MCTG/Tests/Model_UnitTests/RecipeCollection_UT.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Model; + +namespace Model_UnitTests +{ + public class RecipeCollection_UT + { + [Fact] + public void TestResearchByName() + { + RecipeCollection recipes = new RecipeCollection( + description: "test recipe", + recipes: new[] + { + new Recipe(title: "Gateau à la crème", id: 1), + new Recipe(title: "Gateau au chocolat", id: 2), + new Recipe(title: "Gateau aux cerises", id: 3) + }); + + Assert.Equal(2, recipes.ResearchByName("chocolat").FirstOrDefault().Id); + } + } +} From 1a2ecceb258e241bd2d17e1f66ebfb9e3cca0a36 Mon Sep 17 00:00:00 2001 From: Alexandre Agostinho Date: Sun, 7 May 2023 02:10:15 +0200 Subject: [PATCH 8/8] change nested class 'ConsoleMenu' to namespace 'Menu' --- MCTG/ConsoleApp/Menu/ConsoleMenu.cs | 62 -------- MCTG/ConsoleApp/Menu/IMenuDisplay.cs | 2 +- MCTG/ConsoleApp/Menu/SearcherRecipe.cs | 187 ++++++++++++------------- MCTG/ConsoleApp/Menu/SelectMenu.cs | 52 +++++++ MCTG/ConsoleApp/Program.cs | 11 +- 5 files changed, 151 insertions(+), 163 deletions(-) delete mode 100644 MCTG/ConsoleApp/Menu/ConsoleMenu.cs create mode 100644 MCTG/ConsoleApp/Menu/SelectMenu.cs diff --git a/MCTG/ConsoleApp/Menu/ConsoleMenu.cs b/MCTG/ConsoleApp/Menu/ConsoleMenu.cs deleted file mode 100644 index 5e91b27..0000000 --- a/MCTG/ConsoleApp/Menu/ConsoleMenu.cs +++ /dev/null @@ -1,62 +0,0 @@ -using ConsoleApp; -using Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - - -namespace ConsoleApp -{ - /// - /// Define multiple type of menu - ///
See: - ///
- - ///
- - ///
- public partial class ConsoleMenu : Manager - { - /// - /// An abstract class that define the components of a selection-type menu. - /// - /// The return type of the currently selected item - public abstract class SelectMenu : IMenuDisplay - { - protected int _currentLine = 0; - protected int _maxLines = 0; - - /// - /// The currently selected item. - /// - public T? CurrentSelected { get; protected set; } - - /// - /// The current line selected in the menu. - /// - public int CurrentLine - { - get => _currentLine; - protected set - { - _currentLine = value; - if (_currentLine > _maxLines) - { - _currentLine = _maxLines; - } - if (_currentLine < 0) - { - _currentLine = 0; - } - return; - } - } - - public int SelectNextLine() { return ++CurrentLine; } - public int SelectPrevioustLine() { return --CurrentLine; } - - public abstract void UpdateDisplay(); - } - - } -} diff --git a/MCTG/ConsoleApp/Menu/IMenuDisplay.cs b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs index 44341aa..572082c 100644 --- a/MCTG/ConsoleApp/Menu/IMenuDisplay.cs +++ b/MCTG/ConsoleApp/Menu/IMenuDisplay.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace ConsoleApp +namespace ConsoleApp.Menu { internal interface IMenuDisplay { diff --git a/MCTG/ConsoleApp/Menu/SearcherRecipe.cs b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs index 97f5162..4e17512 100644 --- a/MCTG/ConsoleApp/Menu/SearcherRecipe.cs +++ b/MCTG/ConsoleApp/Menu/SearcherRecipe.cs @@ -7,122 +7,119 @@ using System.Threading.Tasks; using Model; -namespace ConsoleApp +namespace ConsoleApp.Menu { - public partial class ConsoleMenu : Manager + /// + /// An utility to find a recipe. + /// + public class SearcherRecipe : SelectMenu { + #region Attribute + private RecipeCollection _recipeOnSearch; + #endregion + + #region Properties /// - /// An utility to find a recipe. + /// A collection of recipe where the title contain the search string /// - public class SearcherRecipe : SelectMenu - { - #region Attribute - private RecipeCollection _recipeOnSearch; - #endregion + public RecipeCollection SearchResult { get; private set; } - #region Properties - /// - /// A collection of recipe where the title contain the search string - /// - public RecipeCollection SearchResult { get; private set; } - - /// - /// The search string - /// - public string ResearchStr { get; set; } - #endregion + /// + /// The search string + /// + public string ResearchStr { get; set; } + #endregion - /// - /// Constructor of the SearcherRecipe utility. - /// - /// The collection of recipe where to search - public SearcherRecipe(RecipeCollection recipeOnSearch) - { - _recipeOnSearch = recipeOnSearch; - SearchResult = _recipeOnSearch; - ResearchStr = ""; - } + /// + /// Constructor of the SearcherRecipe utility. + /// + /// The collection of recipe where to search + public SearcherRecipe(RecipeCollection recipeOnSearch) + { + _recipeOnSearch = recipeOnSearch; + SearchResult = _recipeOnSearch; + ResearchStr = ""; + } - #region Methodes - /// - /// Launch a search by name request in the collection of Recipe with with a string. - /// - /// The string for search - /// True if the result of the search gave at least 1 element. False otherwise. - public bool ComputeSearch(string researchStr = "") - { - ResearchStr = researchStr; - SearchResult = _recipeOnSearch.ResearchByName(ResearchStr.ToLower()); - _maxLines = SearchResult.Count - 1; + #region Methodes + /// + /// Launch a search by name request in the collection of Recipe with with a string. + /// + /// The string for search + /// True if the result of the search gave at least 1 element. False otherwise. + public bool ComputeSearch(string researchStr = "") + { + ResearchStr = researchStr; + SearchResult = _recipeOnSearch.ResearchByName(ResearchStr.ToLower()); + _maxLines = SearchResult.Count - 1; - return SearchResult.Count > 0; - } + return SearchResult.Count > 0; + } - public override void UpdateDisplay() + public override void UpdateDisplay() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine("---------------------------------------------------------"); + sb.AppendLine($" Research: {ResearchStr}"); + sb.AppendLine("---------------------------------------------------------"); + for (int i = 0; i < SearchResult.Count; i++) { - StringBuilder sb = new StringBuilder(); - sb.AppendLine("---------------------------------------------------------"); - sb.AppendLine($" Research: {ResearchStr}"); - sb.AppendLine("---------------------------------------------------------"); - for (int i = 0; i < SearchResult.Count; i++) + if (i == CurrentLine) { - if (i == CurrentLine) - { - CurrentSelected = SearchResult[i]; - sb.Append($">"); - } - sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} "); + CurrentSelected = SearchResult[i]; + sb.Append($">"); } - Console.Clear(); - Console.WriteLine(sb); + sb.AppendLine($" [ {SearchResult[i].Id} ]:\t{SearchResult[i].Title} "); } + Console.Clear(); + Console.WriteLine(sb); + } - /// - /// Launch and pilot the search menu. - /// - /// The collection of recipe where to search - /// The recipe selected - public static Recipe? ResearchOn(RecipeCollection recipeOnSearch) - { - SearcherRecipe sr = new SearcherRecipe(recipeOnSearch); - StringBuilder sb = new StringBuilder(); - sr.ComputeSearch(); - sr.UpdateDisplay(); + /// + /// Launch and pilot the search menu. + /// + /// The collection of recipe where to search + /// The recipe selected + public static Recipe? ResearchOn(RecipeCollection recipeOnSearch) + { + SearcherRecipe sr = new SearcherRecipe(recipeOnSearch); + StringBuilder sb = new StringBuilder(); + sr.ComputeSearch(); + sr.UpdateDisplay(); - ConsoleKeyInfo cki; + ConsoleKeyInfo cki; - do - { - cki = Console.ReadKey(true); + do + { + cki = Console.ReadKey(true); - switch (cki.Key) - { - case ConsoleKey.UpArrow: - sr.SelectPrevioustLine(); - break; - case ConsoleKey.DownArrow: - sr.SelectNextLine(); - break; - case ConsoleKey.Backspace: - if (sb.Length > 0) - { - sb.Remove(sb.Length - 1, 1); - sr.ComputeSearch(sb.ToString()); - } - break; - default: - sb.Append(cki.KeyChar); + switch (cki.Key) + { + case ConsoleKey.UpArrow: + sr.SelectPrevioustLine(); + break; + case ConsoleKey.DownArrow: + sr.SelectNextLine(); + break; + case ConsoleKey.Backspace: + if (sb.Length > 0) + { + sb.Remove(sb.Length - 1, 1); sr.ComputeSearch(sb.ToString()); - break; - } + } + break; + default: + sb.Append(cki.KeyChar); + sr.ComputeSearch(sb.ToString()); + break; + } - sr.UpdateDisplay(); + sr.UpdateDisplay(); - } while (cki.Key != ConsoleKey.Enter); + } while (cki.Key != ConsoleKey.Enter); - return sr.CurrentSelected; - } - #endregion + return sr.CurrentSelected; } + #endregion } } diff --git a/MCTG/ConsoleApp/Menu/SelectMenu.cs b/MCTG/ConsoleApp/Menu/SelectMenu.cs new file mode 100644 index 0000000..0e331c6 --- /dev/null +++ b/MCTG/ConsoleApp/Menu/SelectMenu.cs @@ -0,0 +1,52 @@ +using ConsoleApp; +using Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace ConsoleApp.Menu +{ + /// + /// An abstract class that define the components of a selection-type menu. + /// + /// The return type of the currently selected item + public abstract class SelectMenu : IMenuDisplay + { + protected int _currentLine = 0; + protected int _maxLines = 0; + + /// + /// The currently selected item. + /// + public T? CurrentSelected { get; protected set; } + + /// + /// The current line selected in the menu. + /// + public int CurrentLine + { + get => _currentLine; + protected set + { + _currentLine = value; + if (_currentLine > _maxLines) + { + _currentLine = _maxLines; + } + if (_currentLine < 0) + { + _currentLine = 0; + } + return; + } + } + + public int SelectNextLine() { return ++CurrentLine; } + public int SelectPrevioustLine() { return --CurrentLine; } + + public abstract void UpdateDisplay(); + } +} diff --git a/MCTG/ConsoleApp/Program.cs b/MCTG/ConsoleApp/Program.cs index f3bccbd..ac9a1e9 100644 --- a/MCTG/ConsoleApp/Program.cs +++ b/MCTG/ConsoleApp/Program.cs @@ -1,6 +1,7 @@ // See https://aka.ms/new-console-template for more information using ConsoleApp; +using ConsoleApp.Menu; using Model; using System.Text; @@ -21,8 +22,8 @@ if (allRecipe == null) Manager manager = new Manager(allRecipe); -Console.WriteLine(ConsoleMenu.SearcherRecipe.ResearchOn(manager.AllRecipes)); - - -// press any key to quit -Console.ReadKey(); +Recipe? ret = SearcherRecipe.ResearchOn(allRecipe); +Console.WriteLine(ret); + +// press any key to quit +Console.ReadKey();