Complex Counterbalancing Using Code

Hi, I hope all is well! I have a PsychoPy project. I need to do a lot of counterbalancing using code and not just loops. Essentially the task shows a face with a word (trait). The traits vary on agreeableness or extraversion and can be either positive or negative. Right now I have a routine with an image component called Faces2 where the image is set to “$current_face” and a text component Traits2 where the text says $current_trait, and a loop called Task2_Loop where the conditions file is FaceA.csv. The face csv titled faceA has columns StimuliID, CFD_Rating (with attractiveness ratings: attractive, unattractive, or average), Sex (male or female), and Race (white, black, latino, or asian). Note, there are 2 faces in each sex-race-attractiveness category (i.e 2 Male Asian Attractive, 2 Female White Average…). The trait csv is titled Traits and has the columns Trait (with the word), Valance (positive or negative), and Dimension (agreeableness or extraversion. I need to counterbalance 2 things… 1) so 50% of the words show up on top of the photo and 50% show up under the photo 2) counterbalancing the type of trait (Extraversion/agreeableness) and the valence (positive and negative) across the categories of faces and across participants. I was thinking, participants should be put into 1 of four groups: for example, in group 1 hypothetical face 1 is paired with a positive extraversion trait, face 2 is paired with a negative extraversion trait, face 3 is paired with a positive agreeableness trait, and face 4 is paired with a negative agreeableness trait… then for group 2 that same face 1 would be instead paired with a negative extraversion trait, face 2 with a positive extraversion trait, face 3 with a negative agreeableness trait, and face 4 with a positive agreeableness trait. This would follow for groups 3 and 4 to make 4 groups where a given face would see all 4 possible trait/valence combinations.
Note, within each sex-race-attractiveness-face category, one of the two faces must be paired with a positive trait and one with a negative trait. I also need to ensure all 48 traits and faces are used.

I want to assign participants to the 4 groups based on their participantID, for example group A participants would be 001, 005, 009… and they would all see the group A pairings. For example, any participant who ends up in group A should see the same dimension of traits for the same sex-race-attractiveness category even if the exact trait changes. For example, participant 001 is in group A and sees extraversion traits for the 2 male average asian faces (one gets a positive trait and one a negative trait)… so participant 005, also in group A, should also see extraversion traits for the 2 male average asian faces (one positive one negative), even if its not the exact same traits.

I know this is a bit complicated and I really appreciate any and all help. Thank you!

Putting participants into four groups based on participant number is easy enough.

group = int(expInfo['participant'])%4

However, perhaps you actually want independent randomisation or complex randomisation…for which please see my online demos.