diff --git a/sandbox/grist/functions/prevnext.py b/sandbox/grist/functions/prevnext.py index eb6bb123..53d57602 100644 --- a/sandbox/grist/functions/prevnext.py +++ b/sandbox/grist/functions/prevnext.py @@ -5,24 +5,33 @@ def PREVIOUS(rec, *, group_by=(), order_by): column IDs, and `order_by` allows column IDs to be prefixed with "-" to reverse sort order. For example, - - `PREVIOUS(rec, order_by="Date")` will return the previous record when the list of records is - sorted by the Date column. - - `PREVIOUS(rec, order_by="-Date")` will return the previous record when the list is sorted by - the Date column in descending order. - - `PREVIOUS(rec, group_by="Account", order_by="Date")` will return the previous record with the - same Account as `rec`, when records are filtered by the Account of `rec` and sorted by Date. + ```python + PREVIOUS(rec, order_by="Date") # The previous record when sorted by increasing Date. + PREVIOUS(rec, order_by="-Date") # The previous record when sorted by decreasing Date. + ``` + + You may use `group_by` to search for the previous record within a filtered group. For example, + this finds the previous record with the same Account as `rec`, when records are filtered by the + Account of `rec` and sorted by increasing Date: + ```python + PREVIOUS(rec, group_by="Account", order_by="Date") + ``` When multiple records have the same `order_by` values (e.g. the same Date in the examples above), the order is determined by the relative position of rows in views. This is done internally by falling back to the special column `manualSort` and the row ID column `id`. Use `order_by=None` to find the previous record in an unsorted table (when rows may be - rearranged by dragging them manually). For example, - - `PREVIOUS(rec, order_by=None)` will return the previous record in the unsorted list of records. + rearranged by dragging them manually). For example: + ```python + PREVIOUS(rec, order_by=None) # The previous record in the unsorted list of records. + ``` You may specify multiple column IDs as a tuple, for both `group_by` and `order_by`. This can be used to match views sorted by multiple columns. For example: - - `PREVIOUS(rec, group_by=("Account", "Year"), order_by=("Date", "-Amount"))` + ```python + PREVIOUS(rec, group_by=("Account", "Year"), order_by=("Date", "-Amount")) + ``` """ return _sorted_lookup(rec, group_by=group_by, order_by=order_by)._find.previous(rec) @@ -39,10 +48,10 @@ def RANK(rec, *, group_by=(), order_by, order="asc"): `order_by`, and grouping specified by `group_by`. See [`PREVIOUS`](#previous) for details of these parameters. - The `order` parameter may be "asc" (which is the default) or "desc". + The `order` parameter may be `"asc"` (which is the default) or `"desc"`. - When `order` is "asc" or omitted, the first record in the group in the sorted order would have - the rank of 1. When `order` is "desc", the last record in the sorted order would have the rank + When `order` is `"asc"` or omitted, the first record in the group in the sorted order would have + the rank of 1. When `order` is `"desc"`, the last record in the sorted order would have the rank of 1. If there are multiple groups, there will be multiple records with the same rank. In particular, @@ -50,7 +59,7 @@ def RANK(rec, *, group_by=(), order_by, order="asc"): For example, `RANK(rec, group_by="Year", order_by="Score", order="desc")` will return the rank of the current record (`rec`) among all the records in its table for the same year, ordered by - score. + decreasing score. """ return _sorted_lookup(rec, group_by=group_by, order_by=order_by)._find.rank(rec, order=order) diff --git a/sandbox/grist/records.py b/sandbox/grist/records.py index 4a67ce23..1ff7c6e7 100644 --- a/sandbox/grist/records.py +++ b/sandbox/grist/records.py @@ -243,26 +243,30 @@ class RecordSet(object): @property def find(self): """ - A set of methods for finding values in sorted set of records. For example: + Name: find.* + Usage: RecordSet.**find.\\***(value) + + A set of methods for finding values in sorted sets of records, as returned by + [`lookupRecords`](#lookuprecords). For example: ``` - Transactions.lookupRecords(..., sort_by="Date").find.lt($Date) - Table.lookupRecords(..., sort_by=("Foo", "Bar")).find.le(foo, bar) + Transactions.lookupRecords(..., order_by="Date").find.lt($Date) + Table.lookupRecords(..., order_by=("Foo", "Bar")).find.le(foo, bar) ``` - If the `find` method is shadowed by a same-named user column, you may use `_find` instead. + If the `find` attribute is shadowed by a same-named user column, you may use `_find` instead. The methods available are: - - `lt`: (less than) find nearest record with sort values < the given values - - `le`: (less than or equal to) find nearest record with sort values <= the given values - - `gt`: (greater than) find nearest record with sort values > the given values - - `ge`: (greater than or equal to) find nearest record with sort values >= the given values - - `eq`: (equal to) find nearest record with sort values == the given values + - __`lt`__: (less than) find nearest record with sort values < the given values + - __`le`__: (less than or equal to) find nearest record with sort values <= the given values + - __`gt`__: (greater than) find nearest record with sort values > the given values + - __`ge`__: (greater than or equal to) find nearest record with sort values >= the given values + - __`eq`__: (equal to) find nearest record with sort values == the given values - Example from https://templates.getgrist.com/5pHLanQNThxk/Payroll. Each person has a history of - pay rates, in the Rates table. To find a rate applicable on a certain date, here is how you - can do it old-style: - ``` + Example from [our Payroll template](https://templates.getgrist.com/5pHLanQNThxk/Payroll). + Each person has a history of pay rates, in the Rates table. To find a rate applicable on a + certain date, here is how you can do it old-style: + ```python # Get all the rates for the Person and Role in this row. rates = Rates.lookupRecords(Person=$Person, Role=$Role) @@ -277,8 +281,9 @@ class RecordSet(object): ``` With the new methods, it is much simpler: - ``` - rate = Rates.lookupRecords(Person=$Person, Role=$Role, sort_by="Rate_Start").find.le($Date) + ```python + rates = Rates.lookupRecords(Person=$Person, Role=$Role, order_by="Rate_Start") + rate = rates.find.le($Date) return rate.Hourly_Rate ``` diff --git a/sandbox/grist/table.py b/sandbox/grist/table.py index 94eabeaa..f04f05de 100644 --- a/sandbox/grist/table.py +++ b/sandbox/grist/table.py @@ -95,7 +95,8 @@ class UserTable(object): For backward compatibility, `sort_by` may be used instead of `order_by`, but only allows a single field, and falls back to row ID (rather than `manualSort`). - See [RecordSet](#recordset) for useful properties offered by the returned object. + See [RecordSet](#recordset) for useful properties offered by the returned object. In + particular, methods like [`.find.le`](#find_) allow searching for nearest values. See [CONTAINS](#contains) for an example utilizing `UserTable.lookupRecords` to find records where a field of a list type (such as `Choice List` or `Reference List`) contains the given @@ -127,13 +128,13 @@ class UserTable(object): parameter to the column ID by which to sort the matches, to determine which of them is returned as the first one. By default, the record with the lowest row ID is returned. - See [`lookupRecords`](#lookupRecords) for details of all available options and behavior of + See [`lookupRecords`](#lookuprecords) for details of all available options and behavior of `order_by` (and of its legacy alternative, `sort_by`). For example: ``` - Tasks.lookupOne(Project=$id, order_by="Priority") # Returns the Task with the smallest Priority. - Rates.lookupOne(Person=$id, order_by="-Date") # Returns the Rate with the latest Date. + Tasks.lookupOne(Project=$id, order_by="Priority") # Task with the smallest Priority. + Rates.lookupOne(Person=$id, order_by="-Date") # Rate with the latest Date. ``` """ return self.table.lookup_one_record(**field_value_pairs)