1

I would like to set a tolerance for a certain function argument, but not for others. Let's say I have a function like this:

def myFnc(input1,param0 = 0, param1 =1):
    return "input1:%s [params %s, %s]" %(input1, param0, param1)

These are the expected results:

>>>> myFnc(0.1, param0= 0.1, param1 = 1)
'input1:0.1 [params 0.1, 1]'
>>>> myFnc(0.1, param0= 0.12, param1 = 1)
'input1:0.1 [params 0.12, 1]'
>>>> myFnc(0.12, param0= 0.1, param1 = 1)
'input1:0.1 [params 0.1, 1]' #the same as the first instruction

I tried using tol and ignore, but I don't get what I expect:

>>>> from klepto import inf_cache
>>>> f=inf_cache(tol=0,ignore=("**"))(myFnc);
>>>> f(0.1, param0= 0.1, param1 = 1)
'input1:0.1 [params 0.1, 1]'
>>>> f(0.1, param0= 0.12, param1 = 1)
'input1:0.1 [params 0.1, 1]' #I wanted [params 0.12, 1] 
>>>> f(0.12, param0= 0.1, param1 = 1)
'input1:0.1 [params 0.1, 1]'

I am using klepto installed from pip (klepto.__version__ 0.1.1). Should I maybe change the keymap?

lib
  • 2,918
  • 3
  • 27
  • 53

1 Answers1

0

I'm the klepto author. These look like the expected results to me. Your line f=inf_cache(tol=0,ignore="**")(myFnc) tells me that you want rounding at integer tolerance, and that you want to ignore all additional **kwds in your function.

However, your function myFcn doesn't use **kwds, so I assume that you mean that you want to ignore=('param0','param1'). When you use ignore, it's used to "ignore" the variables in the function declaration… not the function invocation.

When you ignore a variable, it's the cache that's ignoring the variable.

>>> f = inf_cache(tol=0, ignore=('param0','param1'))(myFnc)
>>> f(.1, param0=.1, param1=1)
(0.1, 0.1, 1)
>>> f(.1, param0=.12, param1=1)
(0.1, 0.1, 1)
>>> f(.12, param0=.1, param1=1)
(0.1, 0.1, 1)

Above, only input1 (the first argument) is being cached… and it doesn't change with greater than tol=0. So, when you change param0 or param1… it doesn't invalidate the cache, and you still get the already-cached value returned.

So, regardless of how much you change anything other than input1, you will still get the originally cached value.

>>> f(.1, param0=5.1, param1=1)
(0.1, 0.1, 1)
>>> f(.1, param0=5.1, param1=10)
(0.1, 0.1, 1)

However, when I change input1 outside of the int tolerance… then we have a second cached result.

>>> f(5.1, param0=5.1, param1=10)
(5.1, 5.1, 10)

And even if I use a **, the last two arguments are still ignored because the ignore applies to the function specification and not the invocation.

>>> f(5.1, **dict(param0=100, param1=100))
(5.1, 5.1, 10)

Changing the keymap won't change the results at all. What changing the keymap does is change what is used as keys in the cache.

>>> f.__cache__()
null_archive({5999492624188339149: (0.1, 0.1, 1), 58251017057462798: (5.1, 5.1, 10)}, cached=True)

You can also see that it's using the cached values by using lookup instead of actually using caching.

>>> f.lookup(5.1, 6, 10)
(5.1, 5.1, 10)
>>> f.lookup(4.1, 5.1, 10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mmckerns/lib/python2.7/site-packages/klepto-0.1.2.dev0-py2.7.egg/klepto/_cache.py", line 341, in lookup
    return cache[keymap(*_args, **_kwds)]
KeyError: -2002243791131618159
Patol75
  • 4,342
  • 1
  • 17
  • 28
Mike McKerns
  • 33,715
  • 8
  • 119
  • 139
  • Thanks for the clearer explanation of ignore mechanism! But, leaving apart the ignore keyword misunderstanding, is there a built-in way to get my "expected results" in the example, or should I resort to have a function for processing the first input (applying rounding if needed to) and then use myFnc? – lib Dec 15 '15 at 09:19
  • 1
    I see, so you want to apply rounding, where "ignore" is used to mark which argument/keywords that you don't want to apply rounding to. Is that correct? The syntax in `klepto` is that `ignore` is ignoring an argument/keyword in the caching (not the rounding). I think I have written such a function in one of my other packages (`mystic`, I believe), but you might want to try writing your own. – Mike McKerns Dec 15 '15 at 19:14
  • Ok thanks! I think I will use a helper function for checking the input then. – lib Dec 15 '15 at 19:24