mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
166 lines
3.8 KiB
Python
166 lines
3.8 KiB
Python
|
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
|