Skip to content

Commit 5795f69

Browse files
committed
Finished working on the book-store challenge, started working on the leap challenge
1 parent de022b2 commit 5795f69

File tree

7 files changed

+134
-47
lines changed

7 files changed

+134
-47
lines changed
958 Bytes
Binary file not shown.
Binary file not shown.

book-store/book_store.py

+22-47
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,30 @@
1-
"""
2-
One copy of any of the five books costs $8.
1+
from collections import Counter
32

4-
If, however, you buy two different books, you get a 5% discount on those two books.
3+
PRICE = 800
54

6-
If you buy 3 different books, you get a 10% discount.
5+
PRICE_PER_GROUP = {
6+
1: 1 * PRICE * 1.00,
7+
2: 2 * PRICE * 0.95,
8+
3: 3 * PRICE * 0.90,
9+
4: 4 * PRICE * 0.80,
10+
5: 5 * PRICE * 0.75,
11+
}
712

8-
If you buy 4 different books, you get a 20% discount.
9-
10-
If you buy all 5, you get a 25% discount.
11-
12-
Note: that if you buy four books, of which 3 are different titles, you get a 10% discount on the 3 that form part of a set, but the fourth book still costs $8.
13-
14-
Your mission is to write a piece of code to calculate the price of any conceivable shopping basket (containing only books of the same series), giving as big a discount as possible.
15-
16-
For example, how much does this basket of books cost?
17-
18-
2 copies of the first book
19-
2 copies of the second book
20-
2 copies of the third book
21-
1 copy of the fourth book
22-
1 copy of the fifth book
23-
One way of grouping these 8 books is:
24-
25-
1 group of 5 --> 25% discount (1st,2nd,3rd,4th,5th)
26-
+1 group of 3 --> 10% discount (1st,2nd,3rd)
27-
This would give a total of:
28-
29-
5 books at a 25% discount
30-
+3 books at a 10% discount
31-
Resulting in:
32-
33-
5 x (8 - 2.00) == 5 x 6.00 == $30.00
34-
+3 x (8 - 0.80) == 3 x 7.20 == $21.60
35-
For a total of $51.60
36-
37-
However, a different way to group these 8 books is:
38-
39-
1 group of 4 books --> 20% discount (1st,2nd,3rd,4th)
40-
+1 group of 4 books --> 20% discount (1st,2nd,3rd,5th)
41-
This would give a total of:
13+
def total(basket):
14+
if not basket:
15+
return 0
4216

43-
4 books at a 20% discount
44-
+4 books at a 20% discount
45-
Resulting in:
17+
books_collection = Counter(basket)
18+
prices = [PRICE * len(basket)]
4619

47-
4 x (8 - 1.60) == 4 x 6.40 == $25.60
48-
+4 x (8 - 1.60) == 4 x 6.40 == $25.60
49-
For a total of $51.20
20+
for max_group_size in range(2, len(books_collection) + 1):
21+
remaining_books_in_collection = books_collection.copy()
22+
prices.append(0)
23+
while remaining_books_in_collection:
24+
books_group_collection = Counter(b[0] for b in remaining_books_in_collection.most_common(max_group_size))
25+
prices[max_group_size - 1] += PRICE_PER_GROUP[len(books_group_collection)]
26+
remaining_books_in_collection -= books_group_collection
5027

51-
And $51.20 is the price with the biggest discount.
52-
"""
28+
return min(prices)
5329

54-
def total(basket):
5530
pass

leap/.exercism/metadata.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"track":"python","exercise":"leap","id":"f1fd3d7f2d1648759a688764ca7acecb","url":"https://exercism.io/my/solutions/f1fd3d7f2d1648759a688764ca7acecb","handle":"sinanata","is_requester":true,"auto_approve":false}

leap/README.md

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Leap
2+
3+
Given a year, report if it is a leap year.
4+
5+
The tricky thing here is that a leap year in the Gregorian calendar occurs:
6+
7+
```text
8+
on every year that is evenly divisible by 4
9+
except every year that is evenly divisible by 100
10+
unless the year is also evenly divisible by 400
11+
```
12+
13+
For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap
14+
year, but 2000 is.
15+
16+
## Notes
17+
18+
Though our exercise adopts some very simple rules, there is more to
19+
learn!
20+
21+
For a delightful, four minute explanation of the whole leap year
22+
phenomenon, go watch [this youtube video][video].
23+
24+
[video]: http://www.youtube.com/watch?v=xX96xng7sAE
25+
26+
27+
## Exception messages
28+
29+
Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
30+
indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
31+
every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
32+
a message.
33+
34+
To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
35+
`raise Exception`, you should write:
36+
37+
```python
38+
raise Exception("Meaningful message indicating the source of the error")
39+
```
40+
41+
## Running the tests
42+
43+
To run the tests, run `pytest leap_test.py`
44+
45+
Alternatively, you can tell Python to run the pytest module:
46+
`python -m pytest leap_test.py`
47+
48+
### Common `pytest` options
49+
50+
- `-v` : enable verbose output
51+
- `-x` : stop running tests on first failure
52+
- `--ff` : run failures from previous test before running other test cases
53+
54+
For other options, see `python -m pytest -h`
55+
56+
## Submitting Exercises
57+
58+
Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/python/leap` directory.
59+
60+
You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Workspace`.
61+
62+
For more detailed information about running tests, code style and linting,
63+
please see [Running the Tests](http://exercism.io/tracks/python/tests).
64+
65+
## Source
66+
67+
JavaRanch Cattle Drive, exercise 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.jsp)
68+
69+
## Submitting Incomplete Solutions
70+
71+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

leap/leap.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def leap_year(year):
2+
pass

leap/leap_test.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import unittest
2+
3+
from leap import leap_year
4+
5+
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.6.0
6+
7+
8+
class LeapTest(unittest.TestCase):
9+
def test_year_not_divisible_by_4_in_common_year(self):
10+
self.assertIs(leap_year(2015), False)
11+
12+
def test_year_divisible_by_2_not_divisible_by_4_in_common_year(self):
13+
self.assertIs(leap_year(1970), False)
14+
15+
def test_year_divisible_by_4_not_divisible_by_100_in_leap_year(self):
16+
self.assertIs(leap_year(1996), True)
17+
18+
def test_year_divisible_by_4_and_5_is_still_a_leap_year(self):
19+
self.assertIs(leap_year(1960), True)
20+
21+
def test_year_divisible_by_100_not_divisible_by_400_in_common_year(self):
22+
self.assertIs(leap_year(2100), False)
23+
24+
def test_year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year(self):
25+
self.assertIs(leap_year(1900), False)
26+
27+
def test_year_divisible_by_400_in_leap_year(self):
28+
self.assertIs(leap_year(2000), True)
29+
30+
def test_year_divisible_by_400_but_not_by_125_is_still_a_leap_year(self):
31+
self.assertIs(leap_year(2400), True)
32+
33+
def test_year_divisible_by_200_not_divisible_by_400_in_common_year(self):
34+
self.assertIs(leap_year(1800), False)
35+
36+
37+
if __name__ == "__main__":
38+
unittest.main()

0 commit comments

Comments
 (0)