Skip to main content

Using Advanced Python Features

Unleashing the power of programming

Updated over a month ago

Using Advanced Python Features

ython’s standard library is packed with powerful modules that, when combined with MX8’s survey API, can deliver advanced logic, smarter routing, and richer data handling — all within the sandbox’s safe execution limits. The allowed imports in the MX8 sandbox are:

  • 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.

This article provides examples of some of the stronger use cases for these modules to help you create more dynamic, responsive surveys.


Patterns with itertools

Balanced exposure with cycle

Rotate sequentially through creatives so exposure stays even.

from survey import Survey
import itertools

s = Survey(**globals())

creatives = s.media
rotator = itertools.cycle(creatives)

for _ in range(3):
s.rating_question(
"Rate this creative:",
image=next(rotator),
number_of_points=5
)

Pairwise comparisons with combinations

Efficiently create unique A vs. B questions.

from survey import Survey
import itertools, random

s = Survey(**globals())

brands = ["Nike", "Adidas", "Puma", "Reebok"]
pairs = list(itertools.combinations(brands, 2))

for b1, b2 in random.sample(pairs, k=3):
s.select_question("Which do you prefer?", options=[b1, b2])

Batched blocks with islice

Show only the next N assets from a larger list.

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.

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.

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.set_topics("on-target")

Nonlinear weighting with sqrt

Downweight extremes when aggregating signals.

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.

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

from survey import Survey
import statistics

s = Survey(**globals())

scores = [s.rating_question(f"Rate ad {i+1}", number_of_points=5) 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

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?")

Combining itertools + statistics

Ensure fair rotation and track live average.

from survey import Survey
import itertools, statistics

s = Survey(**globals())

rot = itertools.cycle(s.media)
collected = []
for _ in range(4):
r = s.rating_question("Overall impression", number_of_points=5, image=next(rot))
collected.append(r)

live_avg = statistics.mean(collected)
if live_avg < 3:
s.text_question("What would improve these creatives?")
Did this answer your question?