Claude
Skills
Sign in
Back

parameterization

Included with Lifetime
$97 forever

Master declarative parameter systems with Param for type-safe configuration. Use this skill when building parameterized classes with automatic validation, creating reactive dependencies with @param.depends, implementing watchers for side effects, auto-generating UIs from parameters, or organizing application configuration with hierarchical parameter structures.

General

What this skill does


# Parameterization Skill

## Overview

Master declarative parameter systems with Param and dynamic UI generation. This skill covers building flexible, type-safe, and auto-validated application logic.

## Dependencies

- param >= 2.0.0
- panel >= 1.3.0 (for UI generation)
- numpy >= 1.15.0
- pandas >= 1.0.0

## Core Capabilities

### 1. Parameter Basics

Param provides a framework for parameterized objects with automatic validation:

```python
import param
import numpy as np

class DataProcessor(param.Parameterized):
    # Basic parameters
    name = param.String(default='Processor', doc='Name of processor')
    count = param.Integer(default=10, bounds=(1, 1000), doc='Number of items')
    scale = param.Number(default=1.0, bounds=(0.1, 10.0), doc='Scale factor')

    # String choices
    method = param.Selector(default='mean', objects=['mean', 'median', 'sum'])

    # Boolean flag
    normalize = param.Boolean(default=False)

    # List or array
    tags = param.List(default=[], item_type=str)
    data_array = param.Array(default=np.array([]))

# Instantiate and use
processor = DataProcessor()
print(f"Name: {processor.name}, Count: {processor.count}")

# Validate parameters automatically
processor.count = 500  # OK
processor.count = 2000  # Raises error: out of bounds
```

### 2. Advanced Parameter Types

```python
class AdvancedConfig(param.Parameterized):
    # Date/time parameters
    date = param.Date(default='2024-01-01', doc='Start date')
    time = param.Time(default='12:00', doc='Start time')
    datetime = param.DateTime(default='2024-01-01 12:00:00')

    # File/path parameters
    input_file = param.Path(default=None, doc='Input file path')
    output_dir = param.Fspath(default='.', doc='Output directory')

    # Range parameter
    value_range = param.Range(default=(0, 10), bounds=(0, 100))

    # Color parameter
    color = param.Color(default='#FF0000')

    # JSON/Dict parameter
    config = param.Dict(default={}, per_instance=True)

    # DataFrame parameter
    dataframe = param.Parameter(default=None)
```

### 3. Dynamic Dependencies with @param.depends

```python
class DataAnalyzer(param.Parameterized):
    data_source = param.Selector(
        default='random',
        objects=['random', 'sine', 'exponential']
    )
    amplitude = param.Number(default=1.0, bounds=(0.1, 10.0))
    frequency = param.Number(default=1.0, bounds=(0.1, 10.0))
    size = param.Integer(default=100, bounds=(10, 10000))

    @param.depends('data_source', 'amplitude', 'frequency', 'size')
    def get_data(self):
        """Automatically called when any dependency changes"""
        np.random.seed(42)
        x = np.linspace(0, 2*np.pi, self.size)

        if self.data_source == 'random':
            return x, np.random.randn(self.size) * self.amplitude
        elif self.data_source == 'sine':
            return x, self.amplitude * np.sin(self.frequency * x)
        else:  # exponential
            return x, self.amplitude * np.exp(self.frequency * x / 10)

    @param.depends('data_source', 'amplitude', 'frequency', 'size')
    def summary(self):
        """Display summary that updates automatically"""
        x, y = self.get_data()
        return f"Mean: {y.mean():.2f}, Std: {y.std():.2f}"

# Use in application
analyzer = DataAnalyzer()
print(analyzer.summary)

# Change parameters
analyzer.amplitude = 2.0
analyzer.frequency = 2.0
print(analyzer.summary)  # Updated automatically
```

### 4. Watchers for Side Effects

Watchers allow you to trigger code when parameters change:

```python
class DataModel(param.Parameterized):
    filename = param.String(default='data.csv')
    data = param.Parameter(default=None, precedence=-1)

    @param.depends('filename', watch=True)
    def _load_data(self):
        """Automatically load data when filename changes"""
        print(f"Loading {self.filename}...")
        # Load file here
        self.data = pd.read_csv(self.filename)

    # Alternative: explicit watch
    def __init__(self, **params):
        super().__init__(**params)
        self.param.watch(self._on_count_change, 'count')

    def _on_count_change(self, event):
        print(f"Count changed from {event.old} to {event.new}")

model = DataModel()
model.filename = 'new_file.csv'  # Triggers _load_data automatically
```

### 5. Custom Validation

```python
class ValidatedModel(param.Parameterized):
    email = param.String(default='', doc='Email address')
    age = param.Integer(default=0, bounds=(0, 150))
    password = param.String(default='')

    @param.validators('email')
    def validate_email(self, value):
        if '@' not in value:
            raise ValueError('Invalid email address')
        return value

    @param.validators('password')
    def validate_password(self, value):
        if len(value) < 8:
            raise ValueError('Password must be at least 8 characters')
        return value

    def validate_constraint(self):
        """Cross-parameter validation"""
        if self.age < 18 and self.email == '[email protected]':
            raise ValueError('Minors cannot use this email')

model = ValidatedModel()
model.email = 'invalid'  # Raises ValueError
model.password = 'short'  # Raises ValueError
```

### 6. Hierarchical Parameterization

```python
class DatabaseConfig(param.Parameterized):
    host = param.String(default='localhost')
    port = param.Integer(default=5432, bounds=(1, 65535))
    username = param.String(default='user')
    password = param.String(default='')

class AppConfig(param.Parameterized):
    app_name = param.String(default='MyApp')
    debug = param.Boolean(default=False)
    database = param.Parameter(default=DatabaseConfig())

    @param.depends('database.host', watch=True)
    def _on_db_change(self):
        print(f"Database configuration changed to {self.database.host}")

config = AppConfig()
config.database.host = 'production.db'  # Triggers watch on parent
```

## Integration with Panel UI

### 1. Automatic UI Generation

```python
import panel as pn

class DashboardConfig(param.Parameterized):
    title = param.String(default='Dashboard')
    refresh_interval = param.Integer(default=5000, bounds=(1000, 60000))
    metric = param.Selector(default='revenue', objects=['revenue', 'users', 'engagement'])
    show_legend = param.Boolean(default=True)

config = DashboardConfig()

# Panel automatically creates UI widgets from parameters
widgets = pn.param.ParamMethod.from_param(config.param)

# Or create individual widgets
title_input = pn.param.TextInput.from_param(config.param.title)
metric_select = pn.param.Selector.from_param(config.param.metric)
interval_slider = pn.param.IntSlider.from_param(config.param.refresh_interval)
```

### 2. Reactive Dashboard

```python
import holoviews as hv

class InteractiveDashboard(param.Parameterized):
    metric = param.Selector(default='sales', objects=['sales', 'users', 'traffic'])
    time_range = param.Range(default=(0, 100), bounds=(0, 100))
    aggregation = param.Selector(default='daily', objects=['hourly', 'daily', 'weekly'])

    def __init__(self, data):
        super().__init__()
        self.data = data

    @param.depends('metric', 'time_range', 'aggregation')
    def plot(self):
        filtered = self.data[
            (self.data['metric'] == self.metric) &
            (self.data['value'] >= self.time_range[0]) &
            (self.data['value'] <= self.time_range[1])
        ]
        return filtered.hvplot.line(title=f'{self.metric} ({self.aggregation})')

    @param.depends('metric')
    def summary(self):
        subset = self.data[self.data['metric'] == self.metric]
        return f"Mean: {subset['value'].mean():.2f}"

dashboard = InteractiveDashboard(data_df)

pn.extension('material')
app = pn.Column(
    pn.param.ParamMethod.from_param(dashboard.param),
    pn.Column(dashboard.plot, dashboard.summary)
)
```

## Best Practices

### 1. Parameter Organization
```python
# Group related parameters
class VideoConfig(param.Parameterized):
    # Video in

Related in General