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));
        }
示例#2
0
        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);
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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));
        }
示例#8
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
        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));
        }
示例#13
0
        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);
        }
示例#14
0
        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>());
            }
        }
示例#15
0
        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);
        }
示例#16
0
        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)
                       ));
        }
示例#17
0
        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");
        }
示例#19
0
        /// <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));
 }
示例#21
0
        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
        }
示例#25
0
        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
        }
示例#30
0
        /// <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);
        }