dataframe-textual 1.16.2__py3-none-any.whl → 2.0.0__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.
@@ -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 FrequencyScreen, RowDetailScreen, TableScreen
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
  ]
@@ -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",
@@ -152,8 +152,8 @@ SUBSCRIPT_DIGITS = {
152
152
  # Cursor types ("none" removed)
153
153
  CURSOR_TYPES = ["row", "column", "cell"]
154
154
 
155
- # For row index column
156
- RIDX = "^_ridx_^"
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 len(lst) - 1 - i
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, requires '^__ridx__^' column to be present)
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((pl.col(RIDX)))
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, requires '^__ridx__^' column to be present)
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('^__ridx__^') > 10"
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
- result.append(f"pl.col('{col}')")
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):