Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update exercise-2.py #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 30 additions & 34 deletions exercise-2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@
Open Close Principle to jedna z pięciu zasad SOLID. Mówi ona, że klasy i funkcje
powinny być otwarte na rozszerzenie i zamknięte na modyfikacje. Innymi słowy,
powinno być możliwe ponowne wykorzystanie kodu bez modyfikowania go.

Poniżej znajduje się funkcja `calculate_discount_percentage`, która jest pewną
strategią wyliczania przysługującej klientowi zniżki wyrażonej w procentach.
Każdy klient jest instancją klasy Customer i ma trzy pola:

- first_purchase_date -- data pierwszego zakupu lub None, jeżeli jest to nowy
klient
- birth_date -- data urodzenia
- is_veteran -- flaga informująca, czy dany klient jest VIPem

Zaimplementowano następującą strategię:

- seniorzy (65+) dostają 5% zniżki
- lojalni klienci, którzy są z nami od 1, 5 lub 10 lat, dostają odpowiednio 10%,
12% i 20% zniżki,
Expand All @@ -24,12 +20,9 @@
- pozostali dostają 0% zniżki
- jeżeli przysługuje więcej niż jedna zniżka, zniżki nie sumują się i wybieramy
tę największą

Dodatkowo, niżej widzimy testy jednostkowe tej funkcji.

W tej funkcji złamano zasadę otwarte-zamknięte, ponieważ nie ma możliwości
ponownego wykorzystania jej.

Jako ćwiczenie, postaraj się zrefaktoryzować kod tak, aby możliwe było ponowne
użycie fragmentów obecnej strategii. Innymi słowy, powinno być możliwe
zaimplementowanie podobnej strategii (w której, przykładowo, nie ma zniżki dla
Expand All @@ -51,28 +44,31 @@ def __init__(self, first_purchase_date, birth_date, is_veteran):
self.is_veteran = is_veteran


def calculate_discount_percentage(customer):
def calculate_discount_percentage(customer, age_discount=None, loyalty_discount=None, veteran_discount=None):
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)
if age_discount:
if customer.birth_date <= now - 65*year:
# senior discount
discount = 5
if loyalty_discount:
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 veteran_discount:
if customer.is_veteran:
discount = max(discount, 10)
return discount


Expand All @@ -85,55 +81,55 @@ def test_should_return_zero_for_casual_customer(self):
customer = Customer(first_purchase_date=self.now,
birth_date=self.now-20*self.year,
is_veteran=False)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, loyalty_discount=True)
expected = 0
self.assertEqual(got, expected)

def test_should_return_15_for_new_client(self):
customer = Customer(first_purchase_date=None,
birth_date=self.now-20*self.year,
is_veteran=False)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, loyalty_discount=True)
expected = 15
self.assertEqual(got, expected)

def test_should_return_10_for_veteran(self):
customer = Customer(first_purchase_date=self.now,
birth_date=self.now-20*self.year,
is_veteran=True)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, veteran_discount=True)
expected = 10
self.assertEqual(got, expected)

def test_should_return_5_for_a_senior(self):
customer = Customer(first_purchase_date=self.now,
birth_date=self.now-65*self.year,
is_veteran=False)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, age_discount=True)
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,
is_veteran=False)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, loyalty_discount=True)
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,
is_veteran=False)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, loyalty_discount=True)
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,
is_veteran=False)
got = calculate_discount_percentage(customer)
got = calculate_discount_percentage(customer, loyalty_discount=True)
expected = 20
self.assertEqual(got, expected)

Expand All @@ -142,7 +138,7 @@ def test_should_return_maximum_discount(self):
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)
got = calculate_discount_percentage(customer, loyalty_discount=True)
expected = 15
self.assertEqual(got, expected)

Expand Down