Exemplo n.º 1
0
        private (PracticeResult bestResult, PracticeResult worstResult) EvaluatePartialResults(string[] results, string[] inputs)
        {
            var bestResult  = PracticeResult.Wrong;
            var worstResult = PracticeResult.Correct;

            foreach (string result in results)
            {
                var bestMatch = PracticeResult.Wrong;

                foreach (string input in inputs)
                {
                    PracticeResult match = EvaluateOptionalExpressions(result, input);

                    if (match != PracticeResult.Correct)
                    {
                        string[] partialResults = result.SplitAndTrim(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
                        string[] partialInputs  = input.SplitAndTrim(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);

                        // If the synonym contains separators which match with the input in term of count
                        // we evaluate each part of the input as a synonym and check if we get a better score

                        if (partialResults.Length == partialInputs.Length && partialResults.Length > 1)
                        {
                            (_, PracticeResult partialMatch) = EvaluatePartialResults(partialResults, partialInputs);
                            if (partialMatch > match)
                            {
                                match = partialMatch;
                            }
                        }
                    }

                    if (match > bestMatch)
                    {
                        bestMatch = match;
                    }
                }

                if (bestMatch > bestResult)
                {
                    bestResult = bestMatch;
                }
                if (bestMatch < worstResult)
                {
                    worstResult = bestMatch;
                }
            }

            return(bestResult, worstResult);
        }
Exemplo n.º 2
0
        public async Task <List <PracticeData> > GetPracticeData(int runnerid)
        {
            var practicedata = new List <PracticeData>();
            //Get times by runner
            var listoftimes = await TimeServices.GetListOfTimesbyRunnerId(runnerid);

            //Creates list of dates
            Dictionary <int, DateTime> eventdates = new Dictionary <int, DateTime>();


            //Select times from a events
            var practices = listoftimes.GroupBy(ev => new { ev.EventId }).Select(grp => grp.First()).ToList();

            foreach (var practice in practices)
            {
                var tmpevent = await EventServices.GetEventById(practice.EventId.GetValueOrDefault());

                //if event is a race remove form the list of races
                if (tmpevent.IsRace)
                {
                    listoftimes.RemoveAll(e => e.EventId == practice.EventId.GetValueOrDefault());
                }
                else
                //if event is not a race creates a dictionary with Key the event Id and content the race date to use later
                {
                    eventdates.Add(tmpevent.Id, tmpevent.RaceDate);
                }
            }

            //creates PracticeData
            var grouprun = listoftimes.GroupBy(d => d.Distance).ToList();


            foreach (var group in grouprun)
            {
                var practiceresults = new List <PracticeResult>();

                foreach (var run in group)
                {
                    var practiceresult = new PracticeResult {
                        MaxTime = run.Times.TotalMilliseconds, MinTime = run.Times.TotalMilliseconds, Date = eventdates[run.EventId.GetValueOrDefault()]
                    };
                    practiceresults.Add(practiceresult);
                }

                //Select the lower and higher times if there is more than one for a given distance i n a day
                var tmpresults = practiceresults.GroupBy(d => d.Date).ToList();
                foreach (var date in tmpresults)
                {
                    if (date.Count() > 1)
                    {
                        var maxtime        = date.Max(t => t.MaxTime);
                        var mintime        = date.Min(t => t.MaxTime);
                        var practiceresult = new PracticeResult {
                            Date = date.Key, MaxTime = maxtime, MinTime = mintime
                        };
                        //erase the various entries with same date and distance
                        practiceresults.RemoveAll(d => d.Date == date.Key);
                        //add a single entry with the maxtime and mintime of the day
                        practiceresults.Add(practiceresult);
                    }
                }

                //Add practices results to each distance
                var practice = new PracticeData {
                    Distance = group.Key, PracticeResults = practiceresults
                };
                practicedata.Add(practice);
            }

            return(practicedata);
        }
Exemplo n.º 3
0
 public void TestOptionalEdgeCases(PracticeResult expected, string result, string input)
 {
     Assert.AreEqual(expected, evaluator.GetResult(new[] { result }, new[] { input }));
 }
Exemplo n.º 4
0
        private PracticeResult EvaluateOptionalExpressions(string result, string input)
        {
            if (!OptionalExpressions)
            {
                return(EvaluateToleratedMistakes(result, input));
            }

            List <Segment> segments = GetSegments(result, out int optionalCount);

            if (segments.Count == 1)
            {
                return(EvaluateToleratedMistakes(result, input));
            }

            // Evaluating optional expressions range by range would be efficient but difficult
            // because it's not possible to match result and input indices for partly correct statements.
            // The alternative is to compute all possible combinations which are as many as  3 to the power
            // of n where n is the number of optional segments.

            string[] candidiates   = new string[(int)Math.Pow(3, optionalCount)];
            int      optionalIndex = -1;

            for (int i = 0; i < segments.Count; i++)
            {
                Segment seg        = segments[i];
                var     variations = new string[3];
                variations[0] = result.Substring(seg.Start, seg.End - seg.Start + 1);

                if (segments[i].Optional)
                {
                    if (seg.Space == 0)
                    {
                        variations[1] = result.Substring(seg.Start + 1, seg.End - seg.Start - 1);
                    }
                    else if (seg.Space == -1)
                    {
                        variations[1] = ' ' + result.Substring(seg.Start + 2, seg.End - seg.Start - 2);
                    }
                    else if (seg.Space == 1)
                    {
                        variations[1] = result.Substring(seg.Start + 1, seg.End - seg.Start - 2) + ' ';
                    }

                    variations[2] = string.Empty;
                    optionalIndex++;
                }

                int variationBlockLength = (int)Math.Pow(3, optionalCount - 1 - optionalIndex);

                for (int k = 0; k < candidiates.Length; k++)
                {
                    int variation = seg.Optional
                        ? k / variationBlockLength % 3
                        : 0;

                    if (i == 0)
                    {
                        candidiates[k] = variations[variation];
                    }
                    else
                    {
                        candidiates[k] += variations[variation];
                    }
                }
            }

            // Iterate through all possible candidates and return the result of the best match.

            PracticeResult bestMatch = PracticeResult.Wrong;

            foreach (string candidate in candidiates)
            {
                PracticeResult match = EvaluateToleratedMistakes(candidate, input);
                if (match > bestMatch)
                {
                    bestMatch = match;
                }
            }

            return(bestMatch);
        }