reachy_trivia / app.py
sumuks's picture
sumuks HF Staff
Update app.py
565bae4 verified
#!/usr/bin/env python3
import os
import gradio as gr
from datasets import load_dataset
from dataclasses import dataclass
from typing import Any
# HF token should be set as environment variable HF_TOKEN
@dataclass
class DatasetViewer:
dataset: Any = None
current_index: int = 0
total_items: int = 0
show_answer: bool = False
def load_dataset(self, dataset_name: str = "yourbench/reachy_mini_info_benchmark",
subset: str = "prepared_lighteval"):
try:
self.dataset = load_dataset(dataset_name, subset)
# Try to get the first available split
if isinstance(self.dataset, dict):
first_split = next(iter(self.dataset.keys()))
self.dataset = self.dataset[first_split]
self.total_items = len(self.dataset)
self.current_index = 0
self.show_answer = False
return True
except Exception as e:
print(f"Error loading dataset: {e}")
# Create mock data for demonstration
self.create_mock_data()
return False
def create_mock_data(self):
"""Create mock data that simulates yourbench dataset structure"""
mock_data = [
{
"question": "What is the capital of France?",
"ground_truth_answer": "Paris",
"document_summary": "France is a country in Western Europe.",
"question_category": "geography",
"estimated_difficulty": 2,
"kind": "single_shot",
"additional_instructions": "Ask generalizable questions."
},
{
"question": "Explain the concept of object-oriented programming.",
"ground_truth_answer": "Object-oriented programming (OOP) is a programming paradigm based on the concept of 'objects', which can contain data and code: data in the form of fields, and code in the form of procedures. Key principles include encapsulation, inheritance, and polymorphism.",
"document_summary": "Programming concepts",
"question_category": "computer_science",
"estimated_difficulty": 4,
"kind": "single_shot",
"additional_instructions": "Provide detailed explanations."
},
]
# Create a mock dataset-like structure
class MockDataset:
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx]
self.dataset = MockDataset(mock_data)
self.total_items = len(mock_data)
self.current_index = 0
self.show_answer = False
viewer = DatasetViewer()
viewer.load_dataset()
def get_current_item():
if viewer.dataset is None or viewer.total_items == 0:
return {"question": "No data available", "answer": "", "context": "", "task": "", "difficulty": ""}
item = viewer.dataset[viewer.current_index]
# Map actual dataset fields to expected interface fields
mapped_item = {
"question": item.get("question", "No question available"),
"answer": item.get("ground_truth_answer", "No answer available"),
"context": item.get("document_summary", "No context available"),
"task": item.get("question_category", "Unknown category"),
"difficulty": str(item.get("estimated_difficulty", "Unknown")),
"additional_instructions": item.get("additional_instructions", ""),
"kind": item.get("kind", ""),
"citations": item.get("citations", []),
"document_id": item.get("document_id", ""),
}
return mapped_item
def get_card_content():
item = get_current_item()
if viewer.show_answer:
# Show answer side
content = f"""
<div style="text-align: center; padding: 40px; min-height: 400px; display: flex; flex-direction: column; justify-content: center;">
<h1 style="color: #2d5aa0; font-size: 2.5em; margin-bottom: 30px;">Answer</h1>
<div style="font-size: 1.4em; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto;">
{item['answer']}
</div>
</div>
"""
button_text = "Show Question"
else:
# Show question side
content = f"""
<div style="text-align: center; padding: 40px; min-height: 400px; display: flex; flex-direction: column; justify-content: center;">
<h1 style="color: #2d5aa0; font-size: 2.5em; margin-bottom: 30px;">Question</h1>
<div style="font-size: 1.4em; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto;">
{item['question']}
</div>
</div>
"""
button_text = "Show Answer"
return content, button_text
def get_metadata():
item = get_current_item()
context = item.get('context', 'No context')
task = item.get('task', 'Unknown task')
difficulty = item.get('difficulty', 'Unknown')
kind = item.get('kind', 'Unknown')
additional_instructions = item.get('additional_instructions', '')
metadata = f"Category: {task} | Difficulty: {difficulty}/5 | Type: {kind}"
if additional_instructions:
metadata += f" | Instructions: {additional_instructions}"
# Truncate context if too long
if len(context) > 150:
context = context[:150] + "..."
return metadata, context
def toggle_answer():
viewer.show_answer = not viewer.show_answer
content, button_text = get_card_content()
return content, button_text
def next_item():
if viewer.total_items > 0:
viewer.current_index = (viewer.current_index + 1) % viewer.total_items
viewer.show_answer = False
content, button_text = get_card_content()
metadata, context = get_metadata()
progress = f"{viewer.current_index + 1} of {viewer.total_items}"
return content, button_text, metadata, context, progress
def previous_item():
if viewer.total_items > 0:
viewer.current_index = (viewer.current_index - 1) % viewer.total_items
viewer.show_answer = False
content, button_text = get_card_content()
metadata, context = get_metadata()
progress = f"{viewer.current_index + 1} of {viewer.total_items}"
return content, button_text, metadata, context, progress
def jump_to_item(item_number):
if viewer.total_items > 0 and 1 <= item_number <= viewer.total_items:
viewer.current_index = item_number - 1
viewer.show_answer = False
content, button_text = get_card_content()
metadata, context = get_metadata()
progress = f"{viewer.current_index + 1} of {viewer.total_items}"
return content, button_text, metadata, context, progress
# Initialize
initial_content, initial_button_text = get_card_content()
initial_metadata, initial_context = get_metadata()
initial_progress = f"{viewer.current_index + 1} of {viewer.total_items}"
# Custom CSS for flashcard styling
css = """
.flashcard {
border: 2px solid #ddd;
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
background: white;
margin: 20px 0;
min-height: 500px;
}
.controls {
text-align: center;
padding: 20px;
}
.metadata {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
font-size: 0.9em;
color: #666;
}
.context {
background: #fff3cd;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
font-size: 0.9em;
color: #856404;
border: 1px solid #ffeaa7;
}
.progress {
text-align: center;
font-size: 1.2em;
font-weight: bold;
color: #2d5aa0;
margin: 20px 0;
}
"""
# Create Gradio interface
with gr.Blocks(css=css, title="Reachy Trivia") as demo:
gr.Markdown("# πŸ€– Reachy Trivia")
gr.Markdown("""
**Test your knowledge about Reachy Mini and Reachy 2!**
Reachy Mini is the $299 open-source desktop robot designed for AI developers, educators, and hobbyists.
With its expressive antennas, screen-based eyes, and full Python programmability, it's the perfect companion
for exploring human-robot interaction and AI development.
*Questions generated by Yourbench - HuggingFace's Dynamic Evaluation Generation Platform*
""")
# Main flashcard area
with gr.Row():
with gr.Column(scale=1):
flashcard = gr.HTML(initial_content, elem_classes=["flashcard"])
# Controls
with gr.Row(elem_classes=["controls"]):
prev_btn = gr.Button("Previous", size="lg", variant="secondary")
toggle_btn = gr.Button(initial_button_text, size="lg", variant="primary")
next_btn = gr.Button("Next", size="lg", variant="secondary")
# Progress
progress_display = gr.HTML(f'<div class="progress">{initial_progress}</div>')
# Metadata and navigation sidebar
with gr.Row():
with gr.Column(scale=2):
metadata_display = gr.HTML(f'<div class="metadata">{initial_metadata}</div>')
context_display = gr.HTML(f'<div class="context">Context: {initial_context}</div>')
with gr.Column(scale=1):
gr.Markdown("### Jump to Item")
jump_input = gr.Number(
label="Item Number",
value=1,
minimum=1,
maximum=viewer.total_items,
precision=0
)
jump_btn = gr.Button("Jump", variant="secondary")
gr.Markdown("---")
gr.Markdown("### About Reachy Mini")
gr.Markdown("""
**Key Features:**
- 🎯 $299 open-source desktop robot
- πŸ“± Expressive screen-based eyes
- πŸ”§ Full Python programmability
- 🀝 Human-robot interaction focus
- 🧠 Hugging Face AI integration
- πŸ“¦ DIY assembly kit
""")
gr.Markdown("*Questions powered by [YouBench](https://huggingface.co/yourbench)*")
# Event handlers
toggle_btn.click(
toggle_answer,
outputs=[flashcard, toggle_btn]
)
next_btn.click(
next_item,
outputs=[flashcard, toggle_btn, metadata_display, context_display, progress_display]
)
prev_btn.click(
previous_item,
outputs=[flashcard, toggle_btn, metadata_display, context_display, progress_display]
)
jump_btn.click(
jump_to_item,
inputs=[jump_input],
outputs=[flashcard, toggle_btn, metadata_display, context_display, progress_display]
)
if __name__ == "__main__":
demo.launch()