Esempio n. 1
0
        /// <summary>
        /// Attempts to vend an item
        /// </summary>
        /// <param name="itemPriceInUnits">The unit price of the item</param>
        /// <param name="tenderedChange">The change tendered to purchase the item</param>
        /// <returns>The success of the vend</returns>
        protected override VendingResult DoVend(int itemPriceInUnits, IEnumerable<Change> tenderedChange)
        {
            // We can use the tendered change supplied by the user to work out the change we can give.
            // For examples, for an item costing 20p a user may supply a 2p followed by a 20p.
            // If the machine was empty and we didn't consider that they tendered then we couldn't
            // give change, but if we do include it in the calculation then we can
            // NOTE: In the event we can't give change we will need to remove it

            Add(tenderedChange);

            // The caller methods in the base have validated that the tendered change is at least the price of the item
            int changeRequired = tenderedChange.TotalValue() - itemPriceInUnits;

            VendingResult result = Greedy(changeRequired, this.Balance);

            if(result.Success)
            {
                // We were able to give the exact change.
                // We now need to remove the coins we're going to give from the machine
                Remove(result.Change);
            }
            else
            {
                // We aren't able to give change, so remove the tendered coins
                // from the machine so that the balance is flat
                Remove(tenderedChange);
            }

            return result;
        }
        private ItemVM ToCollection(IEnumerable <ItemData> items)
        {
            var itemVM = new ItemVM
            {
                Items        = items,
                TotalValue   = items.TotalValue(),
                ProfitAmount = items.Profit()
            };

            return(itemVM);
        }
        /// <summary>
        /// Attempts to vend an item
        /// </summary>
        /// <param name="itemPriceInUnits">The unit price of the item</param>
        /// <param name="tenderedChange">The change tendered to purchase the item</param>
        /// <returns>The success of the vend</returns>
        protected override VendingResult DoVend(int itemPriceInUnits, IEnumerable<Change> tenderedChange)
        {
            // We can use the tendered change supplied by the user to work out the change we can give.
            // For examples, for an item costing 20p a user may supply a 2p followed by a 20p.
            // If the machine was empty and we didn't consider that they tendered then we couldn't
            // give change, but if we do include it in the calculation then we can
            // NOTE: In the event we can't give change we will need to remove it

            Add(tenderedChange);

            List<Change> changeToGive = new List<Change>();

            // The caller methods in the base have validated that the tendered change is at least the price of the item
            int outstandingChange = tenderedChange.TotalValue() - itemPriceInUnits;

            // The recursive algorithm is more performance intensive that a regular greedy
            // algorithm as it considers all possibilities. We can simplify this a bit
            // by only using change which the denomination is no bigger than the amount we need to give,
            // as anything bigger will be ignored
            List<Change> changeAvailable = this.Balance.Where(c => (c.Denomination <= outstandingChange)).ToList();

            // Kick off the recursion
            VendingResult result = RecursiveVend(outstandingChange, 0, changeAvailable);

            if(result.Success)
            {
                // We were able to give the exact change.
                // We now need to remove the coins we're going to give from the machine
                Remove(result.Change);
            }
            else
            {
                // We aren't able to give change, so remove the tendered change from the machine
                Remove(tenderedChange);
            }

            return result;
        }
Esempio n. 4
0
        /// <summary>
        /// Validates the supplied vending parameters to save each base class having to do it
        /// </summary>
        /// <param name="itemPriceInUnits">The price of the item</param>
        /// <param name="tenderedChange">The change tendered to purchase the item</param>
        private void ValidateVendData(int itemPriceInUnits, IEnumerable<Change> tenderedChange)
        {
            // We need to be buying something that cost something...
            if(itemPriceInUnits < 1) throw new ArgumentException("invalid price", "itemPriceInUnits");

            // The caller needs to have supplied some money to buy the items
            if(tenderedChange == null) throw new ArgumentNullException("tenderedChange");

            // Make sure there are no nulls in the tendered change
            bool hasNullChange = tenderedChange.Contains(null);
            if(hasNullChange) throw new ArgumentException("there are null items in the tendered change", "tenderedChange");

            // Make sure the change is at least the value of the item
            int totalTenderedAmount = tenderedChange.TotalValue();
            if(totalTenderedAmount < itemPriceInUnits) throw new ArgumentException("not enough change tendered", "tenderedChange");
        }