public SimilarityData(int difference, CorrectCertainty certainty, string correctAnswer, Card card) { Difference = difference; Certainty = certainty; CorrectAnswer = correctAnswer; Card = card; }
private static SimilarityData Similarity(string userAnswer, string correctAnswer, Card card, Rules rules, CorrectCertainty certainty) { var similarityData = new List <SimilarityData>(); void KeepBestSimilarityData() { // Keep best similarity data similarityData = similarityData.OrderBy(x => x.Difference).ThenBy(x => (int)x.Certainty).ToList(); similarityData = similarityData.Take(1).ToList(); } if (rules.HasFlag(Rules.IgnoreOpeningWhitespace)) { similarityData.Add(Similarity(userAnswer.TrimStart(' '), correctAnswer.TrimStart(' '), card, rules & ~Rules.IgnoreOpeningWhitespace, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); // Math.Max to use worst certainty (if the certainty when calling this method was 'maybe correct', new certainty can't be 'probably correct' for instance) } if (rules.HasFlag(Rules.IgnoreEndingWhitespace)) { similarityData.Add(Similarity(userAnswer.TrimEnd(' '), correctAnswer.TrimEnd(' '), card, rules & ~Rules.IgnoreEndingWhitespace, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); } if (rules.HasFlag(Rules.IgnoreFirstCapitalization)) { similarityData.Add(Similarity(CapitalizeFirstChar(userAnswer), CapitalizeFirstChar(correctAnswer), card, rules & ~Rules.IgnoreFirstCapitalization, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); } if (rules.HasFlag(Rules.IgnoreDotsInEnd)) { similarityData.Add(Similarity(userAnswer.TrimEnd('.'), correctAnswer.TrimEnd('.'), card, rules & ~Rules.IgnoreDotsInEnd, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); } if (rules.HasFlag(Rules.TreatWordsBetweenSlashAsSynonyms)) { if (correctAnswer.Contains("/")) { var synonymSimilarities = new List <SimilarityData>(); bool any = false; foreach (var userSynonym in userAnswer.Split('/').Where(x => !string.IsNullOrWhiteSpace(x))) { any = true; var matches = new List <SimilarityData>(); foreach (var correctSynonym in correctAnswer.Split('/').Where(x => !string.IsNullOrWhiteSpace(x))) { matches.Add(Similarity(userSynonym, correctSynonym.TrimStart(' '), card, rules, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); } // Add best match synonymSimilarities.Add(matches.OrderBy(x => x.Difference).First()); } if (any) { // At least one synonym was entered! if (synonymSimilarities.All(x => x.Difference == 0)) { // Provided synonyms are correct similarityData.Add( new SimilarityData(0, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty), correctAnswer, card)); } else { similarityData.Add( new SimilarityData(synonymSimilarities.Select(x => x.Difference).Max(), (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty), correctAnswer, card)); } } } } if (rules.HasFlag(Rules.TreatWordInParenthesisAsOptional)) { if (correctAnswer.Contains("(") && correctAnswer.Contains(")")) { if (!correctAnswer.TrimStart().StartsWith("(")) { string w1 = correctAnswer.Split('(')[0].TrimEnd(' '); // tarp (tarpaulin) => tarp similarityData.Add(Similarity(userAnswer, w1, card, rules, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); } string w2 = correctAnswer.Split('(')[1].Split(')')[0].TrimStart(' ').TrimEnd(' '); // tarp (tarpaulin) => tarpaulin similarityData.Add(Similarity(userAnswer, w2, card, rules, (CorrectCertainty)Math.Max((int)CorrectCertainty.MaybeCorrect, (int)certainty))); //string w3 = correctAnswer.Replace("(", "").Replace(")", ""); // (eye)lash => eyelash var rgp1 = new Regex(Regex.Escape("(")); var rgp2 = new Regex(Regex.Escape(")")); string w3 = rgp1.Replace(correctAnswer, "", 1); // (eye)lash => eye)lash (replace first occurence of starting paranthesis) w3 = rgp2.Replace(w3, "", 1); // eyelash => eyelash (replace first occurence of ending paranthesis) similarityData.Add(Similarity(userAnswer, w3, card, rules, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); if (!correctAnswer.TrimEnd().EndsWith(")") || correctAnswer.Count(c => c == ')') > 1) { string w4 = correctAnswer.Split(new[] { ')' }, 2)[1].TrimStart(' '); // (eye)lash => lash similarityData.Add(Similarity(userAnswer, w4, card, rules, (CorrectCertainty)Math.Max((int)CorrectCertainty.ProbablyCorrect, (int)certainty))); } } } int difference = Fastenshtein.Levenshtein.Distance(userAnswer, correctAnswer); similarityData.Add(new SimilarityData(difference, certainty, correctAnswer, card)); KeepBestSimilarityData(); //#warning the best similarity data that is being kept is not necessarily equal to the written answer in the quiz!!! this potentially shows a wrong answer in "ProbablyCorrectAnswer" dialog SimilarityData best = similarityData.First(); return(best); }