Giải pháp hackrank giỏ hàng trong python

Mã nguồn cho shoppingCart. xe đẩy

#!/usr/bin/python
# -*- encoding: utf-8 -*-
################################################################################
#
#    Copyright [C] 2010 - 2015 Dharmesh Patel .
#    Licence : BSD, see LICENSE for more details.
#
################################################################################

from shoppingCart.tax import calculate
from shoppingCart.utils import id_from_object, get_dict_of_ids, get_list_of_ids

__all__ = ['Cart']

[docs]class Cart[object]: """ Collection of :class:`CartItem` objects. """ def __init__[self, site=None, customer=None]: """ :param site: Unique id or name of :class:`Site` object or instance of :class:`Site`. :param customer: Unique id or name of :class:`Customer` object or instance of :class:`Customer`. """ self.site = site self.customer = customer self.__intiallize[] def __intiallize[self]: """ To intiallize or reset class member variable's value. """ self.__items = list[] self.__taxes = list[] self.currency_rate = 1 self.price_accuracy = 2 self.currency_symbol = '€' self.currency_code = 'EUR' self.__shipping_charge = 0.0 self.shipping_method = 'Flat Rate Per Order' self.tax_type = 'excluded' self.__discounts = list[]

[docs] def add_item[self, product, price=0.0, quantity=1, taxes=[], options={}]: """ To add or update product, price, quantity, taxes and options in :class:`CartItem` object. :param product: Unique id or name of :class:`Product` object or instance of :class:`Product`. :param price: Product price. :param quantity: Product quantity[default 1]. :param taxes: Taxes of the product[default []]. :param options: Options of the product[default {}]. """ if not isinstance[quantity, [int, float]]: raise TypeError['quantity field value must be integer or float type', 'quantity'] elif not [quantity or quantity >= 1]: raise ValueError['quantity field value must be greater then 1', 'quantity'] option_values = [] for option_value in options.values[]: if isinstance[option_value, dict]: option_value = option_value.keys[][0] option_values.append[option_value] cart_item = self.find_item[product, option_values] if cart_item: cart_item.update_quantity[cart_item.quantity + quantity] else: if not price: raise ValueError['price value is 0.0'] elif not isinstance[price, [int, float]]: raise TypeError['price value must be integer or float type', 'price'] cart_item = CartItem[self, product, price, quantity, taxes, options] self.__items.append[cart_item]

[docs] def update_item[self, product, quantity, option_values=[]]: """ To update :class:`CartItem` object quantity. :param product: Unique id or name of :class:`Product` object or instance of :class:`Product`. :param quantity: Updated quantity. :param option_values: Option values of the product[default []]. """ if not isinstance[quantity, [int, float]]: raise TypeError['quantity field value must be integer or float type', 'price'] elif not [quantity or quantity >= 1]: raise ValueError['quantity field value must be greater then 1'] cart_item = self.find_item[product, option_values] if cart_item: cart_item.update_quantity[quantity]

[docs] def remove_item[self, product, option_values=[]]: """ To remove existing :class:`CartItem` object related to product. :param product: Unique id or name of :class:`Product` object or instance of :class:`Product`. :param option_values: Option values of the product[default []]. """ cart_item = self.find_item[product, option_values] if cart_item: self.__items.remove[cart_item]

[docs] def remove_items[self]: """ To remove all existing :class:`CartItem` objects. """ self.__items = list[]

[docs] def find_item[self, product, option_values=[]]: """ To find :class:`CartItem` object related to product. :param product: Unique id or name of :class:`Product` object or instance of :class:`Product`. :param option_values: Option values of the product[default []]. :return: :class:`CartItem` object if cart item is exist else None. """ product = id_from_object[product] option_values = get_list_of_ids[option_values] for cart_item in self.__items: cart_product = id_from_object[cart_item.product] if not cmp[cart_product, product]: if option_values: if not cart_item.has_options: continue cart_item_option_values = [] cart_item_options = get_dict_of_ids[cart_item.get_options[]] for option, option_value in cart_item_options.items[]: if isinstance[option_value, dict]: option_value = option_value.keys[][0] cart_item_option_values.append[option_value] if not cmp[option_values, cart_item_option_values]: return cart_item else: if not cart_item.has_options: return cart_item return None

[docs] def get_items[self]: """ :return: List of :class:`CartItem` objects. """ return self.__items

[docs] def add_discount[self, amount, type='percentage']: """ To apply discount. :param amount: Discount amount. :param type: Discount type like 'percentage' or 'amount'[default amount]. """ self.__discounts.append[{'amount': amount, 'type': type}]

[docs] def remove_discounts[self]: """ To remove all applied discounts. """ self.__discounts = list[]

[docs] def get_discounts[self]: """ :return: List of applied discounts. """ return self.__discounts

[docs] def add_tax[self, amount, type='percentage']: """ To apply taxes. :param tax: Tax amount according to country region. :param type: Tax type like 'percentage' or 'fixed'[default percentage]. :return: True if tax is applied and tax is already exist then False. """ if not isinstance[amount, [int, float]]: raise TypeError['tax field value must be integer or float type', 'price'] if type not in ['percentage', 'fixed']: raise ValueError['type field value must be `percentage` or `fixed`', 'type'] tax_exist = self.find_tax[amount, type] if not tax_exist: self.__taxes.append[{'amount': amount, 'type': type}] return True return False

[docs] def remove_tax[self, amount, type='percentage']: """ To remove existing tax. :param amount: Tax amount according to country region. :param type: Tax type like 'percentage' or 'fixed'[defualt percentage]. """ if not isinstance[amount, [int, float]]: raise TypeError['tax field value must be integer or float type', 'price'] tax_exist = self.find_tax[amount, type] if tax_exist: self.__taxes.remove[{'amount': amount, 'type': type}] return True return False

[docs] def remove_taxes[self]: """ To remove all applied taxes. """ self.__taxes = list[]

[docs] def find_tax[self, amount, type='percentage']: """ To find applied tax. :param amount: Tax amount according to country region. :param type: Tax type like 'percentage' or 'fixed'[defualt percentage]. :return: True if tax is exist else False. """ if {'amount': amount, 'type': type} in self.__taxes: return True return False

[docs] def get_taxes[self]: """ :return: list of applied taxes. """ taxes = [] for cart_item in self.get_items[]: taxes.extend[cart_item.get_taxes[]] taxes.extend[self.__taxes] return taxes

[docs] def sub_total[self]: """ :return: Total cart amount[without discount deduction]. """ total = 0.0 for cart_item in self.__items: total += cart_item.sub_total[] return round[total, self.price_accuracy]

[docs] def total_discount[self]: """ :return: Total discount amount. """ total_discount = 0.0 for cart_item in self.get_items[]: total_discount += cart_item.discount_amount[] return round[total_discount, self.price_accuracy]

[docs] def total_untaxed_amount[self]: """ :return: Untaxed amount after deducating discount amount. """ total_untaxed_amount = self.sub_total[] - self.total_discount[] if self.tax_type == 'included': total_untaxed_amount -= self.total_tax[] return round[total_untaxed_amount, self.price_accuracy]

[docs] def total_tax[self]: """ :return: Total tax amount. """ total_tax = 0.0 if self.tax_type == 'included': total = self.sub_total[] - self.total_discount[] else: total = self.total_untaxed_amount[] total_tax = calculate[total, self.__taxes, self.tax_type, self.currency_rate, self.price_accuracy] for cart_item in self.get_items[]: total_tax += cart_item.tax_amount[] return round[total_tax, self.price_accuracy]

[docs] def total[self]: """ :return: Total amount[`tax excluded` or `tax included`] by adding total untaxed amount, total tax and shipping charge. """ return round[self.total_untaxed_amount[] + self.total_tax[] + self.shipping_charge, self.price_accuracy]

[docs] def count[self]: """ :return: Total quantity. """ self.total_items=0 for cart_item in self.get_items[]: self.total_items += cart_item.quantity return self.total_items

[docs] def clear[self]: """ To clean :class:`Cart` Object. """ self.__intiallize[]

@property def is_empty[self]: """ :return: True if cart has an item else False. """ if self.__items: return False return True @property def is_discount_applied[self]: """ :return: True if discount is applied else False. """ if self.__discounts: return True return False @property def has_taxes[self]: """ :return: True if tax is applied else False. """ if self.get_taxes[]: return True return False def _get__shipping_charge[self]: """ :return: Shipping charge. """ return round[self.__shipping_charge * self.currency_rate, self.price_accuracy] def _set__shipping_charge[self, value]: """ To set shipping charge amount. :param value: Shipping charge amount. """ self.__shipping_charge = value shipping_charge = property[_get__shipping_charge, _set__shipping_charge]

[docs]class CartItem[object]: """ Collection of :class:`Product` and it's quantity, taxes and options. """ def __init__[self, cart, product, price, quantity, taxes=[], options={}]: """ :param cart: Instance of :class:`Cart`. :param product: Unique id or name of :class:`Product` object or instance of :class:`Product`. :param price: Product price. :param quantity: Product quantity. :param taxes: Taxes[default []]. :param options: Options[default {}]. """ for tax in taxes: if not isinstance[tax, dict]: raise TypeError['taxes should be list of `dict` type value', 'taxes'] self.product = product self.__price = price self.quantity = quantity self.__taxes = taxes self.__options = options self.__cart = cart

[docs] def update_quantity[self, quantity]: """ To update existing quantity related to :class:`Product` object. :param quantity: Product quantity. """ self.quantity = quantity

[docs] def get_options[self]: """ :return: Dict of product's option. """ for option, option_value in self.__options.items[]: if isinstance[option_value, dict]: for key, value in option_value.items[]: if value.has_key['price']: value['price'] = round[value['price'] * self.__cart.currency_rate, self.__cart.price_accuracy] return self.__options

[docs] def get_taxes[self]: """ :return: List of applied taxes. """ return self.__taxes

[docs] def sub_total[self]: """ :return: Total amount by multiplying product price and quantity[without discount deduction]. """ price = self.price for option, option_value in self.get_options[].items[]: if isinstance[option_value, dict]: for key, value in option_value.items[]: if value.has_key['price']: price += value['price'] return round[price * self.quantity, self.__cart.price_accuracy]

[docs] def discount_amount[self]: """ :return: Discount amount. """ discount_amount = 0.0 sub_total = self.sub_total[] for discount in self.__cart.get_discounts[]: if discount['type'] == 'percentage': discount_amount += round[sub_total * [float[discount['amount']]/100], self.__cart.price_accuracy] elif discount['type'] == 'amount': discount_amount += round[float[discount['amount']] * self.__cart.currency_rate, self.__cart.price_accuracy] return round[discount_amount, self.__cart.price_accuracy]

[docs] def untaxed_amount[self]: """ :return: Untaxed amount[after deducating discount amount]. """ total = self.sub_total[] - self.discount_amount[] if self.__cart.tax_type == 'included': total -= self.tax_amount[] return round[total, self.__cart.price_accuracy]

[docs] def tax_amount[self]: """ :return: Tax amount. """ tax_amount = 0.0 if self.__cart.tax_type == 'included': total = self.sub_total[] - self.discount_amount[] else: total = self.untaxed_amount[] tax_amount = calculate[total, self.__taxes, self.__cart.tax_type, self.__cart.currency_rate, self.__cart.price_accuracy] return tax_amount

[docs] def total[self]: """ :return: Total amount[`tax excluded` or `tax included`] by adding untaxed and taxed amount. """ return round[self.untaxed_amount[] + self.tax_amount[], self.__cart.price_accuracy]

@property def has_options[self]: """ :return: True if product has an option else False. """ if self.__options: return True return False @property def has_taxes[self]: """ :return: True if product has tax else False. """ if self.__taxes: return True return False def _get_price[self]: """ :return: Price by multiplying currency rate. """ return round[self.__price * self.__cart.currency_rate, self.__cart.price_accuracy] def _set_price[self, value]: """ To set product price. :param value: Product price. """ self.__price = value price = property[_get_price, _set_price] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

Chủ Đề