Claude Code Plugins

Community-maintained marketplace

Feedback

autogenerate-formulas

@foolishimp/ai_sdlc_method
0
0

Autogenerate formula implementations from formula specifications (F-*). Converts mathematical formulas, calculations, and algorithms into production code with tests. Use when F-* includes formula specifications.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name autogenerate-formulas
description Autogenerate formula implementations from formula specifications (F-*). Converts mathematical formulas, calculations, and algorithms into production code with tests. Use when F-* includes formula specifications.
allowed-tools Read, Write, Edit

autogenerate-formulas

Skill Type: Actuator (Code Generation) Purpose: Generate formula implementations from F-* specifications Prerequisites:

  • Formula specifications (F-*) with mathematical definitions

Agent Instructions

You are autogenerating formulas from formula specifications.

Your goal is to transform structured F- formulas* into calculation functions with tests.


Generation Patterns

Pattern 1: Simple Arithmetic Formulas

Input:

F-001: Stripe fee calculation
  Formula: fee = (amount * 0.029) + 0.30
  Inputs: amount (float)
  Output: fee (float, rounded to 2 decimals)

Generated:

# Generated from: F-001
STRIPE_PERCENTAGE_FEE = 0.029  # 2.9%
STRIPE_FIXED_FEE = 0.30        # $0.30

def calculate_stripe_fee(amount: float) -> float:
    """
    Calculate Stripe processing fee.

    Generated from: F-001 (Stripe fee calculation)

    Formula: fee = (amount * 0.029) + 0.30

    Args:
        amount: Payment amount in dollars

    Returns:
        Processing fee in dollars (rounded to 2 decimals)

    Examples:
        >>> calculate_stripe_fee(100.00)
        3.20
        >>> calculate_stripe_fee(1000.00)
        29.30
    """
    # Implements: F-001
    fee = (amount * STRIPE_PERCENTAGE_FEE) + STRIPE_FIXED_FEE
    return round(fee, 2)

# Generated tests
def test_calculate_stripe_fee_100_dollars():
    assert calculate_stripe_fee(100.00) == 3.20

def test_calculate_stripe_fee_1000_dollars():
    assert calculate_stripe_fee(1000.00) == 29.30

def test_calculate_stripe_fee_minimum_charge():
    # For $0.01, fee is still $0.30 fixed + 0.0003% ≈ $0.30
    assert calculate_stripe_fee(0.01) == 0.30

Pattern 2: Date/Time Calculations

Input:

F-002: Password reset token expiry
  Formula: expiry_time = issue_time + (60 * 60) seconds
  Inputs: issue_time (datetime)
  Output: expiry_time (datetime)

Generated:

# Generated from: F-002
from datetime import datetime, timedelta

TOKEN_EXPIRY_SECONDS = 60 * 60  # 1 hour

def calculate_token_expiry(issue_time: datetime) -> datetime:
    """
    Calculate password reset token expiry time.

    Generated from: F-002 (Token expiry calculation)

    Formula: expiry_time = issue_time + 3600 seconds

    Args:
        issue_time: When token was issued

    Returns:
        Expiry time (1 hour after issue)

    Examples:
        >>> issue = datetime(2025, 11, 20, 10, 0, 0)
        >>> expiry = calculate_token_expiry(issue)
        >>> expiry
        datetime(2025, 11, 20, 11, 0, 0)
    """
    # Implements: F-002
    return issue_time + timedelta(seconds=TOKEN_EXPIRY_SECONDS)

# Generated tests
def test_token_expiry_one_hour():
    issue = datetime(2025, 11, 20, 10, 0, 0)
    expiry = calculate_token_expiry(issue)
    assert expiry == datetime(2025, 11, 20, 11, 0, 0)

def test_token_expiry_across_day_boundary():
    issue = datetime(2025, 11, 20, 23, 30, 0)
    expiry = calculate_token_expiry(issue)
    assert expiry == datetime(2025, 11, 21, 0, 30, 0)

Pattern 3: Compound Interest / Growth Formulas

Input:

F-010: Compound interest
  Formula: A = P(1 + r/n)^(nt)
  Inputs:
    - P: principal amount
    - r: annual interest rate (decimal)
    - n: compounding frequency (times per year)
    - t: time in years
  Output: A (final amount, rounded to 2 decimals)

Generated:

# Generated from: F-010
import math

def calculate_compound_interest(
    principal: float,
    rate: float,
    compounding_frequency: int,
    years: float
) -> float:
    """
    Calculate compound interest.

    Generated from: F-010 (Compound interest formula)

    Formula: A = P(1 + r/n)^(nt)

    Args:
        principal: Initial principal amount
        rate: Annual interest rate (decimal, e.g., 0.05 for 5%)
        compounding_frequency: Times compounded per year (e.g., 12 for monthly)
        years: Time period in years

    Returns:
        Final amount (rounded to 2 decimals)

    Examples:
        >>> calculate_compound_interest(1000, 0.05, 12, 1)
        1051.16
        >>> calculate_compound_interest(1000, 0.05, 1, 5)
        1276.28
    """
    # Implements: F-010
    amount = principal * math.pow(
        1 + (rate / compounding_frequency),
        compounding_frequency * years
    )
    return round(amount, 2)

# Generated tests
def test_compound_interest_monthly_one_year():
    # $1000 at 5% compounded monthly for 1 year
    result = calculate_compound_interest(1000, 0.05, 12, 1)
    assert result == 1051.16

def test_compound_interest_annually_five_years():
    # $1000 at 5% compounded annually for 5 years
    result = calculate_compound_interest(1000, 0.05, 1, 5)
    assert result == 1276.28

Pattern 4: Percentage Calculations

Input:

F-020: Discount calculation
  Formula: discounted_price = original_price * (1 - discount_percentage)
  Inputs:
    - original_price: float
    - discount_percentage: float (0.0 to 1.0)
  Output: discounted_price (float, rounded to 2 decimals)
  Constraints: discount_percentage must be 0.0 to 1.0

Generated:

# Generated from: F-020
def calculate_discounted_price(original_price: float, discount_percentage: float) -> float:
    """
    Calculate discounted price.

    Generated from: F-020 (Discount calculation)

    Formula: discounted_price = original_price * (1 - discount_percentage)

    Args:
        original_price: Original price before discount
        discount_percentage: Discount as decimal (0.0 to 1.0)

    Returns:
        Discounted price (rounded to 2 decimals)

    Raises:
        ValueError: If discount_percentage not in range [0.0, 1.0]

    Examples:
        >>> calculate_discounted_price(100.00, 0.20)
        80.00
        >>> calculate_discounted_price(50.00, 0.50)
        25.00
    """
    # Implements: F-020
    # Constraint: discount_percentage must be 0.0 to 1.0
    if not 0.0 <= discount_percentage <= 1.0:
        raise ValueError("Discount percentage must be between 0.0 and 1.0")

    discounted = original_price * (1 - discount_percentage)
    return round(discounted, 2)

# Generated tests
def test_discount_20_percent():
    assert calculate_discounted_price(100.00, 0.20) == 80.00

def test_discount_50_percent():
    assert calculate_discounted_price(50.00, 0.50) == 25.00

def test_discount_0_percent():
    assert calculate_discounted_price(100.00, 0.00) == 100.00

def test_discount_100_percent():
    assert calculate_discounted_price(100.00, 1.00) == 0.00

def test_discount_invalid_negative():
    with pytest.raises(ValueError):
        calculate_discounted_price(100.00, -0.10)

def test_discount_invalid_over_100():
    with pytest.raises(ValueError):
        calculate_discounted_price(100.00, 1.50)

Pattern 5: Hash/Checksum Formulas

Input:

F-030: Idempotency key generation
  Formula: key = SHA256(merchant_id + timestamp + amount + card_last4)
  Inputs:
    - merchant_id: string
    - timestamp: int (unix timestamp)
    - amount: float
    - card_last4: string (last 4 digits)
  Output: key (hex string)

Generated:

# Generated from: F-030
import hashlib

def generate_idempotency_key(
    merchant_id: str,
    timestamp: int,
    amount: float,
    card_last4: str
) -> str:
    """
    Generate idempotency key for payment.

    Generated from: F-030 (Idempotency key generation)

    Formula: SHA256(merchant_id + timestamp + amount + card_last4)

    Args:
        merchant_id: Merchant identifier
        timestamp: Unix timestamp
        amount: Payment amount
        card_last4: Last 4 digits of card

    Returns:
        SHA256 hex digest as idempotency key

    Examples:
        >>> key = generate_idempotency_key("merch_123", 1637000000, 100.00, "4242")
        >>> len(key)
        64
    """
    # Implements: F-030
    data = f"{merchant_id}{timestamp}{amount}{card_last4}"
    return hashlib.sha256(data.encode()).hexdigest()

# Generated tests
def test_idempotency_key_deterministic():
    # Same inputs → same key
    key1 = generate_idempotency_key("merch_123", 1637000000, 100.00, "4242")
    key2 = generate_idempotency_key("merch_123", 1637000000, 100.00, "4242")
    assert key1 == key2

def test_idempotency_key_different_timestamp():
    # Different timestamp → different key
    key1 = generate_idempotency_key("merch_123", 1637000000, 100.00, "4242")
    key2 = generate_idempotency_key("merch_123", 1637000001, 100.00, "4242")
    assert key1 != key2

def test_idempotency_key_length():
    key = generate_idempotency_key("merch_123", 1637000000, 100.00, "4242")
    assert len(key) == 64  # SHA256 hex = 64 chars

Pattern 6: Conversion Formulas

Input:

F-040: Temperature conversion
  Formula: celsius = (fahrenheit - 32) * 5/9
  Inputs: fahrenheit (float)
  Output: celsius (float, rounded to 1 decimal)

Generated:

# Generated from: F-040
def fahrenheit_to_celsius(fahrenheit: float) -> float:
    """
    Convert Fahrenheit to Celsius.

    Generated from: F-040 (Temperature conversion)

    Formula: celsius = (fahrenheit - 32) * 5/9

    Args:
        fahrenheit: Temperature in Fahrenheit

    Returns:
        Temperature in Celsius (rounded to 1 decimal)

    Examples:
        >>> fahrenheit_to_celsius(32.0)
        0.0
        >>> fahrenheit_to_celsius(212.0)
        100.0
        >>> fahrenheit_to_celsius(98.6)
        37.0
    """
    # Implements: F-040
    celsius = (fahrenheit - 32) * 5 / 9
    return round(celsius, 1)

# Generated tests
def test_fahrenheit_to_celsius_freezing():
    assert fahrenheit_to_celsius(32.0) == 0.0

def test_fahrenheit_to_celsius_boiling():
    assert fahrenheit_to_celsius(212.0) == 100.0

def test_fahrenheit_to_celsius_body_temp():
    assert fahrenheit_to_celsius(98.6) == 37.0

Test Generation Strategy

For every formula, generate:

  1. Known value tests: Use example values with known results
  2. Boundary tests: Test formula at edges (0, max, min)
  3. Inverse tests: If inverse formula exists, verify f(f_inv(x)) == x
  4. Edge cases: Test with special values (0, negative, very large)

Output Format

[FORMULA GENERATION]

Input: 5 formulas

Generated Formulas:
  ✓ calculate_stripe_fee() from F-001
  ✓ calculate_token_expiry() from F-002
  ✓ generate_idempotency_key() from F-030
  ✓ calculate_compound_interest() from F-010
  ✓ fahrenheit_to_celsius() from F-040

Generated Constants:
  ✓ STRIPE_PERCENTAGE_FEE = 0.029
  ✓ STRIPE_FIXED_FEE = 0.30
  ✓ TOKEN_EXPIRY_SECONDS = 3600

Generated Tests:
  ✓ 20 tests (5 formulas × 4 tests average)

Running tests...
  ✓ All 20 tests PASSING

Files:
  + src/calculations.py (5 formulas, 145 lines)
  + tests/test_calculations.py (20 tests, 127 lines)

Prerequisites Check

Before invoking this skill, ensure:

  1. Formulas (F-*) exist with complete specifications
  2. Formula includes: inputs, formula expression, output format

If F-* too vague:

  • Ask user: "F-001 says 'fee calculation' - what's the formula?"

Notes

Why autogenerate formulas?

  • Accuracy: No manual coding errors in calculations
  • Documentation: Formula is in code + docstring
  • Testability: Generated tests verify formula correctness
  • Consistency: All formulas follow same pattern

Formula complexity handling:

  • Simple formulas (F = ma): Direct translation
  • Complex formulas (compound interest): Use math library
  • Multi-step formulas: Break into helper functions

Homeostasis Goal:

desired_state:
  all_formulas_have_code: true
  all_formula_code_has_tests: true
  all_tests_passing: true
  formulas_documented: true

"Excellence or nothing" 🔥