dataframe-textual 1.16.2__py3-none-any.whl → 2.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dataframe_textual/__init__.py +27 -1
- dataframe_textual/__main__.py +7 -0
- dataframe_textual/common.py +15 -9
- dataframe_textual/data_frame_help_panel.py +0 -3
- dataframe_textual/data_frame_table.py +622 -559
- dataframe_textual/data_frame_viewer.py +16 -8
- dataframe_textual/sql_screen.py +8 -2
- dataframe_textual/table_screen.py +25 -51
- dataframe_textual/yes_no_screen.py +9 -18
- {dataframe_textual-1.16.2.dist-info → dataframe_textual-2.0.1.dist-info}/METADATA +10 -10
- dataframe_textual-2.0.1.dist-info/RECORD +14 -0
- dataframe_textual-1.16.2.dist-info/RECORD +0 -14
- {dataframe_textual-1.16.2.dist-info → dataframe_textual-2.0.1.dist-info}/WHEEL +0 -0
- {dataframe_textual-1.16.2.dist-info → dataframe_textual-2.0.1.dist-info}/entry_points.txt +0 -0
- {dataframe_textual-1.16.2.dist-info → dataframe_textual-2.0.1.dist-info}/licenses/LICENSE +0 -0
dataframe_textual/__init__.py
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
"""DataFrame Viewer - Interactive CSV/Excel viewer for the terminal."""
|
|
2
2
|
|
|
3
|
+
from importlib.metadata import version
|
|
4
|
+
|
|
5
|
+
__version__ = version("dataframe-textual")
|
|
6
|
+
|
|
3
7
|
from .data_frame_help_panel import DataFrameHelpPanel
|
|
4
8
|
from .data_frame_table import DataFrameTable, History
|
|
5
9
|
from .data_frame_viewer import DataFrameViewer
|
|
6
|
-
from .table_screen import
|
|
10
|
+
from .table_screen import (
|
|
11
|
+
FrequencyScreen,
|
|
12
|
+
MetaColumnScreen,
|
|
13
|
+
MetaShape,
|
|
14
|
+
RowDetailScreen,
|
|
15
|
+
StatisticsScreen,
|
|
16
|
+
TableScreen,
|
|
17
|
+
)
|
|
7
18
|
from .yes_no_screen import (
|
|
19
|
+
AddColumnScreen,
|
|
20
|
+
AddLinkScreen,
|
|
8
21
|
ConfirmScreen,
|
|
9
22
|
EditCellScreen,
|
|
23
|
+
EditColumnScreen,
|
|
10
24
|
FilterScreen,
|
|
25
|
+
FindReplaceScreen,
|
|
11
26
|
FreezeScreen,
|
|
12
27
|
OpenFileScreen,
|
|
28
|
+
RenameColumnScreen,
|
|
29
|
+
RenameTabScreen,
|
|
13
30
|
SaveFileScreen,
|
|
14
31
|
SearchScreen,
|
|
15
32
|
YesNoScreen,
|
|
@@ -23,6 +40,9 @@ __all__ = [
|
|
|
23
40
|
"TableScreen",
|
|
24
41
|
"RowDetailScreen",
|
|
25
42
|
"FrequencyScreen",
|
|
43
|
+
"StatisticsScreen",
|
|
44
|
+
"MetaShape",
|
|
45
|
+
"MetaColumnScreen",
|
|
26
46
|
"YesNoScreen",
|
|
27
47
|
"SaveFileScreen",
|
|
28
48
|
"ConfirmScreen",
|
|
@@ -31,4 +51,10 @@ __all__ = [
|
|
|
31
51
|
"FilterScreen",
|
|
32
52
|
"FreezeScreen",
|
|
33
53
|
"OpenFileScreen",
|
|
54
|
+
"RenameColumnScreen",
|
|
55
|
+
"EditColumnScreen",
|
|
56
|
+
"AddColumnScreen",
|
|
57
|
+
"AddLinkScreen",
|
|
58
|
+
"FindReplaceScreen",
|
|
59
|
+
"RenameTabScreen",
|
|
34
60
|
]
|
dataframe_textual/__main__.py
CHANGED
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
import sys
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
from . import __version__
|
|
7
8
|
from .common import SUPPORTED_FORMATS, load_dataframe
|
|
8
9
|
from .data_frame_viewer import DataFrameViewer
|
|
9
10
|
|
|
@@ -24,6 +25,12 @@ def cli() -> argparse.Namespace:
|
|
|
24
25
|
" cat data.csv | %(prog)s --format csv\n",
|
|
25
26
|
)
|
|
26
27
|
parser.add_argument("files", nargs="*", help="Files to view (or read from stdin)")
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"-V",
|
|
30
|
+
"--version",
|
|
31
|
+
action="version",
|
|
32
|
+
version=f"%(prog)s {__version__}",
|
|
33
|
+
)
|
|
27
34
|
parser.add_argument(
|
|
28
35
|
"-f",
|
|
29
36
|
"--format",
|
dataframe_textual/common.py
CHANGED
|
@@ -152,8 +152,8 @@ SUBSCRIPT_DIGITS = {
|
|
|
152
152
|
# Cursor types ("none" removed)
|
|
153
153
|
CURSOR_TYPES = ["row", "column", "cell"]
|
|
154
154
|
|
|
155
|
-
#
|
|
156
|
-
|
|
155
|
+
# Row index mapping between filtered and original dataframe
|
|
156
|
+
RID = "^_RID_^"
|
|
157
157
|
|
|
158
158
|
|
|
159
159
|
@dataclass
|
|
@@ -224,7 +224,7 @@ def format_row(vals, dtypes, styles: list[str | None] | None = None, thousand_se
|
|
|
224
224
|
return formatted_row
|
|
225
225
|
|
|
226
226
|
|
|
227
|
-
def rindex(lst: list, value) -> int:
|
|
227
|
+
def rindex(lst: list, value, pos: int | None = None) -> int:
|
|
228
228
|
"""Return the last index of value in a list. Return -1 if not found.
|
|
229
229
|
|
|
230
230
|
Searches through the list in reverse order to find the last occurrence
|
|
@@ -237,9 +237,12 @@ def rindex(lst: list, value) -> int:
|
|
|
237
237
|
Returns:
|
|
238
238
|
The index (0-based) of the last occurrence, or -1 if not found.
|
|
239
239
|
"""
|
|
240
|
+
n = len(lst)
|
|
240
241
|
for i, item in enumerate(reversed(lst)):
|
|
242
|
+
if pos is not None and (n - 1 - i) > pos:
|
|
243
|
+
continue
|
|
241
244
|
if item == value:
|
|
242
|
-
return
|
|
245
|
+
return n - 1 - i
|
|
243
246
|
return -1
|
|
244
247
|
|
|
245
248
|
|
|
@@ -272,7 +275,7 @@ def parse_placeholders(template: str, columns: list[str], current_cidx: int) ->
|
|
|
272
275
|
|
|
273
276
|
Supports multiple placeholder types:
|
|
274
277
|
- `$_` - Current column (based on current_cidx parameter)
|
|
275
|
-
- `$#` - Row index (1-based
|
|
278
|
+
- `$#` - Row index (1-based)
|
|
276
279
|
- `$1`, `$2`, etc. - Column index (1-based)
|
|
277
280
|
- `$name` - Column name (e.g., `$product_id`)
|
|
278
281
|
- `` $`col name` `` - Column name with spaces (e.g., `` $`product id` ``)
|
|
@@ -323,7 +326,7 @@ def parse_placeholders(template: str, columns: list[str], current_cidx: int) ->
|
|
|
323
326
|
parts.append(pl.col(col_name))
|
|
324
327
|
elif placeholder == "#":
|
|
325
328
|
# $# refers to row index (1-based)
|
|
326
|
-
parts.append(
|
|
329
|
+
parts.append(pl.col(RID))
|
|
327
330
|
elif placeholder.isdigit():
|
|
328
331
|
# $1, $2, etc. refer to columns by 1-based position index
|
|
329
332
|
col_idx = int(placeholder) - 1 # Convert to 0-based
|
|
@@ -364,14 +367,14 @@ def parse_polars_expression(expression: str, columns: list[str], current_cidx: i
|
|
|
364
367
|
|
|
365
368
|
Replaces column references with Polars col() expressions:
|
|
366
369
|
- $_ - Current selected column
|
|
367
|
-
- $# - Row index (1-based
|
|
370
|
+
- $# - Row index (1-based)
|
|
368
371
|
- $1, $2, etc. - Column index (1-based)
|
|
369
372
|
- $col_name - Column name (valid identifier starting with _ or letter)
|
|
370
373
|
- $`col name` - Column name with spaces (backtick quoted)
|
|
371
374
|
|
|
372
375
|
Examples:
|
|
373
376
|
- "$_ > 50" -> "pl.col('current_col') > 50"
|
|
374
|
-
- "$# > 10" -> "pl.col('^
|
|
377
|
+
- "$# > 10" -> "pl.col('^_RID_^') > 10"
|
|
375
378
|
- "$1 > 50" -> "pl.col('col0') > 50"
|
|
376
379
|
- "$name == 'Alex'" -> "pl.col('name') == 'Alex'"
|
|
377
380
|
- "$age < $salary" -> "pl.col('age') < pl.col('salary')"
|
|
@@ -404,7 +407,10 @@ def parse_polars_expression(expression: str, columns: list[str], current_cidx: i
|
|
|
404
407
|
if isinstance(part, pl.Expr):
|
|
405
408
|
col = part.meta.output_name()
|
|
406
409
|
|
|
407
|
-
|
|
410
|
+
if col == RID: # Convert to 1-based
|
|
411
|
+
result.append(f"(pl.col('{col}') + 1)")
|
|
412
|
+
else:
|
|
413
|
+
result.append(f"pl.col('{col}')")
|
|
408
414
|
else:
|
|
409
415
|
result.append(part)
|
|
410
416
|
|
|
@@ -74,9 +74,6 @@ class DataFrameHelpPanel(Widget):
|
|
|
74
74
|
|
|
75
75
|
Initializes the help panel by setting up a watcher for focused widget changes
|
|
76
76
|
to dynamically update help text based on which widget has focus.
|
|
77
|
-
|
|
78
|
-
Returns:
|
|
79
|
-
None
|
|
80
77
|
"""
|
|
81
78
|
|
|
82
79
|
# def update_help(focused_widget: Widget | None):
|