Contributing Guide.md - himent12/FlashGenie GitHub Wiki

๐Ÿค Contributing to FlashGenie

Welcome to the FlashGenie community! We're excited that you want to contribute to making FlashGenie the best intelligent flashcard application. This guide will help you get started with contributing to the project.

๐ŸŽฏ Quick Start

Prerequisites

  • Python 3.8+ installed on your system
  • Git for version control
  • GitHub account for submitting contributions
  • Basic knowledge of Python and object-oriented programming

Development Environment Setup

  1. Fork the Repository

    # Fork the repository on GitHub, then clone your fork
    git clone https://github.com/yourusername/FlashGenie.git
    cd FlashGenie
    
  2. Set Up Virtual Environment

    # Create virtual environment
    python -m venv venv
    
    # Activate virtual environment
    # On Windows:
    venv\Scripts\activate
    # On macOS/Linux:
    source venv/bin/activate
    
  3. Install Dependencies

    # Install runtime dependencies
    pip install -r requirements.txt
    
    # Install development dependencies
    pip install -r dev-requirements.txt
    
    # Install in development mode
    pip install -e .
    
  4. Verify Installation

    # Run FlashGenie to verify installation
    python -m flashgenie --version
    
    # Run tests to ensure everything works
    python -m pytest tests/
    

๐Ÿ—๏ธ Project Structure

Understanding the project structure will help you navigate and contribute effectively:

FlashGenie/
โ”œโ”€โ”€ flashgenie/           # Main application package
โ”‚   โ”œโ”€โ”€ core/            # Core business logic
โ”‚   โ”œโ”€โ”€ data/            # Data management
โ”‚   โ”œโ”€โ”€ interfaces/      # User interfaces
โ”‚   โ””โ”€โ”€ utils/           # Utility functions
โ”œโ”€โ”€ tests/               # Test suite
โ”œโ”€โ”€ docs/                # Documentation
โ”œโ”€โ”€ assets/              # Sample data and resources
โ””โ”€โ”€ scripts/             # Development scripts

Key Modules

  • flashgenie/core/: Contains the core algorithms and data models
  • flashgenie/data/: Handles data persistence, import/export
  • flashgenie/interfaces/: User interface components (CLI, future GUI)
  • flashgenie/utils/: Shared utilities and helper functions

๐Ÿ”„ Development Workflow

1. Choose an Issue

  • Browse open issues
  • Look for issues labeled good-first-issue for beginners
  • Comment on the issue to let others know you're working on it

2. Create a Feature Branch

# Create and switch to a new branch
git checkout -b feature/your-feature-name

# Or for bug fixes:
git checkout -b fix/bug-description

3. Make Your Changes

  • Write clean, readable code following our coding standards
  • Add tests for new functionality
  • Update documentation as needed
  • Commit your changes with clear messages

4. Test Your Changes

# Run the full test suite
python -m pytest tests/

# Run specific tests
python -m pytest tests/test_flashcard.py

# Run with coverage
python -m pytest tests/ --cov=flashgenie --cov-report=html

5. Submit a Pull Request

# Push your branch to your fork
git push origin feature/your-feature-name

# Create a pull request on GitHub
# Include a clear description of your changes

๐Ÿ“ Coding Standards

Python Style Guide

We follow PEP 8 with some project-specific conventions:

Code Formatting

# Format code with black
black flashgenie/ tests/

# Check with flake8
flake8 flashgenie/ tests/

# Type checking with mypy
mypy flashgenie/

Naming Conventions

  • Classes: PascalCase (e.g., FlashCard, QuizEngine)
  • Functions/Variables: snake_case (e.g., get_next_card, user_answer)
  • Constants: UPPER_CASE (e.g., MAX_DIFFICULTY, DEFAULT_CONFIG)
  • Private methods: _leading_underscore (e.g., _calculate_score)

Documentation

  • All public classes and methods must have docstrings
  • Use Google-style docstrings
  • Include type hints for all function parameters and return values
def calculate_difficulty(card: Flashcard, responses: List[Dict[str, Any]]) -> float:
    """
    Calculate the difficulty adjustment for a flashcard.
    
    Args:
        card: The flashcard to analyze
        responses: List of user responses with timing and correctness data
        
    Returns:
        New difficulty value between 0.1 and 5.0
        
    Raises:
        ValueError: If responses list is empty
    """
    pass

Code Quality Checklist

Before submitting your code, ensure:

  • Code is formatted with black
  • No linting errors from flake8
  • Type hints are present for all public methods
  • Docstrings are written for all public classes and methods
  • Tests are written for new functionality
  • Tests pass locally
  • Documentation is updated if needed

๐Ÿงช Testing Guidelines

Test Structure

tests/
โ”œโ”€โ”€ unit/                # Unit tests for individual components
โ”‚   โ”œโ”€โ”€ test_flashcard.py
โ”‚   โ”œโ”€โ”€ test_deck.py
โ”‚   โ””โ”€โ”€ test_quiz_engine.py
โ”œโ”€โ”€ integration/         # Integration tests
โ”‚   โ”œโ”€โ”€ test_data_flow.py
โ”‚   โ””โ”€โ”€ test_quiz_session.py
โ””โ”€โ”€ fixtures/            # Test data and fixtures
    โ”œโ”€โ”€ sample_decks.json
    โ””โ”€โ”€ test_cards.csv

Writing Tests

Unit Tests

import pytest
from flashgenie.core.flashcard import Flashcard

class TestFlashcard:
    def test_create_flashcard(self):
        """Test basic flashcard creation."""
        card = Flashcard("What is Python?", "A programming language")
        assert card.question == "What is Python?"
        assert card.answer == "A programming language"
        assert card.difficulty == 1.0  # default
    
    def test_add_tag(self):
        """Test adding tags to flashcard."""
        card = Flashcard("Test question", "Test answer")
        card.add_tag("programming")
        assert "programming" in card.tags
    
    @pytest.mark.parametrize("difficulty,expected", [
        (0.5, 0.5),
        (3.0, 3.0),
        (6.0, 5.0),  # Should be clamped to max
        (-1.0, 0.1)  # Should be clamped to min
    ])
    def test_difficulty_clamping(self, difficulty, expected):
        """Test difficulty value clamping."""
        card = Flashcard("Test", "Test")
        card.update_difficulty(difficulty)
        assert card.difficulty == expected

Integration Tests

def test_quiz_session_flow():
    """Test complete quiz session workflow."""
    # Create test data
    cards = [
        Flashcard("Q1", "A1"),
        Flashcard("Q2", "A2")
    ]
    deck = Deck("Test Deck", flashcards=cards)
    
    # Start quiz session
    quiz_engine = QuizEngine()
    session = quiz_engine.start_session(deck)
    
    # Simulate quiz interaction
    card = session.get_next_card()
    assert card is not None
    
    result = session.submit_answer("A1")
    assert result is True
    
    # End session and check results
    summary = session.end_session()
    assert summary['total_questions'] == 1
    assert summary['correct_answers'] == 1

Running Tests

# Run all tests
python -m pytest

# Run specific test file
python -m pytest tests/unit/test_flashcard.py

# Run with verbose output
python -m pytest -v

# Run with coverage report
python -m pytest --cov=flashgenie --cov-report=html

# Run only fast tests (skip slow integration tests)
python -m pytest -m "not slow"

๐Ÿ“š Documentation

Types of Documentation

  1. Code Documentation: Docstrings and inline comments
  2. API Documentation: Technical reference (auto-generated)
  3. User Documentation: Guides and tutorials
  4. Developer Documentation: Architecture and contribution guides

Writing Documentation

Docstrings

Use Google-style docstrings:

def complex_function(param1: str, param2: int = 10) -> Dict[str, Any]:
    """
    Brief description of what the function does.
    
    Longer description if needed, explaining the purpose,
    algorithm, or important details.
    
    Args:
        param1: Description of the first parameter
        param2: Description of the second parameter with default value
        
    Returns:
        Description of the return value and its structure
        
    Raises:
        ValueError: When param1 is empty
        TypeError: When param2 is not an integer
        
    Example:
        >>> result = complex_function("test", 20)
        >>> print(result['status'])
        'success'
    """
    pass

Markdown Documentation

  • Use clear headings and structure
  • Include code examples
  • Add links to related documentation
  • Keep language clear and concise

Building Documentation

# Install documentation dependencies
pip install -r docs-requirements.txt

# Serve documentation locally
mkdocs serve

# Build documentation
mkdocs build

๐Ÿ› Bug Reports

Before Reporting a Bug

  1. Search existing issues to avoid duplicates
  2. Try the latest version to see if it's already fixed
  3. Gather information about your environment

Bug Report Template

**Bug Description**
A clear description of what the bug is.

**Steps to Reproduce**
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected Behavior**
What you expected to happen.

**Actual Behavior**
What actually happened.

**Environment**
- OS: [e.g. Windows 10, macOS 12.0, Ubuntu 20.04]
- Python Version: [e.g. 3.9.7]
- FlashGenie Version: [e.g. 1.5.0]

**Additional Context**
Any other context about the problem.

๐Ÿ’ก Feature Requests

Before Requesting a Feature

  1. Check existing issues and discussions
  2. Consider the scope - does it fit FlashGenie's goals?
  3. Think about implementation - is it technically feasible?

Feature Request Template

**Feature Description**
A clear description of the feature you'd like to see.

**Problem Statement**
What problem does this feature solve?

**Proposed Solution**
How do you envision this feature working?

**Alternatives Considered**
Other solutions you've considered.

**Additional Context**
Any other context, mockups, or examples.

๐Ÿ† Recognition

Contributors are recognized in several ways:

  • Contributors file: Listed in CONTRIBUTORS.md
  • Release notes: Mentioned in changelog for significant contributions
  • GitHub: Contributor statistics and commit history
  • Community: Recognition in discussions and social media

๐Ÿ“ž Getting Help

Communication Channels

  • GitHub Issues: Bug reports and feature requests
  • GitHub Discussions: General questions and ideas
  • Email: Direct contact for sensitive issues
  • Discord/Slack: Real-time chat (coming soon)

Mentorship

New contributors can get help from experienced maintainers:

  • Comment on issues asking for guidance
  • Join our mentorship program
  • Attend virtual office hours (schedule TBD)

๐ŸŽ‰ Thank You!

Every contribution, no matter how small, makes FlashGenie better for everyone. Whether you're fixing a typo, adding a feature, or helping other users, your efforts are appreciated!

Happy coding! ๐Ÿงžโ€โ™‚๏ธโœจ


For more detailed information, see our Developer Guide and API Reference.