예제 #1
0
        /// <summary>
        /// Filter items by feature.
        /// </summary>
        /// <param name="items">Input items to filter.</param>
        /// <param name="featureToAsk">Selected feature which is was asked.</param>
        /// <param name="value">Value which user put. If type of feature is numeric, then this value will be median.</param>
        /// <param name="index">Valid only in numerics type. If user select under median, the index is 0 otherwise 1.</param>
        /// <returns>Filtered items.</returns>
        public async Task <IEnumerable <PimItem> > FilterItemsByFeature(
            IEnumerable <PimFeature> allFeatures,
            IEnumerable <PimItem> items,
            FeatureToAsk featureToAsk,
            string value,
            int index = -1)
        {
            var pimItemResult = new List <PimItem>();

            switch (featureToAsk.Type)
            {
            case FeatureType.Alphanumeric:
                foreach (var item in items)
                {
                    var features = await _featuresService.GetFeaturesByNoAsync(item.No, allFeatures);

                    var filteredItem = features.Where(i => i.Number == featureToAsk.Number).ToList();
                    if (filteredItem.Count() == 0)
                    {
                        pimItemResult.Add(item);
                    }
                    else
                    {
                        if (filteredItem[0].Value == value)
                        {
                            pimItemResult.Add(item);
                        }
                    }
                }

                return(pimItemResult);

            case FeatureType.Numeric:

                // Special case for Unit Price
                if (featureToAsk.Number == Constants.UnitPriceType)
                {
                    if (index == 0)
                    {
                        return(items.Where(i => Convert.ToDouble(i.Unit_Price) <= Convert.ToDouble(value)).ToList());
                    }
                    else if (index == 1)
                    {
                        return(items.Where(i => Convert.ToDouble(i.Unit_Price) > Convert.ToDouble(value)).ToList());
                    }
                }

                foreach (var item in items)
                {
                    var features = await _featuresService.GetFeaturesByNoAsync(item.No, allFeatures);

                    var filteredItem = features.Where(i => i.Number == featureToAsk.Number).ToList();
                    if (filteredItem.Count() == 0)
                    {
                        pimItemResult.Add(item);
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (double.Parse(filteredItem[0].Value, CultureInfo.InvariantCulture) <= double.Parse(value, CultureInfo.InvariantCulture))
                            {
                                pimItemResult.Add(item);
                            }
                        }

                        if (index == 1)
                        {
                            if (double.Parse(filteredItem[0].Value, CultureInfo.InvariantCulture) > double.Parse(value, CultureInfo.InvariantCulture))
                            {
                                pimItemResult.Add(item);
                            }
                        }
                    }
                }

                return(pimItemResult);

            default:
                return(items);
            }
        }
예제 #2
0
        /// <summary>
        /// Method choose from inputs items features to ask. It's sorts features by order and computed information gain.
        /// </summary>
        /// <param name="items">List of items.</param>
        /// <returns>Ordered features to ask.</returns>
        public async Task <List <FeatureToAsk> > GetAllFeaturesToAsk(IEnumerable <PimItem> items)
        {
            var features = await _featuresService.GetAllFeaturesByItemAsync();

            var itemsNos             = items.ToList().Select(i => i.No).ToList();
            var featuresByInputItems = features.Where(f => itemsNos.Contains(f.Key)).ToList();

            var featureToAsks = new List <FeatureToAsk>();

            foreach (var feature in featuresByInputItems)
            {
                List <string> added = new List <string>();
                foreach (var ftr in feature.Value)
                {
                    // Check if already in feature to ask
                    var index = featureToAsks.FindIndex(f => f.Number == ftr.Number);
                    if (!(index >= 0))
                    {
                        // Add to feature to ask
                        var featureToAsk = new FeatureToAsk(ftr.Number, ftr.Description, ftr.Order, ftr.Unit_Shorthand_Description);
                        featureToAsk.ValuesList = new HashSet <string>();

                        // Added new feature value
                        if (ftr.Value != string.Empty)
                        {
                            added.Add(ftr.Description);
                            featureToAsk.ValuesList.Add(ftr.Value);
                        }

                        featureToAsks.Add(featureToAsk);
                    }
                    else
                    {
                        // Check if same item doesnt content same attribut
                        if (!added.Contains(ftr.Description))
                        {
                            if (ftr.Value != string.Empty)
                            {
                                added.Add(ftr.Description);
                                featureToAsks[index].ValuesList.Add(ftr.Value);
                            }
                        }
                    }
                }
            }

            // Added to features to ask the unit price which is by default not in features
            var unitPriceFeature = new FeatureToAsk(Constants.UnitPriceType, Messages.UnitPrice, 1, string.Empty);

            unitPriceFeature.ValuesList = new HashSet <string>();
            foreach (var item in items)
            {
                unitPriceFeature.ValuesList.Add(item.Unit_Price.ToString("F", CultureInfo.CreateSpecificCulture("en-US")));
            }

            featureToAsks.Add(unitPriceFeature);

            // Features without value or with one value are meaningless - they don't help
            var filteredFeatureToAsk = featureToAsks.Where(i => i.ValuesList.Count > 1).ToList();

            // Set type of feature - numeric, text, etc
            filteredFeatureToAsk.ForEach(i => i.SetAndCheckType());

            // For every feature compute information gain
            filteredFeatureToAsk.ForEach(i => i.ComputeInformationGain(items.ToList()));

            // Order features by Order and information gain
            var orderedFeaturesToAsk = filteredFeatureToAsk
                                       .OrderByDescending(i => i.Order)
                                       .ThenByDescending(i => i.InformationGain)
                                       .ToList();

            return(orderedFeaturesToAsk);
        }