/// <summary> /// Given a level classification, returns the corresponding color. /// </summary> /// <param name="self">A level classification.</param> /// <returns>The material color corresponding to the level /// classification.</returns> public static Color ToColor(this LanguageLevelClassification self) { switch (self) { case LanguageLevelClassification.A1: return(Color.FromHex("#FF9800")); case LanguageLevelClassification.A2: return(Color.FromHex("#FFC107")); case LanguageLevelClassification.B1: return(Color.FromHex("#FFEB3B")); case LanguageLevelClassification.B2: return(Color.FromHex("#CDDC39")); case LanguageLevelClassification.C1: return(Color.FromHex("#8BC34A")); case LanguageLevelClassification.C2: return(Color.FromHex("#4CAF50")); case LanguageLevelClassification.UNKNOWN: default: return(Color.FromHex("#9E9E9E")); } }
/// <summary> /// Given a language level classification, returns the corresponding /// parameter suitable for use in an HTTP request. /// </summary> /// <param name="level">A level classification.</param> /// <returns>The parameter corresponding to the given /// classification.</returns> public static string GetHTTPParam(LanguageLevelClassification level) { switch (level) { case LanguageLevelClassification.A1: return("A1"); case LanguageLevelClassification.A2: return("A2"); case LanguageLevelClassification.B1: return("B1"); case LanguageLevelClassification.B2: return("B2"); case LanguageLevelClassification.C1: return("C1"); case LanguageLevelClassification.C2: return("C2"); case LanguageLevelClassification.UNKNOWN: default: return("unknown"); } }
/// <summary> /// Given a language level classification, returns the corresponding human-readable short title. /// </summary> /// <param name="level">A level classification.</param> /// <returns>The human-readable long description corresponding to the given classification.</returns> public static string LevelToShortTitle(LanguageLevelClassification level) { switch (level) { case LanguageLevelClassification.A1: return(Resources.LanguageLevel_A1_Short); case LanguageLevelClassification.A2: return(Resources.LanguageLevel_A2_Short); case LanguageLevelClassification.B1: return(Resources.LanguageLevel_B1_Short); case LanguageLevelClassification.B2: return(Resources.LanguageLevel_B2_Short); case LanguageLevelClassification.C1: return(Resources.LanguageLevel_C1_Short); case LanguageLevelClassification.C2: return(Resources.LanguageLevel_C2_Short); case LanguageLevelClassification.UNKNOWN: default: return(Resources.LanguageLevel_Unknown_Short); } }
/// <summary> /// Given a language level classification, returns the corresponding human-readable long description. /// </summary> /// <param name="level">A level classification.</param> /// <returns>The human-readable long description corresponding to the given classification.</returns> public static string LevelToLongDescription(LanguageLevelClassification level) { switch (level) { case LanguageLevelClassification.A1: return(Resources.LanguageLevel_A1_Long); case LanguageLevelClassification.A2: return(Resources.LanguageLevel_A2_Long); case LanguageLevelClassification.B1: return(Resources.LanguageLevel_B1_Long); case LanguageLevelClassification.B2: return(Resources.LanguageLevel_B2_Long); case LanguageLevelClassification.C1: return(Resources.LanguageLevel_C1_Long); case LanguageLevelClassification.C2: return(Resources.LanguageLevel_C2_Long); case LanguageLevelClassification.UNKNOWN: default: return(Resources.LanguageLevel_Unknown_Long); } }
/// <summary> /// Initializes a new instance of the <see cref="Tips"/> class. /// </summary> /// <param name="account">The instance of the <see cref="Account"/> class to use to store the OAuth 2.0 account /// credentials.</param> /// <param name="language">The language for the tips.</param> /// <param name="cefrLevel">The CEFR level for the tips.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="cefrLevel"/> is /// <see cref="LanguageLevelClassification.Unknown"/>.</exception> public Tips(Account account, SupportedLanguage language, LanguageLevelClassification cefrLevel) : base(new Uri(Config.TellOPConfiguration.GetEndpoint("TellOP.API.Tips") + "?language=" + new SupportedLanguageToLcidConverter().Convert(language, typeof(string), null, CultureInfo.InvariantCulture) + "&cefrLevel=" + (string) new LanguageLevelClassificationToHtmlParamConverter().Convert(cefrLevel, typeof(string), null, CultureInfo.InvariantCulture)), HttpMethod.Get, account) { if (cefrLevel == LanguageLevelClassification.Unknown) { throw new ArgumentOutOfRangeException("cefrLevel", "The CEFR level can not be UNKNOWN"); } }
/// <summary> /// Initializes a new instance of the <see cref="LanguageLevelWordsListView"/> class. /// </summary> /// <param name="level">Language level identifier</param> /// <param name="words">List of <see cref="IWord"/> objects</param> /// <param name="parent">The parent stack layout.</param> public LanguageLevelWordsListView(LanguageLevelClassification level, IList <IWord> words, StackLayout parent) { this._parentPanel = parent; this._level = level; this._buildPanel(); this.TapGestureRecFromInnerFrameVisibilityInverter = new TapGestureRecognizer(); this.Content = this._panel; this.Padding = 0; this.Margin = 0; this.TapGestureRecFromInnerFrameVisibilityInverter.Tapped += (s, e) => { this.InnerFrameVisibilityInverter(!this._panel.IsVisible); }; this.Populate(words); }
/// <summary> /// Converts a <see cref="LanguageLevelClassification"/> enum value to its JSON representation used by the exercise API /// endpoints. If <paramref name="value"/> is not a <see cref="LanguageLevelClassification"/> object, the conversion is /// not performed. /// </summary> /// <param name="writer">A <see cref="JsonWriter"/> object used to translate the object to its JSON /// representation.</param> /// <param name="value">The value to convert.</param> /// <param name="serializer">The calling serializer.</param> public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (writer == null) { throw new ArgumentNullException("writer"); } LanguageLevelClassification level = (LanguageLevelClassification)value; try { writer.WriteValue(_converterDictionary.First(x => x.Value.Equals(level)).Key); } catch (Exception ex) { Tools.Logger.Log("LanguageLevelClassificationConverter", "Apparently something didn't work correctly.", ex); writer.WriteValue(LanguageLevelClassification.Unknown); } }
/// <summary> /// Converts a <see cref="float"/> to a human-readable percentage. /// </summary> /// <param name="value">The value to convert.</param> /// <param name="targetType">The type of the target property.</param> /// <param name="parameter">An optional parameter to be used in the conversion logic.</param> /// <param name="culture">The culture to apply during the conversion.</param> /// <returns>The target value corresponding to the given source value.</returns> public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { try { if (value == null || ((ICollection)value).Count == 0) { return(string.Empty); } LanguageLevelClassification llc = (LanguageLevelClassification)parameter; CultureInfo tmp = (CultureInfo)culture.Clone(); tmp.NumberFormat.PercentDecimalDigits = 0; return(((Dictionary <LanguageLevelClassification, float>)value)[llc].ToString("P", tmp)); } catch (Exception ex) { Tools.Logger.Log(this.GetType().ToString(), ex); return(string.Empty); } }
/// <summary> /// Initializes or reinitializes all properties which can be extracted from an offline analysis of the text. /// </summary> private void InitializeOfflineAnalysisProperties() { // TODO: catch errors in the UI! this.OfflineAnalysisResult = new AsyncLazy <List <IWord> >(async() => { List <IWord> analysisCache = new List <IWord>(); IList <Task <IWord> > searchTokenTasks = new List <Task <IWord> >(); foreach (string token in Regex.Matches(this._essayContents, "\\w+").Cast <Match>().Select(m => m.Value)) { searchTokenTasks.Add(this.ProcessSingleWord(token)); } await Task.WhenAll(searchTokenTasks); foreach (IWord w in searchTokenTasks) { analysisCache.Add(w); } return(analysisCache); }); this.LevelClassification = new AsyncLazy <Dictionary <LanguageLevelClassification, List <IWord> > >(async() => { List <IWord> offlineAnalysis = await this.OfflineAnalysisResult; Dictionary <LanguageLevelClassification, List <IWord> > result = new Dictionary <LanguageLevelClassification, List <IWord> >(); foreach (LanguageLevelClassification level in Enum.GetValues(typeof(LanguageLevelClassification))) { result.Add(level, new List <IWord>()); } foreach (IWord word in offlineAnalysis) { LanguageLevelClassification level = await word.Level; result[level].Add(word); } return(result); }); this.LevelClassificationDistribution = new AsyncLazy <Dictionary <LanguageLevelClassification, float> >(async() => { // TODO: check for any possible loss of precision List <IWord> offlineAnalysis = await this.OfflineAnalysisResult; Dictionary <LanguageLevelClassification, float> result = new Dictionary <LanguageLevelClassification, float>(); foreach (LanguageLevelClassification level in Enum.GetValues(typeof(LanguageLevelClassification))) { result.Add(level, 0); } foreach (IWord word in offlineAnalysis) { LanguageLevelClassification level = await word.Level; result[level] = result[level] + 1; } foreach (LanguageLevelClassification level in Enum.GetValues(typeof(LanguageLevelClassification))) { result[level] = result[level] / (float)offlineAnalysis.Count; } return(result); }); this.NumWords = new AsyncLazy <int>(async() => { List <IWord> offlineAnalysis = await this.OfflineAnalysisResult; return(offlineAnalysis.Count); }); this.Adjectives = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Adjective)); }); this.Adverbs = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Adverb)); }); this.ClauseOpeners = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ClauseOpener)); }); this.Conjunctions = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Conjunction)); }); this.Determiners = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Determiner)); }); this.DeterminerPronouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.DeterminerPronoun)); }); this.ExistentialParticles = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ExistentialParticle)); }); this.ForeignWords = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ForeignWord)); }); this.Genitives = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Genitive)); }); this.InfinitiveMarkers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.InfinitiveMarker)); }); this.Interjections = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.InterjectionOrDiscourseMarker)); }); this.LettersOfAlphabet = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.LetterAsWord)); }); this.NegativeMarkers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.NegativeMarker)); }); this.CommonNouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.CommonNoun)); }); this.ProperNouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ProperNoun)); }); this.PartsOfProperNouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.PartOfProperNoun)); }); this.CardinalNumbers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.CardinalNumber)); }); this.OrdinalNumbers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Ordinal)); }); this.Prepositions = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Preposition)); }); this.Pronouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Pronoun)); }); this.UnclassifiedWords = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Unclassified)); }); this.Verbs = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Verb)); }); this.ModalVerbs = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ModalVerb)); }); }
/// <summary> /// Initializes or reinitializes all properties which can be extracted from an offline analysis of the text. /// </summary> private void InitializeOfflineAnalysisProperties() { // TODO: catch errors in the UI! this.OfflineAnalysisResult = new AsyncLazy <List <IWord> >(async() => { List <IWord> analysisCache = new List <IWord>(); if (this.Language == SupportedLanguage.English) { IList <Task <IWord> > searchTokenTasks = new List <Task <IWord> >(); // Dirty tokens foreach (string token in Regex.Matches(this._essayContents, "[\\w']+").Cast <Match>().Select(m => m.Value)) { foreach (string cleanToken in Regex.Matches(await this.PreprocessSingleWord(token), "[\\w']+").Cast <Match>().Select(m => m.Value)) { searchTokenTasks.Add(this.ProcessSingleWord(cleanToken)); } } IEnumerable <IWord> results = await Task.WhenAll(searchTokenTasks); Tools.Logger.Log("EssayExercise", "I've waited all of them!"); foreach (IWord w in results) { if (this.ExcludeFunctionalWords && ( w.PartOfSpeech == PartOfSpeech.ClauseOpener || w.PartOfSpeech == PartOfSpeech.Conjunction || w.PartOfSpeech == PartOfSpeech.Determiner || w.PartOfSpeech == PartOfSpeech.DeterminerPronoun || w.PartOfSpeech == PartOfSpeech.ExistentialParticle || w.PartOfSpeech == PartOfSpeech.Genitive || w.PartOfSpeech == PartOfSpeech.InfinitiveMarker || w.PartOfSpeech == PartOfSpeech.InterjectionOrDiscourseMarker || w.PartOfSpeech == PartOfSpeech.NegativeMarker || w.PartOfSpeech == PartOfSpeech.CardinalNumber || w.PartOfSpeech == PartOfSpeech.Ordinal || w.PartOfSpeech == PartOfSpeech.Pronoun || w.PartOfSpeech == PartOfSpeech.ModalVerb)) { continue; } analysisCache.Add(w); } } else if (this.Language == SupportedLanguage.Spanish) { Tools.Logger.Log("EssayExerciseES", "Call remote SpanishTagger"); SpanishPOSTagger es_tagger = new SpanishPOSTagger(App.OAuth2Account, this._essayContents); IList <SpanishWord> results = await es_tagger.CallEndpointAsObjectAsync(); Tools.Logger.Log("EssayExerciseES", "Got the results!"); analysisCache.AddRange(results); } else if (this.Language == SupportedLanguage.German) { Tools.Logger.Log("EssayExerciseDE", "Call remote GermanTagger"); GermanPOSTagger de_tagger = new GermanPOSTagger(App.OAuth2Account, this._essayContents); IList <GermanWord> results = await de_tagger.CallEndpointAsObjectAsync(); Tools.Logger.Log("EssayExerciseDE", "Got the results!"); analysisCache.AddRange(results); } return(analysisCache); }); this.LevelClassification = new AsyncLazy <Dictionary <LanguageLevelClassification, List <IWord> > >(async() => { if (this.Language == SupportedLanguage.English) { List <IWord> offlineAnalysis = await this.OfflineAnalysisResult; Dictionary <LanguageLevelClassification, List <IWord> > result = new Dictionary <LanguageLevelClassification, List <IWord> >(); foreach (LanguageLevelClassification level in Enum.GetValues(typeof(LanguageLevelClassification))) { result.Add(level, new List <IWord>()); } foreach (IWord word in offlineAnalysis) { LanguageLevelClassification level = await word.Level; result[level].Add(word); } return(result); } return(new Dictionary <LanguageLevelClassification, List <IWord> >()); }); this.LevelClassificationDistribution = new AsyncLazy <Dictionary <LanguageLevelClassification, float> >(async() => { if (this.Language == SupportedLanguage.English) { // TODO: check for any possible loss of precision List <IWord> offlineAnalysis = await this.OfflineAnalysisResult; Dictionary <LanguageLevelClassification, float> result = new Dictionary <LanguageLevelClassification, float>(); foreach (LanguageLevelClassification level in Enum.GetValues(typeof(LanguageLevelClassification))) { result.Add(level, 0); } foreach (IWord word in offlineAnalysis) { LanguageLevelClassification level = await word.Level; result[level] = result[level] + 1; } foreach (LanguageLevelClassification level in Enum.GetValues(typeof(LanguageLevelClassification))) { result[level] = result[level] / (float)offlineAnalysis.Count; } return(result); } return(new Dictionary <LanguageLevelClassification, float>()); }); this.NumWords = new AsyncLazy <int>(async() => { List <IWord> offlineAnalysis = await this.OfflineAnalysisResult; return(offlineAnalysis.Count); }); this.Adjectives = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Adjective)); }); this.Adverbs = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Adverb)); }); this.ClauseOpeners = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ClauseOpener)); }); this.Conjunctions = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Conjunction)); }); this.Determiners = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Determiner)); }); this.DeterminerPronouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.DeterminerPronoun)); }); this.ExistentialParticles = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ExistentialParticle)); }); this.ForeignWords = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ForeignWord)); }); this.Genitives = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Genitive)); }); this.InfinitiveMarkers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.InfinitiveMarker)); }); this.Interjections = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.InterjectionOrDiscourseMarker)); }); this.LettersOfAlphabet = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.LetterAsWord)); }); this.NegativeMarkers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.NegativeMarker)); }); this.CommonNouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.CommonNoun)); }); this.ProperNouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ProperNoun)); }); this.PartsOfProperNouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.PartOfProperNoun)); }); this.CardinalNumbers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.CardinalNumber)); }); this.OrdinalNumbers = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Ordinal)); }); this.Prepositions = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Preposition)); }); this.Pronouns = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Pronoun)); }); this.UnclassifiedWords = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Unclassified)); }); this.Verbs = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.Verb)); }); this.ModalVerbs = new AsyncLazy <IDictionary <IWord, int> >(async() => { return(await this.GetWordsByPartOfSpeech(PartOfSpeech.ModalVerb)); }); }