Logic and set operaters¶
Ranges¶
The frange()
function takes a string of abbreviated ranges, possibly delimited
by a comma (or some other character) and extrapolates its full,
unabbreviated list of ints.
>>> from quantipy.core.tools.dp.prep import frange
Basic range:
>>> frange('1-5')
[1, 2, 3, 4, 5]
Range in reverse:
>>> frange('15-11')
[15, 14, 13, 12, 11]
Combination:
>>> frange('1-5,7,9,15-11')
[1, 2, 3, 4, 5, 7, 9, 15, 14, 13, 12, 11]
May include spaces for clarity:
>>> frange('1-5, 7, 9, 15-11')
[1, 2, 3, 4, 5, 7, 9, 15, 14, 13, 12, 11]
Complex logic¶
Multiple conditions can be combined using union
or intersection
set
statements. Logical mappers can be arbitrarily nested as long as they are
well-formed.
union
¶
union
takes a list of logical conditions that will be treated with
or logic.
Where any of logic_A, logic_B or logic_C are True
:
>>> union([logic_A, logic_B, logic_C])
intersection
¶
intersection
takes a list of conditions that will be
treated with and logic.
Where all of logic_A, logic_B and logic_C are True
:
>>> intersection([logic_A, logic_B, logic_C])
“List” logic¶
Instead of using the verbose has_any
operator, we can express simple, non-nested
or logics simply as a list of codes. For example {"q1_1": [1, 2]}
is an
example of list-logic, where [1, 2]
will be interpreted as has_any([1, 2])
,
meaning if q1_1 has any of the values 1 or 2.
q1_1
has any of the responses 1, 2 or 3:
>>> l = {"q1_1": [1, 2, 3]}
has_any
¶
q1_1
has any of the responses 1, 2 or 3:
>>> l = {"q1_1": has_any([1, 2, 3])}
q1_1
has any of the responses 1, 2 or 3 and no others:
>>> l = {"q1_1": has_any([1, 2, 3], exclusive=True)}
not_any
¶
q1_1
doesn’t have any of the responses 1, 2 or 3:
>>> l = {"q1_1": not_any([1, 2, 3])}
q1_1
doesn’t have any of the responses 1, 2 or 3 but has some others:
>>> l = {"q1_1": not_any([1, 2, 3], exclusive=True)}
has_all
¶
q1_1
has all of the responses 1, 2 and 3:
>>> l = {"q1_1": has_all([1, 2, 3])}
q1_1
has all of the responses 1, 2 and 3 and no others:
>>> l = {"q1_1": has_all([1, 2, 3], exclusive=True)}
not_all
¶
q1_1
doesn’t have all of the responses 1, 2 and 3:
>>> l = {"q1_1": not_all([1, 2, 3])}
q1_1
doesn’t have all of the responses 1, 2 and 3 but has some others:
>>> l = {"q1_1": not_all([1, 2, 3], exclusive=True)}
has_count
¶
q1_1
has exactly 2 responses:
>>> l = {"q1_1": has_count(2)}
q1_1
has 1, 2 or 3 responses:
>>> l = {"q1_1": has_count([1, 3])}
q1_1
has 1 or more responses:
>>> l = {"q1_1": has_count([is_ge(1)])}
q1_1
has 1, 2 or 3 responses from the response group 5, 6, 7, 8 or 9:
>>> l = {"q1_1": has_count([1, 3, [5, 6, 7, 8, 9]])}
q1_1
has 1 or more responses from the response group 5, 6, 7, 8 or 9:
>>> l = {"q1_1": has_count([is_ge(1), [5, 6, 7, 8, 9]])}
not_count
¶
q1_1
doesn’t have exactly 2 responses:
>>> l = {"q1_1": not_count(2)}
q1_1
doesn’t have 1, 2 or 3 responses:
>>> l = {"q1_1": not_count([1, 3])}
q1_1
doesn’t have 1 or more responses:
>>> l = {"q1_1": not_count([is_ge(1)])}
q1_1
doesn’t have 1, 2 or 3 responses from the response group 5, 6, 7, 8 or 9:
>>> l = {"q1_1": not_count([1, 3, [5, 6, 7, 8, 9]])}
q1_1
doesn’t have 1 or more responses from the response group 5, 6, 7, 8 or 9:
>>> l = {"q1_1": not_count([is_ge(1), [5, 6, 7, 8, 9]])}
Boolean slicers and code existence¶
any()
, all()
code_count()
, is_nan()