Documentation

Using Advanced Python Features

Python's standard library is packed with powerful modules that, when combined with MX8 Labs' survey API, can deliver advanced logic, smarter routing, and richer data handling, all within the sandbox's safe execution limits. The sandbox allows a curated set of standard-library modules — collections, datetime, itertools, json, math, random, re, statistics, string, and time — and no third-party packages such as pandas. The survey code editor flags any other import as it's typed. The allowed modules include:

  • collections - High-performance container datatypes like Counter and defaultdict for counting, grouping, and organizing data.
  • datetime - Date and time handling, including comparisons, formatting, and time-zone safe calculations.
  • itertools - Tools for building iterators, cycles, combinations, permutations, and slices for controlled iteration.
  • math - Mathematical functions for advanced calculations (e.g., logarithms, square roots, trigonometry).
  • re - Regular expressions for pattern matching, searching, and text manipulation.
  • statistics - Functions for averages, medians, variance, and other statistical calculations.
  • string - String manipulation helpers and constants like punctuation and character sets.
  • time - Time-related functions like measuring elapsed time or adding pauses.
  • json - Encoding and decoding JSON strings for configuration-driven surveys.

For randomization, prefer the built-in helpers of the survey API over the standard library random module: s.randomize(items) shuffles a list (keeping any nested groups together, with flatten=True to flatten them afterward), and s.random() returns a float between 0 and 1 that is stable for the same respondent.

For language restrictions and automatic changes to your code when saving, see Differences from standard Python. This article provides examples of these modules for survey logic.

Patterns with itertools

Balanced exposure with cycle

Rotate sequentially through creatives so exposure stays even. (The sandbox does not allow the next() builtin, so index into the list instead of using itertools.cycle directly.)

python
from survey import Survey s = Survey(**globals()) creatives = s.media for i in range(3): s.rating_question( "Rate this creative:", image=creatives[i % len(creatives)], number_of_points=5 )

Pairwise comparisons with combinations

Efficiently create unique A vs. B questions.

python
from survey import Survey import itertools s = Survey(**globals()) brands = ["Nike", "Adidas", "Puma", "Reebok"] pairs = list(itertools.combinations(brands, 2)) for b1, b2 in s.randomize(pairs)[:3]: s.select_question( "Which do you prefer?", options=[b1, b2], tags=s.tag(pair="{} vs {}".format(b1, b2)), )

Batched blocks with islice

Show only the next N assets from a larger list.

python
from survey import Survey from itertools import islice s = Survey(**globals()) subset = list(islice(s.media, 5)) for m in subset: s.select_question("First look: thumbs up?", options=["Yes","No"], image=m)

Patterns with math

Log scaling for skewed spend

Compress extreme numeric values before routing.

python
from survey import Survey import math s = Survey(**globals()) spend = s.numeric_question("Monthly snack spend?", min_max=(0, 10000)) log_spend = math.log(spend + 1) if log_spend > 6: s.text_question("What drives your high spend?")

Euclidean distance for profile fit

Score how close ratings are to a target profile.

python
from survey import Survey import math s = Survey(**globals()) target = (5, 4, 4) resp = ( s.rating_question("Quality?", number_of_points=5), s.rating_question("Value?", number_of_points=5), s.rating_question("Design?", number_of_points=5), ) dist = math.sqrt(sum((r - t)**2 for r, t in zip(resp, target))) if dist <= 2: s.store_value("fit", "on-target")

Nonlinear weighting with sqrt

Downweight extremes when aggregating signals.

python
from survey import Survey import statistics, math s = Survey(**globals()) ratings = [ s.rating_question("Message clarity", number_of_points=5), s.rating_question("Believability", number_of_points=5), s.rating_question("Relevance", number_of_points=5), ] mean_score = statistics.mean(ratings) std_like = math.sqrt(sum((x - mean_score)**2 for x in ratings) / len(ratings)) if std_like > 1.5: s.text_question("Why were your ratings so varied?")

Patterns with statistics

Mean + dispersion check (consistency)

Follow up when responses are inconsistent.

python
from survey import Survey import statistics, math s = Survey(**globals()) ratings = [ s.rating_question("Message clarity", number_of_points=5), s.rating_question("Believability", number_of_points=5), s.rating_question("Relevance", number_of_points=5), ] mean_score = statistics.mean(ratings) std_like = math.sqrt(sum((x - mean_score)**2 for x in ratings) / len(ratings)) if std_like > 1.5: s.text_question("Why were your ratings so varied?")

Top‑2‑box share with fmean

python
from survey import Survey import statistics s = Survey(**globals()) scores = [ s.rating_question( "Rate ad {ad_number}", number_of_points=5, tags=s.tag(ad_number=i + 1), ) for i in range(6) ] Top2 = statistics.fmean(1 if x >= 4 else 0 for x in scores) if Top2 < 0.4: s.text_question("What held these ads back?") else: s.text_question("What made these ads work for you?")

Trimmed sentiment index

python
from survey import Survey import statistics s = Survey(**globals()) vals = [s.rating_question(q, number_of_points=5) for q in [ "Trust", "Uniqueness", "Appeal", "Purchase intent" ]] avg = statistics.mean(vals) med = statistics.median(vals) if abs(avg - med) >= 1: s.text_question("Some answers were polarized. What caused mixed feelings?")

Fair rotation + live average with statistics

Ensure fair rotation and track live average.

python
from survey import Survey import statistics s = Survey(**globals()) creatives = s.media collected = [] for i in range(4): r = s.rating_question( "Overall impression", number_of_points=5, image=creatives[i % len(creatives)] ) collected.append(r) live_avg = statistics.mean(collected) if live_avg < 3: s.text_question("What would improve these creatives?")