Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import torch | |
| from transformers import pipeline | |
| from datetime import datetime | |
| import nltk | |
| from nltk.tokenize import word_tokenize | |
| from nltk.corpus import stopwords | |
| from collections import Counter | |
| import logging | |
| from typing import Dict, List, Tuple, Optional | |
| class GeradorTrilhaAprendizado: | |
| def __init__(self): | |
| try: | |
| self.device = "cuda" if torch.cuda.is_available() else "cpu" | |
| self.transcriber = pipeline("automatic-speech-recognition", | |
| model="openai/whisper-base", | |
| device=self.device) | |
| self.generator = pipeline("text-generation", | |
| model="gpt2-large", | |
| device=self.device) | |
| self.historico: List[Dict] = [] | |
| for resource in ['punkt', 'stopwords']: | |
| try: | |
| nltk.data.find(f'tokenizers/{resource}') | |
| except LookupError: | |
| nltk.download(resource) | |
| self.stop_words = set(stopwords.words('portuguese')) | |
| except Exception as e: | |
| logging.error(f"Initialization error: {str(e)}") | |
| raise | |
| def processar_audio(self, | |
| audio_path: Optional[str], | |
| nome_trilha: str, | |
| nivel: str = "intermediário", | |
| area: str = "geral", | |
| duracao: str = "3 meses", | |
| incluir_recursos: bool = True) -> Tuple[str, str, str, str]: | |
| if not audio_path: | |
| return ("", "", self._formatar_historico(), "❌ Nenhum áudio fornecido") | |
| try: | |
| transcricao = self.transcriber(audio_path)["text"] | |
| if not transcricao.strip(): | |
| return ("", "", self._formatar_historico(), "❌ Nenhum texto detectado no áudio") | |
| analise = self._gerar_trilha_personalizada(transcricao, nivel, area, duracao) | |
| if incluir_recursos: | |
| recursos = self._gerar_recursos(nivel, area, transcricao) | |
| analise += "\n\n" + recursos | |
| self.historico.append({ | |
| "data": datetime.now().strftime("%d/%m/%Y %H:%M"), | |
| "nome": nome_trilha.strip(), | |
| "nivel": nivel, | |
| "area": area, | |
| "duracao": duracao, | |
| "transcricao": transcricao, | |
| "analise": analise | |
| }) | |
| return (transcricao, analise, self._formatar_historico(), "✅ Trilha gerada com sucesso!") | |
| except Exception as e: | |
| logging.error(f"Processing error: {str(e)}") | |
| return ("", "", self._formatar_historico(), f"❌ Erro: {str(e)}") | |
| # Core change needed in _gerar_trilha_personalizada method: | |
| def _gerar_trilha_personalizada(self, transcricao: str, nivel: str, area: str, duracao: str) -> str: | |
| try: | |
| palavras_chave = self._extrair_palavras_chave(transcricao) | |
| modulos = self._get_modulos_por_area(area, nivel) | |
| duracao_meses = int(duracao.split()[0]) | |
| tempo_por_modulo = duracao_meses / len(modulos) | |
| # Generate customized content using the model | |
| prompt = f""" | |
| Gere uma trilha de aprendizado para a área de {area} (nível {nivel}), duração de {duracao}. | |
| Objetivos do usuário: {transcricao} | |
| Palavras-chave identificadas: {', '.join(palavras_chave)} | |
| """ | |
| generated_content = self.generator( | |
| prompt, | |
| max_length=500, | |
| num_return_sequences=1, | |
| temperature=0.7 | |
| )[0]['generated_text'] | |
| # Combine generated content with structured data | |
| return f""" | |
| 🎯 Objetivos Identificados: | |
| {self._formatar_objetivos(palavras_chave, area)} | |
| 📚 Trilha Personalizada para {area.title()} - Nível {nivel}: | |
| {generated_content} | |
| {self._formatar_modulos(modulos, tempo_por_modulo)} | |
| 🚀 Projetos Práticos Sugeridos: | |
| {self._gerar_projetos(area, nivel)} | |
| 📅 Cronograma ({duracao}): | |
| {self._gerar_cronograma(duracao_meses, modulos)} | |
| 🎖️ Marcos de Avaliação: | |
| {self._gerar_marcos_avaliacao(nivel)} | |
| """ | |
| except Exception as e: | |
| logging.error(f"Error generating learning path: {str(e)}") | |
| return "Erro ao gerar trilha de aprendizado" | |
| def _extrair_palavras_chave(self, texto: str) -> List[str]: | |
| try: | |
| tokens = word_tokenize(texto.lower()) | |
| palavras = [palavra for palavra in tokens | |
| if palavra.isalnum() and | |
| len(palavra) > 2 and | |
| palavra not in self.stop_words] | |
| return [palavra[0] for palavra in Counter(palavras).most_common(5)] | |
| except Exception as e: | |
| logging.error(f"Keyword extraction error: {str(e)}") | |
| return ["erro ao extrair palavras-chave"] | |
| def _get_modulos_por_area(self, area: str, nivel: str) -> List[str]: | |
| modulos = { | |
| "programação": { | |
| "iniciante": [ | |
| "Lógica de Programação Básica", | |
| "Introdução a Algoritmos", | |
| "Fundamentos de HTML/CSS", | |
| "JavaScript Básico" | |
| ], | |
| "intermediário": [ | |
| "Estruturas de Dados", | |
| "Programação Orientada a Objetos", | |
| "Frameworks Front-end", | |
| "Banco de Dados" | |
| ], | |
| "avançado": [ | |
| "Arquitetura de Software", | |
| "DevOps e CI/CD", | |
| "Microsserviços", | |
| "Segurança e Performance" | |
| ] | |
| }, | |
| "data science": { | |
| "iniciante": [ | |
| "Estatística Básica", | |
| "Python para Análise de Dados", | |
| "SQL Fundamental", | |
| "Visualização de Dados" | |
| ], | |
| "intermediário": [ | |
| "Machine Learning Básico", | |
| "Deep Learning Fundamentos", | |
| "Big Data Analytics", | |
| "Feature Engineering" | |
| ], | |
| "avançado": [ | |
| "MLOps", | |
| "Análise Avançada", | |
| "IA Generativa", | |
| "Pesquisa Aplicada" | |
| ] | |
| }, | |
| "design": { | |
| "iniciante": [ | |
| "Teoria das Cores", | |
| "Tipografia", | |
| "UI Básica", | |
| "Ferramentas de Design" | |
| ], | |
| "intermediário": [ | |
| "Design Systems", | |
| "UX Research", | |
| "Prototipagem", | |
| "Design Visual" | |
| ], | |
| "avançado": [ | |
| "Design Leadership", | |
| "Design Estratégico", | |
| "Design para Produto", | |
| "Design Thinking Avançado" | |
| ] | |
| } | |
| } | |
| if area not in modulos: | |
| return [ | |
| "Fundamentos da Área", | |
| "Conceitos Intermediários", | |
| "Práticas Avançadas", | |
| "Especialização" | |
| ] | |
| return modulos[area].get(nivel, modulos[area]["intermediário"]) | |
| def _formatar_objetivos(self, palavras_chave: List[str], area: str) -> str: | |
| objetivos = { | |
| "programação": [ | |
| "Desenvolver habilidades técnicas em {}", | |
| "Criar projetos práticos usando {}", | |
| "Dominar conceitos de {}" | |
| ], | |
| "data science": [ | |
| "Analisar dados usando {}", | |
| "Construir modelos de {}", | |
| "Implementar soluções com {}" | |
| ], | |
| "design": [ | |
| "Criar interfaces usando {}", | |
| "Desenvolver projetos de {}", | |
| "Aplicar princípios de {}" | |
| ] | |
| } | |
| templates = objetivos.get(area, objetivos["programação"]) | |
| return "\n".join( | |
| f"• {template.format(palavra)}" | |
| for palavra, template in zip(palavras_chave[:3], templates) | |
| ) | |
| def _formatar_modulos(self, modulos: List[str], tempo: float) -> str: | |
| return "\n".join( | |
| f"Módulo {i+1}: {modulo} ({tempo:.1f} meses)" | |
| for i, modulo in enumerate(modulos) | |
| ) | |
| def _gerar_projetos(self, area: str, nivel: str) -> str: | |
| projetos = { | |
| "iniciante": [ | |
| "Projeto Tutorial Guiado", | |
| "Mini-Projeto Prático", | |
| "Exercícios Fundamentais" | |
| ], | |
| "intermediário": [ | |
| "Projeto Individual", | |
| "Projeto em Equipe", | |
| "Case Study Prático" | |
| ], | |
| "avançado": [ | |
| "Projeto Complexo", | |
| "Contribuição Open Source", | |
| "Projeto de Pesquisa" | |
| ] | |
| } | |
| return "\n".join(f"• {projeto}" for projeto in projetos.get(nivel, projetos["intermediário"])) | |
| def _gerar_cronograma(self, duracao: int, modulos: List[str]) -> str: | |
| meses_por_modulo = duracao / len(modulos) | |
| return "\n".join( | |
| f"Mês {i*meses_por_modulo+1:.1f}-{(i+1)*meses_por_modulo:.1f}: {modulo}" | |
| for i, modulo in enumerate(modulos) | |
| ) | |
| def _gerar_marcos_avaliacao(self, nivel: str) -> str: | |
| marcos = { | |
| "iniciante": [ | |
| "Quiz de Conceitos Básicos", | |
| "Exercícios Práticos", | |
| "Projeto Final Básico" | |
| ], | |
| "intermediário": [ | |
| "Avaliação Técnica", | |
| "Projeto Individual", | |
| "Apresentação de Resultados" | |
| ], | |
| "avançado": [ | |
| "Defesa de Projeto", | |
| "Contribuição Técnica", | |
| "Artigo/Publicação" | |
| ] | |
| } | |
| return "\n".join(f"• {marco}" for marco in marcos.get(nivel, marcos["intermediário"])) | |
| def _gerar_recursos(self, nivel: str, area: str, objetivo: str) -> str: | |
| recursos = { | |
| "iniciante": { | |
| "cursos": ["Fundamentos Básicos", "Introdução Prática"], | |
| "livros": ["Guia do Iniciante", "Primeiros Passos"], | |
| "projetos": ["Projeto inicial guiado", "Mini-projetos práticos"] | |
| }, | |
| "intermediário": { | |
| "cursos": ["Especialização Prática", "Técnicas Avançadas"], | |
| "livros": ["Guia Completo", "Estudos de Caso"], | |
| "projetos": ["Projetos médios", "Desafios práticos"] | |
| }, | |
| "avançado": { | |
| "cursos": ["Masterclass", "Especialização Pro"], | |
| "livros": ["Técnicas Avançadas", "Estado da Arte"], | |
| "projetos": ["Projetos complexos", "Open-source"] | |
| } | |
| } | |
| r = recursos.get(nivel, recursos["intermediário"]) | |
| return f""" | |
| 📚 Recursos Recomendados: | |
| 1. Cursos: | |
| - {r['cursos'][0]} | |
| - {r['cursos'][1]} | |
| 2. Material: | |
| - {r['livros'][0]} | |
| - {r['livros'][1]} | |
| 3. Projetos: | |
| - {r['projetos'][0]} | |
| - {r['projetos'][1]} | |
| 4. Extras: | |
| - Comunidades de prática | |
| - Mentoria entre pares | |
| - Workshops práticos | |
| - Avaliações periódicas | |
| """ | |
| def _formatar_historico(self) -> str: | |
| if not self.historico: | |
| return "Nenhuma trilha gerada ainda" | |
| return "📋 Histórico de Trilhas:\n\n" + "\n".join( | |
| f"• {h['data']} - {h['nome']} ({h['nivel']}, {h['area']})" | |
| for h in self.historico[-5:] | |
| ) | |
| def criar_interface() -> gr.Blocks: | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.Markdown(""" | |
| # 🎓 Gerador de Trilha de Aprendizado | |
| Grave ou faça upload de um áudio descrevendo seus objetivos e receba uma trilha personalizada! | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| audio_input = gr.Audio( | |
| type="filepath", | |
| label="Áudio", | |
| sources=["microphone", "upload"] | |
| ) | |
| nome_trilha = gr.Textbox( | |
| label="Nome da Trilha", | |
| placeholder="Dê um nome para sua trilha", | |
| value="" | |
| ) | |
| nivel = gr.Dropdown( | |
| choices=["iniciante", "intermediário", "avançado"], | |
| value="intermediário", | |
| label="Nível de Dificuldade" | |
| ) | |
| area = gr.Dropdown( | |
| choices=["programação", "data science", "design", "marketing", "negócios", "geral"], | |
| value="geral", | |
| label="Área de Conhecimento" | |
| ) | |
| duracao = gr.Dropdown( | |
| choices=["1 mês", "3 meses", "6 meses", "1 ano"], | |
| value="3 meses", | |
| label="Duração Estimada" | |
| ) | |
| incluir_recursos = gr.Checkbox( | |
| label="Incluir Recursos Recomendados", | |
| value=True | |
| ) | |
| processar_btn = gr.Button("🚀 Gerar Trilha de Aprendizado") | |
| with gr.Row(): | |
| with gr.Column(): | |
| status = gr.Markdown() | |
| transcricao = gr.Textbox(label="Transcrição do Áudio", lines=4) | |
| analise = gr.Textbox(label="Sua Trilha de Aprendizado", lines=10) | |
| historico = gr.Markdown() | |
| with gr.Accordion("ℹ️ Como usar"): | |
| gr.Markdown(""" | |
| 1. Grave um áudio descrevendo seus objetivos de aprendizado | |
| 2. Escolha o nome da trilha, nível, área e duração | |
| 3. Clique em 'Gerar Trilha de Aprendizado' | |
| 4. Revise a transcrição e a trilha gerada | |
| 5. O histórico mostra suas últimas 5 trilhas geradas | |
| """) | |
| gerador = GeradorTrilhaAprendizado() | |
| processar_btn.click( | |
| fn=gerador.processar_audio, | |
| inputs=[audio_input, nome_trilha, nivel, area, duracao, incluir_recursos], | |
| outputs=[transcricao, analise, historico, status] | |
| ) | |
| return app | |
| if __name__ == "__main__": | |
| logging.basicConfig(level=logging.INFO) | |
| app = criar_interface() | |
| app.queue() | |
| app.launch() |