arthrod commited on
Commit
66dad7c
Β·
verified Β·
1 Parent(s): 566fd93

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +408 -0
app.py ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import pandas as pd
4
+ from datetime import datetime
5
+ import os
6
+
7
+ class PreferenceCollector:
8
+ def __init__(self, jsonl_file):
9
+ self.jsonl_file = jsonl_file
10
+ self.data = []
11
+ self.current_index = 0
12
+ self.preferences = {}
13
+ self.load_data()
14
+
15
+ def load_data(self):
16
+ """Load data from JSONL file"""
17
+ try:
18
+ with open(self.jsonl_file, 'r') as f:
19
+ for line in f:
20
+ self.data.append(json.loads(line))
21
+ except FileNotFoundError:
22
+ print(f"File {self.jsonl_file} not found!")
23
+ self.data = []
24
+
25
+ def get_current_question(self):
26
+ """Get the current question data"""
27
+ if 0 <= self.current_index < len(self.data):
28
+ return self.data[self.current_index]
29
+ return None
30
+
31
+ def record_preference(self, sample_choice):
32
+ """Record user's preference for current question"""
33
+ if sample_choice in ["sample_zero", "sample_one", "sample_two"]:
34
+ self.preferences[self.current_index] = {
35
+ "question_index": self.current_index,
36
+ "preferred_sample": sample_choice,
37
+ "timestamp": datetime.now().isoformat()
38
+ }
39
+ return True
40
+ return False
41
+
42
+ def save_results(self, filename="preferences_results.json"):
43
+ """Save preference results to file"""
44
+ with open(filename, 'w') as f:
45
+ json.dump(self.preferences, f, indent=2)
46
+
47
+ # Also create a summary
48
+ summary = {
49
+ "total_questions": len(self.data),
50
+ "answered_questions": len(self.preferences),
51
+ "sample_zero_count": sum(1 for p in self.preferences.values() if p["preferred_sample"] == "sample_zero"),
52
+ "sample_one_count": sum(1 for p in self.preferences.values() if p["preferred_sample"] == "sample_one"),
53
+ "sample_two_count": sum(1 for p in self.preferences.values() if p["preferred_sample"] == "sample_two")
54
+ }
55
+
56
+ with open("preferences_summary.json", 'w') as f:
57
+ json.dump(summary, f, indent=2)
58
+
59
+ return summary
60
+
61
+ # Initialize the preference collector
62
+ collector = None
63
+ selected_sample = None
64
+
65
+ def initialize_collector(file_path):
66
+ """Initialize the collector with a file path"""
67
+ global collector
68
+ if file_path:
69
+ collector = PreferenceCollector(file_path.name)
70
+ if collector.data:
71
+ return update_display()
72
+ else:
73
+ return (
74
+ "No data loaded. Please check your file.",
75
+ "", "", "", "",
76
+ gr.update(interactive=False),
77
+ gr.update(interactive=False),
78
+ gr.update(interactive=False),
79
+ gr.update(interactive=False),
80
+ gr.update(interactive=False),
81
+ "0 / 0"
82
+ )
83
+ return (
84
+ "Please upload a JSONL file to begin.",
85
+ "", "", "", "",
86
+ gr.update(interactive=False),
87
+ gr.update(interactive=False),
88
+ gr.update(interactive=False),
89
+ gr.update(interactive=False),
90
+ gr.update(interactive=False),
91
+ "0 / 0"
92
+ )
93
+
94
+ def update_display():
95
+ """Update the display with current question data"""
96
+ global collector, selected_sample
97
+
98
+ if not collector or not collector.data:
99
+ return (
100
+ "No data loaded",
101
+ "", "", "", "",
102
+ gr.update(interactive=False),
103
+ gr.update(interactive=False),
104
+ gr.update(interactive=False),
105
+ gr.update(interactive=False),
106
+ gr.update(interactive=False),
107
+ "0 / 0"
108
+ )
109
+
110
+ question = collector.get_current_question()
111
+ if not question:
112
+ return (
113
+ "No more questions",
114
+ "", "", "", "",
115
+ gr.update(interactive=False),
116
+ gr.update(interactive=False),
117
+ gr.update(interactive=False),
118
+ gr.update(interactive=False),
119
+ gr.update(interactive=False),
120
+ f"{collector.current_index + 1} / {len(collector.data)}"
121
+ )
122
+
123
+ # Reset selected sample
124
+ selected_sample = None
125
+
126
+ # Check if this question has been answered before
127
+ is_answered = collector.current_index in collector.preferences
128
+
129
+ return (
130
+ question.get("introductory_example", "No introductory example"),
131
+ question.get("sample_zero", "No sample zero"),
132
+ question.get("sample_one", "No sample one"),
133
+ question.get("sample_two", "No sample two"),
134
+ f"{'βœ“ Answered' if is_answered else 'Not answered yet'}",
135
+ gr.update(interactive=True, variant="primary" if selected_sample == "sample_zero" else "secondary"),
136
+ gr.update(interactive=True, variant="primary" if selected_sample == "sample_one" else "secondary"),
137
+ gr.update(interactive=True, variant="primary" if selected_sample == "sample_two" else "secondary"),
138
+ gr.update(interactive=collector.current_index > 0),
139
+ gr.update(interactive=collector.current_index < len(collector.data) - 1),
140
+ f"{collector.current_index + 1} / {len(collector.data)}"
141
+ )
142
+
143
+ def select_sample(sample_name):
144
+ """Handle sample selection"""
145
+ global selected_sample
146
+ selected_sample = sample_name
147
+
148
+ # Update button variants to show selection
149
+ return (
150
+ gr.update(variant="primary" if sample_name == "sample_zero" else "secondary"),
151
+ gr.update(variant="primary" if sample_name == "sample_one" else "secondary"),
152
+ gr.update(variant="primary" if sample_name == "sample_two" else "secondary"),
153
+ gr.update(interactive=True) # Enable confirm button
154
+ )
155
+
156
+ def confirm_selection():
157
+ """Confirm the current selection"""
158
+ global collector, selected_sample
159
+
160
+ if not collector or not selected_sample:
161
+ return (
162
+ gr.update(value="Please select a sample first"),
163
+ gr.update(interactive=False)
164
+ )
165
+
166
+ if collector.record_preference(selected_sample):
167
+ # Auto-advance to next question if not the last one
168
+ if collector.current_index < len(collector.data) - 1:
169
+ collector.current_index += 1
170
+ return (
171
+ gr.update(value="βœ“ Selection recorded! Moving to next question..."),
172
+ gr.update(interactive=False),
173
+ *update_display()
174
+ )
175
+ else:
176
+ return (
177
+ gr.update(value="βœ“ Selection recorded! You've completed all questions."),
178
+ gr.update(interactive=False),
179
+ *update_display()
180
+ )
181
+
182
+ return (
183
+ gr.update(value="Error recording selection"),
184
+ gr.update(interactive=False)
185
+ )
186
+
187
+ def previous_question():
188
+ """Go to previous question"""
189
+ global collector
190
+ if collector and collector.current_index > 0:
191
+ collector.current_index -= 1
192
+ return update_display()
193
+ return update_display()
194
+
195
+ def next_question():
196
+ """Go to next question"""
197
+ global collector
198
+ if collector and collector.current_index < len(collector.data) - 1:
199
+ collector.current_index += 1
200
+ return update_display()
201
+ return update_display()
202
+
203
+ def export_results():
204
+ """Export the results"""
205
+ global collector
206
+ if collector:
207
+ summary = collector.save_results()
208
+ return f"""Results exported successfully!
209
+
210
+ Total questions: {summary['total_questions']}
211
+ Answered: {summary['answered_questions']}
212
+
213
+ Preferences:
214
+ - Sample 0: {summary['sample_zero_count']} votes
215
+ - Sample 1: {summary['sample_one_count']} votes
216
+ - Sample 2: {summary['sample_two_count']} votes
217
+
218
+ Files saved: preferences_results.json, preferences_summary.json"""
219
+ return "No data to export"
220
+
221
+ # Create the Gradio interface
222
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
223
+ gr.Markdown(
224
+ """
225
+ # πŸ“Š Preference Collection Interface
226
+
227
+ Upload a JSONL file and select your preferred sample for each question.
228
+ """
229
+ )
230
+
231
+ with gr.Row():
232
+ file_input = gr.File(
233
+ label="Upload JSONL File",
234
+ file_types=[".jsonl"],
235
+ type="filepath"
236
+ )
237
+ load_btn = gr.Button("Load File", variant="primary")
238
+
239
+ gr.Markdown("---")
240
+
241
+ # Question display
242
+ with gr.Column():
243
+ intro_display = gr.Textbox(
244
+ label="πŸ“ Question / Introductory Example",
245
+ lines=3,
246
+ interactive=False
247
+ )
248
+
249
+ progress_label = gr.Textbox(
250
+ label="Progress",
251
+ value="0 / 0",
252
+ interactive=False,
253
+ max_lines=1
254
+ )
255
+
256
+ status_label = gr.Textbox(
257
+ label="Status",
258
+ value="Not answered yet",
259
+ interactive=False,
260
+ max_lines=1
261
+ )
262
+
263
+ gr.Markdown("### πŸ€” Choose your preferred sample:")
264
+
265
+ # Sample displays
266
+ with gr.Row():
267
+ with gr.Column():
268
+ sample_0_display = gr.Textbox(
269
+ label="Sample 0",
270
+ lines=6,
271
+ interactive=False
272
+ )
273
+ select_0_btn = gr.Button(
274
+ "Select Sample 0",
275
+ variant="secondary",
276
+ interactive=False
277
+ )
278
+
279
+ with gr.Column():
280
+ sample_1_display = gr.Textbox(
281
+ label="Sample 1",
282
+ lines=6,
283
+ interactive=False
284
+ )
285
+ select_1_btn = gr.Button(
286
+ "Select Sample 1",
287
+ variant="secondary",
288
+ interactive=False
289
+ )
290
+
291
+ with gr.Column():
292
+ sample_2_display = gr.Textbox(
293
+ label="Sample 2",
294
+ lines=6,
295
+ interactive=False
296
+ )
297
+ select_2_btn = gr.Button(
298
+ "Select Sample 2",
299
+ variant="secondary",
300
+ interactive=False
301
+ )
302
+
303
+ # Action buttons
304
+ with gr.Row():
305
+ prev_btn = gr.Button("← Previous", interactive=False)
306
+ confirm_btn = gr.Button("βœ“ Confirm Selection", variant="primary", interactive=False)
307
+ next_btn = gr.Button("Next β†’", interactive=False)
308
+
309
+ confirm_status = gr.Textbox(label="Action Status", interactive=False)
310
+
311
+ gr.Markdown("---")
312
+
313
+ # Export section
314
+ with gr.Row():
315
+ export_btn = gr.Button("πŸ“₯ Export Results", variant="primary")
316
+ export_status = gr.Textbox(label="Export Status", interactive=False)
317
+
318
+ # Event handlers
319
+ load_btn.click(
320
+ initialize_collector,
321
+ inputs=[file_input],
322
+ outputs=[
323
+ intro_display, sample_0_display, sample_1_display, sample_2_display,
324
+ status_label, select_0_btn, select_1_btn, select_2_btn,
325
+ prev_btn, next_btn, progress_label
326
+ ]
327
+ )
328
+
329
+ select_0_btn.click(
330
+ lambda: select_sample("sample_zero"),
331
+ outputs=[select_0_btn, select_1_btn, select_2_btn, confirm_btn]
332
+ )
333
+
334
+ select_1_btn.click(
335
+ lambda: select_sample("sample_one"),
336
+ outputs=[select_0_btn, select_1_btn, select_2_btn, confirm_btn]
337
+ )
338
+
339
+ select_2_btn.click(
340
+ lambda: select_sample("sample_two"),
341
+ outputs=[select_0_btn, select_1_btn, select_2_btn, confirm_btn]
342
+ )
343
+
344
+ confirm_btn.click(
345
+ confirm_selection,
346
+ outputs=[
347
+ confirm_status, confirm_btn,
348
+ intro_display, sample_0_display, sample_1_display, sample_2_display,
349
+ status_label, select_0_btn, select_1_btn, select_2_btn,
350
+ prev_btn, next_btn, progress_label
351
+ ]
352
+ )
353
+
354
+ prev_btn.click(
355
+ previous_question,
356
+ outputs=[
357
+ intro_display, sample_0_display, sample_1_display, sample_2_display,
358
+ status_label, select_0_btn, select_1_btn, select_2_btn,
359
+ prev_btn, next_btn, progress_label
360
+ ]
361
+ )
362
+
363
+ next_btn.click(
364
+ next_question,
365
+ outputs=[
366
+ intro_display, sample_0_display, sample_1_display, sample_2_display,
367
+ status_label, select_0_btn, select_1_btn, select_2_btn,
368
+ prev_btn, next_btn, progress_label
369
+ ]
370
+ )
371
+
372
+ export_btn.click(
373
+ export_results,
374
+ outputs=[export_status]
375
+ )
376
+
377
+ # Launch the app
378
+ if __name__ == "__main__":
379
+ # Create a sample JSONL file for testing
380
+ sample_data = [
381
+ {
382
+ "introductory_example": "Which response best explains machine learning?",
383
+ "sample_zero": "Machine learning is a subset of AI that enables systems to learn and improve from experience without being explicitly programmed.",
384
+ "sample_one": "Machine learning involves training computers to recognize patterns in data and make decisions based on those patterns.",
385
+ "sample_two": "Machine learning is the science of getting computers to act without being explicitly programmed by using algorithms and statistical models."
386
+ },
387
+ {
388
+ "introductory_example": "How would you describe cloud computing?",
389
+ "sample_zero": "Cloud computing delivers computing services over the internet, including servers, storage, databases, and software.",
390
+ "sample_one": "Cloud computing is the on-demand availability of computer system resources, especially data storage and computing power.",
391
+ "sample_two": "Cloud computing provides shared processing resources and data to computers and other devices on demand via the internet."
392
+ },
393
+ {
394
+ "introductory_example": "What is the best explanation of blockchain?",
395
+ "sample_zero": "Blockchain is a distributed ledger technology that records transactions across many computers in a way that cannot be altered retroactively.",
396
+ "sample_one": "Blockchain is a system of recording information in a way that makes it difficult to change, hack, or cheat the system.",
397
+ "sample_two": "Blockchain is a decentralized, distributed database that maintains a continuously growing list of ordered records called blocks."
398
+ }
399
+ ]
400
+
401
+ # Save sample data
402
+ with open("sample_questions.jsonl", "w") as f:
403
+ for item in sample_data:
404
+ f.write(json.dumps(item) + "\n")
405
+
406
+ print("Sample file 'sample_questions.jsonl' created!")
407
+
408
+ demo.launch(share=False)