From 2402afaa8119d5bf8a23afd92338bfdf0d80e0a6 Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 19:05:42 -0500 Subject: [PATCH 1/7] Implementing Mnemonic spell checker. --- SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs b/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs index 7bc87c0..d4c6bcd 100644 --- a/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs +++ b/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs @@ -25,7 +25,19 @@ public class MnemonicSpellCheckerIBeforeE : /// true when the word is spelled correctly, false otherwise public bool Check(string word) { - throw new NotImplementedException(); + string invWord = word.ToLowerInvariant(); + if (invWord.Contains("cie")) + { + return false; + } + + int index = invWord.IndexOf("ei"); + if (index > 0 && invWord[index - 1] != 'c') + { + return false; + } + + return true; } } From 9b7b5ac1872e6411a3214168af5f1bbf36f4fb80 Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 19:18:50 -0500 Subject: [PATCH 2/7] Added sentence splitting and added the spell checkers. --- SpellChecker.Console/Program.cs | 64 +++++++++++++++++++++++++++++-- SpellChecker.Core/SpellChecker.cs | 12 +++++- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/SpellChecker.Console/Program.cs b/SpellChecker.Console/Program.cs index f076301..4b738db 100644 --- a/SpellChecker.Console/Program.cs +++ b/SpellChecker.Console/Program.cs @@ -1,4 +1,7 @@ -using SpellChecker.Contracts; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SpellChecker.Contracts; using SpellChecker.Core; namespace SpellChecker.Console @@ -50,10 +53,65 @@ public static void Main(string[] args) var spellChecker = new Core.SpellChecker(new ISpellChecker[] { new MnemonicSpellCheckerIBeforeE(), - new DictionaryDotComSpellChecker(), + //// new DictionaryDotComSpellChecker(), }); + + #region My Code + + var builder = new StringBuilder("Misspelled words: "); + Dictionary uniqueWords = GetUniqueWords(sentence); + foreach (var word in uniqueWords.Keys) + { + if (!spellChecker.Check(word)) + { + builder.Append($" {word},"); + } + } + + // Remove the last comma if present. + if (builder[builder.Length - 1] == ',') + { + builder.Remove(builder.Length - 1, 1); + } + + System.Console.WriteLine(builder); + System.Console.WriteLine("\nPress any key to quit."); + System.Console.ReadKey(); + + #endregion } - } + #region Added Methods + /// + /// Get all unique words in the sentence. + /// + /// The sentence to parse. + /// Collection of all unique words and how frequent they were. + /// + /// I decided to go ahead and track which of the words are unique. It's not truly necessary, + /// but could be useful for statistics. If memory is really an issue, use a List instead. + /// + public static Dictionary GetUniqueWords(string sentence) + { + var runOnSentence = new string(sentence.Where(c => !char.IsPunctuation(c) && !char.IsSymbol(c)).ToArray()); + string[] words = runOnSentence.Split(' '); + var wordsDic = new Dictionary(); + foreach (var word in words) + { + if (!wordsDic.ContainsKey(word)) + { + wordsDic.Add(word, 1); + } + else + { + wordsDic[word]++; + } + } + + return wordsDic; + } + + #endregion + } } diff --git a/SpellChecker.Core/SpellChecker.cs b/SpellChecker.Core/SpellChecker.cs index be6aa01..24b207e 100644 --- a/SpellChecker.Core/SpellChecker.cs +++ b/SpellChecker.Core/SpellChecker.cs @@ -22,7 +22,7 @@ public class SpellChecker : /// public SpellChecker(ISpellChecker[] spellCheckers) { - + this.spellCheckers = spellCheckers; } /// @@ -33,7 +33,15 @@ public SpellChecker(ISpellChecker[] spellCheckers) /// True if all spell checkers agree that a word is spelled correctly, false otherwise public bool Check(string word) { - throw new NotImplementedException(); + foreach (var spellChecker in this.spellCheckers) + { + if (!spellChecker.Check(word)) + { + return false; + } + } + + return true; } } From ff977a47f2594f86c444f887cc2d7236d3048a62 Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 20:36:55 -0500 Subject: [PATCH 3/7] Implemented dictionary.com web search and changed each Check method to be asynchronous. --- SpellChecker.Console/Program.cs | 39 ++++++++++++------- .../SpellChecker.Console.csproj | 6 +++ SpellChecker.Contracts/ISpellChecker.cs | 6 ++- .../DictionaryDotComSpellChecker.cs | 22 +++++++++-- .../MnemonicSpellCheckerIBeforeE.cs | 10 +++-- SpellChecker.Core/SpellChecker.cs | 7 ++-- 6 files changed, 65 insertions(+), 25 deletions(-) diff --git a/SpellChecker.Console/Program.cs b/SpellChecker.Console/Program.cs index 4b738db..92b24eb 100644 --- a/SpellChecker.Console/Program.cs +++ b/SpellChecker.Console/Program.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using SpellChecker.Contracts; using SpellChecker.Core; @@ -53,36 +54,46 @@ public static void Main(string[] args) var spellChecker = new Core.SpellChecker(new ISpellChecker[] { new MnemonicSpellCheckerIBeforeE(), - //// new DictionaryDotComSpellChecker(), + new DictionaryDotComSpellChecker(), }); - #region My Code + + Task.Run(() => TestSentence(sentence, spellChecker)); - var builder = new StringBuilder("Misspelled words: "); + System.Console.WriteLine("\nPress any key to quit."); + System.Console.ReadKey(); + } + + #region Added Methods + + /// + /// The asynchronous method to use inside Main. + /// + /// The sentence to test. + /// The spell checker to use. + public static async void TestSentence(string sentence, Core.SpellChecker spellChecker) + { + var badWords = new StringBuilder("Misspelled words: "); Dictionary uniqueWords = GetUniqueWords(sentence); + foreach (var word in uniqueWords.Keys) { - if (!spellChecker.Check(word)) + bool isSpelledCorrectly = await spellChecker.Check(word); + if (!isSpelledCorrectly) { - builder.Append($" {word},"); + badWords.Append($" {word},"); } } // Remove the last comma if present. - if (builder[builder.Length - 1] == ',') + if (badWords[badWords.Length - 1] == ',') { - builder.Remove(builder.Length - 1, 1); + badWords.Remove(badWords.Length - 1, 1); } - System.Console.WriteLine(builder); - System.Console.WriteLine("\nPress any key to quit."); - System.Console.ReadKey(); - - #endregion + System.Console.WriteLine(badWords); } - #region Added Methods - /// /// Get all unique words in the sentence. /// diff --git a/SpellChecker.Console/SpellChecker.Console.csproj b/SpellChecker.Console/SpellChecker.Console.csproj index ec9a449..22caf52 100644 --- a/SpellChecker.Console/SpellChecker.Console.csproj +++ b/SpellChecker.Console/SpellChecker.Console.csproj @@ -8,6 +8,12 @@ + + DEBUG;TRACE + full + true + + diff --git a/SpellChecker.Contracts/ISpellChecker.cs b/SpellChecker.Contracts/ISpellChecker.cs index f70fb0a..4d440ec 100644 --- a/SpellChecker.Contracts/ISpellChecker.cs +++ b/SpellChecker.Contracts/ISpellChecker.cs @@ -1,4 +1,6 @@ -namespace SpellChecker.Contracts +using System.Threading.Tasks; + +namespace SpellChecker.Contracts { /// @@ -13,7 +15,7 @@ public interface ISpellChecker /// /// The word that needs to be checked /// true, if the word is spelled correctly, false otherwise - bool Check(string word); + Task Check(string word); } } diff --git a/SpellChecker.Core/DictionaryDotComSpellChecker.cs b/SpellChecker.Core/DictionaryDotComSpellChecker.cs index a9dff56..4788e77 100644 --- a/SpellChecker.Core/DictionaryDotComSpellChecker.cs +++ b/SpellChecker.Core/DictionaryDotComSpellChecker.cs @@ -1,5 +1,7 @@ using System; - +using System.IO; +using System.Net; +using System.Threading.Tasks; using SpellChecker.Contracts; namespace SpellChecker.Core @@ -19,9 +21,23 @@ public class DictionaryDotComSpellChecker : ISpellChecker { - public bool Check(string word) + public async Task Check(string word) { - throw new NotImplementedException(); + string url = "http://dictionary.reference.com/browse/" + word; + + try + { + var request = HttpWebRequest.Create(url); + var webResponse = await request.GetResponseAsync() as HttpWebResponse; + bool result = webResponse.StatusCode == HttpStatusCode.OK; + webResponse.Close(); + + return result; + } + catch (WebException) + { + return false; + } } } diff --git a/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs b/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs index d4c6bcd..f844278 100644 --- a/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs +++ b/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs @@ -1,5 +1,5 @@ using System; - +using System.Threading.Tasks; using SpellChecker.Contracts; namespace SpellChecker.Core @@ -23,7 +23,12 @@ public class MnemonicSpellCheckerIBeforeE : /// /// The word to be checked /// true when the word is spelled correctly, false otherwise - public bool Check(string word) + public async Task Check(string word) + { + return await Task.FromResult(CheckSynchronous(word)); + } + + public bool CheckSynchronous(string word) { string invWord = word.ToLowerInvariant(); if (invWord.Contains("cie")) @@ -39,7 +44,6 @@ public bool Check(string word) return true; } - } } diff --git a/SpellChecker.Core/SpellChecker.cs b/SpellChecker.Core/SpellChecker.cs index 24b207e..81f647c 100644 --- a/SpellChecker.Core/SpellChecker.cs +++ b/SpellChecker.Core/SpellChecker.cs @@ -1,5 +1,5 @@ using System; - +using System.Threading.Tasks; using SpellChecker.Contracts; namespace SpellChecker.Core @@ -31,11 +31,12 @@ public SpellChecker(ISpellChecker[] spellCheckers) /// /// Word to check /// True if all spell checkers agree that a word is spelled correctly, false otherwise - public bool Check(string word) + public async Task Check(string word) { foreach (var spellChecker in this.spellCheckers) { - if (!spellChecker.Check(word)) + bool isCorrect = await spellChecker.Check(word); + if (!isCorrect) { return false; } From 5a036475ff9f6c1ef10734cf555b43787451684f Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 22:39:53 -0500 Subject: [PATCH 4/7] Implementing unit tests. --- SpellChecker.Core/SpellChecker.cs | 3 +-- .../DictionaryDotComSpellCheckerTests.cs | 14 ++++++++++++-- .../MnemonicSpellCheckerIBeforeETests.cs | 16 +++++++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/SpellChecker.Core/SpellChecker.cs b/SpellChecker.Core/SpellChecker.cs index 81f647c..2f87319 100644 --- a/SpellChecker.Core/SpellChecker.cs +++ b/SpellChecker.Core/SpellChecker.cs @@ -1,5 +1,4 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using SpellChecker.Contracts; namespace SpellChecker.Core diff --git a/SpellChecker.Tests/DictionaryDotComSpellCheckerTests.cs b/SpellChecker.Tests/DictionaryDotComSpellCheckerTests.cs index eedd108..31c581c 100644 --- a/SpellChecker.Tests/DictionaryDotComSpellCheckerTests.cs +++ b/SpellChecker.Tests/DictionaryDotComSpellCheckerTests.cs @@ -23,13 +23,23 @@ public void TestFixureSetUp() [TestMethod] public void Check_That_FileAndServe_Is_Misspelled() { - throw new NotImplementedException(); + string word = "FileAndServe"; + bool result; + + result = spellChecker.Check(word).Result; + + Assert.AreEqual(false, result); } [TestMethod] public void Check_That_South_Is_Not_Misspelled() { - throw new NotImplementedException(); + string word = "South"; + bool result; + + result = spellChecker.Check(word).Result; + + Assert.AreEqual(true, result); } } diff --git a/SpellChecker.Tests/MnemonicSpellCheckerIBeforeETests.cs b/SpellChecker.Tests/MnemonicSpellCheckerIBeforeETests.cs index 59ede10..9a5454e 100644 --- a/SpellChecker.Tests/MnemonicSpellCheckerIBeforeETests.cs +++ b/SpellChecker.Tests/MnemonicSpellCheckerIBeforeETests.cs @@ -1,5 +1,5 @@ using System; - +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using SpellChecker.Contracts; @@ -23,13 +23,23 @@ public void TestFixtureSetUp() [TestMethod] public void Check_Word_That_Contains_I_Before_E_Is_Spelled_Correctly() { - throw new NotImplementedException(); + string word = "fierce"; // correctly spelled + bool result; + + result = spellChecker.Check(word).Result; + + Assert.AreEqual(true, result); } [TestMethod] public void Check_Word_That_Contains_I_Before_E_Is_Spelled_Incorrectly() { - throw new NotImplementedException(); + string word = "decieve"; // incorrectly spelled + bool result; + + result = spellChecker.Check(word).Result; + + Assert.AreEqual(false, result); } } From d31a95688150aa949bcc262559c52d83c22ac150 Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 23:15:38 -0500 Subject: [PATCH 5/7] Fixing bug in mnemonic spell checker after implementing unit tests. --- SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs b/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs index f844278..f38f0f6 100644 --- a/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs +++ b/SpellChecker.Core/MnemonicSpellCheckerIBeforeE.cs @@ -31,14 +31,9 @@ public async Task Check(string word) public bool CheckSynchronous(string word) { string invWord = word.ToLowerInvariant(); - if (invWord.Contains("cie")) - { - return false; - } - - int index = invWord.IndexOf("ei"); - if (index > 0 && invWord[index - 1] != 'c') + if (invWord.Contains("cie") && invWord != "science") { + // I couldn't really let "science" go by... return false; } From e9ac54e6ff183230c578dc073bf0934cec0c8fd3 Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 23:19:15 -0500 Subject: [PATCH 6/7] Fixed some presentation text. --- SpellChecker.Console/Program.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SpellChecker.Console/Program.cs b/SpellChecker.Console/Program.cs index 92b24eb..e143cbb 100644 --- a/SpellChecker.Console/Program.cs +++ b/SpellChecker.Console/Program.cs @@ -59,8 +59,8 @@ public static void Main(string[] args) Task.Run(() => TestSentence(sentence, spellChecker)); + System.Console.WriteLine("\nSpellcheckers are running..."); - System.Console.WriteLine("\nPress any key to quit."); System.Console.ReadKey(); } @@ -92,6 +92,7 @@ public static async void TestSentence(string sentence, Core.SpellChecker spellCh } System.Console.WriteLine(badWords); + System.Console.WriteLine("\n\nPress any key to quit."); } /// From f057627072d8709b9fd498d3b558e3a0bbd63e48 Mon Sep 17 00:00:00 2001 From: David Thomas Date: Tue, 9 Jul 2019 23:45:54 -0500 Subject: [PATCH 7/7] Converting spell checker instances to instantiate at run-time. --- SpellChecker.Console/Program.cs | 6 +++--- SpellChecker.Core/SpellChecker.cs | 21 ++++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/SpellChecker.Console/Program.cs b/SpellChecker.Console/Program.cs index e143cbb..4450130 100644 --- a/SpellChecker.Console/Program.cs +++ b/SpellChecker.Console/Program.cs @@ -51,10 +51,10 @@ public static void Main(string[] args) // capturing distinct words that are misspelled // use this spellChecker to evaluate the words - var spellChecker = new Core.SpellChecker(new ISpellChecker[] + var spellChecker = new Core.SpellChecker(new string[] { - new MnemonicSpellCheckerIBeforeE(), - new DictionaryDotComSpellChecker(), + typeof(MnemonicSpellCheckerIBeforeE).AssemblyQualifiedName, + typeof(DictionaryDotComSpellChecker).AssemblyQualifiedName, }); diff --git a/SpellChecker.Core/SpellChecker.cs b/SpellChecker.Core/SpellChecker.cs index 2f87319..1e5f4c9 100644 --- a/SpellChecker.Core/SpellChecker.cs +++ b/SpellChecker.Core/SpellChecker.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using SpellChecker.Contracts; namespace SpellChecker.Core @@ -12,14 +13,13 @@ namespace SpellChecker.Core public class SpellChecker : ISpellChecker { - - readonly ISpellChecker[] spellCheckers; + readonly string[] spellCheckers; /// /// Initializes a new instance. /// - /// - public SpellChecker(ISpellChecker[] spellCheckers) + /// The asssembly qualified names of the types of spell checkers. + public SpellChecker(string[] spellCheckers) { this.spellCheckers = spellCheckers; } @@ -32,9 +32,16 @@ public SpellChecker(ISpellChecker[] spellCheckers) /// True if all spell checkers agree that a word is spelled correctly, false otherwise public async Task Check(string word) { - foreach (var spellChecker in this.spellCheckers) + foreach (var spellCheckerType in this.spellCheckers) { - bool isCorrect = await spellChecker.Check(word); + var checker = Activator.CreateInstance(Type.GetType(spellCheckerType)) as ISpellChecker; + if (checker == null) + { + Console.WriteLine($"The {spellCheckerType} checker was not instantiated properly"); + continue; + } + + bool isCorrect = await checker.Check(word); if (!isCorrect) { return false;