Spaces:
Sleeping
Sleeping
| """ | |
| generate_flash_cards.py | |
| ----------------------- | |
| Tool for generating educational flash cards for medical topics. | |
| This tool creates flash card style educational content to help with memorization and | |
| quick review of key medical concepts, facts, and clinical pearls. | |
| Key Features: | |
| - Creates front/back flash card format | |
| - Generates multiple cards per topic | |
| - Includes mnemonics and memory aids | |
| - Covers key facts, clinical pearls, and high-yield information | |
| - Organizes cards by difficulty and subtopic | |
| """ | |
| import asyncio | |
| from typing import Any, Dict, List, Union | |
| from tools.base import Tool | |
| from tools.utils import ToolExecutionError, logger | |
| class GenerateFlashCardsTool(Tool): | |
| """ | |
| Tool for generating educational flash cards for medical topics. | |
| This tool creates flash card style educational content to help with memorization | |
| and quick review of key medical concepts. | |
| """ | |
| def __init__(self) -> None: | |
| """Initialize the GenerateFlashCardsTool.""" | |
| super().__init__() | |
| self.name = "generate_flash_cards" | |
| self.description = "Generate educational flash cards for medical topics to aid memorization and quick review." | |
| self.args_schema = { | |
| "type": "object", | |
| "properties": { | |
| "topic": { | |
| "type": "string", | |
| "description": "The medical topic to create flash cards about (e.g., 'hypertension', 'diabetes medications', 'heart murmurs')" | |
| }, | |
| "number_of_cards": { | |
| "type": "integer", | |
| "description": "Number of flash cards to generate (default: 10)", | |
| "default": 10, | |
| "minimum": 5, | |
| "maximum": 20 | |
| }, | |
| "card_type": { | |
| "type": "string", | |
| "description": "Type of flash cards to generate", | |
| "enum": ["basic_facts", "clinical_pearls", "mnemonics", "differential_diagnosis", "medications", "mixed"], | |
| "default": "mixed" | |
| }, | |
| "difficulty_level": { | |
| "type": "string", | |
| "description": "Difficulty level for the cards", | |
| "enum": ["medical_student", "resident", "board_review", "advanced"], | |
| "default": "medical_student" | |
| } | |
| }, | |
| "required": ["topic"] | |
| } | |
| def openai_spec(self, legacy=False): | |
| """Return OpenAI function specification.""" | |
| return { | |
| "name": self.name, | |
| "description": self.description, | |
| "parameters": self.args_schema | |
| } | |
| async def run( | |
| self, | |
| topic: str, | |
| number_of_cards: int = 10, | |
| card_type: str = "mixed", | |
| difficulty_level: str = "medical_student" | |
| ) -> Dict[str, Any]: | |
| """ | |
| Generate educational flash cards for a medical topic. | |
| Args: | |
| topic (str): The medical topic to create flash cards about | |
| number_of_cards (int): Number of flash cards to generate | |
| card_type (str): Type of flash cards (basic_facts, clinical_pearls, mnemonics, etc.) | |
| difficulty_level (str): Difficulty level for the cards | |
| Returns: | |
| Dict[str, Any]: Complete flash card set with organized cards | |
| """ | |
| try: | |
| logger.info(f"Generating {number_of_cards} flash cards for topic: {topic}") | |
| # Generate flash cards | |
| flash_cards = self._generate_flash_cards(topic, number_of_cards, card_type, difficulty_level) | |
| # Organize cards by subtopic | |
| organized_cards = self._organize_cards_by_subtopic(flash_cards, topic) | |
| # Generate study tips and usage instructions | |
| study_tips = self._generate_study_tips(topic, card_type) | |
| # Create the complete flash card set | |
| flash_card_set = { | |
| "topic": topic, | |
| "card_type": card_type, | |
| "difficulty_level": difficulty_level, | |
| "total_cards": len(flash_cards), | |
| "flash_cards": flash_cards, | |
| "organized_by_subtopic": organized_cards, | |
| "study_tips": study_tips, | |
| "review_schedule": self._generate_review_schedule(), | |
| "created_date": "2025-07-18" | |
| } | |
| logger.info(f"Successfully generated {len(flash_cards)} flash cards for {topic}") | |
| return flash_card_set | |
| except Exception as e: | |
| logger.error(f"GenerateFlashCardsTool failed: {e}", exc_info=True) | |
| raise ToolExecutionError(f"Failed to generate flash cards: {e}") | |
| def _generate_flash_cards(self, topic: str, number_of_cards: int, card_type: str, difficulty_level: str) -> List[Dict[str, Any]]: | |
| """Generate individual flash cards.""" | |
| flash_cards = [] | |
| # Define card templates based on topic and type | |
| card_templates = self._get_card_templates(topic, card_type, difficulty_level) | |
| # Generate cards using templates | |
| for i in range(number_of_cards): | |
| if i < len(card_templates): | |
| card = card_templates[i] | |
| else: | |
| # Generate additional cards if needed | |
| card = self._generate_additional_card(topic, card_type, difficulty_level, i) | |
| flash_cards.append(card) | |
| return flash_cards | |
| def _get_card_templates(self, topic: str, card_type: str, difficulty_level: str) -> List[Dict[str, Any]]: | |
| """Get predefined card templates for common topics.""" | |
| templates = { | |
| "hypertension": [ | |
| { | |
| "card_id": 1, | |
| "subtopic": "Definition", | |
| "front": "What is the definition of hypertension?", | |
| "back": "Blood pressure ≥140/90 mmHg on two separate occasions, or ≥130/80 mmHg for patients with diabetes or chronic kidney disease.", | |
| "memory_aid": "Remember: 140/90 for general population, 130/80 for high-risk groups", | |
| "difficulty": "basic" | |
| }, | |
| { | |
| "card_id": 2, | |
| "subtopic": "Classification", | |
| "front": "What are the stages of hypertension according to AHA/ACC guidelines?", | |
| "back": "Normal: <120/80\nElevated: 120-129/<80\nStage 1: 130-139/80-89\nStage 2: ≥140/90\nCrisis: >180/120", | |
| "memory_aid": "Mnemonic: Never Ever Stop Managing Crises (Normal, Elevated, Stage 1, Stage 2, Crisis)", | |
| "difficulty": "basic" | |
| }, | |
| { | |
| "card_id": 3, | |
| "subtopic": "First-line medications", | |
| "front": "What are the first-line medications for hypertension?", | |
| "back": "ACE inhibitors, ARBs, Calcium channel blockers, Thiazide diuretics", | |
| "memory_aid": "Mnemonic: ACCT (ACE, ARB, CCB, Thiazide) - ACCounT for first-line HTN meds", | |
| "difficulty": "basic" | |
| }, | |
| { | |
| "card_id": 4, | |
| "subtopic": "Complications", | |
| "front": "What are the major complications of untreated hypertension?", | |
| "back": "Stroke, Heart attack, Heart failure, Kidney disease, Vision loss, Peripheral artery disease", | |
| "memory_aid": "Mnemonic: SHOCKS (Stroke, Heart attack, Heart failure, Kidney disease, Vision loss, PAD)", | |
| "difficulty": "intermediate" | |
| } | |
| ], | |
| "diabetes": [ | |
| { | |
| "card_id": 1, | |
| "subtopic": "Diagnosis", | |
| "front": "What are the diagnostic criteria for diabetes mellitus?", | |
| "back": "Fasting glucose ≥126 mg/dL OR Random glucose ≥200 mg/dL + symptoms OR HbA1c ≥6.5% OR 2-hour OGTT ≥200 mg/dL", | |
| "memory_aid": "Remember: 126 fasting, 200 random, 6.5% A1c, 200 OGTT", | |
| "difficulty": "basic" | |
| }, | |
| { | |
| "card_id": 2, | |
| "subtopic": "HbA1c targets", | |
| "front": "What is the HbA1c target for most adults with diabetes?", | |
| "back": "<7% for most adults. <6.5% for selected patients if achievable without hypoglycemia. <8% for patients with limited life expectancy or high risk of hypoglycemia.", | |
| "memory_aid": "Lucky 7: <7% for most, adjust based on individual factors", | |
| "difficulty": "basic" | |
| } | |
| ] | |
| } | |
| # Return templates for the topic or generate generic ones | |
| if topic.lower() in templates: | |
| return templates[topic.lower()] | |
| else: | |
| return self._generate_generic_templates(topic, card_type, difficulty_level) | |
| def _generate_generic_templates(self, topic: str, card_type: str, difficulty_level: str) -> List[Dict[str, Any]]: | |
| """Generate generic card templates for any topic.""" | |
| generic_templates = [ | |
| { | |
| "card_id": 1, | |
| "subtopic": "Definition", | |
| "front": f"What is {topic}?", | |
| "back": f"[Definition and key characteristics of {topic}]", | |
| "memory_aid": f"Key concept: {topic}", | |
| "difficulty": "basic" | |
| }, | |
| { | |
| "card_id": 2, | |
| "subtopic": "Clinical Presentation", | |
| "front": f"What are the main signs and symptoms of {topic}?", | |
| "back": f"[List of key clinical features of {topic}]", | |
| "memory_aid": f"Clinical pearl for {topic}", | |
| "difficulty": "basic" | |
| }, | |
| { | |
| "card_id": 3, | |
| "subtopic": "Diagnosis", | |
| "front": f"How is {topic} diagnosed?", | |
| "back": f"[Diagnostic criteria and tests for {topic}]", | |
| "memory_aid": f"Diagnostic approach for {topic}", | |
| "difficulty": "intermediate" | |
| }, | |
| { | |
| "card_id": 4, | |
| "subtopic": "Treatment", | |
| "front": f"What is the treatment for {topic}?", | |
| "back": f"[Treatment options and management for {topic}]", | |
| "memory_aid": f"Treatment strategy for {topic}", | |
| "difficulty": "intermediate" | |
| }, | |
| { | |
| "card_id": 5, | |
| "subtopic": "Complications", | |
| "front": f"What are the complications of {topic}?", | |
| "back": f"[Potential complications and monitoring for {topic}]", | |
| "memory_aid": f"Watch for complications of {topic}", | |
| "difficulty": "advanced" | |
| } | |
| ] | |
| return generic_templates | |
| def _generate_additional_card(self, topic: str, card_type: str, difficulty_level: str, card_number: int) -> Dict[str, Any]: | |
| """Generate additional cards when more are needed.""" | |
| additional_subtopics = [ | |
| "Pathophysiology", "Epidemiology", "Risk factors", "Differential diagnosis", | |
| "Prognosis", "Prevention", "Monitoring", "Patient education", "Guidelines" | |
| ] | |
| subtopic_index = (card_number - 5) % len(additional_subtopics) | |
| subtopic = additional_subtopics[subtopic_index] | |
| return { | |
| "card_id": card_number + 1, | |
| "subtopic": subtopic, | |
| "front": f"What should you know about {subtopic.lower()} of {topic}?", | |
| "back": f"[Key information about {subtopic.lower()} related to {topic}]", | |
| "memory_aid": f"Clinical pearl: {subtopic} in {topic}", | |
| "difficulty": "intermediate" | |
| } | |
| def _organize_cards_by_subtopic(self, flash_cards: List[Dict], topic: str) -> Dict[str, List[Dict]]: | |
| """Organize cards by subtopic for structured learning.""" | |
| organized = {} | |
| for card in flash_cards: | |
| subtopic = card.get("subtopic", "General") | |
| if subtopic not in organized: | |
| organized[subtopic] = [] | |
| organized[subtopic].append(card) | |
| return organized | |
| def _generate_study_tips(self, topic: str, card_type: str) -> List[str]: | |
| """Generate study tips for using the flash cards effectively.""" | |
| tips = [ | |
| "Review cards daily for optimal retention", | |
| "Use spaced repetition - review difficult cards more frequently", | |
| "Study the memory aids and mnemonics separately", | |
| "Test yourself by covering the back of the card first", | |
| "Create your own examples for each concept", | |
| "Review in both directions (front-to-back and back-to-front)", | |
| "Focus on understanding, not just memorization", | |
| "Connect concepts to real patient cases when possible" | |
| ] | |
| if card_type == "mnemonics": | |
| tips.append("Practice writing out the mnemonics from memory") | |
| elif card_type == "clinical_pearls": | |
| tips.append("Think of patient scenarios where each pearl would apply") | |
| return tips | |
| def _generate_review_schedule(self) -> Dict[str, str]: | |
| """Generate a spaced repetition review schedule.""" | |
| schedule = { | |
| "Day 1": "Initial learning - review all cards", | |
| "Day 2": "Review all cards again", | |
| "Day 4": "Review cards you found difficult", | |
| "Day 7": "Review entire set", | |
| "Day 14": "Review difficult cards only", | |
| "Day 30": "Complete review of all cards", | |
| "Day 60": "Final review and assessment" | |
| } | |
| return schedule | |