dataframe-textual 2.6.2__tar.gz → 2.8.0__tar.gz

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.
Files changed (19) hide show
  1. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/PKG-INFO +11 -9
  2. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/README.md +10 -8
  3. dataframe_textual-2.8.0/glycosmos_glycans_list.csv.gz +0 -0
  4. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/pyproject.toml +1 -1
  5. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/__main__.py +24 -4
  6. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/common.py +10 -0
  7. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/data_frame_table.py +20 -5
  8. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/uv.lock +1 -1
  9. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/.gitignore +0 -0
  10. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/1811.csv.gz +0 -0
  11. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/LICENSE +0 -0
  12. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/large_malformed.tsv.gz +0 -0
  13. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/main.py +0 -0
  14. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/__init__.py +0 -0
  15. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/data_frame_help_panel.py +0 -0
  16. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/data_frame_viewer.py +0 -0
  17. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/sql_screen.py +0 -0
  18. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/table_screen.py +0 -0
  19. {dataframe_textual-2.6.2 → dataframe_textual-2.8.0}/src/dataframe_textual/yes_no_screen.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataframe-textual
3
- Version: 2.6.2
3
+ Version: 2.8.0
4
4
  Summary: Interactive terminal viewer/editor for tabular data
5
5
  Project-URL: Homepage, https://github.com/need47/dataframe-textual
6
6
  Project-URL: Repository, https://github.com/need47/dataframe-textual.git
@@ -184,14 +184,15 @@ options:
184
184
  -t, --truncate-ragged-lines
185
185
  Truncate ragged lines when reading CSV/TSV
186
186
  -E, --ignore-errors Ignore errors when reading CSV/TSV
187
- -c, --comment-prefix [COMMENT_PREFIX]
188
- Comment lines are skipped when reading CSV/TSV
189
- -q, --quote-char [QUOTE_CHAR]
190
- Quote character for reading CSV/TSV
191
- -l, --skip-lines SKIP_LINES
192
- Skip lines when reading CSV/TSV
193
- -a, --skip-rows-after-header SKIP_ROWS_AFTER_HEADER
194
- Skip rows after header when reading CSV/TSV
187
+ -c, --comment-prefix [PREFIX]
188
+ Comment lines starting with `PREFIX` are skipped when reading CSV/TSV
189
+ -q, --quote-char [C]
190
+ Use `C` as quote character for reading CSV/TSV
191
+ -L, --skip-lines N
192
+ Skip first N lines when reading CSV/TSV
193
+ -A, --skip-rows-after-header N
194
+ Skip N rows after header when reading CSV/TSV
195
+ -N, --n-rows N Stop after reading N rows from CSV/TSV
195
196
  -n, --null NULL [NULL ...]
196
197
  Values to interpret as null values when reading CSV/TSV
197
198
  ```
@@ -357,6 +358,7 @@ zcat compressed_data.csv.gz | dv -f csv
357
358
  | Key | Action |
358
359
  |-----|--------|
359
360
  | `"` (quote) | Filter selected rows (others removed) |
361
+ | `.` | View rows with non-null values in current column (others hidden) |
360
362
  | `v` | View selected rows (others hidden) |
361
363
  | `V` | View selected by expression (others hidden) |
362
364
 
@@ -145,14 +145,15 @@ options:
145
145
  -t, --truncate-ragged-lines
146
146
  Truncate ragged lines when reading CSV/TSV
147
147
  -E, --ignore-errors Ignore errors when reading CSV/TSV
148
- -c, --comment-prefix [COMMENT_PREFIX]
149
- Comment lines are skipped when reading CSV/TSV
150
- -q, --quote-char [QUOTE_CHAR]
151
- Quote character for reading CSV/TSV
152
- -l, --skip-lines SKIP_LINES
153
- Skip lines when reading CSV/TSV
154
- -a, --skip-rows-after-header SKIP_ROWS_AFTER_HEADER
155
- Skip rows after header when reading CSV/TSV
148
+ -c, --comment-prefix [PREFIX]
149
+ Comment lines starting with `PREFIX` are skipped when reading CSV/TSV
150
+ -q, --quote-char [C]
151
+ Use `C` as quote character for reading CSV/TSV
152
+ -L, --skip-lines N
153
+ Skip first N lines when reading CSV/TSV
154
+ -A, --skip-rows-after-header N
155
+ Skip N rows after header when reading CSV/TSV
156
+ -N, --n-rows N Stop after reading N rows from CSV/TSV
156
157
  -n, --null NULL [NULL ...]
157
158
  Values to interpret as null values when reading CSV/TSV
158
159
  ```
@@ -318,6 +319,7 @@ zcat compressed_data.csv.gz | dv -f csv
318
319
  | Key | Action |
319
320
  |-----|--------|
320
321
  | `"` (quote) | Filter selected rows (others removed) |
322
+ | `.` | View rows with non-null values in current column (others hidden) |
321
323
  | `v` | View selected rows (others hidden) |
322
324
  | `V` | View selected by expression (others hidden) |
323
325
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dataframe-textual"
7
- version = "2.6.2"
7
+ version = "2.8.0"
8
8
  description = "Interactive terminal viewer/editor for tabular data"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -51,15 +51,34 @@ def cli() -> argparse.Namespace:
51
51
  )
52
52
  parser.add_argument("-E", "--ignore-errors", action="store_true", help="Ignore errors when reading CSV/TSV")
53
53
  parser.add_argument(
54
- "-c", "--comment-prefix", nargs="?", const="#", help="Comment lines are skipped when reading CSV/TSV"
54
+ "-c",
55
+ "--comment-prefix",
56
+ metavar="PREFIX",
57
+ nargs="?",
58
+ const="#",
59
+ help="Comment lines starting with `PREFIX` are skipped when reading CSV/TSV",
55
60
  )
56
61
  parser.add_argument(
57
- "-q", "--quote-char", nargs="?", const=None, default='"', help="Quote character for reading CSV/TSV"
62
+ "-q",
63
+ "--quote-char",
64
+ metavar="C",
65
+ nargs="?",
66
+ const=None,
67
+ default='"',
68
+ help="Use `C` as quote character for reading CSV/TSV",
58
69
  )
59
- parser.add_argument("-l", "--skip-lines", type=int, default=0, help="Skip lines when reading CSV/TSV")
60
70
  parser.add_argument(
61
- "-a", "--skip-rows-after-header", type=int, default=0, help="Skip rows after header when reading CSV/TSV"
71
+ "-L", "--skip-lines", metavar="N", type=int, default=0, help="Skip first N lines when reading CSV/TSV"
62
72
  )
73
+ parser.add_argument(
74
+ "-A",
75
+ "--skip-rows-after-header",
76
+ metavar="N",
77
+ type=int,
78
+ default=0,
79
+ help="Skip N rows after header when reading CSV/TSV",
80
+ )
81
+ parser.add_argument("-N", "--n-rows", metavar="N", type=int, help="Stop after reading N rows from CSV/TSV")
63
82
  parser.add_argument("-n", "--null", nargs="+", help="Values to interpret as null values when reading CSV/TSV")
64
83
 
65
84
  args = parser.parse_args()
@@ -98,6 +117,7 @@ def main() -> None:
98
117
  null_values=args.null,
99
118
  ignore_errors=args.ignore_errors,
100
119
  truncate_ragged_lines=args.truncate_ragged_lines,
120
+ n_rows=args.n_rows,
101
121
  )
102
122
  app = DataFrameViewer(*sources)
103
123
  app.run()
@@ -485,6 +485,7 @@ def load_dataframe(
485
485
  null_values: list[str] | None = None,
486
486
  ignore_errors: bool = False,
487
487
  truncate_ragged_lines: bool = False,
488
+ n_rows: int | None = None,
488
489
  ) -> list[Source]:
489
490
  """Load DataFrames from file specifications.
490
491
 
@@ -502,6 +503,8 @@ def load_dataframe(
502
503
  skip_rows_after_header: Number of rows to skip after header. Defaults to 0.
503
504
  null_values: List of values to interpret as null when reading CSV/TSV files. Defaults to None.
504
505
  ignore_errors: Whether to ignore errors when reading CSV/TSV files. Defaults to False.
506
+ truncate_ragged_lines: Whether to truncate ragged lines when reading CSV/TSV files. Defaults to False.
507
+ n_rows: Number of rows to read from CSV/TSV files. Defaults to None (read all rows).
505
508
 
506
509
  Returns:
507
510
  List of `Source` objects.
@@ -551,6 +554,7 @@ def load_dataframe(
551
554
  null_values=null_values,
552
555
  ignore_errors=ignore_errors,
553
556
  truncate_ragged_lines=truncate_ragged_lines,
557
+ n_rows=n_rows,
554
558
  )
555
559
  )
556
560
 
@@ -635,6 +639,7 @@ def load_file(
635
639
  null_values: list[str] | None = None,
636
640
  ignore_errors: bool = False,
637
641
  truncate_ragged_lines: bool = False,
642
+ n_rows: int | None = None,
638
643
  ) -> list[Source]:
639
644
  """Load a single file.
640
645
 
@@ -660,6 +665,8 @@ def load_file(
660
665
  schema_overrides: Optional dictionary of column name to Polars data type to override inferred schema.
661
666
  null_values: List of values to interpret as null when reading CSV/TSV files. Defaults to None.
662
667
  ignore_errors: Whether to ignore errors when reading CSV/TSV files.
668
+ truncate_ragged_lines: Whether to truncate ragged lines when reading CSV/TSV files. Defaults to False.
669
+ n_rows: Number of rows to read from CSV/TSV files. Defaults to None (read all rows).
663
670
 
664
671
  Returns:
665
672
  List of `Source` objects.
@@ -684,6 +691,7 @@ def load_file(
684
691
  null_values=null_values,
685
692
  ignore_errors=ignore_errors,
686
693
  truncate_ragged_lines=truncate_ragged_lines,
694
+ n_rows=n_rows,
687
695
  )
688
696
  data.append(Source(lf, filename, filepath.stem))
689
697
  elif file_format in ("xlsx", "xls"):
@@ -740,6 +748,8 @@ def load_file(
740
748
  schema_overrides=schema_overrides,
741
749
  null_values=null_values,
742
750
  ignore_errors=ignore_errors,
751
+ truncate_ragged_lines=truncate_ragged_lines,
752
+ n_rows=n_rows,
743
753
  )
744
754
 
745
755
  return data
@@ -188,9 +188,10 @@ class DataFrameTable(DataTable):
188
188
  - *(Supports case-insensitive & whole-word matching)*
189
189
 
190
190
  ## 👁️ View & Filter
191
- - **"** - 📍 Filter selected rows (removes others)
192
- - **v** - 👁️ View selected rows (hides others)
193
- - **V** - 🔧 View selected rows matching expression (hides others)
191
+ - **"** - 📍 Filter selected rows (others removed)
192
+ - **.** - 👁️ View rows with non-null values in current column (others hidden)
193
+ - **v** - 👁️ View selected rows (others hidden)
194
+ - **V** - 🔧 View selected rows matching expression (others hidden)
194
195
 
195
196
  ## 🔍 SQL Interface
196
197
  - **l** - 💬 Open simple SQL interface (select columns & where clause)
@@ -264,6 +265,7 @@ class DataFrameTable(DataTable):
264
265
  ("left_square_bracket", "sort_ascending", "Sort ascending"), # `[`
265
266
  ("right_square_bracket", "sort_descending", "Sort descending"), # `]`
266
267
  # View & Filter
268
+ ("full_stop", "view_rows_non_null", "View rows with non-null values in current column"),
267
269
  ("v", "view_rows", "View selected rows"),
268
270
  ("V", "view_rows_expr", "View selected rows matching expression"),
269
271
  ("quotation_mark", "filter_rows", "Filter selected rows"), # `"`
@@ -761,6 +763,10 @@ class DataFrameTable(DataTable):
761
763
  """Show metadata for the current column."""
762
764
  self.do_metadata_column()
763
765
 
766
+ def action_view_rows_non_null(self) -> None:
767
+ """View rows with non-null values in the current column."""
768
+ self.do_view_rows_non_null()
769
+
764
770
  def action_view_rows(self) -> None:
765
771
  """View rows by current cell value."""
766
772
  self.do_view_rows()
@@ -3603,6 +3609,15 @@ class DataFrameTable(DataTable):
3603
3609
  self.show_next_replace_confirmation()
3604
3610
 
3605
3611
  # View & Filter
3612
+ def do_view_rows_non_null(self) -> None:
3613
+ """View non-null rows based on the cursor column."""
3614
+ cidx = self.cursor_col_idx
3615
+ col_name = self.cursor_col_name
3616
+
3617
+ term = pl.col(col_name).is_not_null()
3618
+
3619
+ self.view_rows((term, cidx, False, True))
3620
+
3606
3621
  def do_view_rows(self) -> None:
3607
3622
  """View rows.
3608
3623
 
@@ -3712,7 +3727,7 @@ class DataFrameTable(DataTable):
3712
3727
  return
3713
3728
 
3714
3729
  # Add to history
3715
- self.add_history(f"Filtered by expression [$success]{expr_str}[/]")
3730
+ self.add_history(f"Viewed rows by expression [$success]{expr_str}[/]")
3716
3731
 
3717
3732
  ok_rids = set(df_filtered[RID])
3718
3733
 
@@ -3734,7 +3749,7 @@ class DataFrameTable(DataTable):
3734
3749
  # Recreate table for display
3735
3750
  self.setup_table()
3736
3751
 
3737
- self.notify(f"Filtered to [$success]{matched_count}[/] matching row(s)", title="View Rows")
3752
+ self.notify(f"Showing [$success]{matched_count}[/] matching row(s)", title="View Rows")
3738
3753
 
3739
3754
  def do_filter_rows(self) -> None:
3740
3755
  """Filter rows.
@@ -171,7 +171,7 @@ wheels = [
171
171
 
172
172
  [[package]]
173
173
  name = "dataframe-textual"
174
- version = "2.6.2"
174
+ version = "2.8.0"
175
175
  source = { editable = "." }
176
176
  dependencies = [
177
177
  { name = "polars" },