When and Why to Use
Use this when you need a numeric input within a defined range. It's best for:
Age, year, count, or frequency questions
Questions that require range-based recoding (e.g. age bands)
Validating attention checks with specific values
Supports optional recoding and validation logic.
Portrait Experience
Respondent is shown a numeric input with increment/decrement buttons.
Range boundaries are visible.
If input is outside the range or invalid, an error message appears inline.
Landscape Experience
Same as portrait, but with more space for contextual text or images.
Navigation and focus-friendly for remote/TV-based interactions.
Configuration Options
Option | Type | Required | Default | Description |
|
| yes | - | The prompt shown to the user |
|
| no | - | Optional image from |
|
| no |
| The valid numeric range for answers |
|
| no | random between range | Default test data for QA |
|
| no | - | Map ranges or percentages to buckets |
| `Callable[[str], str | None]` | no | - |
|
| no | - | Used to fill tokens in text and for reporting groupings |
Example Code
Simple numeric:
s.numeric_question("What year were you born in?", min_max=(1900, 2024))
With recodes:
s.numeric_question( "How old are you?", min_max=(18, 100), recodes={ "18-25": "18-25", "26-54": "26-54", "55-74": "55-74", "75-100": "75+" } )
With percentage-based recodes:
s.numeric_question( "How many times have you visited our website?", min_max=(0, 100), recodes={ "0-30%": "Low", "31-70%": "Medium", "71-100%": "High" } )
With custom validator:
s.numeric_question( "How old are you?", min_max=(0, 120), custom_validator=lambda x: "Are you sure that you're 150 years old?" if x > 150 else None )
Recoding Numeric Responses
Sometimes it’s useful to group numeric values into labeled categories — for instance, turning income ranges into brackets like “Low”, “Middle”, and “High”. You define a set of rules that map numeric ranges to labels. Supported formats include:
Fixed Ranges (e.g. "0-49" → "Low")
Percentage Ranges (e.g. "0-25%")
→ Interpreted relative to a known min and max.
Open-ended Ranges (e.g. "80+")
→ Interpreted as “80 and above”.
Example 1: Satisfaction Score (0–100)
_recodes = { "0-25%": "Very Dissatisfied", "25-50%": "Dissatisfied", "50-75%": "Satisfied", "75-100%": "Very Satisfied" }
This scales the numeric value based on known min/max and assigns the appropriate label.
Example 2: Age Brackets
_recodes = { "0-17": "Underage", "18-64": "Adult", "65+": "Senior" }
In this case, "65+" means any value 65 or greater gets labeled "Senior".
What If No Match?
If the value doesn’t fall into any defined range, the original number is returned unchanged.