from otree.api import Currency as c, currency_range from . import models from ._builtin import Page, WaitPage from .models import Constants from collections import Counter from captcha.fields import ReCaptchaField from otree_tools.utils import get_focused_time, get_unfocused_time import time, random import pandas as pd import re selected_news_formfields = [ 'selected_finance_news1', 'selected_finance_news2', 'selected_finance_news3', 'selected_finance_news4', 'selected_finance_news5', 'selected_finance_news6', 'selected_finance_news7', 'selected_finance_news8', 'selected_regulation_news1', 'selected_regulation_news2', 'selected_regulation_news3', 'selected_regulation_news4', 'selected_regulation_news5', 'selected_regulation_news6', 'selected_regulation_news7', 'selected_regulation_news8', 'selected_product_news1', 'selected_product_news2', 'selected_product_news3', 'selected_product_news4', 'selected_product_news5', 'selected_product_news6', 'selected_product_news7', 'selected_product_news8', 'product_time1', 'product_time2', 'product_time3', 'finance_time1', 'finance_time2', 'finance_time3', 'regulation_time1', 'regulation_time2', 'regulation_time3', 'product_next', 'finance_next', 'regulation_next'] class Validation(Page): _allow_custom_attributes = True form_model = models.Player def get_form(self, data=None, files=None, **kwargs): frm = super().get_form(data, files, **kwargs) frm.fields['captcha'] = ReCaptchaField(label='') return frm class Welcome(Page): form_model = models.Player form_fields = ['user_information'] def vars_for_template(self): return{ 'base_payment': float(self.session.config['participation_fee']), 'lower_exp_payment': Constants.lower_exp_payment, 'upper_exp_payment': Constants.upper_exp_payment } class Instructions(Page): def vars_for_template(self): return { 'news_bias': self.player.participant.vars['news_bias'] * 100, 'opposite_news_bias': 100 - self.player.participant.vars['news_bias'] * 100, 'num_facts_per_page': Constants.num_facts_per_page, 'num_facts_to_select_per_page': Constants.num_facts_to_select_per_page, } class NewsPage1(Page): timeout_seconds = Constants.news_timeout form_model = models.Player random.shuffle(selected_news_formfields) form_fields = selected_news_formfields #this is defined at the top of this file def vars_for_template(self): news_path = self.player.np_order.split('; ')[0] return {'news_source1': 'news_and_beliefs/' + news_path + '.html'} class NewsPage2(Page): timeout_seconds = Constants.news_timeout form_model = models.Player random.shuffle(selected_news_formfields) form_fields = selected_news_formfields def vars_for_template(self): news_path = self.player.np_order.split('; ')[1] return {'news_source2': 'news_and_beliefs/' + news_path + '.html'} class NewsPage3(Page): timeout_seconds = Constants.news_timeout form_model = models.Player random.shuffle(selected_news_formfields) form_fields = selected_news_formfields def vars_for_template(self): news_path = self.player.np_order.split('; ')[2] return {'news_source3':'news_and_beliefs/' + news_path + '.html'} def before_next_page(self): if self.session.vars['otree_tools_used'] == True: ############ Store focused time (otree-tools 0.3.4) of pages up to this point #(need this so that even players # who get failedSelectingFacts=True have their focused time recorded) self.participant.vars['focused_time_Validation'] = get_focused_time(self.player,'Validation') self.participant.vars['focused_time_Welcome'] = get_focused_time(self.player,'Welcome') self.participant.vars['focused_time_Instructions'] = get_focused_time(self.player,'Instructions') self.participant.vars['focused_time_NewsPage1'] = get_focused_time(self.player,'NewsPage1') self.participant.vars['focused_time_NewsPage2'] = get_focused_time(self.player,'NewsPage2') self.participant.vars['focused_time_NewsPage3'] = get_focused_time(self.player,'NewsPage3') #############''' Evaluate and Store Selected News ''' def standardize_language(mystr): """ Finds the seclected fact """ return 'news_' + re.findall(r'(finance|product|regulation)', mystr)[0] + str(re.search(r'\d+$', mystr).group()) factidvalence_dict = self.player.participant.vars['factidvalence_dict'] contentid2factidvalence = Constants.contentid2factidvalence fact_positivity_dict = Constants.fact_positivity # First find the selected form fields selected_news = [news for news in selected_news_formfields if getattr(self.player, news) == "T"] #Check if all facts to select per page were indeed selected and assign the result to failedSelectingFacts self.player.participant.vars['failedSelectingFacts'] = (len(selected_news) != 3*Constants.num_facts_to_select_per_page) # Map the selected form fields back to the contentid (THIS USED TO BE FACTID BUT NOW FACTID DOES NOT TELL US POSITIVITY) selected_factidvalence = [factidvalence_dict[standardize_language(news)] for news in selected_news] # Parse the selected facts unique_selected_factidvalence = set(selected_factidvalence) counted_selected_facts = Counter(selected_factidvalence) repeated_facts = [fact for fact, count in counted_selected_facts.items() if count > 1] self.player.all_selected_facts = '; '.join(map(str, selected_factidvalence)) self.player.unique_selected_facts = '; '.join(map(str, unique_selected_factidvalence)) self.player.participant.vars['all_selected_facts'] = selected_factidvalence self.player.participant.vars['unique_selected_facts'] = unique_selected_factidvalence self.player.participant.vars['repeated_facts'] = repeated_facts self.player.participant.vars['num_positive_facts'] = len([t for t in unique_selected_factidvalence if t > 0]) self.player.participant.vars['num_negative_facts'] = len([t for t in unique_selected_factidvalence if t < 0]) if self.player.participant.vars['num_positive_facts'] > self.player.participant.vars['num_negative_facts']: self.player.participant.vars['positivity_balance'] = 'More Positive Facts' elif self.player.participant.vars['num_positive_facts'] == self.player.participant.vars['num_negative_facts']: self.player.participant.vars['positivity_balance'] = 'Equal Amount' else: self.player.participant.vars['positivity_balance'] = 'More Negative Facts' # Otree does not have a sophisticated way for page randomization # (they use rounds, but that would repeat all pages per round, setting some visible some invisible per round) # Instead repeat in the page sequence here page_sequence =[ Validation, Welcome, Instructions, NewsPage1, NewsPage2, NewsPage3 ]