Skip to content

Commit

Permalink
tutorial: Fixes for Exercise 3
Browse files Browse the repository at this point in the history
The PR fixes the issues with the exercise 3 from the tutorial:

- There was an inconsistency between the code in the solution vs the
  exercise, as the exercise used `@classmethod` and the solution did
  not. Now that's been made consistent
- The 2nd solution did not lower the memory usage. Not sure why it was
  added there - the PR removes it
- An edit to the solution for consistency to utilise the same global
  variables instead of magic numbers

Signed-off-by: Gintare Statkute <[email protected]>
  • Loading branch information
statkute authored and godlygeek committed Jul 2, 2024
1 parent 98cdceb commit 409b761
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 26 deletions.
21 changes: 3 additions & 18 deletions docs/tutorials/3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,7 @@ There are many different approaches to fix this memory issue - here are a few of
self.factorial_plus = functools.cache(self._uncached_factorial_plus)

def _uncached_factorial_plus(self, n: int) -> int:
return n * self.factorial_plus(n - 1) + self.inc if n else 1 + self.inc

return n * self.factorial_plus(n - 1) + self.inc if n > 1 else 1 + self.inc

def generate_factorial_plus_last_digit(plus_range: int, factorial_range: int):
for i in range(plus_range):
Expand All @@ -144,21 +143,7 @@ There are many different approaches to fix this memory issue - here are a few of
Full code solution `here
<https://github.com/bloomberg/memray/blob/main/docs/tutorials/solutions/exercise_3/lru_cache.py>`_.

2. Or you can use a ``classmethod`` for the cache instead of an instance method::

class Algorithms:
def __init__(self, inc: int):
self.inc = inc

def factorial_plus(self, n: int) -> int:
return self.factorial_plus_impl(n, self.inc)

@classmethod
@functools.cache
def factorial_plus_impl(cls, n: int, inc: int) -> int:
return n * cls.factorial_plus_impl(n - 1, inc) + inc if n > 1 else 1 + inc

3. Another approach would be setting a maximum size for the cache. We can do
2. Another approach would be setting a maximum size for the cache. We can do
that by passing an argument to ``@lru_cache`` decorator directly.

.. note::
Expand All @@ -175,7 +160,7 @@ There are many different approaches to fix this memory issue - here are a few of
``maxsize=`` here sets the maximum number of values stored in the cache.

4. Finally, we can periodically manually invoke the cleanup of the cache. This can be done by calling
3. Finally, we can periodically manually invoke the cleanup of the cache. This can be done by calling
``Algorithms.factorial_plus.cache_clear()``

.. raw:: html
Expand Down
8 changes: 2 additions & 6 deletions docs/tutorials/exercise_3/lru_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@ class Algorithms:
def __init__(self, inc: int):
self.inc = inc

@functools.cache # pylint: disable=W1518
def factorial_plus(self, n: int) -> int:
return self.factorial_plus_impl(n, self.inc)

@classmethod
@functools.cache
def factorial_plus_impl(cls, n: int, inc: int) -> int:
return n * cls.factorial_plus_impl(n - 1, inc) + inc if n > 1 else 1 + inc
return n * self.factorial_plus(n - 1) + self.inc if n > 1 else 1 + self.inc


def generate_factorial_plus_last_digit(plus_range: int, factorial_range: int):
Expand Down
13 changes: 11 additions & 2 deletions docs/tutorials/solutions/exercise_3/lru_cache.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import functools
from collections import Counter

# DO NOT CHANGE
FIRST_COUNTER_RANGE = 500
SECOND_COUNTER_RANGE = 1000
# DO NOT CHANGE


class Algorithms:
def __init__(self, inc: int):
Expand All @@ -19,8 +24,12 @@ def generate_factorial_plus_last_digit(plus_range: int, factorial_range: int):


def compare_counts_different_factorials():
counts_500 = Counter(generate_factorial_plus_last_digit(500, 500))
counts_1000 = Counter(generate_factorial_plus_last_digit(1000, 1000))
counts_500 = Counter(
generate_factorial_plus_last_digit(FIRST_COUNTER_RANGE, FIRST_COUNTER_RANGE)
)
counts_1000 = Counter(
generate_factorial_plus_last_digit(SECOND_COUNTER_RANGE, SECOND_COUNTER_RANGE)
)
print(counts_500.most_common())
print(counts_1000.most_common())

Expand Down

0 comments on commit 409b761

Please sign in to comment.