from otree.api import * import random from ast import literal_eval from pprint import pprint import json doc = """ "Widget to rank/reorder items". See http://sortablejs.github.io/Sortable/ for more examples. """ class C(BaseConstants): NAME_IN_URL = 'rank_widget' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 OBJECTS = { "Measuring Tape": {"info1": "1.5m long", "info2": "cm and inches", "info3": "Retractable and flexible", "name": "Measuring Tape", "img": "objects/Measuring-Tape.jpg",}, "Cutlery": {"info1": "Plastic", "info2": "Reusable", "info3": "Case dimensions: 21 x 6 x 2.5 cm", "name": "Cutlery", "img": "objects/Cutlery.jpg",}, "Bottle": {"info1": "BPA-free", "info2": "Flexible silicone", "info3": "21 oz capacity", "name": "Bottle", "img": "objects/Bottle.jpg", }, "Notebook": {"info1": "320 lined pages", "info2": "Vegan leather", "info3": "14.6 x 21 cm", "name": "Notebook", "img": "objects/Notebook.jpg",}, "Battery": {"info1": "10,000 mAh (2.25 charges for iPhone 12, 1.6 charges for Galaxy S20)", "info2": "Overcharge protection", "info3": "Temperature control", "name": "Battery" , "img": "objects/Battery.jpg",}, "Blender": {"info1": "1.9L capacity", "info2": "450W", "info3": "16.4D x 19.2W x 27.7H cm", "name": "Blender", "img": "objects/Blender.jpg",}, "Speaker": {"info1": "Bluetooth speaker", "info2": "66ft range", "info3": "24h battery life", "name": "Speaker", "img": "objects/Speaker.jpg",}, "Air Frier": {"info1": "4.3L capacity", "info2": "1500W", "info3": "29D x 36.5W x 32.5H cm", "name": "Air Frier", "img": "objects/Air-Frier.jpg",}, "£1": {"info1": "One pound", "info2": "in", "info3": "cash", "name": "£1", "img": "objects/One.jpg", }, "£10": {"info1": "Ten pounds", "info2": "in", "info3": "cash", "name": "£10", "img": "objects/Ten.jpg", }, "£25": {"info1": "Twenty-five pounds", "info2": "in", "info3": "cash", "name": "£25", "img": "objects/Twentyfive.jpg", }, } class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): ranking = models.StringField() objects_ordered = models.StringField() ranked1 = models.StringField() def setup(self): p = self ### gives me the names (i.e., the name of each entry in the dictionary) allobjects = list(C.OBJECTS.keys()) random.shuffle(allobjects) ##both of the following do the same (but represent the lists in slightly diff ways) ## dumps => dump string; loads => load string #p.participant.vars['objects_ordered'] = str(allobjects) p.participant.vars['objects_ordered'] = json.dumps(allobjects) p.objects_ordered = json.dumps(allobjects) #this one splits the ranking variable, which stores the whole ranking as a comma-separated string @property def ranking_as_list(self): return self.ranking.split(",") @property def ranking_as_list_no_money(self): return [ item for item in self.ranking_as_list if C.OBJECTS[item]["info3"] != "cash"] ######## PAGES class generalinfo(Page): def before_next_page(self,timeout_happened): self.setup() class ranking(Page): form_model = 'player' form_fields = ['ranking'] @staticmethod def vars_for_template(player): return { "objects_ordered_names": json.loads(player.participant.vars['objects_ordered']), "objects_ordered": [C.OBJECTS.get(name) for name in json.loads(player.participant.vars['objects_ordered'])], } def before_next_page(self,timeout_happened): self.participant.vars['ranked1'] = self.ranking_as_list_no_money[0] self.participant.vars['ranked2'] = self.ranking_as_list_no_money[1] self.participant.vars['ranked3'] = self.ranking_as_list_no_money[2] self.participant.vars['ranked4'] = self.ranking_as_list_no_money[3] self.participant.vars['ranked5'] = self.ranking_as_list_no_money[4] self.participant.vars['ranked6'] = self.ranking_as_list_no_money[5] self.participant.vars['ranked7'] = self.ranking_as_list_no_money[6] self.participant.vars['ranked8'] = self.ranking_as_list_no_money[7] self.participant.vars['rankpay1'] = self.ranking_as_list[0] self.participant.vars['rankpay2'] = self.ranking_as_list[1] self.participant.vars['rankpay3'] = self.ranking_as_list[2] self.participant.vars['rankpay4'] = self.ranking_as_list[3] self.participant.vars['rankpay5'] = self.ranking_as_list[4] self.participant.vars['rankpay6'] = self.ranking_as_list[5] self.participant.vars['rankpay7'] = self.ranking_as_list[6] self.participant.vars['rankpay8'] = self.ranking_as_list[7] self.participant.vars['rankpay9'] = self.ranking_as_list[8] self.participant.vars['rankpay10'] = self.ranking_as_list[9] self.participant.vars['rankpay11'] = self.ranking_as_list[10] class questionsinfo(Page): pass page_sequence = [generalinfo, ranking, questionsinfo]