dataframe-textual 1.9.0__py3-none-any.whl → 1.10.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/data_frame_table.py +32 -28
- dataframe_textual/data_frame_viewer.py +0 -4
- dataframe_textual/sql_screen.py +6 -9
- dataframe_textual/table_screen.py +56 -58
- dataframe_textual/yes_no_screen.py +2 -2
- {dataframe_textual-1.9.0.dist-info → dataframe_textual-1.10.1.dist-info}/METADATA +1 -1
- dataframe_textual-1.10.1.dist-info/RECORD +14 -0
- dataframe_textual-1.9.0.dist-info/RECORD +0 -14
- {dataframe_textual-1.9.0.dist-info → dataframe_textual-1.10.1.dist-info}/WHEEL +0 -0
- {dataframe_textual-1.9.0.dist-info → dataframe_textual-1.10.1.dist-info}/entry_points.txt +0 -0
- {dataframe_textual-1.9.0.dist-info → dataframe_textual-1.10.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -916,6 +916,27 @@ class DataFrameTable(DataTable):
|
|
|
916
916
|
self.check_and_load_more()
|
|
917
917
|
|
|
918
918
|
# Setup & Loading
|
|
919
|
+
def reset_df(self, new_df: pl.DataFrame, dirty: bool = True) -> None:
|
|
920
|
+
"""Reset the dataframe to a new one and refresh the table.
|
|
921
|
+
|
|
922
|
+
Args:
|
|
923
|
+
new_df: The new Polars DataFrame to set.
|
|
924
|
+
dirty: Whether to mark the table as dirty (unsaved changes). Defaults to True.
|
|
925
|
+
"""
|
|
926
|
+
# Set new dataframe and reset table
|
|
927
|
+
self.df = new_df
|
|
928
|
+
self.loaded_rows = 0
|
|
929
|
+
self.sorted_columns = {}
|
|
930
|
+
self.hidden_columns = set()
|
|
931
|
+
self.selected_rows = [False] * len(self.df)
|
|
932
|
+
self.visible_rows = [True] * len(self.df)
|
|
933
|
+
self.fixed_rows = 0
|
|
934
|
+
self.fixed_columns = 0
|
|
935
|
+
self.matches = defaultdict(set)
|
|
936
|
+
self.histories.clear()
|
|
937
|
+
self.history = None
|
|
938
|
+
self.dirty = dirty # Mark as dirty since data changed
|
|
939
|
+
|
|
919
940
|
def setup_table(self, reset: bool = False) -> None:
|
|
920
941
|
"""Setup the table for display.
|
|
921
942
|
|
|
@@ -927,18 +948,7 @@ class DataFrameTable(DataTable):
|
|
|
927
948
|
|
|
928
949
|
# Reset to original dataframe
|
|
929
950
|
if reset:
|
|
930
|
-
self.
|
|
931
|
-
self.loaded_rows = 0
|
|
932
|
-
self.sorted_columns = {}
|
|
933
|
-
self.hidden_columns = set()
|
|
934
|
-
self.selected_rows = [False] * len(self.df)
|
|
935
|
-
self.visible_rows = [True] * len(self.df)
|
|
936
|
-
self.fixed_rows = 0
|
|
937
|
-
self.fixed_columns = 0
|
|
938
|
-
self.matches = defaultdict(set)
|
|
939
|
-
self.histories.clear()
|
|
940
|
-
self.history = None
|
|
941
|
-
self.dirty = False
|
|
951
|
+
self.reset_df(self.dataframe, dirty=False)
|
|
942
952
|
|
|
943
953
|
# Lazy load up to INITIAL_BATCH_SIZE visible rows
|
|
944
954
|
stop, visible_count = self.INITIAL_BATCH_SIZE, 0
|
|
@@ -3010,20 +3020,15 @@ class DataFrameTable(DataTable):
|
|
|
3010
3020
|
# Apply filter to dataframe with row indices
|
|
3011
3021
|
df_filtered = self.df.with_row_index(RIDX).filter(filter_expr)
|
|
3012
3022
|
|
|
3013
|
-
# Update selections and matches
|
|
3014
|
-
self.selected_rows = [self.selected_rows[ridx] for ridx in df_filtered[RIDX]]
|
|
3015
|
-
self.matches = {
|
|
3016
|
-
idx: self.matches[ridx].copy() for idx, ridx in enumerate(df_filtered[RIDX]) if ridx in self.matches
|
|
3017
|
-
}
|
|
3018
|
-
|
|
3019
3023
|
# Update dataframe
|
|
3020
|
-
self.
|
|
3024
|
+
self.reset_df(df_filtered.drop(RIDX))
|
|
3021
3025
|
|
|
3022
3026
|
# Recreate table for display
|
|
3023
3027
|
self.setup_table()
|
|
3024
3028
|
|
|
3025
3029
|
self.notify(
|
|
3026
|
-
f"
|
|
3030
|
+
f"Filtered rows with selections or matches and removed others. Now showing [$accent]{len(self.df)}[/] rows",
|
|
3031
|
+
title="Filter",
|
|
3027
3032
|
)
|
|
3028
3033
|
|
|
3029
3034
|
def do_view_rows(self) -> None:
|
|
@@ -3043,7 +3048,8 @@ class DataFrameTable(DataTable):
|
|
|
3043
3048
|
# Otherwise, use the current cell value
|
|
3044
3049
|
else:
|
|
3045
3050
|
ridx = self.cursor_row_idx
|
|
3046
|
-
|
|
3051
|
+
value = self.df.item(ridx, cidx)
|
|
3052
|
+
term = NULL if value is None else str(value)
|
|
3047
3053
|
|
|
3048
3054
|
self.view_rows((term, cidx, False, True))
|
|
3049
3055
|
|
|
@@ -3051,10 +3057,11 @@ class DataFrameTable(DataTable):
|
|
|
3051
3057
|
"""Open the filter screen to enter an expression."""
|
|
3052
3058
|
ridx = self.cursor_row_idx
|
|
3053
3059
|
cidx = self.cursor_col_idx
|
|
3054
|
-
cursor_value =
|
|
3060
|
+
cursor_value = self.df.item(ridx, cidx)
|
|
3061
|
+
term = NULL if cursor_value is None else str(cursor_value)
|
|
3055
3062
|
|
|
3056
3063
|
self.app.push_screen(
|
|
3057
|
-
FilterScreen(self.df, cidx,
|
|
3064
|
+
FilterScreen(self.df, cidx, term),
|
|
3058
3065
|
callback=self.view_rows,
|
|
3059
3066
|
)
|
|
3060
3067
|
|
|
@@ -3108,10 +3115,7 @@ class DataFrameTable(DataTable):
|
|
|
3108
3115
|
if False in self.visible_rows:
|
|
3109
3116
|
lf = lf.filter(self.visible_rows)
|
|
3110
3117
|
|
|
3111
|
-
if isinstance(expr, (list, pl.Series))
|
|
3112
|
-
expr_str = str(list(expr)[:10]) + ("..." if len(expr) > 10 else "")
|
|
3113
|
-
else:
|
|
3114
|
-
expr_str = str(expr)
|
|
3118
|
+
expr_str = "boolean list or series" if isinstance(expr, (list, pl.Series)) else str(expr)
|
|
3115
3119
|
|
|
3116
3120
|
# Apply the filter expression
|
|
3117
3121
|
try:
|
|
@@ -3128,7 +3132,7 @@ class DataFrameTable(DataTable):
|
|
|
3128
3132
|
return
|
|
3129
3133
|
|
|
3130
3134
|
# Add to history
|
|
3131
|
-
self.add_history(f"Filtered by expression [$success]{expr_str}[/]"
|
|
3135
|
+
self.add_history(f"Filtered by expression [$success]{expr_str}[/]")
|
|
3132
3136
|
|
|
3133
3137
|
# Mark unfiltered rows as invisible
|
|
3134
3138
|
filtered_row_indices = set(df_filtered[RIDX].to_list())
|
dataframe_textual/sql_screen.py
CHANGED
|
@@ -157,11 +157,8 @@ class SimpleSqlScreen(SqlScreen):
|
|
|
157
157
|
"""
|
|
158
158
|
super().__init__(
|
|
159
159
|
dftable,
|
|
160
|
-
on_yes_callback=self.
|
|
161
|
-
on_maybe_callback=partial(
|
|
162
|
-
self._handle_simple,
|
|
163
|
-
view=False,
|
|
164
|
-
),
|
|
160
|
+
on_yes_callback=self.handle_simple,
|
|
161
|
+
on_maybe_callback=partial(self.handle_simple, view=False),
|
|
165
162
|
)
|
|
166
163
|
|
|
167
164
|
def compose(self) -> ComposeResult:
|
|
@@ -177,7 +174,7 @@ class SimpleSqlScreen(SqlScreen):
|
|
|
177
174
|
yield Input(placeholder="e.g., age > 30 and height < 180", id="where-input")
|
|
178
175
|
yield from super().compose()
|
|
179
176
|
|
|
180
|
-
def
|
|
177
|
+
def handle_simple(self, view: bool = True) -> None:
|
|
181
178
|
"""Handle Yes button/Enter key press."""
|
|
182
179
|
selections = self.query_one(SelectionList).selected
|
|
183
180
|
if not selections:
|
|
@@ -221,8 +218,8 @@ class AdvancedSqlScreen(SqlScreen):
|
|
|
221
218
|
"""
|
|
222
219
|
super().__init__(
|
|
223
220
|
dftable,
|
|
224
|
-
on_yes_callback=self.
|
|
225
|
-
on_maybe_callback=partial(self.
|
|
221
|
+
on_yes_callback=self.handle_advanced,
|
|
222
|
+
on_maybe_callback=partial(self.handle_advanced, view=False),
|
|
226
223
|
)
|
|
227
224
|
|
|
228
225
|
def compose(self) -> ComposeResult:
|
|
@@ -236,6 +233,6 @@ class AdvancedSqlScreen(SqlScreen):
|
|
|
236
233
|
)
|
|
237
234
|
yield from super().compose()
|
|
238
235
|
|
|
239
|
-
def
|
|
236
|
+
def handle_advanced(self, view: bool = True) -> None:
|
|
240
237
|
"""Handle Yes button/Enter key press."""
|
|
241
238
|
return self.query_one(TextArea).text.strip(), view
|
|
@@ -97,60 +97,61 @@ class TableScreen(ModalScreen):
|
|
|
97
97
|
self.build_table()
|
|
98
98
|
event.stop()
|
|
99
99
|
|
|
100
|
-
def
|
|
101
|
-
|
|
102
|
-
) -> None:
|
|
103
|
-
"""Apply filter or highlight action by the selected value.
|
|
100
|
+
def filter_or_view_selected_value(self, cidx_name_value: tuple[int, str, Any] | None, action: str = "view") -> None:
|
|
101
|
+
"""Apply filter or view action by the selected value.
|
|
104
102
|
|
|
105
|
-
Filters or
|
|
103
|
+
Filters or views rows in the main table based on a selected value from
|
|
106
104
|
this table (typically frequency or row detail). Updates the main table's display
|
|
107
105
|
and notifies the user of the action.
|
|
108
106
|
|
|
109
107
|
Args:
|
|
110
|
-
col_name_value: Tuple of (column_name, column_value) to filter/
|
|
111
|
-
action: Either "filter" to hide non-matching rows, or "
|
|
112
|
-
|
|
113
|
-
Returns:
|
|
114
|
-
None
|
|
108
|
+
col_name_value: Tuple of (column_name, column_value) to filter/view by, or None.
|
|
109
|
+
action: Either "filter" to hide non-matching rows, or "view" to show matching rows. Defaults to "view".
|
|
115
110
|
"""
|
|
116
|
-
if
|
|
111
|
+
if cidx_name_value is None:
|
|
117
112
|
return
|
|
118
|
-
col_name, col_value =
|
|
113
|
+
cidx, col_name, col_value = cidx_name_value
|
|
114
|
+
self.log(f"Filtering or viewing by {col_name} == {col_value}")
|
|
119
115
|
|
|
120
116
|
# Handle NULL values
|
|
121
117
|
if col_value == NULL:
|
|
122
118
|
# Create expression for NULL values
|
|
123
119
|
expr = pl.col(col_name).is_null()
|
|
124
|
-
value_display = "[$success]
|
|
120
|
+
value_display = f"[$success]{NULL_DISPLAY}[/]"
|
|
125
121
|
else:
|
|
126
122
|
# Create expression for the selected value
|
|
127
123
|
expr = pl.col(col_name) == col_value
|
|
128
124
|
value_display = f"[$success]{col_value}[/]"
|
|
129
125
|
|
|
130
|
-
|
|
126
|
+
df_filtered = self.dftable.df.with_row_index(RIDX).filter(expr)
|
|
127
|
+
self.log(f"Filtered dataframe has {len(df_filtered)} rows")
|
|
128
|
+
|
|
129
|
+
matched_indices = set(df_filtered[RIDX].to_list())
|
|
130
|
+
if not matched_indices:
|
|
131
|
+
self.notify(
|
|
132
|
+
f"No matches found for [$warning]{col_name}[/] == {value_display}",
|
|
133
|
+
title="No Matches",
|
|
134
|
+
severity="warning",
|
|
135
|
+
)
|
|
136
|
+
return
|
|
131
137
|
|
|
132
138
|
# Apply the action
|
|
133
139
|
if action == "filter":
|
|
134
|
-
# Update
|
|
135
|
-
for i in range(len(self.dftable.visible_rows)):
|
|
136
|
-
self.dftable.visible_rows[i] = i in matched_indices
|
|
137
|
-
title = "Filter"
|
|
138
|
-
message = f"Filtered by [$accent]{col_name}[/] == [$success]{value_display}[/]"
|
|
139
|
-
else: # action == "highlight"
|
|
140
|
-
# Update selected_rows to reflect the highlights
|
|
140
|
+
# Update selections
|
|
141
141
|
for i in range(len(self.dftable.selected_rows)):
|
|
142
142
|
self.dftable.selected_rows[i] = i in matched_indices
|
|
143
|
-
title = "Highlight"
|
|
144
|
-
message = f"Highlighted [$accent]{col_name}[/] == [$success]{value_display}[/]"
|
|
145
143
|
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
# Update main table display
|
|
145
|
+
self.dftable.do_filter_rows()
|
|
146
|
+
|
|
147
|
+
else: # action == "view"
|
|
148
|
+
# Update visible rows
|
|
149
|
+
expr = [i in matched_indices for i in range(len(self.dftable.df))]
|
|
150
|
+
self.dftable.view_rows((expr, cidx, False, True))
|
|
148
151
|
|
|
149
152
|
# Dismiss the frequency screen
|
|
150
153
|
self.app.pop_screen()
|
|
151
154
|
|
|
152
|
-
self.notify(message, title=title)
|
|
153
|
-
|
|
154
155
|
|
|
155
156
|
class RowDetailScreen(TableScreen):
|
|
156
157
|
"""Modal screen to display a single row's details."""
|
|
@@ -199,30 +200,27 @@ class RowDetailScreen(TableScreen):
|
|
|
199
200
|
|
|
200
201
|
Args:
|
|
201
202
|
event: The key event object.
|
|
202
|
-
|
|
203
|
-
Returns:
|
|
204
|
-
None
|
|
205
203
|
"""
|
|
206
204
|
if event.key == "v":
|
|
207
|
-
#
|
|
208
|
-
self.
|
|
205
|
+
# View the main table by the selected value
|
|
206
|
+
self.filter_or_view_selected_value(self.get_cidx_name_value(), action="view")
|
|
209
207
|
event.stop()
|
|
210
208
|
elif event.key == "quotation_mark": # '"'
|
|
211
|
-
#
|
|
212
|
-
self.
|
|
209
|
+
# Filter the main table by the selected value
|
|
210
|
+
self.filter_or_view_selected_value(self.get_cidx_name_value(), action="filter")
|
|
213
211
|
event.stop()
|
|
214
212
|
elif event.key == "comma":
|
|
215
213
|
event.stop()
|
|
216
214
|
|
|
217
|
-
def
|
|
218
|
-
|
|
219
|
-
if
|
|
215
|
+
def get_cidx_name_value(self) -> tuple[int, str, Any] | None:
|
|
216
|
+
cidx = self.table.cursor_row
|
|
217
|
+
if cidx >= len(self.df.columns):
|
|
220
218
|
return None # Invalid row
|
|
221
219
|
|
|
222
|
-
col_name = self.df.columns[
|
|
223
|
-
col_value = self.df.item(self.ridx,
|
|
220
|
+
col_name = self.df.columns[cidx]
|
|
221
|
+
col_value = self.df.item(self.ridx, cidx)
|
|
224
222
|
|
|
225
|
-
return col_name, col_value
|
|
223
|
+
return cidx, col_name, col_value
|
|
226
224
|
|
|
227
225
|
|
|
228
226
|
class StatisticsScreen(TableScreen):
|
|
@@ -244,14 +242,14 @@ class StatisticsScreen(TableScreen):
|
|
|
244
242
|
|
|
245
243
|
if self.col_idx is None:
|
|
246
244
|
# Dataframe statistics
|
|
247
|
-
self.
|
|
245
|
+
self.build_dataframe_stats()
|
|
248
246
|
self.table.cursor_type = "column"
|
|
249
247
|
else:
|
|
250
248
|
# Column statistics
|
|
251
|
-
self.
|
|
249
|
+
self.build_column_stats()
|
|
252
250
|
self.table.cursor_type = "row"
|
|
253
251
|
|
|
254
|
-
def
|
|
252
|
+
def build_column_stats(self) -> None:
|
|
255
253
|
"""Build statistics for a single column."""
|
|
256
254
|
col_name = self.df.columns[self.col_idx]
|
|
257
255
|
lf = self.df.lazy()
|
|
@@ -292,7 +290,7 @@ class StatisticsScreen(TableScreen):
|
|
|
292
290
|
Text(value, style=dc.style, justify=dc.justify),
|
|
293
291
|
)
|
|
294
292
|
|
|
295
|
-
def
|
|
293
|
+
def build_dataframe_stats(self) -> None:
|
|
296
294
|
"""Build statistics for the entire dataframe."""
|
|
297
295
|
lf = self.df.lazy()
|
|
298
296
|
|
|
@@ -351,16 +349,16 @@ class FrequencyScreen(TableScreen):
|
|
|
351
349
|
|
|
352
350
|
CSS = TableScreen.DEFAULT_CSS.replace("TableScreen", "FrequencyScreen")
|
|
353
351
|
|
|
354
|
-
def __init__(self,
|
|
352
|
+
def __init__(self, cidx: int, dftable: "DataFrameTable") -> None:
|
|
355
353
|
super().__init__(dftable)
|
|
356
|
-
self.
|
|
354
|
+
self.cidx = cidx
|
|
357
355
|
self.sorted_columns = {
|
|
358
356
|
1: True, # Count
|
|
359
357
|
}
|
|
360
358
|
|
|
361
359
|
df = dftable.df.filter(dftable.visible_rows) if False in dftable.visible_rows else dftable.df
|
|
362
360
|
self.total_count = len(df)
|
|
363
|
-
self.df: pl.DataFrame = df[df.columns[self.
|
|
361
|
+
self.df: pl.DataFrame = df[df.columns[self.cidx]].value_counts(sort=True).sort("count", descending=True)
|
|
364
362
|
|
|
365
363
|
def on_mount(self) -> None:
|
|
366
364
|
"""Create the frequency table."""
|
|
@@ -369,19 +367,19 @@ class FrequencyScreen(TableScreen):
|
|
|
369
367
|
def on_key(self, event):
|
|
370
368
|
if event.key == "left_square_bracket": # '['
|
|
371
369
|
# Sort by current column in ascending order
|
|
372
|
-
self.
|
|
370
|
+
self.sort_by_column(descending=False)
|
|
373
371
|
event.stop()
|
|
374
372
|
elif event.key == "right_square_bracket": # ']'
|
|
375
373
|
# Sort by current column in descending order
|
|
376
|
-
self.
|
|
374
|
+
self.sort_by_column(descending=True)
|
|
377
375
|
event.stop()
|
|
378
376
|
elif event.key == "v":
|
|
379
377
|
# Filter the main table by the selected value
|
|
380
|
-
self.
|
|
378
|
+
self.filter_or_view_selected_value(self.get_cidx_name_value(), action="view")
|
|
381
379
|
event.stop()
|
|
382
380
|
elif event.key == "quotation_mark": # '"'
|
|
383
381
|
# Highlight the main table by the selected value
|
|
384
|
-
self.
|
|
382
|
+
self.filter_or_view_selected_value(self.get_cidx_name_value(), action="filter")
|
|
385
383
|
event.stop()
|
|
386
384
|
|
|
387
385
|
def build_table(self) -> None:
|
|
@@ -389,8 +387,8 @@ class FrequencyScreen(TableScreen):
|
|
|
389
387
|
self.table.clear(columns=True)
|
|
390
388
|
|
|
391
389
|
# Create frequency table
|
|
392
|
-
column = self.dftable.df.columns[self.
|
|
393
|
-
dtype = self.dftable.df.dtypes[self.
|
|
390
|
+
column = self.dftable.df.columns[self.cidx]
|
|
391
|
+
dtype = self.dftable.df.dtypes[self.cidx]
|
|
394
392
|
dc = DtypeConfig(dtype)
|
|
395
393
|
|
|
396
394
|
# Add column headers with sort indicators
|
|
@@ -468,7 +466,7 @@ class FrequencyScreen(TableScreen):
|
|
|
468
466
|
key="total",
|
|
469
467
|
)
|
|
470
468
|
|
|
471
|
-
def
|
|
469
|
+
def sort_by_column(self, descending: bool) -> None:
|
|
472
470
|
"""Sort the dataframe by the selected column and refresh the main table."""
|
|
473
471
|
row_idx, col_idx = self.table.cursor_coordinate
|
|
474
472
|
col_sort = col_idx if col_idx == 0 else 1
|
|
@@ -493,15 +491,15 @@ class FrequencyScreen(TableScreen):
|
|
|
493
491
|
# order = "desc" if descending else "asc"
|
|
494
492
|
# self.notify(f"Sorted by [on $primary]{col_name}[/] ({order})", title="Sort")
|
|
495
493
|
|
|
496
|
-
def
|
|
494
|
+
def get_cidx_name_value(self) -> tuple[str, str, str] | None:
|
|
497
495
|
row_idx = self.table.cursor_row
|
|
498
496
|
if row_idx >= len(self.df[:, 0]): # first column
|
|
499
497
|
return None # Skip the last `Total` row
|
|
500
498
|
|
|
501
|
-
col_name = self.dftable.df.columns[self.
|
|
502
|
-
col_dtype = self.dftable.df.dtypes[self.
|
|
499
|
+
col_name = self.dftable.df.columns[self.cidx]
|
|
500
|
+
col_dtype = self.dftable.df.dtypes[self.cidx]
|
|
503
501
|
|
|
504
502
|
cell_value = self.table.get_cell_at(Coordinate(row_idx, 0))
|
|
505
503
|
col_value = NULL if cell_value.plain == NULL_DISPLAY else DtypeConfig(col_dtype).convert(cell_value.plain)
|
|
506
504
|
|
|
507
|
-
return col_name, col_value
|
|
505
|
+
return self.cidx, col_name, col_value
|
|
@@ -494,13 +494,13 @@ class FilterScreen(YesNoScreen):
|
|
|
494
494
|
|
|
495
495
|
CSS = YesNoScreen.DEFAULT_CSS.replace("YesNoScreen", "FilterScreen")
|
|
496
496
|
|
|
497
|
-
def __init__(self, df: pl.DataFrame, cidx: int,
|
|
497
|
+
def __init__(self, df: pl.DataFrame, cidx: int, term: str | None = None):
|
|
498
498
|
self.df = df
|
|
499
499
|
self.cidx = cidx
|
|
500
500
|
super().__init__(
|
|
501
501
|
title="Filter by Expression",
|
|
502
502
|
label="e.g., NULL, $1 > 50, $name == 'text', $_ > 100, $a < $b, $_.str.contains('sub')",
|
|
503
|
-
input=
|
|
503
|
+
input=term,
|
|
504
504
|
checkbox="Match Nocase",
|
|
505
505
|
checkbox2="Match Whole",
|
|
506
506
|
on_yes_callback=self._get_input,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dataframe-textual
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.10.1
|
|
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
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
dataframe_textual/__init__.py,sha256=IFPb8RMUgghw0eRomehkkC684Iny_gs1VkiZMQ5ZpFk,813
|
|
2
|
+
dataframe_textual/__main__.py,sha256=VRH80gWJGLxfURg1GiN3cwWI7O_TQM5PqhqXbUCC1bg,3253
|
|
3
|
+
dataframe_textual/common.py,sha256=fh5dkN06VgFMItgFMlB7BMdiBjalc24jdqaGTJI7yCM,25409
|
|
4
|
+
dataframe_textual/data_frame_help_panel.py,sha256=iEKaur-aH1N_oqHu-vMwEEjfkjQiThK24UO5izsOiW0,3416
|
|
5
|
+
dataframe_textual/data_frame_table.py,sha256=bzKD7PKz2CP7HeZIqUkpDYZHhx7amBaEzHWRlq2i3XY,127578
|
|
6
|
+
dataframe_textual/data_frame_viewer.py,sha256=4fPIj-dvqhoTRxxOPfwTfRpYcfle7VtwTZfP4sJHA6E,21254
|
|
7
|
+
dataframe_textual/sql_screen.py,sha256=Pk2ENyDVkOXBLcsEMeXOEMkdzRH_NJ3T1biVUcY8j4Q,7411
|
|
8
|
+
dataframe_textual/table_screen.py,sha256=IhaGAWjzXaLvvc4JLBlAM6_Hl3t7du7vuHQYhrvW_5o,18055
|
|
9
|
+
dataframe_textual/yes_no_screen.py,sha256=qbuhywLIGBL52zQfSGVZQCfsdSmDz9JH6C4YFLrLYKU,26233
|
|
10
|
+
dataframe_textual-1.10.1.dist-info/METADATA,sha256=F0pCwiggF6y2WVr9Fs4YDgII5Rh-JZHuGeJq1y5AQpA,30381
|
|
11
|
+
dataframe_textual-1.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
12
|
+
dataframe_textual-1.10.1.dist-info/entry_points.txt,sha256=R_GoooOxcq6ab4RaHiVoZ4zrZJ-phMcGmlL2rwqncW8,107
|
|
13
|
+
dataframe_textual-1.10.1.dist-info/licenses/LICENSE,sha256=AVTg0gk1X-LHI-nnHlAMDQetrwuDZK4eypgSMDO46Yc,1069
|
|
14
|
+
dataframe_textual-1.10.1.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
dataframe_textual/__init__.py,sha256=IFPb8RMUgghw0eRomehkkC684Iny_gs1VkiZMQ5ZpFk,813
|
|
2
|
-
dataframe_textual/__main__.py,sha256=VRH80gWJGLxfURg1GiN3cwWI7O_TQM5PqhqXbUCC1bg,3253
|
|
3
|
-
dataframe_textual/common.py,sha256=fh5dkN06VgFMItgFMlB7BMdiBjalc24jdqaGTJI7yCM,25409
|
|
4
|
-
dataframe_textual/data_frame_help_panel.py,sha256=iEKaur-aH1N_oqHu-vMwEEjfkjQiThK24UO5izsOiW0,3416
|
|
5
|
-
dataframe_textual/data_frame_table.py,sha256=GfjknW0xzjEyz6syIW_BvCLBjGdEZpn1jW87PefBlOo,127408
|
|
6
|
-
dataframe_textual/data_frame_viewer.py,sha256=WI6e6AujRQkfCk2yerIRhuiTwtn86y1yWg3WesqdmAs,21315
|
|
7
|
-
dataframe_textual/sql_screen.py,sha256=9s9V-pcyYvXoaqsW_85hs-JSsllzayqhENC6ETGq7Xw,7464
|
|
8
|
-
dataframe_textual/table_screen.py,sha256=t2eNYS4a-G95qxRU9CFSM8kFjm-STIzkcP_o998ilqY,18135
|
|
9
|
-
dataframe_textual/yes_no_screen.py,sha256=HF2Z1WgOEof7NdA_u0s3pCxP26n69Kr6sQWwQvjK-YE,26247
|
|
10
|
-
dataframe_textual-1.9.0.dist-info/METADATA,sha256=bE00p7b3HACIwJzqeHRt28F99qMyruWKNEaxzm8wGVk,30380
|
|
11
|
-
dataframe_textual-1.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
12
|
-
dataframe_textual-1.9.0.dist-info/entry_points.txt,sha256=R_GoooOxcq6ab4RaHiVoZ4zrZJ-phMcGmlL2rwqncW8,107
|
|
13
|
-
dataframe_textual-1.9.0.dist-info/licenses/LICENSE,sha256=AVTg0gk1X-LHI-nnHlAMDQetrwuDZK4eypgSMDO46Yc,1069
|
|
14
|
-
dataframe_textual-1.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|