# ========================================== # app.py - Calcul OCR v3.0 - Version ultra-simplifiée # ========================================== """ Application principale ultra-simplifiée pour ZeroGPU HuggingFace Spaces OCR en fin de session uniquement - Performance optimale """ import gradio as gr import warnings import os warnings.filterwarnings("ignore") # Import GPU uniquement from image_processing_gpu import init_ocr_model, create_white_canvas, cleanup_memory from game_engine import MathGame, export_to_clean_dataset print("🚀 Initialisation Calcul OCR v3.0 (Ultra-simplifié)...") print("🔄 Chargement modèle TrOCR...") init_ocr_model() print("✅ Modèle TrOCR prêt") def create_new_game_session(): """Crée une nouvelle instance de jeu pour chaque session""" return MathGame() def start_game_wrapper(duration: str, operation: str, difficulty: str, game_state) -> tuple: """Démarre une nouvelle session de jeu""" if game_state is None: game_state = create_new_game_session() cleanup_memory() result = game_state.start_game(duration, operation, difficulty) return result + (game_state, "") def next_question_wrapper(image_data, game_state) -> tuple: """Passe à la question suivante - Stockage simple, pas d'OCR""" if game_state is None: game_state = create_new_game_session() result = game_state.next_question(image_data) return result + (game_state,) def export_current_session(game_state) -> str: """Export de la session vers le dataset""" if game_state is None: return "❌ Aucune session active" if not hasattr(game_state, 'session_data') or not game_state.session_data: return "❌ Aucune donnée de session à exporter" export_info = game_state.get_export_status() if export_info["status"] == "exported": return f"""✅ Session déjà exportée ! 📅 Exporté le: {export_info['timestamp'][:19].replace('T', ' ')} 📊 Résultat: {export_info['result'][:100]}... 💡 Jouez une nouvelle session pour contribuer davantage !""" if export_info["status"] == "exporting": return "⏳ Export en cours..." if not export_info["can_export"]: return "❌ Aucune donnée à exporter" game_state.mark_export_in_progress() try: result = export_to_clean_dataset(game_state.session_data) game_state.mark_export_completed(result) cleanup_memory() return result except Exception as e: game_state.export_status = "not_exported" return f"❌ Erreur export: {str(e)}" # Interface Gradio with gr.Blocks( title="🧮 Calcul OCR - Entraînement mathématiques", theme=gr.themes.Soft(), css=""" .gradio-container { max-width: 1200px !important; } .config-section { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px; border-radius: 10px; margin: 10px 0; } .dataset-info { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); color: white; padding: 15px; border-radius: 10px; margin: 10px 0; } .radio-group { background: #f8f9fa; padding: 10px; border-radius: 8px; margin: 5px 0; } """, head="" ) as demo: # State management - Isolation par utilisateur game_state = gr.State(value=None) gr.Markdown( """ # 🧮 Entraînement au calcul mental avec OCR **Comment jouer :** 1. **Configurez** votre session ci-dessous 2. Cliquez sur **🚀 GO !** pour démarrer 3. **Écrivez** ✏️ votre réponse sur le tableau 4. Cliquez sur **➡️ NEXT !** pour la question suivante À la fin, vous pourrez consulter vos résultats et contribuer au dataset ouvert ! """ ) # Configuration de la session duration_choice = gr.Radio( choices=["30 secondes", "60 secondes"], value="30 secondes", label="⏱️ Durée" ) operation_choice = gr.Radio( choices=["×", "+", "-", "÷", "Aléatoire"], value="×", label="🔢 Opération" ) difficulty_choice = gr.Radio( choices=["Facile", "Difficile"], value="Facile", label="🎯 Difficulté" ) with gr.Row(): with gr.Column(scale=1): # Question question_display = gr.HTML( value='
Prêt(e) ?
' ) # Contrôles with gr.Row(): go_button = gr.Button("🚀 GO !", variant="primary", size="lg") next_button = gr.Button("➡️ NEXT !", variant="secondary", size="lg", interactive=False) # Status status_display = gr.Markdown("### 🎯 Configurez votre session et cliquez sur GO !") timer_display = gr.Markdown("### ⏱️ --") with gr.Column(scale=1): # Zone de dessin canvas = gr.ImageEditor( label="✏️ Votre réponse", height=350, width=350, value=create_white_canvas(350, 350), brush=gr.Brush(default_size=8, default_color="#000000"), sources=[], layers=False, transforms=[], eraser=gr.Eraser(default_size=20) ) # Résultats results_display = gr.HTML("") # Export vers dataset export_button = gr.Button("📤 Exporter la série vers le dataset", variant="primary", size="lg") export_status = gr.Markdown("") # Événements go_button.click( fn=start_game_wrapper, inputs=[duration_choice, operation_choice, difficulty_choice, game_state], outputs=[question_display, canvas, status_display, timer_display, go_button, next_button, results_display, game_state, export_status] ) next_button.click( fn=next_question_wrapper, inputs=[canvas, game_state], outputs=[question_display, canvas, status_display, timer_display, go_button, next_button, results_display, game_state] ) export_button.click( fn=export_current_session, inputs=[game_state], outputs=[export_status] ) if __name__ == "__main__": print("🚀 Lancement Calcul OCR v3.0 - Ultra-simplifié") print("🎯 ZeroGPU HuggingFace Spaces") print("⚡ Performance optimale : OCR en fin de session") print("🎯 Dataset: calcul_ocr_dataset") print("📊 Opérations: ×, +, -, ÷, Aléatoire") print("⚙️ Durées: 30s, 60s") print("🎯 Difficultés: Facile, Difficile") demo.launch( share=False, show_error=True, server_name="0.0.0.0", server_port=7860, show_api=False, favicon_path=None )