1

I currently script a lot of surveys that use XML where you can create routing logic, exec blocks etc. I know / use some very basic python and I am trying to learn more that I can apply to my surveys.

At the start of my surveys I gather customer segmentation info such as Age, Location, Social grade etc. These are then combined for quota purposes.

These are saved in autofills with the following categories (IL stands for interlock)

IL_Gender
r1: Male
r2: Female
r3: Other

IL_Age
r1: 18-34
r2: 35-54
r3: 55plus

IL_Region
r1: North
r2: South
r3: East r4: West

IL_SEG
r1: ABC1
r2: C2DE

From these autofills I would like to create all of the possible combinations (in this case 72) of these using the following syntax:

<row label="r1" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r1) and (IL_SEG.r1)">1_Male_Age_1834_North_ABC1</row>
<row label="r2" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r1) and (IL_SEG.r2)">2_Male_Age_1834_North_C2DE</row>
<row label="r3" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r2) and (IL_SEG.r1)">3_Male_Age_1834_South_ABC1</row>
<row label="r4" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r2) and (IL_SEG.r2)">4_Male_Age_1834_South_C2DE</row>
<row label="r5" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r3) and (IL_SEG.r1)">5_Male_Age_1834_East_ABC1</row>
<row label="r6" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r3) and (IL_SEG.r2)">6_Male_Age_1834_East_C2DE</row>
<row label="r7" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r4) and (IL_SEG.r1)">7_Male_Age_1834_West_ABC1</row>
<row label="r8" autofill="(IL_Gender.r1) and (IL_Age.r1) and (IL_Region.r4) and (IL_SEG.r2)">8_Male_Age_1834_West_C2DE</row>
<row label="r9" autofill="(IL_Gender.r1) and (IL_Age.r2) and (IL_Region.r1) and (IL_SEG.r1)">9_Male_Age_3554_North_ABC1</row>
<row label="r10" autofill="(IL_Gender.r1) and (IL_Age.r2) and (IL_Region.r1) and (IL_SEG.r2)">10_Male_Age_3554_North_C2DE</row>
<row label="r11" autofill="(IL_Gender.r1) and (IL_Age.r2) and (IL_Region.r2) and (IL_SEG.r1)">11_Male_Age_3554_South_ABC1</row>
<row label="r12" autofill="(IL_Gender.r1) and (IL_Age.r2) and (IL_Region.r2) and (IL_SEG.r2)">12_Male_Age_3554_South_C2DE</row>

And so on...

I'm not asking for people to do this for me I'm just wondering how difficult this would be and if anyone could point me in the right direction on what functions to use / steps I can take and any resources that might help me learn how to do this.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 2
    Does this answer your question? [How to apply itertools.product to elements of a list of lists?](https://stackoverflow.com/questions/3034014/how-to-apply-itertools-product-to-elements-of-a-list-of-lists) – Max Feb 11 '22 at 15:48
  • @joeroberts881 I left one example of how to accomplish what your looking for in python. You mention you're learning more python so I'll mention that in the approach I wrote take a look at linked library pages in my answer and also list comprehensions which I'm using to generate the list of lists. The advantage of this approach is that it generalizes to more-or fewer-segments in your surveys, either add or remove inner dictionaries. – Lucas Roberts Feb 11 '22 at 16:59
  • @LucasRoberts This is perfect thanks a lot! – joeroberts881 Feb 14 '22 at 09:49
  • @joeroberts881 My pleasure. If the answer is satisfactory please consider marking as correct and up voting. – Lucas Roberts Feb 14 '22 at 15:32

1 Answers1

1

Ultimately this really depends on how your customer segmentation info is stored. Let's assume it's in dictionary form. Then you can use the itertools.product function to get everything you want but you also need to do a bit of preprocessing and some postprocessing to store it all in the html in the desired form. If you have a template library that will do this for you (your web framework may have something that is preferable. Ultimately this really depends on how you want to use the output. Here's one way:

from itertools import product
from string import Template


oneDict = {"IL_Gender":{"r1": "Male", "r2": "Female", "r3": "Other"}, 
           "IL_Age": {"r1": "18-34", "r2": "35-54", "r3": "55plus"},
           "IL_Region": {"r1": "North", "r2": "South", "r3": "East", "r4": "West"},
           "IL_SEG": {"r1": "ABC1", "r2": "C2DE"}
          }


# create list of lists of outerkey.innerkey
arrays = []
for key in oneDict.keys():
    arrays.append([key + '.' + val for val in oneDict[key].keys()])

table_rows = []
t=Template('<row label=\"r$label\" autofill=\"($gender) and ($age) and ($region) \
            and ($seg)\">${label}_${gender}_${age}_${region}_${seg}</row>')

for idx, tup in enumerate(product(*arrays)):
    d = dict(label=idx, gender=tup[0], age=tup[1], region=tup[2], seg=tup[3])
    table_rows.append(t.safe_substitute(d))

# show first and last row
print(table_rows[0])
print(table_rows[71])

Here I use Python's builtin Template strings which require the {}s around the use of the keys with trailing _ in the template string but are not required in the earlier instances in the templated string.

Lucas Roberts
  • 1,252
  • 14
  • 17