From 57b3176ce58f3c23bf1a0ed4b430d67eeaad4955 Mon Sep 17 00:00:00 2001 From: WhereIsMySnake Date: Fri, 15 Jun 2018 16:55:24 +0200 Subject: [PATCH] Create exercise-2.py --- exercise-2.py | 109 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/exercise-2.py b/exercise-2.py index 1a0cbde..0fa7408 100644 --- a/exercise-2.py +++ b/exercise-2.py @@ -38,9 +38,29 @@ import datetime import unittest +from collections import OrderedDict -class Customer: +class Date(object): + @classmethod + def now(cls): + return datetime.datetime.now() + + @classmethod + def year(cls): + return datetime.timedelta(days=365) + + +def get_years_delta(years=1): + return Date.now() - years * Date.year() + + +class Customer(object): + loyalty_discount_map = OrderedDict(((10, 20), (5, 12), (1, 10))) + senior_discount_percentage = 5 + new_customer_discount_percentage = 15 + veteran_discount_percentage = 10 + def __init__(self, first_purchase_date, birth_date, is_veteran): assert isinstance(first_purchase_date, (type(None), datetime.datetime)) assert isinstance(birth_date, datetime.datetime) @@ -50,40 +70,56 @@ def __init__(self, first_purchase_date, birth_date, is_veteran): self.birth_date = birth_date self.is_veteran = is_veteran + @property + def loyalty_discount(self): + if not self.first_purchase: + for years, discount in self.loyalty_discount_map.items(): + if self.first_purchase_date <= get_years_delta(years): + return discount + return 0 + + @property + def new_customer_discount(self): + if self.first_purchase: + return self.new_customer_discount_percentage + else: + return 0 + + @property + def first_purchase(self): + return self.first_purchase_date is None + + @property + def veteran_discount(self): + if self.is_veteran: + return self.veteran_discount_percentage + else: + return 0 + + @property + def senior_discount(self): + if self.have_senior_discount(): + return self.senior_discount_percentage + else: + return 0 + + def have_senior_discount(self): + return self.birth_date <= get_years_delta(65) + def calculate_discount_percentage(customer): - discount = 0 - now = datetime.datetime.now() - year = datetime.timedelta(days=365) - if customer.birth_date <= now - 65*year: - # senior discount - discount = 5 - if customer.first_purchase_date is not None: - if customer.first_purchase_date <= now - year: - # after one year, loyal customers get 10% - discount = 10 - if customer.first_purchase_date <= now - 5*year: - # after five years, 12% - discount = 12 - if customer.first_purchase_date <= now - 10*year: - # after ten years, 20% - discount = 20 - else: - # first time purchase ==> 15% discount - discount = 15 - if customer.is_veteran: - discount = max(discount, 10) - return discount + return max(customer.loyalty_discount, customer.veteran_discount, customer.senior_discount, + customer.new_customer_discount) class CalculateDiscountPercentageTests(unittest.TestCase): def setUp(self): - self.now = datetime.datetime.now() - self.year = datetime.timedelta(days=365) + self.now = Date.now() + self.year = Date.year() def test_should_return_zero_for_casual_customer(self): customer = Customer(first_purchase_date=self.now, - birth_date=self.now-20*self.year, + birth_date=self.now - 20 * self.year, is_veteran=False) got = calculate_discount_percentage(customer) expected = 0 @@ -91,7 +127,7 @@ def test_should_return_zero_for_casual_customer(self): def test_should_return_15_for_new_client(self): customer = Customer(first_purchase_date=None, - birth_date=self.now-20*self.year, + birth_date=self.now - 20 * self.year, is_veteran=False) got = calculate_discount_percentage(customer) expected = 15 @@ -99,7 +135,7 @@ def test_should_return_15_for_new_client(self): def test_should_return_10_for_veteran(self): customer = Customer(first_purchase_date=self.now, - birth_date=self.now-20*self.year, + birth_date=self.now - 20 * self.year, is_veteran=True) got = calculate_discount_percentage(customer) expected = 10 @@ -107,31 +143,31 @@ def test_should_return_10_for_veteran(self): def test_should_return_5_for_a_senior(self): customer = Customer(first_purchase_date=self.now, - birth_date=self.now-65*self.year, + birth_date=self.now - 65 * self.year, is_veteran=False) got = calculate_discount_percentage(customer) expected = 5 self.assertEqual(got, expected) def test_should_return_10_for_a_loyal_customer(self): - customer = Customer(first_purchase_date=self.now-1*self.year, - birth_date=self.now-20*self.year, + customer = Customer(first_purchase_date=self.now - 1 * self.year, + birth_date=self.now - 20 * self.year, is_veteran=False) got = calculate_discount_percentage(customer) expected = 10 self.assertEqual(got, expected) def test_should_return_12_for_a_more_loyal_customer(self): - customer = Customer(first_purchase_date=self.now-5*self.year, - birth_date=self.now-20*self.year, + customer = Customer(first_purchase_date=self.now - 5 * self.year, + birth_date=self.now - 20 * self.year, is_veteran=False) got = calculate_discount_percentage(customer) expected = 12 self.assertEqual(got, expected) def test_should_return_20_for_a_most_loyal_customer(self): - customer = Customer(first_purchase_date=self.now-10*self.year, - birth_date=self.now-20*self.year, + customer = Customer(first_purchase_date=self.now - 10 * self.year, + birth_date=self.now - 20 * self.year, is_veteran=False) got = calculate_discount_percentage(customer) expected = 20 @@ -139,12 +175,13 @@ def test_should_return_20_for_a_most_loyal_customer(self): def test_should_return_maximum_discount(self): customer = Customer(first_purchase_date=None, - birth_date=self.now-20*self.year, + birth_date=self.now - 20 * self.year, is_veteran=True) # eligible for 15% discount as a new client and 10% as a veteran got = calculate_discount_percentage(customer) expected = 15 self.assertEqual(got, expected) + if __name__ == "__main__": unittest.main()