Skip to content

Commit

Permalink
feat(look), #24: Improve performances of look functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
vinci1it2000 committed Apr 13, 2019
1 parent f783b0a commit 0f4387b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 18 deletions.
14 changes: 8 additions & 6 deletions formulas/functions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,14 @@ def is_number(number):


def flatten(l, check=is_number):
if not isinstance(l, str) and isinstance(l, collections.Iterable):
try:
for el in l:
yield from flatten(el, check)
except TypeError:
yield from flatten(l.tolist(), check)
if isinstance(l, np.ndarray):
if not check:
yield from l.ravel()
else:
yield from filter(check, l.ravel())
elif not isinstance(l, str) and isinstance(l, collections.Iterable):
for el in l:
yield from flatten(el, check)
elif not check or check(l):
yield l

Expand Down
20 changes: 8 additions & 12 deletions formulas/functions/look.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import collections
import numpy as np
from . import (
wrap_func, wrap_ufunc, Error, flatten, get_error, XlError, FoundError, Array
wrap_func, wrap_ufunc, Error, get_error, XlError, FoundError, Array
)
from ..cell import CELL

Expand Down Expand Up @@ -109,42 +109,38 @@ def check(j, x, val, r):


FUNCTIONS['MATCH'] = wrap_ufunc(
xmatch,
input_parser=lambda val, vec, match_type=1: (
val, list(flatten(vec, None)), match_type
),
check_error=lambda *a: get_error(a[:1]), excluded={1, 2}
xmatch, check_error=lambda *a: get_error(a[:1]), excluded={1, 2},
input_parser=lambda val, vec, match_type=1: (val, np.ravel(vec), match_type)
)


def xlookup(lookup_val, lookup_vec, result_vec=None, match_type=1):
result_vec = lookup_vec if result_vec is None else result_vec
r = xmatch(lookup_val, lookup_vec, match_type)
if not isinstance(r, XlError):
r = result_vec[r - 1]
r = np.ravel(result_vec[r - 1])[0]
return r


FUNCTIONS['LOOKUP'] = wrap_ufunc(
xlookup,
input_parser=lambda val, vec, res=None: (
val, list(flatten(vec, None)),
res if res is None else list(flatten(res, None))
val, np.ravel(vec), res if res is None else np.ravel(res)
),
check_error=lambda *a: get_error(a[:1]), excluded={1, 2}
)


def _hlookup_parser(val, vec, index, match_type=1, transpose=False):
index = list(flatten(index, None))[0] - 1
index = np.ravel(index)[0] - 1
vec = np.matrix(vec)
if transpose:
vec = vec.T
try:
ref = list(flatten(vec[index].A1, None))
ref = vec[index].A1.ravel()
except IndexError:
raise FoundError(err=Error.errors['#REF!'])
vec = list(flatten(vec[0].A1, None))
vec = vec[0].A1.ravel()
return val, vec, ref, bool(match_type)


Expand Down
2 changes: 2 additions & 0 deletions test/test_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def inp_ranges(*rng):
@ddt.ddt
class TestCell(unittest.TestCase):
@ddt.idata((
('A1', '=LOOKUP(2,{-1.1,2.1,3.1,4.1})', {}, '<Ranges>(A1)=[[-1.1]]'),
('A1', '=LOOKUP(3,{-1.1,2.1,3.1,4.1})', {}, '<Ranges>(A1)=[[2.1]]'),
('A1', '=SWITCH(TRUE,1,0,,,TRUE,1,7)', {}, '<Ranges>(A1)=[[1]]'),
('A1:D1', '=SWITCH({0,1,TRUE},1,0,,,TRUE,1,7)', {},
'<Ranges>(A1:D1)=[[0 0 1 #N/A]]'),
Expand Down

0 comments on commit 0f4387b

Please sign in to comment.