Skip to content

Commit

Permalink
Add "or" filters to python. (#1650)
Browse files Browse the repository at this point in the history
* Add an or filter

* Update filter.py

* Fixed unit test and code after running.

* Addressed code review.

Co-authored-by: Jianfeng Mao <4297243+jmao-denver@users.noreply.github.com>
  • Loading branch information
chipkent and jmao-denver authored Dec 6, 2021
1 parent fcf6cc6 commit 237ea84
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
4 changes: 3 additions & 1 deletion Integrations/python/deephaven/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@
ParquetTools as pt, \
TableTools as ttools, \
TableLoggers as tloggers, \
Types as dh
Types as dh, \
filter as _filter

from .Plot import figure_wrapper as figw

Expand Down Expand Up @@ -119,6 +120,7 @@ def initialize():
ttools._defineSymbols()
tloggers._defineSymbols()
csv._defineSymbols()
_filter._defineSymbols()

import deephaven.TableManipulation
deephaven.TableManipulation._defineSymbols()
Expand Down
59 changes: 59 additions & 0 deletions Integrations/python/deephaven/filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# Copyright (c) 2016-2021 Deephaven Data Labs and Patent Pending
#
""" The deephaven.filter module provides methods for filtering Deephaven tables."""

import jpy
import wrapt

_JFilter = None
_JFilterOr = None


def _defineSymbols():
"""
Defines appropriate java symbol, which requires that the jvm has been initialized through the :class:`jpy` module,
for use throughout the module AT RUNTIME. This is versus static definition upon first import, which would lead to an
exception if the jvm wasn't initialized BEFORE importing the module.
"""

if not jpy.has_jvm():
raise SystemError("No java functionality can be used until the JVM has been initialized through the jpy module")

global _JFilter, _JFilterOr

if _JFilter is None:
# This will raise an exception if the desired object is not the classpath
_JFilter = jpy.get_type("io.deephaven.api.filter.Filter")
_JFilterOr = jpy.get_type("io.deephaven.api.filter.FilterOr")


# every module method should be decorated with @_passThrough
@wrapt.decorator
def _passThrough(wrapped, instance, args, kwargs):
"""
For decoration of module methods, to define necessary symbols at runtime
:param wrapped: the method to be decorated
:param instance: the object to which the wrapped function was bound when it was called
:param args: the argument list for `wrapped`
:param kwargs: the keyword argument dictionary for `wrapped`
:return: the decorated version of the method
"""

_defineSymbols()
return wrapped(*args, **kwargs)


@_passThrough
def or_(*filters) -> object:
""" Filters on cases where any of the input filters evaluate to true.
Args:
*filters (str): the filter expressions
Returns:
a filter that evaluates to true when any of the input filters evaluates to true
"""

return _JFilterOr.of(_JFilter.from_(filters))
30 changes: 30 additions & 0 deletions Integrations/python/test/test_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# Copyright (c) 2016-2021 Deephaven Data Labs and Patent Pending
#
import unittest

from deephaven.TableTools import newTable, intCol, diff
from deephaven.filter import or_
from unittest import TestCase


class FilterTestCase(TestCase):
def test_or(self):
t = newTable(
intCol("A", 1, 2, 3, 4, 5),
intCol("B", 11, 12, 13, 14, 15)
)

t_target = newTable(
intCol("A", 1, 4, 5),
intCol("B", 11, 14, 15)
)

t_actual = t.where(or_("A<2", "B>=14"))

diff_string = diff(t_actual, t_target, 1)
self.assertEqual("", diff_string)


if __name__ == '__main__':
unittest.main()

0 comments on commit 237ea84

Please sign in to comment.