mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) move data engine code to core
Summary: this moves sandbox/grist to core, and adds a requirements.txt file for reconstructing the content of sandbox/thirdparty. Test Plan: existing tests pass. Tested core functionality manually. Tested docker build manually. Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2563
This commit is contained in:
165
sandbox/grist/functions/logical.py
Normal file
165
sandbox/grist/functions/logical.py
Normal file
@@ -0,0 +1,165 @@
|
||||
from info import lazy_value_or_error, is_error
|
||||
from usertypes import AltText # pylint: disable=unused-import,import-error
|
||||
|
||||
|
||||
def AND(logical_expression, *logical_expressions):
|
||||
"""
|
||||
Returns True if all of the arguments are logically true, and False if any are false.
|
||||
Same as `all([value1, value2, ...])`.
|
||||
|
||||
>>> AND(1)
|
||||
True
|
||||
>>> AND(0)
|
||||
False
|
||||
>>> AND(1, 1)
|
||||
True
|
||||
>>> AND(1,2,3,4)
|
||||
True
|
||||
>>> AND(1,2,3,4,0)
|
||||
False
|
||||
"""
|
||||
return all((logical_expression,) + logical_expressions)
|
||||
|
||||
|
||||
def FALSE():
|
||||
"""
|
||||
Returns the logical value `False`. You may also use the value `False` directly. This
|
||||
function is provided primarily for compatibility with other spreadsheet programs.
|
||||
|
||||
>>> FALSE()
|
||||
False
|
||||
"""
|
||||
return False
|
||||
|
||||
|
||||
def IF(logical_expression, value_if_true, value_if_false):
|
||||
"""
|
||||
Returns one value if a logical expression is `True` and another if it is `False`.
|
||||
|
||||
The equivalent Python expression is:
|
||||
```
|
||||
value_if_true if logical_expression else value_if_false
|
||||
```
|
||||
|
||||
Since Grist supports multi-line formulas, you may also use Python blocks such as:
|
||||
```
|
||||
if logical_expression:
|
||||
return value_if_true
|
||||
else:
|
||||
return value_if_false
|
||||
```
|
||||
|
||||
NOTE: Grist follows Excel model by only evaluating one of the value expressions, by
|
||||
automatically wrapping the expressions to use lazy evaluation. This allows `IF(False, 1/0, 1)`
|
||||
to evaluate to `1` rather than raise an exception.
|
||||
|
||||
>>> IF(12, "Yes", "No")
|
||||
'Yes'
|
||||
>>> IF(None, "Yes", "No")
|
||||
'No'
|
||||
>>> IF(True, 0.85, 0.0)
|
||||
0.85
|
||||
>>> IF(False, 0.85, 0.0)
|
||||
0.0
|
||||
|
||||
More tests:
|
||||
>>> IF(True, lambda: (1/0), lambda: (17))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ZeroDivisionError: integer division or modulo by zero
|
||||
>>> IF(False, lambda: (1/0), lambda: (17))
|
||||
17
|
||||
"""
|
||||
return lazy_value(value_if_true) if logical_expression else lazy_value(value_if_false)
|
||||
|
||||
|
||||
def IFERROR(value, value_if_error=""):
|
||||
"""
|
||||
Returns the first argument if it is not an error value, otherwise returns the second argument if
|
||||
present, or a blank if the second argument is absent.
|
||||
|
||||
NOTE: Grist handles values that raise an exception by wrapping them to use lazy evaluation.
|
||||
|
||||
>>> IFERROR(float('nan'), "**NAN**")
|
||||
'**NAN**'
|
||||
>>> IFERROR(17.17, "**NAN**")
|
||||
17.17
|
||||
>>> IFERROR("Text")
|
||||
'Text'
|
||||
>>> IFERROR(AltText("hello"))
|
||||
''
|
||||
|
||||
More tests:
|
||||
>>> IFERROR(lambda: (1/0.1), "X")
|
||||
10.0
|
||||
>>> IFERROR(lambda: (1/0.0), "X")
|
||||
'X'
|
||||
>>> IFERROR(lambda: AltText("A"), "err")
|
||||
'err'
|
||||
>>> IFERROR(lambda: None, "err")
|
||||
|
||||
>>> IFERROR(lambda: foo.bar, 123)
|
||||
123
|
||||
>>> IFERROR(lambda: "test".bar(), 123)
|
||||
123
|
||||
>>> IFERROR(lambda: "test".bar())
|
||||
''
|
||||
>>> IFERROR(lambda: "test".upper(), 123)
|
||||
'TEST'
|
||||
"""
|
||||
value = lazy_value_or_error(value)
|
||||
return value if not is_error(value) else value_if_error
|
||||
|
||||
|
||||
def NOT(logical_expression):
|
||||
"""
|
||||
Returns the opposite of a logical value: `NOT(True)` returns `False`; `NOT(False)` returns
|
||||
`True`. Same as `not logical_expression`.
|
||||
|
||||
>>> NOT(123)
|
||||
False
|
||||
>>> NOT(0)
|
||||
True
|
||||
"""
|
||||
return not logical_expression
|
||||
|
||||
|
||||
def OR(logical_expression, *logical_expressions):
|
||||
"""
|
||||
Returns True if any of the arguments is logically true, and false if all of the
|
||||
arguments are false.
|
||||
Same as `any([value1, value2, ...])`.
|
||||
|
||||
>>> OR(1)
|
||||
True
|
||||
>>> OR(0)
|
||||
False
|
||||
>>> OR(1, 1)
|
||||
True
|
||||
>>> OR(0, 1)
|
||||
True
|
||||
>>> OR(0, 0)
|
||||
False
|
||||
>>> OR(0,False,0.0,"",None)
|
||||
False
|
||||
>>> OR(0,None,3,0)
|
||||
True
|
||||
"""
|
||||
return any((logical_expression,) + logical_expressions)
|
||||
|
||||
|
||||
def TRUE():
|
||||
"""
|
||||
Returns the logical value `True`. You may also use the value `True` directly. This
|
||||
function is provided primarily for compatibility with other spreadsheet programs.
|
||||
|
||||
>>> TRUE()
|
||||
True
|
||||
"""
|
||||
return True
|
||||
|
||||
def lazy_value(value):
|
||||
"""
|
||||
Evaluates a lazy value by calling it when it's a callable, or returns it unchanged otherwise.
|
||||
"""
|
||||
return value() if callable(value) else value
|
||||
Reference in New Issue
Block a user