0

the memoization can't be initiated. if I make it memoglobal, then the subsequent print function will take stored memo during the first print. Please advise,

def howsumhelper(targetsum,numbers):
      memo = dict() #this memoization will not initiate. Why?
      return howsum(targetsum,numbers,[])


def howsum(targetsum,numbers,combo):
      print("Debug==",memo)
      if targetsum in memo: return memo[targetsum]
      if targetsum == 0:return combo
      if targetsum < 0: return None

      for number in numbers:
            remainder = targetsum - number
            if howsum(remainder,numbers,combo) != None:
                  combo.append(number)
                  memo[targetsum] = combo
                  return combo
      memo[targetsum] = None
      return None

print(howsumhelper(7,[3,4])) #output should be [3,4]
print(howsumhelper(8,[2,3])) #output should be [2,2,2,2]
print(howsumhelper(7,[2,4])) #output should be None
SoraHeart
  • 400
  • 3
  • 14
  • The "memo" is local to the howsumhelper. Make it global by declaring it outside the function and use `global memo` to reference it inside howsumhelper Reference: https://www.programiz.com/python-programming/global-local-nonlocal-variables – Shashank Holla Dec 20 '20 at 13:16
  • Hi can you please explain more. I read up that global memo will change the memo value. What i wanted is everytime the `howsumhelper()` is called. the memo should start from empty dictionary. – SoraHeart Dec 20 '20 at 13:30
  • A dict will not work with a list as key. A key should be a single object. You could use a tuple containing an integer and a FrozenSet as a key and whatever you want as value. Example: memo[(7, FrozenSet([3, 4]))] = [3, 4] – Tarik Dec 20 '20 at 13:36

1 Answers1

0

Suggest following changes

  • Make memo a mutable default argument of howsum (to make it callable in function)
  • You don't need howsumhelper

Reference--Efficient memorization in Python--using posted solution #2

Revised Code

def howsum(targetsum,numbers,combo=None,memo=None):
      # Initiaze default arguments
      if combo is None:
        combo = []
      if memo is None:
        memo = {}
        
      #print("Debug==",memo)
      if targetsum in memo: return memo[targetsum]
      if targetsum == 0:return combo
      if targetsum < 0: return None

      for number in numbers:
            remainder = targetsum - number
            if howsum(remainder,numbers,combo,memo) != None:
                  combo.append(number)
                  memo[targetsum] = combo
                  return combo
      memo[targetsum] = None
      return None

print(howsum(7,[3,4])) #output should be [3,4] #actually or [4, 3]
print(howsum(8,[2,3])) #output should be [2,2,2,2]
print(howsum(7,[2,4])) #output should be None

Output

[4, 3]
[2, 2, 2, 2]
None

Explanation

Function signature is : howsum(targetsum,numbers,combo=None,memo=None):

Arguments a value in function definition are called default arguments. So combo, and memo are have default arguments.

Python's default arguments are evaluated once when the function is defined, not each time the function is called.

Default values are used only when actual values are passed.

Thus:

howsum(7,[3,4]) # uses default values, so called with combo = None and memo = None
howsum(8,[2,3]) # uses default values, so called with combo = None and memo = None
howsum(7,[2,4]) # uses default values, so called with combo = None and memo = None

But:

howsum(remainder,numbers,combo,memo) # does not use defaults for combo and memo
                                     # since we are passing values for these arguments
DarrylG
  • 16,732
  • 2
  • 17
  • 23
  • Hi Thanks. How to i call the howsum function? there is a combo argument there. I tried `print(howsum(7,[3,4],[ ])` but it is not working – SoraHeart Dec 20 '20 at 13:36
  • Hi Thanks!, making the combo=None works. Will read up on this more. – SoraHeart Dec 20 '20 at 13:43
  • @josephgan--"making the combo=None works"? Are you referring to this or a different solution? – DarrylG Dec 20 '20 at 13:44
  • Hi sorry again. can you please explain is `combo=None ` in the function argument assigning the combo as None? just wondering why subsequently when `howsum(remainder,numbers,combo,memo)` was called during the loop. the combo\memo will not be cleared up as None – SoraHeart Dec 20 '20 at 13:50
  • @josephgan--does the explanation help? – DarrylG Dec 20 '20 at 14:03
  • Hi DarryIG. Yes. it help greatly. I tested with some simplier code, i see that as long the argument has a value, the None will not kicked in. Thanks! – SoraHeart Dec 20 '20 at 14:13
  • Hi Daryl, do you mind helping me again. I tried manually walk through the code but i couldnt get it[link] https://stackoverflow.com/questions/65386932/python-recursive-function-how-to-return-all-subsets-of-targetsum – SoraHeart Dec 21 '20 at 05:42
  • Hi Daryl. Please ignore above request. I have managed to find the answer. Thanks. – SoraHeart Dec 21 '20 at 06:11
  • @josephgan--I answered the request since your answer does not provide the correct result for your test case. – DarrylG Dec 21 '20 at 11:51