abir-hr196 commited on
Commit
763946d
·
1 Parent(s): fd7f4b4
Files changed (2) hide show
  1. app.py +67 -29
  2. tinysql_dataset_viewer.py +84 -46
app.py CHANGED
@@ -10,9 +10,25 @@ custom_css = """
10
  --martian-gray-medium: #2A2A2A;
11
  }
12
 
 
 
 
 
 
13
  .gradio-container {
14
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
15
  background-color: var(--martian-black) !important;
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  /* Better tabs - bold, bigger, no icons, ORANGE selection */
@@ -32,6 +48,7 @@ custom_css = """
32
  transition: all 0.3s ease !important;
33
  color: #888 !important;
34
  border: none !important;
 
35
  }
36
 
37
  .tab-nav button:hover {
@@ -45,7 +62,7 @@ custom_css = """
45
  box-shadow: 0 2px 8px rgba(255, 107, 74, 0.3) !important;
46
  }
47
 
48
- /* REMOVE ALL PURPLE - Replace with orange */
49
  label, .label-wrap {
50
  color: #E0E0E0 !important;
51
  }
@@ -59,7 +76,7 @@ label, .label-wrap {
59
  font-size: 0.9rem !important;
60
  }
61
 
62
- /* Orange dropdown and inputs - NO PURPLE */
63
  select, input, textarea {
64
  background: var(--martian-gray-medium) !important;
65
  border: 1px solid #3A3A3A !important;
@@ -72,7 +89,7 @@ select:focus, input:focus, textarea:focus {
72
  box-shadow: 0 0 0 2px rgba(255, 107, 74, 0.2) !important;
73
  }
74
 
75
- /* Orange sliders - properly following thumb position */
76
  input[type="range"] {
77
  -webkit-appearance: none;
78
  appearance: none;
@@ -120,25 +137,42 @@ input[type="range"]::-moz-range-progress {
120
  border-radius: 3px;
121
  }
122
 
123
- /* For Webkit browsers, use a gradient workaround */
124
- input[type="range"]::-webkit-slider-runnable-track {
125
- background: linear-gradient(to right,
126
- var(--martian-orange) 0%,
127
- var(--martian-orange) var(--value, 0%),
128
- #3A3A3A var(--value, 0%),
129
- #3A3A3A 100%);
130
- height: 6px;
131
- border-radius: 3px;
132
- }
133
-
134
- /* Remove any purple/blue colors */
135
  .primary, .secondary {
136
  background: var(--martian-orange) !important;
137
  border-color: var(--martian-orange) !important;
 
138
  }
139
 
140
  button {
141
  border: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
 
144
  /* Footer */
@@ -165,7 +199,7 @@ button {
165
  }
166
 
167
  .footer-text {
168
- color: #999;
169
  font-size: 0.95rem;
170
  margin: 0.5rem 0;
171
  }
@@ -175,13 +209,17 @@ button {
175
  animation: heartbeat 1.5s ease-in-out infinite;
176
  }
177
 
 
 
 
 
178
  @keyframes heartbeat {
179
  0%, 100% { transform: scale(1); }
180
  50% { transform: scale(1.1); }
181
  }
182
 
183
  .citation-box {
184
- background: #2A2A2A;
185
  border: 1px solid #3A3A3A;
186
  border-radius: 12px;
187
  padding: 1.5rem;
@@ -193,15 +231,15 @@ button {
193
 
194
  .citation-header {
195
  font-weight: 700;
196
- color: #FF6B4A;
197
  margin-bottom: 1rem;
198
  font-size: 1.1rem;
199
  text-align: center;
200
  }
201
 
202
  .citation-box pre {
203
- color: #D0D0D0;
204
- background: #1A1A1A;
205
  padding: 1rem;
206
  border-radius: 8px;
207
  overflow-x: auto;
@@ -210,12 +248,12 @@ button {
210
  """
211
 
212
  with gr.Blocks(css=custom_css, title="TinySQL Demo", theme=gr.themes.Soft()) as demo:
213
- # Martian Logo Header
214
  gr.HTML("""
215
- <div style="text-align: center; padding: 2rem 0 1rem 0;">
216
- <img src="https://withmartian.com/logo.png" alt="Martian" style="height: 60px; margin-bottom: 1rem;" onerror="this.style.display='none'">
217
- <h1 style="font-size: 2.5rem; font-weight: 700; color: #FF6B4A; margin: 0;">TinySQL</h1>
218
- <p style="color: #999; font-size: 1.1rem; margin-top: 0.5rem;">Mechanistic Interpretability for Text-to-SQL</p>
219
  </div>
220
  """)
221
 
@@ -252,11 +290,11 @@ with gr.Blocks(css=custom_css, title="TinySQL Demo", theme=gr.themes.Soft()) as
252
  <p class="footer-text">
253
  Brought to you with <span class="heart">❤️</span> from the Martian science team
254
  </p>
255
- <img src="static/images/martian_logo.jpg" alt="Martian" class="footer-logo" style="width: 80px; margin: 1rem auto; display: block;">
256
  <p class="footer-text" style="font-size: 0.85rem; margin-top: 1rem;">
257
- <a href="https://arxiv.org/abs/2503.12730" style="color: #FF6B4A; text-decoration: none;">Paper</a> •
258
- <a href="https://github.com/withmartian/TinySQL" style="color: #FF6B4A; text-decoration: none;">Code</a> •
259
- <a href="https://huggingface.co/collections/withmartian/tinysql-6760e92748b63fa56a6ffc9f" style="color: #FF6B4A; text-decoration: none;">Dataset</a>
260
  </p>
261
  </div>
262
  """)
 
10
  --martian-gray-medium: #2A2A2A;
11
  }
12
 
13
+ /* FORCE DARK MODE - Override Gradio's light mode */
14
+ .gradio-container, .gradio-container * {
15
+ color-scheme: dark !important;
16
+ }
17
+
18
  .gradio-container {
19
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
20
  background-color: var(--martian-black) !important;
21
+ color: #E0E0E0 !important;
22
+ }
23
+
24
+ /* Force dark backgrounds everywhere */
25
+ .block, .panel, div, section {
26
+ background-color: var(--martian-black) !important;
27
+ }
28
+
29
+ /* Force text colors */
30
+ h1, h2, h3, h4, h5, h6, p, span, label, div {
31
+ color: #E0E0E0 !important;
32
  }
33
 
34
  /* Better tabs - bold, bigger, no icons, ORANGE selection */
 
48
  transition: all 0.3s ease !important;
49
  color: #888 !important;
50
  border: none !important;
51
+ background: transparent !important;
52
  }
53
 
54
  .tab-nav button:hover {
 
62
  box-shadow: 0 2px 8px rgba(255, 107, 74, 0.3) !important;
63
  }
64
 
65
+ /* Orange labels */
66
  label, .label-wrap {
67
  color: #E0E0E0 !important;
68
  }
 
76
  font-size: 0.9rem !important;
77
  }
78
 
79
+ /* Orange inputs */
80
  select, input, textarea {
81
  background: var(--martian-gray-medium) !important;
82
  border: 1px solid #3A3A3A !important;
 
89
  box-shadow: 0 0 0 2px rgba(255, 107, 74, 0.2) !important;
90
  }
91
 
92
+ /* Orange sliders */
93
  input[type="range"] {
94
  -webkit-appearance: none;
95
  appearance: none;
 
137
  border-radius: 3px;
138
  }
139
 
140
+ /* Orange buttons */
 
 
 
 
 
 
 
 
 
 
 
141
  .primary, .secondary {
142
  background: var(--martian-orange) !important;
143
  border-color: var(--martian-orange) !important;
144
+ color: white !important;
145
  }
146
 
147
  button {
148
  border: none !important;
149
+ color: #E0E0E0 !important;
150
+ }
151
+
152
+ /* Compact header */
153
+ .compact-header {
154
+ text-align: center;
155
+ padding: 1.5rem 0 1rem 0;
156
+ background: var(--martian-black);
157
+ }
158
+
159
+ .compact-header img {
160
+ height: 35px;
161
+ margin-bottom: 0.5rem;
162
+ }
163
+
164
+ .compact-header h1 {
165
+ font-size: 2rem;
166
+ font-weight: 700;
167
+ color: #FF6B4A;
168
+ margin: 0;
169
+ line-height: 1.2;
170
+ }
171
+
172
+ .compact-header p {
173
+ color: #999;
174
+ font-size: 0.95rem;
175
+ margin-top: 0.25rem;
176
  }
177
 
178
  /* Footer */
 
199
  }
200
 
201
  .footer-text {
202
+ color: #999 !important;
203
  font-size: 0.95rem;
204
  margin: 0.5rem 0;
205
  }
 
209
  animation: heartbeat 1.5s ease-in-out infinite;
210
  }
211
 
212
+ .footer-text a {
213
+ color: #FF6B4A !important;
214
+ }
215
+
216
  @keyframes heartbeat {
217
  0%, 100% { transform: scale(1); }
218
  50% { transform: scale(1.1); }
219
  }
220
 
221
  .citation-box {
222
+ background: #2A2A2A !important;
223
  border: 1px solid #3A3A3A;
224
  border-radius: 12px;
225
  padding: 1.5rem;
 
231
 
232
  .citation-header {
233
  font-weight: 700;
234
+ color: #FF6B4A !important;
235
  margin-bottom: 1rem;
236
  font-size: 1.1rem;
237
  text-align: center;
238
  }
239
 
240
  .citation-box pre {
241
+ color: #D0D0D0 !important;
242
+ background: #1A1A1A !important;
243
  padding: 1rem;
244
  border-radius: 8px;
245
  overflow-x: auto;
 
248
  """
249
 
250
  with gr.Blocks(css=custom_css, title="TinySQL Demo", theme=gr.themes.Soft()) as demo:
251
+ # Compact Header
252
  gr.HTML("""
253
+ <div class="compact-header">
254
+ <img src="file/static/images/martian_logo.jpg" alt="Martian">
255
+ <h1>TinySQL</h1>
256
+ <p>Mechanistic Interpretability for Text-to-SQL</p>
257
  </div>
258
  """)
259
 
 
290
  <p class="footer-text">
291
  Brought to you with <span class="heart">❤️</span> from the Martian science team
292
  </p>
293
+ <img src="/static/images/martian_logo.jpg" alt="Martian" class="footer-logo">
294
  <p class="footer-text" style="font-size: 0.85rem; margin-top: 1rem;">
295
+ <a href="https://arxiv.org/abs/2503.12730">Paper</a> •
296
+ <a href="https://github.com/withmartian/TinySQL">Code</a> •
297
+ <a href="https://huggingface.co/collections/withmartian/tinysql-6760e92748b63fa56a6ffc9f">Dataset</a>
298
  </p>
299
  </div>
300
  """)
tinysql_dataset_viewer.py CHANGED
@@ -13,42 +13,60 @@ DATASETS = {
13
 
14
  COLUMNS = ["create_statement", "english_prompt", "sql_statement"]
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def load_preview(dataset_name):
17
- try:
18
- ds = load_dataset(DATASETS[dataset_name], split="train")
19
- df = pd.DataFrame(ds).head(500)
20
- if all(col in df.columns for col in COLUMNS):
21
- df = df[COLUMNS]
22
- # Add index column
23
- df.insert(0, 'index', range(len(df)))
24
- return df
25
- except Exception as e:
26
- return pd.DataFrame({"Error": [str(e)]})
27
 
28
- def filter_dataframe(df, search_query):
29
  if not search_query or df.empty or "Error" in df.columns:
30
  return df
31
 
32
- mask = df.astype(str).apply(
33
- lambda row: row.str.contains(search_query, case=False, na=False).any(),
34
- axis=1
35
- )
 
 
 
 
36
  return df[mask]
37
 
38
  def dataset_viewer(shared_instruction, shared_schema):
39
  gr.HTML("""
40
- <div style="text-align: center; padding: 2rem 1.5rem; background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%); border-radius: 16px; margin-bottom: 1.5rem; box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
41
- <h2 style="font-size: 2rem; font-weight: 700; margin-bottom: 0.5rem; color: #FF6B4A;">Dataset Explorer</h2>
42
- <p style="font-size: 1rem; opacity: 0.9; line-height: 1.6; color: #D0D0D0;">
43
  Browse, search, and explore TinySQL datasets
44
  </p>
45
  </div>
46
  """)
47
 
48
  gr.HTML("""
49
- <div style="background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%); border-radius: 12px; padding: 1.5rem; margin: 1rem 0; border-left: 4px solid #FF6B4A;">
50
  <p style="color: #D0D0D0; margin: 0; line-height: 1.6;">
51
- <strong style="color: #FF6B4A;">Quick Start:</strong> Select a dataset, click Load Dataset, then use search to filter. Pick any row and send it to the Model Demo tab.
52
  </p>
53
  </div>
54
  """)
@@ -64,28 +82,27 @@ def dataset_viewer(shared_instruction, shared_schema):
64
  info="Select complexity level"
65
  )
66
 
67
- # Simpler dataset guide - no colors, no beginner/intermediate
 
68
  gr.HTML("""
69
- <div style="background: #2A2A2A; border-radius: 12px; padding: 1.5rem; margin: 1.5rem 0; border: 1px solid #3A3A3A;">
70
- <h4 style="color: #FF6B4A; font-size: 1rem; margin: 0 0 1.25rem 0; font-weight: 700; border-bottom: 2px solid #3A3A3A; padding-bottom: 0.75rem;">Dataset Complexity Levels</h4>
71
 
72
- <div style="color: #D0D0D0; font-size: 0.9rem; line-height: 2;">
73
- <div><strong>CS1:</strong> Basic SELECT-FROM queries</div>
74
- <div><strong>CS2:</strong> Adds ORDER BY clauses</div>
75
- <div><strong>CS3:</strong> Aggregations (COUNT, SUM, AVG)</div>
76
- <div><strong>CS4:</strong> Adds WHERE filters</div>
77
  <div><strong>CS5:</strong> Multi-table JOINs</div>
78
  </div>
79
 
80
- <div style="margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid #3A3A3A;">
81
- <div style="color: #FF6B4A; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.5rem;">Synonym Variants</div>
82
- <div style="color: #999; font-size: 0.85rem; line-height: 1.6;">Natural language variations with semantic mappings</div>
83
  </div>
84
  </div>
85
  """)
86
 
87
- load_btn = gr.Button("Load Dataset", variant="primary", size="lg")
88
-
89
  gr.Markdown("### Test Example")
90
  row_selector = gr.Number(
91
  label="Row Number",
@@ -100,16 +117,29 @@ def dataset_viewer(shared_instruction, shared_schema):
100
  with gr.Column(scale=3):
101
  gr.Markdown("### Dataset Preview")
102
 
103
- search_box = gr.Textbox(
104
- label="Search",
105
- placeholder="Search across all columns...",
106
- lines=1
107
- )
 
 
 
 
 
 
 
 
 
108
 
109
- # HuggingFace-style table with row index on hover
110
  gr.HTML("""
111
  <style>
112
- /* True HuggingFace-style table - NO "Results" label */
 
 
 
 
 
113
  .dataframe-container label {
114
  display: none !important;
115
  }
@@ -124,6 +154,7 @@ def dataset_viewer(shared_instruction, shared_schema):
124
  border-collapse: collapse !important;
125
  width: 100% !important;
126
  font-size: 0.875rem !important;
 
127
  }
128
 
129
  .dataframe thead {
@@ -139,6 +170,7 @@ def dataset_viewer(shared_instruction, shared_schema):
139
  font-size: 0.75rem !important;
140
  text-transform: uppercase !important;
141
  letter-spacing: 0.05em !important;
 
142
  }
143
 
144
  .dataframe tbody tr {
@@ -177,13 +209,13 @@ def dataset_viewer(shared_instruction, shared_schema):
177
  max-width: 400px !important;
178
  overflow: hidden !important;
179
  text-overflow: ellipsis !important;
 
180
  }
181
 
182
  .dataframe tbody tr:last-child {
183
  border-bottom: none !important;
184
  }
185
 
186
- /* Hide index column but keep it for reference */
187
  .dataframe tbody td:first-child,
188
  .dataframe thead th:first-child {
189
  width: 0 !important;
@@ -202,7 +234,7 @@ def dataset_viewer(shared_instruction, shared_schema):
202
  elem_classes="dataframe-container"
203
  )
204
 
205
- stats_display = gr.Markdown("Click **Load Dataset** to begin exploring")
206
 
207
  df_state = gr.State(value=pd.DataFrame())
208
 
@@ -219,19 +251,25 @@ def dataset_viewer(shared_instruction, shared_schema):
219
  outputs=[df_state, df_display, stats_display]
220
  )
221
 
222
- def search_and_display(df, query):
223
  if df.empty:
224
  return df, "Load a dataset first"
225
 
226
- filtered_df = filter_dataframe(df, query)
227
  stats = f"**Showing {len(filtered_df)} of {len(df)} rows**"
228
  if query:
229
- stats += f" • Search: '{query}'"
230
  return filtered_df, stats
231
 
232
  search_box.change(
233
  fn=search_and_display,
234
- inputs=[df_state, search_box],
 
 
 
 
 
 
235
  outputs=[df_display, stats_display]
236
  )
237
 
 
13
 
14
  COLUMNS = ["create_statement", "english_prompt", "sql_statement"]
15
 
16
+ # Pre-cache datasets on startup
17
+ dataset_cache = {}
18
+
19
+ def preload_datasets():
20
+ """Load first 500 rows of all datasets into cache"""
21
+ for name, path in DATASETS.items():
22
+ try:
23
+ ds = load_dataset(path, split="train")
24
+ df = pd.DataFrame(ds).head(500)
25
+ if all(col in df.columns for col in COLUMNS):
26
+ df = df[COLUMNS]
27
+ df.insert(0, 'index', range(len(df)))
28
+ dataset_cache[name] = df
29
+ print(f"✓ Cached {name}")
30
+ except Exception as e:
31
+ print(f"✗ Failed to cache {name}: {e}")
32
+
33
+ # Preload on import
34
+ preload_datasets()
35
+
36
  def load_preview(dataset_name):
37
+ """Load from cache instantly"""
38
+ if dataset_name in dataset_cache:
39
+ return dataset_cache[dataset_name]
40
+ return pd.DataFrame({"Error": ["Dataset not found in cache"]})
 
 
 
 
 
 
41
 
42
+ def filter_dataframe(df, search_query, search_column):
43
  if not search_query or df.empty or "Error" in df.columns:
44
  return df
45
 
46
+ if search_column == "All Columns":
47
+ mask = df.astype(str).apply(
48
+ lambda row: row.str.contains(search_query, case=False, na=False).any(),
49
+ axis=1
50
+ )
51
+ else:
52
+ mask = df[search_column].astype(str).str.contains(search_query, case=False, na=False)
53
+
54
  return df[mask]
55
 
56
  def dataset_viewer(shared_instruction, shared_schema):
57
  gr.HTML("""
58
+ <div style="text-align: center; padding: 1.5rem; background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%); border-radius: 16px; margin-bottom: 1.5rem; box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
59
+ <h2 style="font-size: 1.75rem; font-weight: 700; margin-bottom: 0.5rem; color: #FF6B4A;">Dataset Explorer</h2>
60
+ <p style="font-size: 0.95rem; opacity: 0.9; line-height: 1.6; color: #D0D0D0;">
61
  Browse, search, and explore TinySQL datasets
62
  </p>
63
  </div>
64
  """)
65
 
66
  gr.HTML("""
67
+ <div style="background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%); border-radius: 12px; padding: 1.25rem; margin: 1rem 0; border-left: 4px solid #FF6B4A;">
68
  <p style="color: #D0D0D0; margin: 0; line-height: 1.6;">
69
+ <strong style="color: #FF6B4A;">Quick Start:</strong> Select a dataset and click Load Dataset. Use search to filter results.
70
  </p>
71
  </div>
72
  """)
 
82
  info="Select complexity level"
83
  )
84
 
85
+ load_btn = gr.Button("Load Dataset", variant="primary", size="lg")
86
+
87
  gr.HTML("""
88
+ <div style="background: #2A2A2A; border-radius: 12px; padding: 1.25rem; margin: 1.25rem 0; border: 1px solid #3A3A3A;">
89
+ <h4 style="color: #FF6B4A; font-size: 0.95rem; margin: 0 0 1rem 0; font-weight: 700; border-bottom: 2px solid #3A3A3A; padding-bottom: 0.75rem;">Dataset Levels</h4>
90
 
91
+ <div style="color: #D0D0D0; font-size: 0.85rem; line-height: 1.8;">
92
+ <div><strong>CS1:</strong> Basic SELECT-FROM</div>
93
+ <div><strong>CS2:</strong> Adds ORDER BY</div>
94
+ <div><strong>CS3:</strong> Aggregations</div>
95
+ <div><strong>CS4:</strong> WHERE filters</div>
96
  <div><strong>CS5:</strong> Multi-table JOINs</div>
97
  </div>
98
 
99
+ <div style="margin-top: 1rem; padding-top: 1rem; border-top: 1px solid #3A3A3A;">
100
+ <div style="color: #FF6B4A; font-weight: 600; font-size: 0.85rem; margin-bottom: 0.5rem;">Synonym Variants</div>
101
+ <div style="color: #999; font-size: 0.8rem; line-height: 1.5;">Natural language variations</div>
102
  </div>
103
  </div>
104
  """)
105
 
 
 
106
  gr.Markdown("### Test Example")
107
  row_selector = gr.Number(
108
  label="Row Number",
 
117
  with gr.Column(scale=3):
118
  gr.Markdown("### Dataset Preview")
119
 
120
+ with gr.Row():
121
+ search_box = gr.Textbox(
122
+ label="Search",
123
+ placeholder="Enter search term...",
124
+ lines=1,
125
+ scale=3
126
+ )
127
+
128
+ search_column = gr.Dropdown(
129
+ choices=["All Columns", "create_statement", "english_prompt", "sql_statement"],
130
+ value="All Columns",
131
+ label="Search In",
132
+ scale=1
133
+ )
134
 
 
135
  gr.HTML("""
136
  <style>
137
+ /* HuggingFace-style table - FORCE DARK MODE */
138
+ .dataframe-container, .dataframe-container * {
139
+ color: #E0E0E0 !important;
140
+ background: var(--martian-black) !important;
141
+ }
142
+
143
  .dataframe-container label {
144
  display: none !important;
145
  }
 
154
  border-collapse: collapse !important;
155
  width: 100% !important;
156
  font-size: 0.875rem !important;
157
+ background: #111827 !important;
158
  }
159
 
160
  .dataframe thead {
 
170
  font-size: 0.75rem !important;
171
  text-transform: uppercase !important;
172
  letter-spacing: 0.05em !important;
173
+ background: #1f2937 !important;
174
  }
175
 
176
  .dataframe tbody tr {
 
209
  max-width: 400px !important;
210
  overflow: hidden !important;
211
  text-overflow: ellipsis !important;
212
+ background: #111827 !important;
213
  }
214
 
215
  .dataframe tbody tr:last-child {
216
  border-bottom: none !important;
217
  }
218
 
 
219
  .dataframe tbody td:first-child,
220
  .dataframe thead th:first-child {
221
  width: 0 !important;
 
234
  elem_classes="dataframe-container"
235
  )
236
 
237
+ stats_display = gr.Markdown("Click **Load Dataset** to begin")
238
 
239
  df_state = gr.State(value=pd.DataFrame())
240
 
 
251
  outputs=[df_state, df_display, stats_display]
252
  )
253
 
254
+ def search_and_display(df, query, column):
255
  if df.empty:
256
  return df, "Load a dataset first"
257
 
258
+ filtered_df = filter_dataframe(df, query, column)
259
  stats = f"**Showing {len(filtered_df)} of {len(df)} rows**"
260
  if query:
261
+ stats += f" • Search: '{query}' in {column}"
262
  return filtered_df, stats
263
 
264
  search_box.change(
265
  fn=search_and_display,
266
+ inputs=[df_state, search_box, search_column],
267
+ outputs=[df_display, stats_display]
268
+ )
269
+
270
+ search_column.change(
271
+ fn=search_and_display,
272
+ inputs=[df_state, search_box, search_column],
273
  outputs=[df_display, stats_display]
274
  )
275