protected override Task <InputState> OnRecognizeInputAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken)) { var input = dc.State.GetValue <object>(VALUE_PROPERTY); var culture = GetCulture(dc); var results = NumberRecognizer.RecognizeNumber(input.ToString(), culture); if (results.Count > 0) { // Try to parse value based on type var text = results[0].Resolution["value"].ToString(); if (int.TryParse(text, out var intValue)) { input = intValue; } else { if (float.TryParse(text, out var value)) { input = value; } else { return(Task.FromResult(InputState.Unrecognized)); } } } else { return(Task.FromResult(InputState.Unrecognized)); } dc.State.SetValue(VALUE_PROPERTY, input); if (OutputFormat != null) { var(outputValue, error) = this.OutputFormat.TryGetValue(dc.State); if (error == null) { dc.State.SetValue(VALUE_PROPERTY, outputValue); } else { throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {this.OutputFormat}. Error: {error}"); } } return(Task.FromResult(InputState.Valid)); }
private static List <ModelResult <FoundChoice> > RecognizeOrdinal(string utterance, string culture) { var model = new NumberRecognizer(culture).GetOrdinalModel(culture); var result = model.Parse(utterance); return(result.Select(r => new ModelResult <FoundChoice> { Start = r.Start, End = r.End, Text = r.Text, Resolution = new FoundChoice { Value = r.Resolution["value"].ToString(), }, }).ToList()); }
public void TestPercentageModel() { var model = NumberRecognizer.GetPercentageModel(Culture.English); BasicTest(model, "100%", "100%"); BasicTest(model, " 100% ", "100%"); BasicTest(model, " 100 percent", "100%"); BasicTest(model, " 100 percentage", "100%"); BasicTest(model, "240 percent", "240%"); BasicTest(model, "twenty percent", "20%"); BasicTest(model, "thirty percentage", "30%"); BasicTest(model, "one hundred percent", "100%"); BasicTest(model, "one hundred percents", "100%"); BasicTest(model, "percents of twenty", "20%"); BasicTest(model, "percent of 10", "10%"); BasicTest(model, "per cent of twenty-two", "22%"); BasicTest(model, "per cent of 210", "210%"); BasicTest(model, "10 percent", "10%"); }
private static double TryExtractWorkHours(List <string> possibleValues) { var hourTokens = new[] { "hours", "hrs", "hr", "h" }; var minuteTokens = new[] { "minutes", "min", "mn", "m" }; var result = 0.0; foreach (var val in possibleValues) { var hours = 0.0; var hoursMultiplier = 0.0; foreach (var token in hourTokens) { if (val.ToLower().Contains(token)) { hoursMultiplier = 1.0; } } foreach (var token in minuteTokens) { if (val.ToLower().Contains(token)) { hoursMultiplier = 1.0 / 60.0; } } if (double.TryParse(val.Split(' ')[0], out hours)) { if (result <= 0) { result = hours * hoursMultiplier; } } else { var possibleHours = NumberRecognizer.RecognizeNumber(val.Split(' ')[0], Culture.English); if (possibleHours.Count > 0) { possibleHours.FirstOrDefault().Resolution.TryGetValue("value", out var hoursString); result = Convert.ToDouble(hoursString) * hoursMultiplier; } } } return(result); }
/// <summary> /// Validator function to verify if the quantity the user entered gets recognized. /// </summary> /// <param name="promptContext">Context for this prompt.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> private async Task <bool> ValidateQuantity(PromptValidatorContext <string> promptContext, CancellationToken cancellationToken) { var result = promptContext.Recognized.Value ?? string.Empty; var results = NumberRecognizer.RecognizeNumber(result, culture); if (results.Count == 0) { await promptContext.Context.SendActivityAsync(InvalidQuantityErrorMessage); return(false); } if (results.First().TypeName == "number" && double.TryParse(results.First().Resolution["value"].ToString(), out double value)) { // Validate number if ((value < 1) || (value % 1 != 0)) { await promptContext.Context.SendActivityAsync(InvalidQuantityErrorMessage); return(false); } if (value > 100) { await promptContext.Context.SendActivityAsync(InvalidOverQuantityErrorMessage); return(false); } var quantityRoses = Convert.ToInt32(results.First().Resolution["value"]); var quantityMessage = quantityRoses == 1 ? "I'll send just one rose." : $"I'll send {quantityRoses} roses."; promptContext.Recognized.Value = quantityRoses.ToString(); await promptContext.Context.SendActivityAsync(quantityMessage); return(true); } else { await promptContext.Context.SendActivityAsync(InvalidQuantityErrorMessage); return(false); } }
public static int ParserNumberFromText(string text, int defValue = 0) { var number = defValue; const string DefaultCulture = Culture.Chinese; var result = NumberRecognizer.RecognizeNumber(text, DefaultCulture); if (result.Count > 0) { var resolution = result[0].Resolution; if (resolution.ContainsKey("value")) { int.TryParse(resolution["value"].ToString(), out number); } } return(number); }
protected override Task <InputState> OnRecognizeInput(DialogContext dc) { var input = dc.GetState().GetValue <object>(VALUE_PROPERTY); var culture = GetCulture(dc); var results = NumberRecognizer.RecognizeNumber(input.ToString(), culture); if (results.Count > 0) { // Try to parse value based on type var text = results[0].Resolution["value"].ToString(); if (float.TryParse(text, out var value)) { input = value; } else { return(Task.FromResult(InputState.Unrecognized)); } } else { return(Task.FromResult(InputState.Unrecognized)); } dc.GetState().SetValue(VALUE_PROPERTY, input); if (!string.IsNullOrEmpty(OutputFormat)) { var outputExpression = new ExpressionEngine().Parse(OutputFormat); var(outputValue, error) = outputExpression.TryEvaluate(dc.GetState()); if (error == null) { dc.GetState().SetValue(VALUE_PROPERTY, outputValue); } else { throw new Exception($"In TextInput, OutputFormat Expression evaluation resulted in an error. Expression: {outputExpression.ToString()}. Error: {error}"); } } return(Task.FromResult(InputState.Valid)); }
private static IEnumerable <ModelResult> ParseAll(string query, string culture) { return(MergeResults(new List <ModelResult>[] { // Number recognizer will find any number from the input // E.g "I have two apples" will return "2". NumberRecognizer.RecognizeNumber(query, culture), // Ordinal number recognizer will find any ordinal number // E.g "eleventh" will return "11". NumberRecognizer.RecognizeOrdinal(query, culture), // Percentage recognizer will find any number presented as percentage // E.g "one hundred percents" will return "100%" NumberRecognizer.RecognizePercentage(query, culture), // Number Range recognizer will find any cardinal or ordinal number range // E.g. "between 2 and 5" will return "(2,5)" NumberRecognizer.RecognizeNumberRange(query, culture), // Age recognizer will find any age number presented // E.g "After ninety five years of age, perspectives change" will return "95 Year" NumberWithUnitRecognizer.RecognizeAge(query, culture), // Currency recognizer will find any currency presented // E.g "Interest expense in the 1988 third quarter was $ 75.3 million" will return "75300000 Dollar" NumberWithUnitRecognizer.RecognizeCurrency(query, culture), // Dimension recognizer will find any dimension presented // E.g "The six-mile trip to my airport hotel that had taken 20 minutes earlier in the day took more than three hours." will return "6 Mile" NumberWithUnitRecognizer.RecognizeDimension(query, culture), // Temperature recognizer will find any temperature presented // E.g "Set the temperature to 30 degrees celsius" will return "30 C" NumberWithUnitRecognizer.RecognizeTemperature(query, culture), // Datetime recognizer This model will find any Date even if its write in colloquial language // E.g "I'll go back 8pm today" will return "2017-10-04 20:00:00" DateTimeRecognizer.RecognizeDateTime(query, culture) })); }
protected override async Task <PromptRecognizerResult <string> > OnRecognizeAsync(ITurnContext turnContext, IDictionary <string, object> state, PromptOptions options, CancellationToken cancellationToken = default(CancellationToken)) { if (turnContext == null) { throw new ArgumentNullException(nameof(turnContext)); } var result = new PromptRecognizerResult <string>(); if (turnContext.Activity.Type == ActivityTypes.Message) { var message = turnContext.Activity.AsMessageActivity().Text.ToUpper(); var regex = new Regex("INC[0-9]{7}"); if (regex.IsMatch(message)) { result.Succeeded = true; result.Value = message; } if (!result.Succeeded) { var culture = turnContext.Activity.Locale ?? DefaultLocale ?? English; var results = NumberRecognizer.RecognizeNumber(message, culture); if (results.Count > 0) { var text = results[0].Resolution["value"].ToString(); if (int.TryParse(text, NumberStyles.Any, new CultureInfo(culture), out var value)) { if (value >= 1 && value <= 9999999) { result.Succeeded = true; result.Value = $"INC{value:D7}"; } } } } } return(await Task.FromResult(result)); }
private int?ParseFloorNumber(string utterance, string culture) { var model_ordinal = new NumberRecognizer(culture).GetOrdinalModel(culture); var result = model_ordinal.Parse(utterance); if (result.Any()) { return(int.Parse(result.First().Resolution["value"].ToString())); } else { var model_number = new NumberRecognizer(culture).GetNumberModel(culture); result = model_number.Parse(utterance); if (result.Any()) { return(int.Parse(result.First().Resolution["value"].ToString())); } } return(null); }
private static bool IsValidNumberCurrency(string ammount, string currency) { if ((String.IsNullOrEmpty(currency)) || (String.IsNullOrEmpty(ammount))) { return(false); } if (NumberWithUnitRecognizer.RecognizeCurrency(ammount, Culture.French).Where(x => x.TypeName == "currency").FirstOrDefault() != null) { // var ret = res.Resolution["value"]; return(true); } else { if (NumberRecognizer.RecognizeNumber(ammount, Culture.French).Where(x => x.TypeName == "number").FirstOrDefault() != null) { return(true); } } return(false); }
protected override Task <InputState> OnRecognizeInput(DialogContext dc) { var input = dc.State.GetValue <object>(VALUE_PROPERTY); var culture = GetCulture(dc); var results = NumberRecognizer.RecognizeNumber(input.ToString(), culture); if (results.Count > 0) { // Try to parse value based on type var text = results[0].Resolution["value"].ToString(); if (float.TryParse(text, out var value)) { input = value; } else { return(Task.FromResult(InputState.Unrecognized)); } } else { return(Task.FromResult(InputState.Unrecognized)); } switch (this.OutputFormat) { case NumberOutputFormat.Float: default: dc.State.SetValue(VALUE_PROPERTY, input); break; case NumberOutputFormat.Integer: dc.State.SetValue(VALUE_PROPERTY, Math.Floor((float)input)); break; } return(Task.FromResult(InputState.Valid)); }
protected override bool TryParse(IMessageActivity message, out int result) { result = 0; // Get Number for the specified culture var results = NumberRecognizer.RecognizeNumber(message.Text, this.culture); if (results.Count > 0) { if (results.First().TypeName == "number" && double.TryParse(results.First().Resolution["value"].ToString(), out double value)) { // Validate number if (value < 1) { this.promptOptions.DefaultRetry = "I need to deliver at least one rose =)"; return(false); } else if (value > 100) { this.promptOptions.DefaultRetry = "You cannot order more than 100 roses per day. Sorry!"; return(false); } else if (value % 1 != 0) { this.promptOptions.DefaultRetry = "I need to send whole roses, not fractions of them. How many would you like to send?"; return(false); } // return as Int result = Convert.ToInt32(value); return(true); } } // No parse results this.promptOptions.DefaultRetry = "I'm sorry, that doesn't seem to be a valid quantity"; return(false); }
private static List <ModelResult> RecognizeNumberWithUnit(string utterance, string culture) { var number = NumberRecognizer.RecognizeNumber(utterance, culture); if (number.Any()) { // Result when it matches with a number recognizer return(number); } else { // Analyze every option for numberWithUnit var results = new List <List <ModelResult> >(); results.Add(NumberWithUnitRecognizer.RecognizeCurrency(utterance, culture)); results.Add(NumberWithUnitRecognizer.RecognizeAge(utterance, culture)); results.Add(NumberWithUnitRecognizer.RecognizeTemperature(utterance, culture)); results.Add(NumberWithUnitRecognizer.RecognizeDimension(utterance, culture)); // Filter the options that returned nothing and return the one that matched return(results.FirstOrDefault(r => r.Any()) ?? new List <ModelResult>()); } }
public bool TryGetIntent(string input, IEnumerable <Intent> possibleIntents, out Intent intent) { var result = new List <ModelResult>(); result.AddRange(NumberRecognizer.RecognizeNumber(input, RecognitionCulture)); result.AddRange(NumberRecognizer.RecognizeOrdinal(input, RecognitionCulture)); intent = default; if (result.Count != 1) { return(false); } var recognizedResolution = result[0].Resolution; if (recognizedResolution.TryGetValue("value", out var value) && int.TryParse(value?.ToString(), out var possibleIntentIndex)) { intent = possibleIntents.FirstOrDefault(p => p.Index != default && p.Index == possibleIntentIndex); } return(intent != default); }
private static IEnumerable <ModelResult> ParseAll(string query, string culture) { return(MergeResults( // Number recognizer will find any number from the input NumberRecognizer.RecognizeNumber(query, culture), // Ordinal number recognizer will find any ordinal number NumberRecognizer.RecognizeOrdinal(query, culture), // Percentage recognizer will find any number presented as percentage NumberRecognizer.RecognizePercentage(query, culture), // Number Range recognizer will find any cardinal or ordinal number range NumberRecognizer.RecognizeNumberRange(query, culture), // Age recognizer will find any age number presented NumberWithUnitRecognizer.RecognizeAge(query, culture), // Currency recognizer will find any currency presented NumberWithUnitRecognizer.RecognizeCurrency(query, culture), // Dimension recognizer will find any dimension presented NumberWithUnitRecognizer.RecognizeDimension(query, culture), // Temperature recognizer will find any temperature presented NumberWithUnitRecognizer.RecognizeTemperature(query, culture), // Datetime recognizer This model will find any Date even if its write in coloquial language DateTimeRecognizer.RecognizeDateTime(query, culture), // PhoneNumber recognizer will find any phone number presented SequenceRecognizer.RecognizePhoneNumber(query, culture), // Add IP recognizer - This recognizer will find any Ipv4/Ipv6 presented SequenceRecognizer.RecognizeIpAddress(query, culture) )); }
private bool TryGetNumber(string text, out decimal result) { // Get Number for the specified culture var results = NumberRecognizer.RecognizeNumber(text, Culture.English); if (results.Count > 0) { if (results.First().TypeName == "number" && decimal.TryParse(results.First().Resolution["value"].ToString(), out result)) { // Validate number if (result < 0) { result = 0; return(false); } return(true); } } result = 0; return(false); }
public void TestOrdinalModel() { var model = NumberRecognizer.GetOrdinalModel(Culture.Chinese); BasicTest(model, "第二百五十", "250"); BasicTest(model, "第250", "250"); MultiTest(model, "第一名第二名第三名第四名", 4); BasicTest(model, "第十四", "14"); BasicTest(model, "第三", "3"); }
/// <summary> /// Parse query with all recognizers. /// </summary> private static IEnumerable <ModelResult> ParseAll(string query, string culture) { return(MergeResults(new List <ModelResult>[] { // Number recognizer will find any number from the input // E.g "I have two apples" will return "2". NumberRecognizer.RecognizeNumber(query, culture), // Ordinal number recognizer will find any ordinal number // E.g "eleventh" will return "11". NumberRecognizer.RecognizeOrdinal(query, culture), // Percentage recognizer will find any number presented as percentage // E.g "one hundred percents" will return "100%" NumberRecognizer.RecognizePercentage(query, culture), // Number Range recognizer will find any cardinal or ordinal number range // E.g. "between 2 and 5" will return "(2,5)" NumberRecognizer.RecognizeNumberRange(query, culture), // Age recognizer will find any age number presented // E.g "After ninety five years of age, perspectives change" will return "95 Year" NumberWithUnitRecognizer.RecognizeAge(query, culture), // Currency recognizer will find any currency presented // E.g "Interest expense in the 1988 third quarter was $ 75.3 million" will return "75300000 Dollar" NumberWithUnitRecognizer.RecognizeCurrency(query, culture), // Dimension recognizer will find any dimension presented // E.g "The six-mile trip to my airport hotel that had taken 20 minutes earlier in the day took more than three hours." will return "6 Mile" NumberWithUnitRecognizer.RecognizeDimension(query, culture), // Temperature recognizer will find any temperature presented // E.g "Set the temperature to 30 degrees celsius" will return "30 C" NumberWithUnitRecognizer.RecognizeTemperature(query, culture), // Datetime recognizer This model will find any Date even if its write in colloquial language // E.g "I'll go back 8pm today" will return "2017-10-04 20:00:00" DateTimeRecognizer.RecognizeDateTime(query, culture), // PhoneNumber recognizer will find any phone number presented // E.g "My phone number is ( 19 ) 38294427." SequenceRecognizer.RecognizePhoneNumber(query, culture), // Add IP recognizer - This recognizer will find any Ipv4/Ipv6 presented // E.g "My Ip is 8.8.8.8" SequenceRecognizer.RecognizeIpAddress(query, culture), // Mention recognizer will find all the mention usages // E.g "@Cicero" SequenceRecognizer.RecognizeMention(query, culture), // Hashtag recognizer will find all the hash tag usages // E.g "task #123" SequenceRecognizer.RecognizeHashtag(query, culture), // Email recognizer will find all the emails // E.g "*****@*****.**" SequenceRecognizer.RecognizeEmail(query, culture), // URL recognizer will find all the urls // E.g "bing.com" SequenceRecognizer.RecognizeURL(query, culture), // GUID recognizer will find all the GUID usages // E.g "{123e4567-e89b-12d3-a456-426655440000}" SequenceRecognizer.RecognizeGUID(query, culture), // Quoted text recognizer // E.g "I meant "no"" SequenceRecognizer.RecognizeQuotedText(query, culture), // Add Boolean recognizer - This model will find yes/no like responses, including emoji - // E.g "yup, I need that" will return "True" ChoiceRecognizer.RecognizeBoolean(query, culture), })); }
protected override List <ModelResult> Recognize(string text, string culture) { return(NumberRecognizer.RecognizeNumberRange(text, culture)); }
protected override Task <PromptRecognizerResult <T> > OnRecognizeAsync(ITurnContext turnContext, IDictionary <string, object> state, PromptOptions options) { if (turnContext == null) { throw new ArgumentNullException(nameof(turnContext)); } var result = new PromptRecognizerResult <T>(); if (turnContext.Activity.Type == ActivityTypes.Message) { var message = turnContext.Activity.AsMessageActivity(); var culture = turnContext.Activity.Locale ?? DefaultLocale ?? English; var results = NumberRecognizer.RecognizeNumber(message.Text, culture); if (results.Count > 0) { // Try to parse value based on type var text = results[0].Resolution["value"].ToString(); if (typeof(T) == typeof(float)) { if (float.TryParse(text, out var value)) { result.Succeeded = true; result.Value = (T)(object)value; } } else if (typeof(T) == typeof(int)) { if (int.TryParse(text, out var value)) { result.Succeeded = true; result.Value = (T)(object)value; } } else if (typeof(T) == typeof(long)) { if (long.TryParse(text, out var value)) { result.Succeeded = true; result.Value = (T)(object)value; } } else if (typeof(T) == typeof(double)) { if (double.TryParse(text, out var value)) { result.Succeeded = true; result.Value = (T)(object)value; } } else if (typeof(T) == typeof(decimal)) { if (decimal.TryParse(text, out var value)) { result.Succeeded = true; result.Value = (T)(object)value; } } else { throw new NotSupportedException($"NumberPrompt: type argument T of type 'typeof(T)' is not supported"); } } } return(Task.FromResult(result)); }
public void TestFractionModel() { var ci = new SpanishNumberParserConfiguration().CultureInfo; var model = NumberRecognizer.GetNumberModel(Culture.Spanish); BasicTest(model, "un quinto", "0,2"); BasicTest(model, "un billonesimo", "1E-12"); BasicTest(model, "cien mil billonesima", "1E-07"); BasicTest(model, "tres quintos", "0,6"); BasicTest(model, "veinte quintos", "4"); BasicTest(model, "veintitres quintas", "4,6"); BasicTest(model, "tres con un quinto", "3,2"); BasicTest(model, "veintiun quintos", "4,2"); BasicTest(model, "un veintiunavo", ((double)1 / 21).ToString(ci)); BasicTest(model, "ciento treinta y tres veintiunavos", ((double)133 / 21).ToString(ci)); BasicTest(model, "ciento treinta con tres veintiunavos", (130 + (double)3 / 21).ToString(ci)); BasicTest(model, "veintidos treintavos", ((double)22 / 30).ToString(ci)); BasicTest(model, "un veinticincoavo", ((double)1 / 25).ToString(ci)); BasicTest(model, "veinte veinticincoavos", "0,8"); BasicTest(model, "tres veintiunavos", ((double)3 / 21).ToString(ci)); BasicTest(model, "tres veinteavos", ((double)3 / 20).ToString(ci)); BasicTest(model, "tres doscientosavos", ((double)3 / 200).ToString(ci)); BasicTest(model, "tres dosmilesimos", ((double)3 / 2000).ToString(ci)); BasicTest(model, "tres veintemilesimos", ((double)3 / 20000).ToString(ci)); BasicTest(model, "tres doscientosmilesimos", ((double)3 / 200000).ToString(ci)); BasicTest(model, "tres dosmillonesimos", ((double)3 / 2000000).ToString(ci)); // act like Google BasicTest(model, "ciento treinta quintos", ((double)130 / 5).ToString(ci)); BasicTest(model, "cien treintaicincoavos", ((double)100 / 35).ToString(ci)); // this is spanish can be interpreted as 130 + 2/5 or 132 / 5 - in this case go for 2nd option for simplicity BasicTest(model, "ciento treinta y dos cincoavos", ((double)132 / 5).ToString(ci)); // and we go for the first option if the user writes it using 'con' BasicTest(model, "ciento treinta con dos cincoavos", (130 + (double)2 / 5).ToString(ci)); BasicTest(model, "ciento treinta y dos quintos", ((double)132 / 5).ToString(ci)); BasicTest(model, "ciento treinta con dos quintos", (130 + (double)2 / 5).ToString(ci)); BasicTest(model, "un cientocincoavos", ((double)1 / 105).ToString(ci)); BasicTest(model, "cien milcincoavos", ((double)100 / 1005).ToString(ci)); BasicTest(model, "uno sobre tres", ((double)1 / 3).ToString(ci)); BasicTest(model, "1 sobre 21", ((double)1 / 21).ToString(ci)); BasicTest(model, "1 sobre tres", ((double)1 / 3).ToString(ci)); BasicTest(model, "1 sobre 3", ((double)1 / 3).ToString(ci)); BasicTest(model, "uno sobre 3", ((double)1 / 3).ToString(ci)); BasicTest(model, "uno sobre 20", ((double)1 / 20).ToString(ci)); BasicTest(model, "uno sobre veinte", ((double)1 / 20).ToString(ci)); BasicTest(model, "uno sobre cien", ((double)1 / 100).ToString(ci)); BasicTest(model, "1 sobre ciento veintiuno", ((double)1 / 121).ToString(ci)); BasicTest(model, "uno sobre ciento treinta y cinco", ((double)1 / 135).ToString(ci)); BasicTest(model, "cinco medios", ((double)5 / 2).ToString(ci)); BasicTest(model, "tres cuartos", ((double)3 / 4).ToString(ci)); BasicTest(model, "dos tercios", ((double)2 / 3).ToString(ci)); BasicTest(model, "ciento treinta y cinco medios", ((double)135 / 2).ToString(ci)); // not supported should be written as integer + decimal part => once con uno y medio //BasicTest(model, "diez con tres medios", (10 + (double)3 / 2).ToString(ci)); BasicTest(model, "once con uno y medio", (10 + (double)3 / 2).ToString(ci)); BasicTest(model, "diez con un medio", (10 + (double)1 / 2).ToString(ci)); BasicTest(model, "diez con un cuarto", (10 + (double)1 / 4).ToString(ci)); }
public void TestOrdinalModel() { var model = NumberRecognizer.GetOrdinalModel(Culture.Spanish); BasicTest(model, "tresmillonesimo", "3000000"); BasicTest(model, "dos mil millonesimo", "2000000000"); BasicTest(model, "septimo", "7"); BasicTest(model, "cuadragesimo septimo", "47"); BasicTest(model, "tricentesimo cuadragesimo septimo", "347"); BasicTest(model, "dosmilesimo tricentesimo cuadragesimo septimo", "2347"); BasicTest(model, "cincuenta y dos milesimo tricentesimo cuadragesimo septimo", "52347"); BasicTest(model, "cuatrocientos cincuenta y dos milesimo tricentesimo cuadragesimo septimo", "452347"); BasicTest(model, "tresmillonesimo septimo", "3000007"); BasicTest(model, "tresmillonesimo cuadragesimo septimo", "3000047"); BasicTest(model, "tresmillonesimo tricentesimo cuadragesimo septimo", "3000347"); BasicTest(model, "tres millones dos milesimo tricentesimo cuadragesimo septimo", "3002347"); BasicTest(model, "tres millones cincuenta y dos milesimo tricentesimo cuadragesimo septimo", "3052347"); BasicTest(model, "tres millones cuatrocientos cincuenta y dos milesimo tricentesimo cuadragesimo septimo", "3452347"); BasicTest(model, "trece millones cuatrocientos cincuenta y dos milesimo tricentesimo cuadragesimo septimo", "13452347"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos milesimo tricentesimo cuadragesimo septimo", "513452347"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos milesimo tricentesimo cuadragesimo", "513452340"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos milesimo tricentesimo", "513452300"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos milesimo", "513452000"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta milesimo", "513450000"); BasicTest(model, "quinientos trece millones cuatrocientos milesimo", "513400000"); BasicTest(model, "quinientos trece millonesimo", "513000000"); BasicTest(model, "quinientos diez millonesimo", "510000000"); BasicTest(model, "quinientosmillonesimo", "500000000"); BasicTest(model, "milesimo quingentesimo vigesimo tercero", "1523"); // a little number :p BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millones quinientos cincuenta y seis milesimo octingentesimo trigesimo segundo", "3455228556832"); BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millones quinientos cincuenta y seis milesimo", "3455228556000"); BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millonesimo", "3455228000000"); BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil millonesimo", "3455000000000"); BasicTest(model, "tresbillonesimo", "3000000000000"); BasicTest(model, "vigesimo quinto", "25"); BasicTest(model, "vigesimo primero", "21"); BasicTest(model, "centesimo vigesimo quinto", "125"); BasicTest(model, "ducentesimo", "200"); BasicTest(model, "tres mil quinientos veinticuatro millones seiscientos noventa y cuatro milesimo sexcentesimo septuagesimo tercero", "3524694673"); BasicTest(model, "tres mil quinientos veinticuatro millones seiscientos noventa y cuatro milesimo sexcentesimo septuagesimo", "3524694670"); BasicTest(model, "tres mil quinientos veinticuatro millones seiscientos noventa y cuatro milesimo sexcentesimo", "3524694600"); BasicTest(model, "tres mil quinientos veinticuatro millones seiscientos milesimo", "3524600000"); BasicTest(model, "tres mil millonesimo", "3000000000"); BasicTest(model, "tres mil millonesimo tercero", "3000000003"); BasicTest(model, "tres mil millonesimo septuagesimo tercero", "3000000073"); BasicTest(model, "tres mil millonesimo sexcentesimo septuagesimo tercero", "3000000673"); BasicTest(model, "tres mil millones cuatro milesimo sexcentesimo septuagesimo tercero", "3000004673"); BasicTest(model, "tres mil veinticuatro millones seiscientos noventa y cuatro milesimo sexcentesimo septuagesimo tercero", "3024694673"); BasicTest(model, "11mo", "11"); BasicTest(model, "11vo", "11"); BasicTest(model, "12vo", "12"); BasicTest(model, "111ro", "111"); BasicTest(model, "111ro", "111"); BasicTest(model, "21ro", "21"); BasicTest(model, "30ma", "30"); BasicTest(model, "2da", "2"); BasicTest(model, "undecimo", "11"); BasicTest(model, "veintidosmilesimo", "22000"); BasicTest(model, "cincuenta y cinco billones quinientos cincuenta y cinco mil quinientos cincuenta y cinco millones quinientos cincuenta y cinco milesimo quingentesimo quincuagesimo quinto", "55555555555555"); BasicTest(model, "vigesimo", "20"); BasicTest(model, "centesimo", "100"); BasicTest(model, "tres billonesimo", "3000000000000"); BasicTest(model, "tres billonesima", "3000000000000"); BasicTest(model, "cien billonesimo", "100000000000000"); }
public void TestNumberModel() { var ci = new SpanishNumberParserConfiguration().CultureInfo; var model = NumberRecognizer.GetNumberModel(Culture.Spanish); #region Integer numbers BasicTest(model, "2 mil millones", "2000000000"); BasicTest(model, " 123456789101231", "123456789101231"); BasicTest(model, "-123456789101231", "-123456789101231"); BasicTest(model, " -123456789101231", "-123456789101231"); BasicTest(model, " -1", "-1"); BasicTest(model, "1.234.567", "1234567"); BasicTest(model, "3 docenas", "36"); BasicTest(model, "dos mil millones", "2000000000"); BasicTest(model, "una docena", "12"); BasicTest(model, "quince docenas", "180"); BasicTest(model, "dos mil y cuatro docenas", "2048"); BasicTest(model, "siete", "7"); BasicTest(model, "cuarenta y siete", "47"); BasicTest(model, "trescientos cuarenta y siete", "347"); BasicTest(model, "dos mil trescientos cuarenta y siete", "2347"); BasicTest(model, "cincuenta y dos mil trescientos cuarenta y siete", "52347"); BasicTest(model, "cuatrocientos cincuenta y dos mil trescientos cuarenta y siete", "452347"); BasicTest(model, "tres millones", "3000000"); BasicTest(model, "tres millones siete", "3000007"); BasicTest(model, "tres millones cuarenta y siete", "3000047"); BasicTest(model, "tres millones trescientos cuarenta y siete", "3000347"); BasicTest(model, "tres millones dos mil trescientos cuarenta y siete", "3002347"); BasicTest(model, "tres millones cincuenta y dos mil trescientos cuarenta y siete", "3052347"); BasicTest(model, "tres millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete", "3452347"); BasicTest(model, "trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete", "13452347"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete", "513452347"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta", "513452340"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil trescientos", "513452300"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil", "513452000"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta mil", "513450000"); BasicTest(model, "quinientos trece millones cuatrocientos mil", "513400000"); BasicTest(model, "quinientos trece millones", "513000000"); BasicTest(model, "quinientos diez millones", "510000000"); BasicTest(model, "quinientos millones", "500000000"); BasicTest(model, "mil quinientos veintitres", "1523"); // a little number :p BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millones quinientos cincuenta y seis mil ochocientos treinta y dos", "3455228556832"); BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millones quinientos cincuenta y seis mil", "3455228556000"); BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millones", "3455228000000"); BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil millones", "3455000000000"); BasicTest(model, "tres billones", "3000000000000"); // super number :p - supported by extractor but not by parser //BasicTest(GetOrdinalModel(), "ciento sesenta y tres septillones quinientos ochenta y dos mil ochocientos setenta y un sextillones ciento dieciocho mil novecientos trece quintillones quinientos ochenta y cinco mil trescientos cuarenta y seis cuatrillones novecientos noventa y siete mil doscientos setenta y tres trillones cuatrocientos treinta y cuatro mil trescientos veinticinco billones quinientos cincuenta y cinco mil ochocientos veintiún millones novecientos cincuenta y tres mil seiscientos setenta y cinco", "163582871118913585346997273434325555821953675"); // numbers within sentences BasicTest(model, "dame un mil", "1000", "un mil"); BasicTest(model, "tirate un paso", "1", "un"); BasicTest(model, "voy a comprar solo una vaca", "1", "una"); BasicTest(model, "voy a comprar doscientas vacas", "200", "doscientas"); BasicTest(model, "tengo solamente mil cien pesos", "1100", "mil cien"); BasicTest(model, "tengo solamente siete mil doscientos treinta y cinco pesos", "7235", "siete mil doscientos treinta y cinco"); BasicTest(model, "no mucho, creo que voy a gastar algo asi como trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete bolivares en todo el proyecto", "13452347", "trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete"); #endregion #region Double numbers BasicTest(model, " 101231,2353", "101231,2353"); BasicTest(model, "-101231,4323", "-101231,4323"); BasicTest(model, " -89101231,5127", "-89101231,5127"); BasicTest(model, " -1,1234567", "-1,1234567"); BasicTest(model, "1.234.567,51274", "1234567,51274"); BasicTest(model, "192,", "192", "192"); BasicTest(model, ",23456000", "0,23456"); BasicTest(model, "4,800", "4,8"); BasicTest(model, ",08", "0,08"); BasicTest(model, "9,2321312", "9,2321312"); BasicTest(model, " -9,2321312", "-9,2321312"); BasicTest(model, "1e10", "10000000000"); BasicTest(model, "1,1^23", "8,95430243255239"); BasicTest(model, "siete con cincuenta", "7,5"); BasicTest(model, "cuarenta y siete coma veintiocho", "47,28"); BasicTest(model, "trescientos cuarenta y siete con quinientos doce", "347,512"); BasicTest(model, "dos mil trescientos cuarenta y siete coma mil quinientos setenta y ocho", "2347,1578"); BasicTest(model, "cincuenta y dos mil trescientos cuarenta y siete con doscientos", "52347,2"); BasicTest(model, "cuatrocientos cincuenta y dos mil trescientos cuarenta y siete coma veintidos", "452347,22"); BasicTest(model, "1,1^+23", "8,95430243255239"); BasicTest(model, "2,5^-1", "0,4"); BasicTest(model, "-2500^-1", "-0,0004"); BasicTest(model, "-1,1^+23", "-8,95430243255239"); BasicTest(model, "-2,5^-1", "-0,4"); BasicTest(model, "-1,1^--23", "-8,95430243255239"); BasicTest(model, "-127,32e13", "-1,2732E+15"); BasicTest(model, "12,32e+14", "1,232E+15"); BasicTest(model, "-12e-1", "-1,2"); #endregion #region Translated numbers from english BasicTest(model, "192.", "192", "192"); // '.' is group separator in spanish - so not understood as IP MultiTest(model, "192.168.1.2", 3); //this will be supported for the NumberWithUnitModel MultiTest(model, "son 180,25ml liquidos", 0); MultiTest(model, "son 180ml liquidos", 0); MultiTest(model, " 29km caminando ", 0); MultiTest(model, " subamos al 4to piso ", 0); MultiTest(model, "son ,25ml liquidos", 0); BasicTest(model, ",08", "0,08"); MultiTest(model, "uno", 1); MultiTest(model, "un", 1); BasicTest(model, ",23456000", "0,23456"); BasicTest(model, "4,800", "4,8"); BasicTest(model, "ciento tres con dos tercios", (103 + (double)2 / 3).ToString(ci)); BasicTest(model, "dieciseis", "16"); BasicTest(model, "dos tercios", ((double)2 / 3).ToString(ci)); BasicTest(model, "ciento dieciseis", "116"); BasicTest(model, "ciento seis", "106"); BasicTest(model, "ciento sesenta y un", "161"); BasicTest(model, "un billonesimo", "1E-12"); BasicTest(model, "cien billonesimos", "1E-10"); BasicTest(model, " media docena ", "6"); BasicTest(model, " 3 docenas", "36"); BasicTest(model, "una docena", "12"); BasicTest(model, " tres docenas ", "36"); BasicTest(model, "1.234.567", "1234567"); MultiTest(model, "1. 234. 567", 3); BasicTest(model, "9,2321312", "9,2321312"); BasicTest(model, " -9,2321312", "-9,2321312"); BasicTest(model, " -1", "-1"); BasicTest(model, "-4/5", "-0,8"); BasicTest(model, "- 1 4/5", "-1,8"); BasicTest(model, "tres", "3"); BasicTest(model, " 123456789101231", "123456789101231"); BasicTest(model, "-123456789101231", "-123456789101231"); BasicTest(model, " -123456789101231", "-123456789101231"); BasicTest(model, "1", "1"); BasicTest(model, "10k", "10000"); BasicTest(model, "10G", "10000000000"); BasicTest(model, "- 10 k", "-10000"); BasicTest(model, "2 millones", "2000000"); BasicTest(model, "1 billon", "1000000000000"); BasicTest(model, " tres ", "3"); BasicTest(model, "un billon", "1000000000000"); BasicTest(model, "veintiun billones", "21000000000000"); BasicTest(model, "veintiun billones trescientos", "21000000000300"); BasicTest(model, "cincuenta y dos", "52"); BasicTest(model, "trescientos treinta y uno", "331"); BasicTest(model, "doscientos dos mil", "202000"); BasicTest(model, "dos mil doscientos", "2200"); BasicTest(model, " 2,33 k", "2330"); BasicTest(model, " doscientos coma cero tres", "200,03"); BasicTest(model, " doscientos con setenta y uno", "200,71"); BasicTest(model, "1e10", "10000000000"); BasicTest(model, "1,1^23", "8,95430243255239"); BasicTest(model, " 322 millones ", "322000000"); BasicTest(model, "setenta", "70"); BasicTest(model, "cincuenta y dos", "52"); BasicTest(model, "2 1/4", "2,25"); BasicTest(model, "3/4", "0,75"); BasicTest(model, "un octavo", "0,125"); BasicTest(model, "cinco octavos", "0,625"); BasicTest(model, "un medio", "0,5"); BasicTest(model, "tres cuartos", "0,75"); BasicTest(model, "veinte con tres quintos", "20,6"); BasicTest(model, "veintitres quintos", "4,6"); BasicTest(model, "veintitres con tres quintos", "23,6"); BasicTest(model, "un millon dos mil doscientos tres quintos", "200440,6"); BasicTest(model, "uno con un medio", "1,5"); BasicTest(model, "uno con un cuarto", "1,25"); BasicTest(model, "cinco con un cuarto", "5,25"); BasicTest(model, "cien con tres cuartos", "100,75"); BasicTest(model, "un centesimo", "0,01"); #endregion }
public void InitializationWithIntOption_ResolveOptionsEnum() { var recognizer = new NumberRecognizer(EnglishCulture, 0); Assert.IsTrue(recognizer.Options.HasFlag(NumberOptions.None)); }
public void TestFractionModel() { var model = NumberRecognizer.GetNumberModel(Culture.Chinese); BasicTest(model, "五 分之 一", (1.0 / 5).ToString()); BasicTest(model, "三 百 五 又 三 分之 一", (350 + 1.0 / 3).ToString()); BasicTest(model, "4 6/3", (4 + (double)6 / 3).ToString()); BasicTest(model, "-3/2", "-1.5"); BasicTest(model, "五分之一", "0.2"); BasicTest(model, "一百万又五十万分之二十五", (1000000 + (double)25 / 500000).ToString()); BasicTest(model, "一百分之二", "0.02"); BasicTest(model, "四千二分之三", ((double)3 / 4200).ToString()); BasicTest(model, "一百分之2", "0.02"); BasicTest(model, "五百分之2333", ((double)2333 / 500).ToString()); BasicTest(model, "3又一千分之23", (3 + (double)23 / 1000).ToString()); BasicTest(model, "3/5", "0.6"); BasicTest(model, "1 3/5", "1.6"); BasicTest(model, "16/5", "3.2"); BasicTest(model, "16分之5", ((double)5 / 16).ToString()); BasicTest(model, "16分之2225", ((double)2225 / 16).ToString()); BasicTest(model, "负一又二分之一", "-1.5"); BasicTest(model, "二分之一", "0.5"); BasicTest(model, "三百 五又三分之一", (350 + (double)1 / 3).ToString()); BasicTest(model, "三百五十又3分之1", (350 + (double)1 / 3).ToString()); BasicTest(model, "3分之一百五十七", ((double)157 / 3).ToString()); BasicTest(model, "负3分之负一百五十七", ((double)157 / 3).ToString()); MultiTest(model, @"一百四十四。一百五十万五千二百四十五,二千零四十五个,三千零五个,和四千万零五十,一百五十四点零,四百亿点零五零,二十五分之一百四十四,十一又十四分之一,1个", 10); MultiTest(model, @"1 4/3的美梦,1/2的努力", 2); BasicTest(model, "二分 之一", "0.5"); BasicTest(model, "三百 五 又 三分 之一", (350 + (double)1 / 3).ToString()); BasicTest(model, "三百五十 又 3分 之1", (350 + (double)1 / 3).ToString()); BasicTest(model, "3 分 之 一百五十七", ((double)157 / 3).ToString()); BasicTest(model, "负3 分 之 负一百五十七", ((double)157 / 3).ToString()); BasicTest(model, "五 分之 壹", (1.0 / 5).ToString()); BasicTest(model, "三 百 五 又 三 分之 壹", (350 + 1.0 / 3).ToString()); BasicTest(model, "4 6/3", (4 + (double)6 / 3).ToString()); BasicTest(model, "-3/2", "-1.5"); BasicTest(model, "五分之壹", "0.2"); BasicTest(model, "壹百萬又五十萬分之二十五", (1000000 + (double)25 / 500000).ToString()); BasicTest(model, "壹百分之二", "0.02"); BasicTest(model, "四千二分之三", ((double)3 / 4200).ToString()); BasicTest(model, "壹百分之2", "0.02"); BasicTest(model, "五百分之2333", ((double)2333 / 500).ToString()); BasicTest(model, "3又壹千分之23", (3 + (double)23 / 1000).ToString()); BasicTest(model, "3/5", "0.6"); BasicTest(model, "1 3/5", "1.6"); BasicTest(model, "16/5", "3.2"); BasicTest(model, "16分之5", ((double)5 / 16).ToString()); BasicTest(model, "16分之2225", ((double)2225 / 16).ToString()); BasicTest(model, "負壹又二分之壹", "-1.5"); BasicTest(model, "二分之壹", "0.5"); BasicTest(model, "三百 五又三分之壹", (350 + (double)1 / 3).ToString()); BasicTest(model, "三百五十又3分之1", (350 + (double)1 / 3).ToString()); BasicTest(model, "3分之壹百五十七", ((double)157 / 3).ToString()); BasicTest(model, "負3分之負壹百五十七", ((double)157 / 3).ToString()); MultiTest(model, @"壹百四十四。壹百五十萬五千二百四十五,二千零四十五個,三千零五個,和四千萬零五十,壹百五十四點零,四百億點零五零,二十五分之壹百四十四,十壹又十四分之壹,1個", 10); MultiTest(model, @"1 4/3的美夢,1/2的努力", 2); BasicTest(model, "二分 之壹", "0.5"); BasicTest(model, "三百 五 又 三分 之壹", (350 + (double)1 / 3).ToString()); BasicTest(model, "三百五十 又 3分 之1", (350 + (double)1 / 3).ToString()); BasicTest(model, "3 分 之 壹百五十七", ((double)157 / 3).ToString()); BasicTest(model, "負3 分 之 負壹百五十七", ((double)157 / 3).ToString()); }
public void TestPercentageModel() { var model = NumberRecognizer.GetPercentageModel(Culture.Chinese); MultiTest(model, "打对折", 1); MultiOneTest(model, "打对折", 1, "50%"); MultiTest(model, "对折", 0); BasicTest(model, "陆 点 五 折", "65%"); BasicTest(model, "9成", "90%"); BasicTest(model, "七成 六", "76%"); BasicTest(model, "7.2成", "72%"); BasicTest(model, "7 2 折", "72%"); BasicTest(model, "六 点 五 成", "65%"); BasicTest(model, "10 成", "100%"); BasicTest(model, "10 成", "100%"); BasicTest(model, "十 成", "100%"); BasicTest(model, "75折", "75%"); BasicTest(model, "9.9折", "99%"); BasicTest(model, "九 九 折", "99%"); BasicTest(model, "三点一折", "31%"); BasicTest(model, "三成", "30%"); BasicTest(model, "半成", "5%"); BasicTest(model, "半折", "50%"); BasicTest(model, "10成", "100%"); BasicTest(model, "十成", "100%"); MultiTest(model, "十折", 0); BasicTest(model, "9.5成", "95%"); BasicTest(model, "九成", "90%"); BasicTest(model, "三成半", "35%"); BasicTest(model, "2.5成", "25%"); BasicTest(model, "2成", "20%"); BasicTest(model, "2折", "20%"); BasicTest(model, "两折", "20%"); BasicTest(model, "两成", "20%"); BasicTest(model, "三八折", "38%"); BasicTest(model, "三点一折", "31%"); MultiTest(model, "2成,2.5成,2.1成,2成", 4); MultiTest(model, "九成,五成,八点五成", 3); BasicTest(model, "2折", "20%"); MultiTest(model, "2折,2.5折,2.1折,2折", 4); MultiTest(model, "九折,五五折,八点五折", 3); MultiTest(model, "五折", 1); BasicTest(model, "百分之2.4", "2.4%"); MultiTest(model, "二三十个百分点", 0); MultiTest(model, "百分之二三十", 0); BasicTest(model, "百分之2.4", "2.4%"); BasicTest(model, "百分之五", "5%"); BasicTest(model, "一百五十 个百分点", "150%"); BasicTest(model, "六个百分点", "6%"); BasicTest(model, "2.4个百分点", "2.4%"); BasicTest(model, "-22.2%", "-22.2%"); BasicTest(model, "22%", "22%"); BasicTest(model, "-122%", "-122%"); BasicTest(model, "百分之22", "22%"); BasicTest(model, "百分之120", "120%"); BasicTest(model, "百分之15K", "15000%"); BasicTest(model, "百分之1,111", "1111%"); BasicTest(model, "百分之9,999", "9999%"); BasicTest(model, "12个百分点", "12%"); BasicTest(model, "2,123个百分点", "2123%"); BasicTest(model, "二十个百分点", "20%"); BasicTest(model, "四点 五个百分点", "4.5%"); BasicTest(model, "百分之五 十", "50%"); BasicTest(model, "百分之一 点五", "1.5%"); BasicTest(model, "百分之56.2", "56.2%"); BasicTest(model, "百分之12", "12%"); BasicTest(model, "百分之3,000", "3000%"); BasicTest(model, "百分之1,123", "1123%"); BasicTest(model, "百分之3.2k", "3200%"); BasicTest(model, "百分之3.2M", "3200000%"); BasicTest(model, "12.56个百分点", "12.56%"); BasicTest(model, "0.4个百分点", "0.4%"); BasicTest(model, "15,123个百分点", "15123%"); BasicTest(model, "111,111个百分点", "111111%"); BasicTest(model, "25%", "25%"); BasicTest(model, "12k个百分点", "12000%"); BasicTest(model, "15k个百分点", "15000%"); BasicTest(model, "一百五十个百分点", "150%"); BasicTest(model, "七十五万个百分点", "750000%"); BasicTest(model, "拾万零五十六点叁叁个百分点", "100056.33%"); BasicTest(model, "75.2个百分点", "75.2%"); BasicTest(model, "75个百分点", "75%"); BasicTest(model, "1,075个百分点", "1075%"); BasicTest(model, "百分之一百", "100%"); BasicTest(model, "百分之百", "100%"); BasicTest(model, "百分之一百二十点五", "120.5%"); BasicTest(model, "百分之2.4", "2.4%"); BasicTest(model, "百分之2", "2%"); BasicTest(model, "百分之1,669", "1669%"); BasicTest(model, "百分之52.5", "52.5%"); MultiTest(model, "五百分之2.2", 0); MultiTest(model, "上升了百分之2.2", 1); BasicTest(model, "5%", "5%"); BasicTest(model, "5.5%", "5.5%"); BasicTest(model, "一 百 五 十 个 百 分 点", "150%"); BasicTest(model, "六 个 百 分点", "6%"); BasicTest(model, "2.4 个百分 点", "2.4%"); BasicTest(model, "百 分之 一百二十点五", "120.5%"); BasicTest(model, "百 分 之2.4", "2.4%"); BasicTest(model, "百 分之 2", "2%"); BasicTest(model, "百 分 之 669", "669%"); BasicTest(model, "百 分 之 52.5 k", "52500%"); BasicTest(model, "百 分 之 一 百二 十点 五", "120.5%"); MultiTest(model, "打對折", 1); MultiOneTest(model, "打對折", 1, "50%"); MultiTest(model, "對折", 0); BasicTest(model, "陸 點 五 折", "65%"); BasicTest(model, "9成", "90%"); BasicTest(model, "七成 六", "76%"); BasicTest(model, "7.2成", "72%"); BasicTest(model, "7 2 折", "72%"); BasicTest(model, "六 點 五 成", "65%"); BasicTest(model, "10 成", "100%"); BasicTest(model, "10 成", "100%"); BasicTest(model, "十 成", "100%"); BasicTest(model, "75折", "75%"); BasicTest(model, "9.9折", "99%"); BasicTest(model, "九 九 折", "99%"); BasicTest(model, "三點一折", "31%"); BasicTest(model, "三成", "30%"); BasicTest(model, "半成", "5%"); BasicTest(model, "半折", "50%"); BasicTest(model, "10成", "100%"); BasicTest(model, "十成", "100%"); MultiTest(model, "十折", 0); BasicTest(model, "9.5成", "95%"); BasicTest(model, "九成", "90%"); BasicTest(model, "三成半", "35%"); BasicTest(model, "2.5成", "25%"); BasicTest(model, "2成", "20%"); BasicTest(model, "2折", "20%"); BasicTest(model, "兩折", "20%"); BasicTest(model, "兩成", "20%"); BasicTest(model, "三八折", "38%"); BasicTest(model, "三點一折", "31%"); MultiTest(model, "2成,2.5成,2.1成,2成", 4); MultiTest(model, "九成,五成,八點五成", 3); BasicTest(model, "2折", "20%"); MultiTest(model, "2折,2.5折,2.1折,2折", 4); MultiTest(model, "九折,五五折,八點五折", 3); MultiTest(model, "五折", 1); BasicTest(model, "百分之2.4", "2.4%"); MultiTest(model, "二三十個百分點", 0); MultiTest(model, "百分之二三十", 0); BasicTest(model, "百分之2.4", "2.4%"); BasicTest(model, "百分之五", "5%"); BasicTest(model, "一百五十 個百分點", "150%"); BasicTest(model, "六個百分點", "6%"); BasicTest(model, "2.4個百分點", "2.4%"); BasicTest(model, "-22.2%", "-22.2%"); BasicTest(model, "22%", "22%"); BasicTest(model, "-122%", "-122%"); BasicTest(model, "百分之22", "22%"); BasicTest(model, "百分之120", "120%"); BasicTest(model, "百分之15K", "15000%"); BasicTest(model, "百分之1,111", "1111%"); BasicTest(model, "百分之9,999", "9999%"); BasicTest(model, "12個百分點", "12%"); BasicTest(model, "2,123個百分點", "2123%"); BasicTest(model, "二十個百分點", "20%"); BasicTest(model, "四點 五個百分點", "4.5%"); BasicTest(model, "百分之五 十", "50%"); BasicTest(model, "百分之一 點五", "1.5%"); BasicTest(model, "百分之56.2", "56.2%"); BasicTest(model, "百分之12", "12%"); BasicTest(model, "百分之3,000", "3000%"); BasicTest(model, "百分之1,123", "1123%"); BasicTest(model, "百分之3.2k", "3200%"); BasicTest(model, "百分之3.2M", "3200000%"); BasicTest(model, "12.56個百分點", "12.56%"); BasicTest(model, "0.4個百分點", "0.4%"); BasicTest(model, "15,123個百分點", "15123%"); BasicTest(model, "111,111個百分點", "111111%"); BasicTest(model, "25%", "25%"); BasicTest(model, "12k個百分點", "12000%"); BasicTest(model, "15k個百分點", "15000%"); BasicTest(model, "一百五十個百分點", "150%"); BasicTest(model, "七十五萬個百分點", "750000%"); BasicTest(model, "拾萬零五十六點叁叁個百分點", "100056.33%"); BasicTest(model, "75.2個百分點", "75.2%"); BasicTest(model, "75個百分點", "75%"); BasicTest(model, "1,075個百分點", "1075%"); BasicTest(model, "百分之一百", "100%"); BasicTest(model, "百分之百", "100%"); BasicTest(model, "百分之一百二十點五", "120.5%"); BasicTest(model, "百分之2.4", "2.4%"); BasicTest(model, "百分之2", "2%"); BasicTest(model, "百分之1,669", "1669%"); BasicTest(model, "百分之52.5", "52.5%"); MultiTest(model, "五百分之2.2", 0); MultiTest(model, "上升了百分之2.2", 1); BasicTest(model, "5%", "5%"); BasicTest(model, "5.5%", "5.5%"); BasicTest(model, "一 百 五 十 個 百 分 點", "150%"); BasicTest(model, "六 個 百 分點", "6%"); BasicTest(model, "2.4 個百分 點", "2.4%"); BasicTest(model, "百 分之 一百二十點五", "120.5%"); BasicTest(model, "百 分 之2.4", "2.4%"); BasicTest(model, "百 分之 2", "2%"); BasicTest(model, "百 分 之 669", "669%"); BasicTest(model, "百 分 之 52.5 k", "52500%"); BasicTest(model, "佰 分 之 一 百二 十點 五", "120.5%"); }
public void TestPercentageModel() { var ci = new SpanishNumberParserConfiguration().CultureInfo; var model = NumberRecognizer.GetPercentageModel(Culture.Spanish);; #region Integer percentages BasicTest(model, "100%", "100%"); BasicTest(model, " 100% ", "100%"); BasicTest(model, " 100 por ciento", "100%"); BasicTest(model, " cien por cien", "100%"); BasicTest(model, "cien por ciento", "100%"); BasicTest(model, "243 por ciento", "243%"); BasicTest(model, "veinte por ciento", "20%"); BasicTest(model, "treinta y cinco por ciento", "35%"); BasicTest(model, "quinientos treinta y cinco por ciento", "535%"); BasicTest(model, "10 por ciento", "10%"); BasicTest(model, "diez por ciento", "10%"); BasicTest(model, "tres millones cincuenta y dos mil trescientos cuarenta y siete por ciento", "3052347%"); BasicTest(model, "tres millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete por ciento", "3452347%"); BasicTest(model, "trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete por ciento", "13452347%"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta y siete por ciento", "513452347%"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil trescientos cuarenta por ciento", "513452340%"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil trescientos por ciento", "513452300%"); BasicTest(model, "quinientos trece millones cuatrocientos cincuenta y dos mil por ciento", "513452000%"); // a little percentage :p BasicTest(model, "tres billones cuatrocientos cincuenta y cinco mil doscientos veintiocho millones quinientos cincuenta y seis mil ochocientos treinta y dos por ciento", "3455228556832%"); // percentages within sentences BasicTest(model, "algo asi como un 11%", "11%", "11%"); BasicTest(model, "claro, solamente un 15 por ciento", "15%", "15 por ciento"); BasicTest(model, "si, nada mas un veinticinco por ciento", "25%", "veinticinco por ciento"); BasicTest(model, "todo, dejame el cien por cien del combustible", "100%", "cien por cien"); BasicTest(model, "un porcentaje del 25%", "25%", "25%"); BasicTest(model, "un porcentaje del treinta y seis por ciento del total", "36%", "treinta y seis por ciento"); BasicTest(model, "un porcentaje del ochenta y cuatro por cien solamente", "84%", "ochenta y cuatro por cien"); #endregion #region Double percentages BasicTest(model, " 101231,2353%", "101231,2353%"); BasicTest(model, "-101231,4323%", "-101231,4323%"); BasicTest(model, " -89101231,5127 por ciento", "-89101231,5127%"); BasicTest(model, " -1,1234567 por cien", "-1,1234567%"); BasicTest(model, "1.234.567,51274 por ciento", "1234567,51274%"); BasicTest(model, ",23456000%", "0,23456%"); BasicTest(model, "4,800%", "4,8%"); BasicTest(model, ",08 por ciento", "0,08%"); BasicTest(model, "9,2321312%", "9,2321312%"); BasicTest(model, " -9,2321312 por cien", "-9,2321312%"); BasicTest(model, "1e10%", "10000000000%"); BasicTest(model, "1,1^23 por ciento", "8,95430243255239%"); BasicTest(model, "siete con cincuenta por ciento", "7,5%"); BasicTest(model, "cuarenta y siete coma veintiocho por ciento", "47,28%"); BasicTest(model, "trescientos cuarenta y siete con quinientos doce por ciento", "347,512%"); BasicTest(model, "dos mil trescientos cuarenta y siete coma mil quinientos setenta y ocho por ciento", "2347,1578%"); BasicTest(model, "cincuenta y dos mil trescientos cuarenta y siete con doscientos por ciento", "52347,2%"); BasicTest(model, "cuatrocientos cincuenta y dos mil trescientos cuarenta y siete coma veintidos por ciento", "452347,22%"); #endregion #region Fraction percentages BasicTest(model, "tres quintos por ciento", ((double)3 / 5).ToString(ci) + "%"); BasicTest(model, "dos coma cinco por ciento", "2,5%"); BasicTest(model, "un quinto por ciento", "0,2%"); BasicTest(model, "un billonesimo por cien", "1E-12%"); BasicTest(model, "un veintiunavo por ciento", ((double)1 / 21).ToString(ci) + "%"); BasicTest(model, "ciento treinta y tres veintiunavos por ciento", ((double)133 / 21).ToString(ci) + "%"); BasicTest(model, "ciento treinta con tres veintiunavos por ciento", (130 + (double)3 / 21).ToString(ci) + "%"); BasicTest(model, "veintidos treintavos por ciento", ((double)22 / 30).ToString(ci) + "%"); BasicTest(model, "tres dosmilesimos por ciento", ((double)3 / 2000).ToString(ci) + "%"); BasicTest(model, "tres veintemilesimos por ciento", ((double)3 / 20000).ToString(ci) + "%"); // act like Google BasicTest(model, "ciento treinta quintos por ciento", ((double)130 / 5).ToString(ci) + "%"); BasicTest(model, "cien treintaicincoavos por ciento", ((double)100 / 35).ToString(ci) + "%"); // this is spanish can be interpreted as 130 + 2/5 or 132 / 5 - in this case go for 2nd option for simplicity BasicTest(model, "ciento treinta y dos cincoavos por ciento", ((double)132 / 5).ToString(ci) + "%"); // and we go for the first option if the user writes it using 'con' BasicTest(model, "ciento treinta con dos cincoavos por ciento", (130 + (double)2 / 5).ToString(ci) + "%"); BasicTest(model, "ciento treinta y dos quintos por ciento", ((double)132 / 5).ToString(ci) + "%"); BasicTest(model, "ciento treinta con dos quintos por ciento", (130 + (double)2 / 5).ToString(ci) + "%"); BasicTest(model, "uno sobre tres por ciento", ((double)1 / 3).ToString(ci) + "%"); BasicTest(model, "1 sobre 3 por ciento", ((double)1 / 3).ToString(ci) + "%"); BasicTest(model, "3/4%", ((double)3 / 4).ToString(ci) + "%"); BasicTest(model, "2/3%", ((double)2 / 3).ToString(ci) + "%"); #endregion }
public void TestNumberModel() { var model = NumberRecognizer.GetNumberModel(Culture.Chinese); #region Integer numbers BasicTest(model, "肆佰陸拾", "460"); BasicTest(model, "十 余 万", "100000"); BasicTest(model, "一百五十二", "152"); BasicTest(model, "壹佰伍拾", "150"); BasicTest(model, "两千四百五", "2450"); BasicTest(model, "负三十二", "-32"); MultiTest(model, "万", 0); MultiTest(model, "万万", 0); BasicTest(model, "二", "2"); BasicTest(model, "10万万", "1000000000"); BasicTest(model, "4.78万亿", "4780000000000"); BasicTest(model, "7 万5 千4 百", "75400"); BasicTest(model, "40k", "40000"); BasicTest(model, "二十 億", "2000000000"); BasicTest(model, "4,565", "4565"); BasicTest(model, "四百五十", "450"); BasicTest(model, "四百五", "450"); BasicTest(model, "一千零一", "1001"); BasicTest(model, "一百零一万一千", "1011000"); BasicTest(model, "一千两百三十四万", "12340000"); BasicTest(model, "五亿零六", "500000006"); BasicTest(model, "七十八万五佰零六", "780506"); BasicTest(model, "肆拾肆", "44"); BasicTest(model, "倆千两百贰拾二", "2222"); BasicTest(model, "5万4千6百", "54600"); BasicTest(model, "5亿1万4千6百", "500014600"); BasicTest(model, "-10000", "-10000"); BasicTest(model, "一打", "12"); BasicTest(model, "拾万零五十六", "100056"); BasicTest(model, "十", "10"); BasicTest(model, "十五", "15"); BasicTest(model, "一百", "100"); BasicTest(model, "九百九十九", "999"); BasicTest(model, "九百九", "990"); BasicTest(model, "二百五十", "250"); BasicTest(model, "一千零五十", "1050"); BasicTest(model, "一千零五", "1005"); BasicTest(model, "一千陆", "1600"); BasicTest(model, "一万三", "13000"); BasicTest(model, "一万二百五十", "10250"); BasicTest(model, "一万零二百五十", "10250"); BasicTest(model, "九万四", "94000"); BasicTest(model, "九十二万四", "924000"); BasicTest(model, "九万零四百", "90400"); BasicTest(model, "九百万零四百", "9000400"); BasicTest(model, "四千零五万", "40050000"); BasicTest(model, "四千万", "40000000"); BasicTest(model, "四千万零六千", "40006000"); BasicTest(model, "四亿", "400000000"); BasicTest(model, "四亿五千六百四十二万零一十五", "456420015"); BasicTest(model, "四万五千六百二十二", "45622"); BasicTest(model, "五兆六十二亿四万五千二", "5006200045200"); BasicTest(model, "五十五兆一十二亿四万五千二", "55001200045200"); BasicTest(model, "十万柒仟捌佰伍拾肆", "107854"); BasicTest(model, "半百", "50"); BasicTest(model, "拾万零五十六", "100056"); BasicTest(model, "拾六万零五百零六", "160506"); BasicTest(model, "拾亿零六万零五百零六", "1000060506"); BasicTest(model, "一百万零四", "1000004"); BasicTest(model, "四十万", "400000"); BasicTest(model, "四千零四万", "40040000"); BasicTest(model, "四十五亿四千零四万", "4540040000"); BasicTest(model, "负四十五亿零四百零四万", "-4504040000"); BasicTest(model, "负四百零五亿零四百零四万", "-40504040000"); BasicTest(model, "四万万", "400000000"); BasicTest(model, "五十打", "600"); BasicTest(model, "百三", "130"); MultiTest(model, "1, 234, 567", 3); MultiTest(model, "二百五, 二百五, 还有二百五。", 3); MultiTest(model, "1502222, 二百五, 还有二分之。", 3); MultiTest(model, "199个", 1); BasicTest(model, "1,050,000,000", "1050000000"); BasicTest(model, "两千三百五", "2350"); BasicTest(model, "一百 五 十 二", "152"); BasicTest(model, "两千 四 百 五", "2450"); BasicTest(model, "7万 5千 4百", "75400"); BasicTest(model, "三千 八百 九十六 万 四千 九百 六十五", "38964965"); BasicTest(model, "三千 九百 六十五 ", "3965"); BasicTest(model, "五百 余万", "5000000"); BasicTest(model, "一千多万", "10000000"); BasicTest(model, "十多万", "100000"); BasicTest(model, "二十几万", "200000"); BasicTest(model, "一百零几万", "1000000"); BasicTest(model, "一千五百零几万", "15000000"); BasicTest(model, "一百 二 十 几亿", "12000000000"); BasicTest(model, "三双", "6"); BasicTest(model, "一百对", "200"); BasicTest(model, "十双", "20"); BasicTest(model, "一百五十对", "300"); MultiOneTest(model, "十打苹果", 1, "120"); MultiTest(model, "1991年1月16日晚巴黎时间20点:法国总统密特朗发表电视讲话,宣布和平解决海湾危机已经让位于战争,法国已经作好一切战斗准备。", 4); BasicTest(model, "500余万", "5000000"); BasicTest(model, "八千 三百 八十五 万 二千 三百 二十六 点三三", "83852326.33"); BasicTest(model, "2^5", "32"); BasicTest(model, "2e5", "200000"); MultiOneTest(model, "四百多", 1, "400"); BasicTest(model, "两双", "4"); BasicTest(model, "一百五 ", "150"); BasicTest(model, "十 余 萬", "100000"); BasicTest(model, "壹百五十二", "152"); BasicTest(model, "壹佰伍拾", "150"); BasicTest(model, "兩千四百五", "2450"); BasicTest(model, "負三十二", "-32"); MultiTest(model, "萬", 0); MultiTest(model, "萬萬", 0); BasicTest(model, "二", "2"); BasicTest(model, "10萬萬", "1000000000"); BasicTest(model, "4.78萬億", "4780000000000"); BasicTest(model, "7 萬5 千4 百", "75400"); BasicTest(model, "40k", "40000"); BasicTest(model, "二十 億", "2000000000"); BasicTest(model, "4,565", "4565"); BasicTest(model, "四百五十", "450"); BasicTest(model, "四百五", "450"); BasicTest(model, "壹千零壹", "1001"); BasicTest(model, "壹百零壹萬壹千", "1011000"); BasicTest(model, "壹千兩百三十四萬", "12340000"); BasicTest(model, "五億零六", "500000006"); BasicTest(model, "七十八萬五佰零六", "780506"); BasicTest(model, "肆拾肆", "44"); BasicTest(model, "兩千兩百貳拾二", "2222"); BasicTest(model, "5萬4千6百", "54600"); BasicTest(model, "5億1萬4千6百", "500014600"); BasicTest(model, "-10000", "-10000"); BasicTest(model, "壹打", "12"); BasicTest(model, "拾萬零五十六", "100056"); BasicTest(model, "十", "10"); BasicTest(model, "十五", "15"); BasicTest(model, "壹百", "100"); BasicTest(model, "九百九十九", "999"); BasicTest(model, "九百九", "990"); BasicTest(model, "二百五十", "250"); BasicTest(model, "壹千零五十", "1050"); BasicTest(model, "壹千零五", "1005"); BasicTest(model, "壹千六", "1600"); BasicTest(model, "壹萬三", "13000"); BasicTest(model, "壹萬二百五十", "10250"); BasicTest(model, "壹萬零二百五十", "10250"); BasicTest(model, "九萬四", "94000"); BasicTest(model, "九十二萬四", "924000"); BasicTest(model, "九萬零四百", "90400"); BasicTest(model, "九百萬零四百", "9000400"); BasicTest(model, "四千零五萬", "40050000"); BasicTest(model, "四千萬", "40000000"); BasicTest(model, "四千萬零六千", "40006000"); BasicTest(model, "四億", "400000000"); BasicTest(model, "四億五千六百四十二萬零壹十五", "456420015"); BasicTest(model, "四萬五千六百二十二", "45622"); BasicTest(model, "五兆六十二億四萬五千二", "5006200045200"); BasicTest(model, "五十五兆壹十二億四萬五千二", "55001200045200"); BasicTest(model, "十萬柒仟捌佰伍拾肆", "107854"); BasicTest(model, "半百", "50"); BasicTest(model, "拾萬零五十六", "100056"); BasicTest(model, "拾六萬零五百零六", "160506"); BasicTest(model, "拾億零六萬零五百零六", "1000060506"); BasicTest(model, "壹百萬零四", "1000004"); BasicTest(model, "四十萬", "400000"); BasicTest(model, "四千零四萬", "40040000"); BasicTest(model, "四十五億四千零四萬", "4540040000"); BasicTest(model, "負四十五億零四百零四萬", "-4504040000"); BasicTest(model, "負四百零五億零四百零四萬", "-40504040000"); BasicTest(model, "四萬萬", "400000000"); BasicTest(model, "五十打", "600"); BasicTest(model, "百三", "130"); BasicTest(model, "5,236", "5236"); MultiTest(model, "1, 234, 567", 3); MultiTest(model, "二百五, 二百五, 還有二百五。", 3); MultiTest(model, "1502222, 二百五, 還有二分之。", 3); MultiTest(model, "199個", 1); BasicTest(model, "1,050,000,000", "1050000000"); BasicTest(model, "兩千三百五", "2350"); BasicTest(model, "壹百 五 十 二", "152"); BasicTest(model, "兩千 四 百 五", "2450"); BasicTest(model, "7萬 5千 4百", "75400"); BasicTest(model, "三千 八百 九十六 萬 四千 九百 六十五", "38964965"); BasicTest(model, "三千 九百 六十五 ", "3965"); BasicTest(model, "五百 余萬", "5000000"); BasicTest(model, "壹千多萬", "10000000"); BasicTest(model, "十多萬", "100000"); BasicTest(model, "二十幾萬", "200000"); BasicTest(model, "壹百零幾萬", "1000000"); BasicTest(model, "壹千五百零幾萬", "15000000"); BasicTest(model, "壹百 二 十 幾億", "12000000000"); BasicTest(model, "三雙", "6"); BasicTest(model, "壹百對", "200"); BasicTest(model, "十雙", "20"); BasicTest(model, "壹百五十對", "300"); MultiOneTest(model, "十打蘋果", 1, "120"); MultiTest(model, "1991年1月16日晚巴黎時間20點:法國總統密特朗發表電視講話,宣布和平解抉海灣危機已經讓位於戰爭,法國已經作好壹切戰鬥準備。", 4); BasicTest(model, "500余萬", "5000000"); BasicTest(model, "八千 三百 八十五 萬 二千 三百 二十六 點三三", "83852326.33"); BasicTest(model, "2^5", "32"); BasicTest(model, "2e5", "200000"); MultiOneTest(model, "四百多", 1, "400"); BasicTest(model, "兩雙", "4"); BasicTest(model, "壹百五 ", "150"); #endregion #region Double numbers MultiTest(model, "百分之五十五点五七九", 0); MultiTest(model, "百分之十万零六百五十一", 0); MultiTest(model, "六千零五十一个百分点", 0); MultiTest(model, "六百一十一点二五五个百分点", 0); BasicTest(model, "负六点六", "-6.6"); BasicTest(model, "十五点七", "15.7"); BasicTest(model, "11.92亿", "1192000000"); BasicTest(model, "2.2", "2.2"); BasicTest(model, "2.2亿", "220000000"); BasicTest(model, "1000 万", "10000000"); BasicTest(model, "21.2E0", "21.2"); BasicTest(model, "2^-1", "0.5"); BasicTest(model, "四百 点 五", "400.5"); BasicTest(model, "零点五", "0.5"); BasicTest(model, "10.233", "10.233"); BasicTest(model, "-1e1", "-10"); BasicTest(model, "-2.5 M", "-2500000"); BasicTest(model, "二点五", "2.5"); BasicTest(model, "十点二三三", "10.233"); BasicTest(model, "两千万点五五四四", "20000000.5544"); BasicTest(model, "两千点零", "2000"); BasicTest(model, "两千三点一", "2300.1"); BasicTest(model, "10.233", "10.233"); BasicTest(model, "10,000.233", "10000.233"); BasicTest(model, ".23456000", "0.23456"); BasicTest(model, "4.800", "4.8"); BasicTest(model, "2.7890", "2.789"); BasicTest(model, "2.3", "2.3"); BasicTest(model, "2.3万", "23000"); BasicTest(model, "2.7890e-1", "0.2789"); BasicTest(model, ".5", "0.5"); BasicTest(model, "-.5", "-0.5"); MultiTest(model, "1, 234, 567.3", 3); MultiTest(model, "1, 244, 667.123 五点八", 4); MultiTest(model, "二百三十三,五百七十七,一千六点五。", 3); MultiTest(model, "2222.2222.22222.222", 4); MultiOneTest(model, "...9", 1, "9"); MultiOneTest(model, "--9", 1, "9"); BasicTest(model, "1.1^+23", "8.95430243255239"); BasicTest(model, "2.5^-1", "0.4"); BasicTest(model, "-1.1^+23", "-8.95430243255239"); BasicTest(model, "-2.5^-1", "-0.4"); BasicTest(model, "-1.1^--23", "-8.95430243255239"); BasicTest(model, "-127.32e13", "-1.2732E+15"); BasicTest(model, "12.32e+14", "1.232E+15"); BasicTest(model, "-12e-1", "-1.2"); #endregion }
/// <summary> /// Check the Forms Recognizer response - once complete map it to a POCO /// </summary> /// <param name="receipt"></param> /// <returns></returns> private async Task <Receipt> ReceiptAnalysisResult(Receipt receipt) { _logger.LogInformation($"Getting receipt analysis result: {receipt.Id}"); using HttpResponseMessage response = await _httpClient.GetAsync(receipt.OCRRequestUrl); var ocrResponse = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { var serviceError = JsonSerializer.Deserialize <OCRError>(ocrResponse); _logger.LogError($"OCR Response status code: {response.IsSuccessStatusCode} : Error Code: {serviceError.error.code}, Error Message: {serviceError.error.message}"); receipt.Status = serviceError.error.message; return(receipt); } try { var ocrResult = JsonSerializer.Deserialize <OCRResult>(ocrResponse); receipt.Status = ocrResult.status; _logger.LogInformation($"OCR response status: {receipt.Status}"); if (receipt.Status.Equals(Constants.OCRServiceOperationStatus.Succeeded.ToString(), StringComparison.InvariantCultureIgnoreCase) || receipt.Status.Equals(Constants.OCRServiceOperationStatus.Failed.ToString(), StringComparison.InvariantCultureIgnoreCase)) { receipt.OCRComplete = true; } if (ocrResult.analyzeResult?.documentResults?.Length > 0) { // Assuming only 1 receipt per scan var ocrReceipt = ocrResult.analyzeResult?.documentResults.FirstOrDefault(); receipt.RequestComplete = DateTime.Now; receipt.Merchant = ocrReceipt.fields.MerchantName?.text; receipt.Total = Convert.ToDouble(ocrReceipt.fields.Total?.valueNumber); receipt.SubTotal = Convert.ToDouble(ocrReceipt.fields.Subtotal?.valueNumber); receipt.Tax = Convert.ToDouble(ocrReceipt.fields.Tax?.valueNumber); receipt.Tip = Convert.ToDouble(ocrReceipt.fields.Tip?.valueNumber); //receipt.Address = ocrReceipt.fields.MerchantAddress?.text; if (ocrReceipt.fields.TransactionTime != null && DateTime.TryParse(ocrReceipt.fields.TransactionTime.text, out DateTime time)) { receipt.Time = time; } if (ocrReceipt.fields.TransactionDate != null) { // Dates could come in a variety of different formats and styles var recognizerDate = DateTimeRecognizer.RecognizeDateTime(ocrReceipt.fields.TransactionDate.text, Culture.English); if (recognizerDate.Any()) { var recognizerValues = (List <Dictionary <string, string> >)recognizerDate.First().Resolution["values"]; if (recognizerValues.Any()) { if (recognizerValues[0].TryGetValue("value", out string v)) { DateTime.TryParse(v, out DateTime outputDate); receipt.Date = outputDate; } } } } // Extract line items if (ocrReceipt.fields.Items?.valueArray?.Length > 0) { receipt.Items = new LineItem[ocrReceipt.fields.Items.valueArray.Length]; for (int i = 0; i < ocrReceipt.fields.Items.valueArray.Length; i++) { LineItem lineItem = new LineItem { Item = ocrReceipt.fields.Items?.valueArray[i].valueObject?.Name?.text, }; if (ocrReceipt.fields.Items?.valueArray[i].valueObject?.Quantity?.text != null) { var quantityRecognizer = NumberRecognizer.RecognizeNumber(ocrReceipt.fields.Items.valueArray[i].valueObject.Quantity.text, Culture.English); if (quantityRecognizer.Any()) { var recognizerValue = quantityRecognizer.FirstOrDefault().Resolution["value"]; if (recognizerValue != null) { double.TryParse(recognizerValue.ToString(), out double outputQuantity); lineItem.Quantity = outputQuantity; } } } // Total price could include currency symbol if (ocrReceipt.fields.Items?.valueArray[i].valueObject?.TotalPrice?.text != null) { var numberRecognizer = NumberRecognizer.RecognizeNumber(ocrReceipt.fields.Items.valueArray[i].valueObject.TotalPrice.text, Culture.English); if (numberRecognizer.Any()) { var recognizerValue = numberRecognizer.FirstOrDefault().Resolution["value"]; if (recognizerValue != null) { double.TryParse(recognizerValue.ToString(), out double outputTotal); lineItem.TotalPrice = outputTotal; } } } receipt.Items[i] = lineItem; } } _logger.LogInformation($"Successful OCR receipt extraction Id: {receipt.Id} Total: {receipt.Total}"); } } catch (Exception exp) { _logger.LogError($"Error deserialising the OCR response: {exp.Message}"); receipt.Status = exp.Message; } return(receipt); }