def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] if trial['phase']=='TEST': if trial['hit']==True: bonus += 0.02 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def worker_complete(): """Overide the psiTurk worker_complete route. This skirts around an issue where the participant's status reverts to 3 because of rogue calls to this route. It does this by changing the status only if it's not already >= 100. """ exp = experiment(session) if 'uniqueId' not in request.args: resp = {"status": "bad request"} return jsonify(**resp) else: unique_id = request.args['uniqueId'] exp.log("Completed experiment %s" % unique_id) try: user = Participant.query.\ filter(Participant.uniqueid == unique_id).one() if user.status < 100: user.status = 3 user.endhit = datetime.datetime.now() session_psiturk.add(user) session_psiturk.commit() status = "success" except exc.SQLAlchemyError: status = "database error" resp = {"status": status} return jsonify(**resp)
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key('uniqueId'): raise ExperimentError( 'improper_inputs' ) # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] if trial['phase'] == 'TEST': if trial['hit'] == True: bonus += 0.02 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def patch(self, campaign_id): campaign = Campaign.query.filter(Campaign.id == campaign_id).one() data = request.json did_something = False if 'is_active' in data and campaign.is_active and not data['is_active']: campaign.end() did_something = True elif 'goal' in data: goal = data['goal'] completed_count = Participant.count_completed( codeversion=services_manager.codeversion, mode=services_manager.mode) assert goal > completed_count, 'Goal {} must be greater than current completed {}.'.format( goal, completed_count) campaign.goal = goal did_something = True if did_something: db_session.add(campaign) db_session.commit() return campaign
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if 'uniqueId' not in request.args: raise ExperimentError( 'improper_inputs') # original author wants to change this line uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query\ .filter(Participant.uniqueid == uniqueId)\ .one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] if trial['phase'] == 'TEST': if trial['hit'] is True: bonus += 0.02 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except Exception as e: current_app.logger.info("Error: %s", repr(e)) abort(404) # again, bad to display HTML, but...
def compute_bonus(): current_app.logger.info("accessing route /compute_bonus") # check that request includes a uniqueId if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON import random r = random.random() whichToBonus = 0 if r > 0.5: whichToBonus = 1 bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] # get part of line holding trial info if trial['phase']=='apav': #check that trial is in test phase, not instructions if trial['trial']==243 and trial['habitatNum'] == whichToBonus: bonus = float(trial['scoreAfter']) user.bonus = bonus #set bonus field to new value db_session.add(user) db_session.commit() #commit to database resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def compute_bonus(): current_app.logger.info("accessing route /compute_bonus") # check that request includes a uniqueId if not request.args.has_key('uniqueId'): raise ExperimentError( 'improper_inputs' ) # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON import random r = random.random() whichToBonus = 0 if r > 0.5: whichToBonus = 1 bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] # get part of line holding trial info if trial[ 'phase'] == 'apav': #check that trial is in test phase, not instructions if trial['trial'] == 243 and trial[ 'habitatNum'] == whichToBonus: bonus = float(trial['scoreAfter']) user.bonus = bonus #set bonus field to new value db_session.add(user) db_session.commit() #commit to database resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascript client if not request.args.has_key('uniqueId'): raise ExperimentError( 'improper_inputs' ) # i don't like returning HTML to JSON requests... maybe should change this unique_id = request.args['uniqueId'] # try: # lookup user in database # in order to check for IP address violations get the user this way and then check for user.ipaddress user = Participant.query. \ filter(Participant.uniqueid == unique_id). \ one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] if trial['phase'] == 'trial' and trial['included']: bonus += float(trial['choice']) elif trial['phase'] == 'exit': bonus = 0 break user.bonus = "%.2f" % round(bonus, 2) db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp)
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key("uniqueId"): raise ExperimentError( "improper_inputs" ) # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args["uniqueId"] try: # lookup user in database user = Participant.query.filter(Participant.uniqueid == uniqueId).one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 for record in user_data["data"]: # for line in data file trial = record["trialdata"] if trial["blockID"] != "Practice" and trial["blockID"] != "Test": bonus += trial["dollars"] # if trial['phase']=='TEST': # if trial['hit']==True: # bonus += 0.02 user.bonus = round(bonus, 2) db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def check_secret_code(): current_app.logger.info(request.form['workerid']) current_app.logger.info(request.form['code']) uniqueId = request.form['uniqueid'] try: worker = LegitWorker.query.filter(and_(LegitWorker.amt_worker_id ==request.form['workerid'], \ LegitWorker.completion_code == request.form['code'], \ LegitWorker.status=='owed')).one() except: abort(406) worker.submitted() db_session.add(worker) db_session.commit() try: user = Participant.query.\ filter(Participant.uniqueid == uniqueId).one() user.bonus = worker.bonus user.status = COMPLETED user.endhit = datetime.datetime.now() db_session.add(user) db_session.commit() except: abort(406) resp = {"bonus": user.bonus} return jsonify(**resp)
def saveLink(): try: file = request.files['participant'] if not file: raise Exception('Couldn\'t load .csv file') stream = io.StringIO(file.stream.read().decode("UTF8"), newline=None) csv_input = csv.reader(stream) next(csv_input) unique_links = [] for row in csv_input: if len(row) > 3: continue link = generateUniqueLink() unique_link_attributes = dict(name=row[0], unique_identifier=row[1], email=row[2], link=link, expiresAt=None, file=file.filename) if 'expires' in request.form and 'expiresAt' in request.form: expiresAt = int(request.form['expiresAt']) unique_link_attributes['expiresAt'] = datetime.now( ) + timedelta(hours=expiresAt) unique_link = UniqueLink(**unique_link_attributes) db_session.add(unique_link) unique_links.append(unique_link) db_session.commit() sendMail(unique_links) return redirect(url_for('custom_code.generateLink')) except Exception as e: app.logger.error(e) return redirect(url_for('custom_code.generateLink'))
def compute_bonus(): current_app.logger.info("accessing route /compute_bonus") # check that request includes a uniqueId if not request.args.has_key('uniqueId'): raise ExperimentError( 'improper_inputs' ) # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON bonuses = [] for record in user_data['data']: # for line in data file trial = record['trialdata'] # get part of line holding trial info if trial['phase'] == 'apavPhase' and trial['globalTrial'] == 252: user.bonus = float( trial['scoreAfter']) #set bonus field to the final bonus db_session.add(user) db_session.commit() #commit to database resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def check_secret_code(): current_app.logger.info(request.form["workerid"]) current_app.logger.info(request.form["code"]) uniqueId = request.form["uniqueid"] try: worker = LegitWorker.query.filter( and_( LegitWorker.amt_worker_id == request.form["workerid"], LegitWorker.completion_code == request.form["code"], LegitWorker.status == "owed", ) ).one() except: abort(406) worker.submitted() db_session.add(worker) db_session.commit() try: user = Participant.query.filter(Participant.uniqueid == uniqueId).one() user.bonus = worker.bonus user.status = COMPLETED user.endhit = datetime.datetime.now() db_session.add(user) db_session.commit() except: abort(406) resp = {"bonus": user.bonus} return jsonify(**resp)
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if 'uniqueId' not in request.args: raise ExperimentError('improper_inputs') # original author wants to change this line uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query\ .filter(Participant.uniqueid == uniqueId)\ .one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] if trial['phase'] == 'TEST': if trial['hit'] is True: bonus += 0.02 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except Exception as e: current_app.logger.info("Error: %s", repr(e)) abort(404) # again, bad to display HTML, but...
def useUniqueLink(link): try: unique_link = UniqueLink.query.\ filter(UniqueLink.link == link).one() if unique_link.status < LINK_SUBMITTED and unique_link.expiresAt != None and unique_link.expiresAt < datetime.now( ): unique_link.status = LINK_EXPIRED elif unique_link.status == LINK_PENDING: unique_link.status = LINK_EXPIRED elif unique_link.status == LINK_UNUSED: unique_link.status = LINK_PENDING db_session.add(unique_link) db_session.commit() if unique_link.status == LINK_EXPIRED: return render_template('expired.html') elif unique_link.status == LINK_SUBMITTED: return render_template('thanks.html') link = unique_link.link show_consent = config.get('Unique Links Parameters', 'show_consent') redirect_to = 'give_consent' if show_consent else 'start_exp' return redirect( url_for(redirect_to, hitId=link, assignmentId=link, workerId=link, mode='lab')) except Exception as e: app.logger.error(e) abort(404)
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not 'uniqueId' in request.args: # i don't like returning HTML to JSON requests... maybe should change this raise ExperimentError('improper_inputs') uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON for record in user_data['data']: # for line in data file trial = record['trialdata'] if trial['phase'] == 'Points Collected': bonus = float( trial['Total Points'] ) / 10. * 0.01 # payout one cent per trial, for now user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def complete_override(): ''' Debugging route for complete. ''' if not 'uniqueId' in request.args: raise ExperimentError('improper_inputs') else: unique_id = request.args['uniqueId'] mode = request.args['mode'] try: user = Participant.query.\ filter(Participant.uniqueid == unique_id).one() user.status = COMPLETED user.endhit = datetime.now() db_session.add(user) db_session.commit() except: raise ExperimentError('error_setting_worker_complete') else: # send them back to mturk. if (mode == 'sandbox' or mode == 'live'): return render_template('closepopup.html') else: if mode == 'lab': link = unique_id.split(':')[0] try: unique_link = UniqueLink.query.\ filter(UniqueLink.link == link).one() unique_link.status = LINK_SUBMITTED db_session.add(unique_link) db_session.commit() except: current_app.logger.error( "Couldn't change status to SUBMITTED for %s" % link) return render_template('complete.html')
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON n_trials = 0 for record in user_data['data']: # for line in data file trial = record['trialdata'] cur_trl_type = data_trl.get('trial', '') if cur_trl_type != trl_type: continue if trl_type == 'train': points = int(data_trl['points']) if 'points' in data_trl else np.nan n_trials += 1 bonus = points * .01 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def create_participant(worker_id, hit_id, assignment_id, mode): """Create a participant. This route will be hit very early on as any nodes the participant creates will be defined in reference to the participant object. You must specify the worker_id, hit_id, assignment_id and mode in the url. """ # check this worker hasn't already taken part parts = models.Participant.query.filter_by(worker_id=worker_id).all() if parts: print "participant already exists!" return Response(status=200) # make the participant participant = models.Participant(worker_id=worker_id, assignment_id=assignment_id, hit_id=hit_id, mode=mode) session.add(participant) session.commit() # make a psiturk participant too, for now from psiturk.models import Participant as PsiturkParticipant psiturk_participant = PsiturkParticipant(workerid=worker_id, assignmentid=assignment_id, hitid=hit_id) session_psiturk.add(psiturk_participant) session_psiturk.commit() # return the data return success_response(field="participant", data=participant.__json__(), request_type="participant post")
def dashboard(): if 'mode' in request.form: if request.form['mode'] == 'add': if ('workerid' in request.form) and ('bonus' in request.form): if (LegitWorker.query.filter( LegitWorker.amt_worker_id == request.form['workerid']).count() == 0): newworker = LegitWorker(workerid=request.form['workerid']) newworker.set_bonus(float(request.form['bonus'])) db_session.add(newworker) db_session.commit() else: flash('That worker has already been added!', 'error') elif request.form['mode'] == 'delete': if ('index' in request.form): current_app.logger.info('deleting') try: lw = LegitWorker.query.filter( LegitWorker.index == int(request.form['index'])).one() db_session.delete(lw) db_session.commit() except: flash( u'Sorry, was unable to delete that worker. Perhaps they were already deleted!', 'error') elif request.form['mode'] == 'refresh': failed_workers = [] workers = LegitWorker.query.all() for lw in workers: try: user = Participant.query.filter( Participant.workerid == lw.amt_worker_id).one() if user.status == BONUSED: try: lw.paid() db_session.add(lw) db_session.commit() except Exception as ex: current_app.logger.error( 'Could not update worker %s to paid status: %s', lw.amt_worker_id, ex) failed_workers.append(w.amt_worker_id) except NoResultFound: pass # hasn't submitted yet... if len(failed_workers) > 0: display_str = u'Could not update the following workers:' for w in failed_workers: display_str += '\n%s' % (w) flash(display_str, 'error') try: workers = LegitWorker.query.all() return render_template('dashboard.html', workers=workers) except TemplateNotFound: abort(404)
def set_new_goal(self, goal): self.goal = goal db_session.add(self) db_session.commit() from .experiment import app job = app.apscheduler.get_job(self.campaign_job_id) kwargs = job.kwargs kwargs['campaign'] = self job.modify(kwargs=kwargs) return self
def end(self): self.is_active = False self.ended = datetime.datetime.now(datetime.timezone.utc) from .experiment import app try: app.apscheduler.remove_job(self.campaign_job_id) except JobLookupError: pass db_session.add(self) db_session.commit() return self
def ineligible(): current_app.logger.info("Participant ineligible") try: unique_id = request.args['uniqueId'] current_app.logger.info("Marking ineligible %s" % unique_id) user = Participant.query. \ filter(Participant.uniqueid == unique_id).one() user.status = 8 # INELIGIBLE db_session.add(user) db_session.commit() except exc.SQLAlchemyError: raise ExperimentError('tried_to_quit') raise IneligibilityError()
def set_initial_state(self, actor, state, level_path=None): """ handles an initial_state coming from an actor, or call with predefined level to """ if self.current_task_record is not None: try: db_session.add(self.current_task_record) except Exception: pass if self.current_task_record.task_number == self.current_task: return #already set initial state for this task #if self.initial_state is None: self.initial_state = state self.current_state = state print("level loaded for task " + str(self.current_task) + " current state set: " + str(hash(frozenset(state))) + ", size: " + str(len(state))) new_task = Task(session_id=self.session_id, task_number=self.current_task, init_state=state) new_task.level_path = level_path self.current_task_record = new_task session_record = db_session.query(Session).filter( Session.session_id == self.session_id).one() session_record.tasks.append(new_task) new_task.student = self.student #db_session.query(User).filter(User.user_id == self.student).one() new_task.teacher = self.teacher #db_session.query(User).filter(User.user_id == self.teacher).one() new_task.init_state = json.dumps(state) db_session.commit() print("creating task with id: " + str(new_task.session_id) + "::" + str(new_task.task_number)) #self.current_task_id = (BLAH) # first initial state submitted is chosen #self.current_state = state self.prev_state = state #self.state_stack=[state] self.unity_lock = self.init_unity_lock self.html_lock = self.init_html_lock self.emit('load', self.current_state, room=actor) self.update_ui(actor) if len(self.unity_lock) > 1: self.emit('load', self.current_state, room=self.partner(actor)) self.update_ui(self.partner(actor))
def mark_bad(): if not 'uniqueId' in request.args: raise ExperimentError('improper_inputs') else: uniqueId = request.args['uniqueId'] user = Participant\ .query.\ filter(Participant.uniqueid == uniqueId).\ one() user.status = BAD db_session.add(user) db_session.commit() resp = {user.uniqueid: user.status} return jsonify(**resp)
def compute_bonus(): uniqueId = request.args['uniqueId'] try: user = Participant.query.filter(Participant.uniqueid == uniqueId).one() user_data = loads(user.datastring) final_record = user_data['data'][-2] trial = final_record['trialdata'] bonus = max(0, min(17, trial['totalReward'])) user.bonus = "{:.2f}".format(bonus) db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} except: resp = {"bonusComputed": "failure"} return jsonify(**resp)
def dashboard(): if 'mode' in request.form: if request.form['mode']=='add': if ('workerid' in request.form) and ('bonus' in request.form): if (LegitWorker.query.filter(LegitWorker.amt_worker_id == request.form['workerid']).count() == 0): newworker = LegitWorker(workerid=request.form['workerid']) newworker.set_bonus(float(request.form['bonus'])) db_session.add(newworker) db_session.commit() else: flash('That worker has already been added!', 'error') elif request.form['mode']=='delete': if ('index' in request.form): current_app.logger.info('deleting') try: lw=LegitWorker.query.filter(LegitWorker.index == int(request.form['index'])).one() db_session.delete(lw) db_session.commit() except: flash(u'Sorry, was unable to delete that worker. Perhaps they were already deleted!', 'error') elif request.form['mode']=='refresh': failed_workers = [] workers = LegitWorker.query.all() for lw in workers: try: user = Participant.query.filter(Participant.workerid == lw.amt_worker_id).one() if user.status == BONUSED: try: lw.paid() db_session.add(lw) db_session.commit() except Exception as ex: current_app.logger.error('Could not update worker %s to paid status: %s', lw.amt_worker_id, ex) failed_workers.append(w.amt_worker_id) except NoResultFound: pass # hasn't submitted yet... if len(failed_workers) > 0: display_str = u'Could not update the following workers:' for w in failed_workers: display_str += '\n%s' % (w) flash(display_str, 'error') try: workers = LegitWorker.query.all() return render_template('dashboard.html', workers = workers) except TemplateNotFound: abort(404)
def do_it(participant_attributes={}): participant_attribute_defaults = { 'workerid': faker.md5(raw_output=False), 'hitid': faker.md5(raw_output=False), 'assignmentid': faker.md5(raw_output=False), } participant_attributes = dict(list( participant_attribute_defaults.items()) + list(participant_attributes.items())) init_db() participant = Participant(**participant_attributes) db_session.add(participant) db_session.commit() return participant
def campaign(): from psiturk.models import Campaign parameters = { 'codeversion': '1.0', 'mode': 'sandbox', 'goal': 100, 'minutes_between_rounds': 1, 'assignments_per_round': 10, 'hit_reward': 1.00, 'hit_duration_hours': 1, } new_campaign = Campaign(**parameters) from psiturk.db import db_session db_session.add(new_campaign) db_session.commit() return new_campaign
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # lookup user in database uniqueid = request.args['uniqueId'] user = Participant.query.\ filter(Participant.uniqueid == uniqueid).\ one() final_bonus = 'NONE' # load the bonus information try: all_data = json.loads(user.datastring) question_data = all_data['questiondata'] final_bonus = question_data['final_bonus'] final_bonus = round(float(final_bonus), 2) if final_bonus > MAX_BONUS: raise ValueError('Bonus of {} excedes MAX_BONUS of {}'.format( final_bonus, MAX_BONUS)) user.bonus = final_bonus db_session.add(user) db_session.commit() resp = { 'uniqueId': uniqueid, 'bonusComputed': 'success', 'bonusAmount': final_bonus } except: current_app.logger.error( 'error processing bonus for {}'.format(uniqueid)) current_app.logger.error(format_exc()) resp = { 'uniqueId': uniqueid, 'bonusComputed': 'failure', 'bonusAmount': final_bonus } current_app.logger.info(str(resp)) return jsonify(**resp)
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascript client if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON bonus = 0 # find actual reward/max expected reward and multiply by max $ amount to give ($1?) # take average over each collaboration setting? questiondata = user_data['questiondata'] num_iterations = questiondata['num_iterations'] bonuses = [] for robot in questiondata['robot_order']: key = str(robot) + "_hard_collaborate_suggest" data_dict = questiondata[key] # payoffs = np.array(data_dict['arm_payoffs']) # probabilities = np.array(data_dict['arm_probabilities']) # max_exp_reward = max(payoffs * probabilities) * num_iterations payoff_matrix = np.array(data_dict['arms_payoff_matrix']) max_exp_reward = max(payoff_matrix.dot([0, 1, 2, 3, 4])) * num_iterations actual_reward = data_dict['all_total_rewards'][-1] bonuses.append(min(1, 1 * (actual_reward / max_exp_reward))) bonus = np.average(bonuses) if bonus >= 0.5: user.bonus = round(bonus, 2) else: user.bonus = 0.00 db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except Exception as e: print "error updating bonus" print e abort(404) # again, bad to display HTML, but...
def complete_exp(): if not 'uniqueId' in request.form: raise ExperimentError('improper_inputs') unique_id = request.form['uniqueId'] current_app.logger.info("completed experimente") try: user = Participant.query.\ filter(Participant.uniqueid == unique_id).one() user.status = COMPLETED user.endhit = datetime.datetime.now() db_session.add(user) db_session.commit() resp = {"status": "success"} except exc.SQLAlchemyError: current_app.logger.error("DB error: Unique user not found.") resp = {"status": "error, uniqueId not found"} return jsonify(**resp)
def complete_condition(): if not 'filename' in request.form: abort(404) else: try: pix = Pixels.query.filter(Pixels.filename==request.form['filename']).one() pix.n_completed = pix.n_completed + 1 if pix.illustrations == None: pix.illustrations = request.form['drawing_data'] else: pix.illustrations = pix.illustrations + request.form['drawing_data'] db_session.add(pix) db_session.commit() except: current_app.logger.info("error saving") abort(404) else: return jsonify(status="saved")
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascript client if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.filter(Participant.uniqueid == uniqueId).one() user_data = loads(user.datastring) # load datastring from JSON user.bonus = user_data['questiondata']['bonus'] db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404)
def compute_bonus(): uniqueId = request.args['uniqueId'] try: user = Participant.query.filter(Participant.uniqueid == uniqueId).one() user_data = loads(user.datastring) #! Your bonus computing logic here! # A common bonus technique is to continually save a running bonus in the # data and then take the last data row from the user_data object and # set the bonus from that. bonus = 0 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} except: resp = {"bonusComputed": "failure"} return jsonify(**resp)
def launch_new_campaign(cls, **kwargs): kwargs['is_active'] = True new_campaign = cls(**kwargs) db_session.add(new_campaign) db_session.commit() _kwargs = { 'campaign': new_campaign, 'job_id': new_campaign.campaign_job_id } from .experiment import app app.apscheduler.add_job(id=new_campaign.campaign_job_id, func=do_campaign_round, kwargs=_kwargs, trigger='interval', minutes=new_campaign.minutes_between_rounds, next_run_time=datetime.datetime.now()) return new_campaign
def compute_bonus(): current_app.logger.info("accessing route /compute_bonus") # check that request includes a uniqueId if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON user.bonus = float(user_data['questiondata']['finalBonus']) db_session.add(user) db_session.commit() #commit to database resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key('uniqueId'): raise ExperimentError( 'improper_inputs' ) # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads( user.datastring ) # load datastring from JSON [values are all of type str?] #user_data=loads(user.datastring, parse_float=decimal.Decimal) bonus = 6.00 for record in user_data['data']: # for line in data file trial = record['trialdata'] # part of line holding trial data if trial['phase'] == 'task': # for 'task' trials only if trial['rt'] > -1: bonus -= 0.02 if trial['rt'] == -1 and trial[ 'tt'] == 2: #float(trial['tt'])== 2: bonus -= 0.10 if trial['rt'] == -1 and trial['tt'] == 4: bonus -= 0.10 if bonus < 0: # no negative bonuses bonus = 0 user.bonus = bonus db_session.add(user) db_session.commit() resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def useUniqueLink(link): try: app.logger.warning('[unique_links] the link was opened') unique_link = UniqueLink.query.\ filter(UniqueLink.link == link).one() if unique_link.status < LINK_SUBMITTED and unique_link.expiresAt != None and unique_link.expiresAt < datetime.utcnow( ): app.logger.warning( '[unique_links] %s tried accessing the experiment after the link has expired', unique_link.link) app.logger.warning( '[unique_links] status: %d, expires at: %s, now: %s', unique_link.status, unique_link.expiresAt, datetime.utcnow()) unique_link.status = LINK_EXPIRED elif unique_link.status == LINK_PENDING: app.logger.warning( '[unique_links] %s tried accessing the experiment after the link has been already used', unique_link.link) unique_link.status = LINK_EXPIRED db_session.add(unique_link) db_session.commit() app.logger.warning('[unique_links] link status updated') if unique_link.status == LINK_EXPIRED: return render_template('expired.html') elif unique_link.status == LINK_SUBMITTED: return render_template('thanks.html') show_consent = config.get('Unique Links Parameters', 'show_consent') return redirect( url_for('give_consent', hitId=link, assignmentId=link, workerId=link, mode='lab', show_consent=show_consent)) except Exception as e: app.logger.error(e) abort(404)
def dashboard(): if "mode" in request.form: if request.form["mode"] == "add": if ("workerid" in request.form) and ("bonus" in request.form): newworker = LegitWorker(workerid=request.form["workerid"]) newworker.set_bonus(float(request.form["bonus"])) db_session.add(newworker) db_session.commit() elif request.form["mode"] == "delete": if "index" in request.form: current_app.logger.info("deleting") try: lw = LegitWorker.query.filter(LegitWorker.index == int(request.form["index"])).one() db_session.delete(lw) db_session.commit() except: flash(u"Sorry, was unable to delete that worker. Perhaps they were already deleted!", "error") try: workers = LegitWorker.query.all() return render_template("dashboard.html", workers=workers) except TemplateNotFound: abort(404)
def compute_bonus(): current_app.logger.info("accessing route /compute_bonus") # check that request includes a uniqueId if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this uniqueId = request.args['uniqueId'] try: # lookup user in database user = Participant.query.\ filter(Participant.uniqueid == uniqueId).\ one() user_data = loads(user.datastring) # load datastring from JSON bonuses = [] for record in user_data['data']: # for line in data file trial = record['trialdata'] # get part of line holding trial info if trial['phase']=='apavPhase' and trial['globalTrial']==252: user.bonus = float(trial['scoreAfter']) #set bonus field to the final bonus db_session.add(user) db_session.commit() #commit to database resp = {"bonusComputed": "success"} return jsonify(**resp) except: abort(404) # again, bad to display HTML, but...
def complete_session(): if not 'trialdata' in request.form: abort(404) else: trialdata = loads(request.form['trialdata']) try: for trial in trialdata: log_print(trial) word_txt = trial['word'] rt = trial['rt'] features = trial['features'] log_print(word_txt) # update word word = Word.query.filter(Word.word_string==word_txt).one() log_print(word.word_string) for feature_index in features.keys(): feature_name = features[feature_index]['feat'] log_print(feature_index) log_print(feature_name) # update feature feature = Feature.query.filter(Feature.feature_string==feature_name).one() log_print(feature.feature_string) db_session.add(feature) # record rating myrating = Rating(word, feature, request.form['uniqueId']) myrating.set_rating(float(features[feature_index]['rating'][:-1])) log_print(request.form['uniqueId']) db_session.add(feature) db_session.add(myrating) db_session.add(word) db_session.commit() log_print("saved") except: log_print("error saving") abort(404) else: return jsonify(status="saved")
with open('./stims/amt_unique_words.csv', 'rb') as f: amt_words = list(tuple(rec) for rec in csv.reader(f, delimiter='\t')) with open('./stims/amt_unique_defs.csv', 'rb') as f: amt_defs = list(tuple(rec) for rec in csv.reader(f, delimiter='\t')) with open('./stims/amt_feats.csv', 'rb') as f: amt_feats = list(tuple(rec) for rec in csv.reader(f, delimiter='\t')) # populate words table with words and definitions for idx in range(len(amt_words[0])): word=Word() word.word_string=amt_words[0][idx] word.word_definition=amt_defs[0][idx] db_session.add(word) db_session.commit() # put features in the feature table for cfeat in amt_feats[0]: feature=Feature() feature.feature_string=cfeat db_session.add(feature) db_session.commit() # rating=Rating(word, feature) # rating.set_rating(98) # db_session.add(rating)
TILEPATH = './static/images/tiles/' TARGETFILE = 'brain.png' NTILES = 16 # first delete all the files in the static/images/tiles folder files = os.listdir(TILEPATH) for myfile in files: if myfile != 'placeholder.txt': print "removing existing file", TILEPATH+myfile os.remove(TILEPATH+myfile) # query existing pixels Pixels.query.delete() # create the tiles using the target image tiles = image_slicer.slice(TARGETFILE, NTILES, save=False) image_slicer.save_tiles(tiles, prefix='tile', directory='static/images/tiles', format='png') # add tiles to database for tile in tiles: pixel_width, pixel_height = tile.image.size print "dimensions:", (pixel_width, pixel_height) , "filename:", tile.filename pixel_attributes = dict(filename = tile.filename, n_completed = 0, width = pixel_width, height = pixel_height) pixel = Pixels(**pixel_attributes) db_session.add(pixel) db_session.commit()
def compensate(): #getrequest parts try: workerId = request.args['workerId'] except: #keyError: now workerId was provided #render dat entry page try: return render_template('compensateentry.html') except TemplateNotFound: abort(404) if workerId == "": try: return render_template('compensateentry.html') except TemplateNotFound: abort(404) # Messages. Maybe move into the template? messages = { "hitSubbed": {"type": "success", "title": "Your HIT is under review.", "content": "It looks like you already submitted your HIT. We'll take action on it soon!"}, "returnHIT": {"type": "info", "title":"Please return your HIT.", "content":"In order to recieve compensation, please submit or return your HIT then refresh this page. Thanks."}, "notEnough": {"type": "info", "title":"Sorry; you're not eligible for payment.", "content": "It looks like you didn't make it far enough into the experiment to be eligible for payment. However, we've removed you from our list of participants so if we ever run the experiment again, you may participate!"}, "takeDummy": {"type": "info", "title":"Please complete the Compensation HIT.", "content": """Because you haven't submitted work for us in the past, we need you to complete a 'dummy' compensation HIT. Follow these instructions: <ol> <li>Return the HIT if you have not yet done so. <li>Go here: <a href="https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&requesterId=AH1PO6KC4YRE3" target="_blank">CPL's HITs on MTurk</a> <li>Take and submit the HIT called "Psiturk Compensation HIT - DO NOT TAKE UNLESS INSTRUCTED TO DO SO" <li>Wait 3-5 minutes and refresh this page. </ol>"""}, "success": {"type": "success", "title": "We have credited your account.", "content": "Thanks - you've been given a bonus of $%s for your time."}, "alreadyPayed": {"type": "success", "title": "You've been payed.", "content": "Our records show you have already been payed for this HIT. Thanks for your participation!"}, "fatal": {"type": "warning", "title": "Something went wrong.", "content": """Please contact us at <a href="mailto:[email protected]">[email protected]</a> and include the following information: <ul> <li>worker id: %(workerid)s <li>assignmentid: %(assignmentid)s </ul> """} } # Get the row of the worker in the database worker = Participant.query.\ filter(Participant.workerid == workerId).first() # filter(Participant.assignmentid == assignmentId, # Participant.hitid == hitId).first() # If the worker is in the db, check status if worker: #grab the rest of the info hitId = worker.hitid assignmentId = worker.assignmentid #if worker has already submitted, if worker.status in [4]: message = messages['hitSubbed'] #if the worker was already bonused elif worker.status in [5,7]: message = messages['alreadyPayed'] #if the worker's HIT is still in progress, tell them to turn it in elif worker.status in [0,1,2,3]: message = messages['returnHIT'] #if the worker did in fact quit early (meaning they can't finish it) else: # worker.status == 6 #get trialCount and conditionNum conditionNum = "" trialCount = 0 if hasattr(worker, 'datastring'): try: # get condition workerobj = loads(worker.datastring) conditionNum = workerobj['questiondata']['realCondition'] except: #print "malformed datastring for worker", worker.workerid pass try: #count trials trials = workerobj['data'] for trial in trials: trialCount += int(trial['trialdata']['phase'] == 'TEST') except: # print "no data" pass #If they didn't complete any trials, # remove them from db and display sorry print "Num trials completed:", trialCount if trialCount == 0: db_session.delete(worker) db_session.commit() message = messages['notEnough'] else: #they completed some of the trials #min bonus is 1 c. amount = max(0.01,round(float(trialCount)/[417,818][conditionNum]*2.50,2)) amount = min(amount, 2.50) #sanity check try: bonusAssignment = getAnAssignmentId(workerId) worker_bonus(bonusAssignment, amount, 'auto bonus system') #update worker worker.status = 7 db_session.add(worker) db_session.commit() message = messages['success'] message['content'] = message['content'] % amount except NoAMTConnection: abort(503) except WorkerAlreadyCredited: message = messages['alreadyPayed'] except CreditTransactionError: message = messages['fatal'] message['content'] = message['content'] % {"workerid": workerId, "assignmentid": assignmentId} except WorkerNotRegistered: message = messages['takeDummy'] else: message = messages['notEnough'] try: return render_template('compensate.html', message = message, workerId = workerId) except TemplateNotFound: abort(404)
def compute_bonus(): # check that user provided the correct keys # errors will not be that gracefull here if being # accessed by the Javascrip client if not request.args.has_key('uniqueId'): raise ExperimentError('improper_inputs') # i don't like returning HTML to JSON requests... maybe should change this # lookup user in database uniqueid = request.args['uniqueId'] user = Participant.query.\ filter(Participant.uniqueid == uniqueid).\ one() # load the bonus information with open("static/json/bonus_map_adp_pac_nonadp.json", "r") as fh: bonuses = json.load(fh)['stim_bonus'] current_app.logger.info("Computing bonus for unique id '%s'", uniqueid) total_bonus = 0 try: stim = None data = json.loads(user.datastring)["data"] for record in data: trialdata = record['trialdata'] if trialdata['eventType'] == "INITIALIZE_TRIAL": #and trialdata['stimType'] == "normal": stim = trialdata['stimId'] elif trialdata['eventType'] == "END_TRIAL" and stim is not None: #sequence = "".join([str(int(x) + 1) for x in trialdata['humanGoalSeq']]) if stim.find("h_move") != -1: sequence = "".join([str(int(x) + 1) for x in trialdata['humanCapSeq']]) elif stim.find("r_move") != -1: sequence = "".join([str(int(x) + 1) for x in trialdata['predGoalSeq']]) if sequence not in bonuses[stim]: current_app.logger.error( "no such sequence '{}' for stimulus '{}' ({})".format( sequence, stim, uniqueid)) raise KeyError trial_bonus = round(bonuses[stim][sequence], 2) # stored_bonus = round(trialdata['trialBonus'] / 100.0, 2) total_bonus = round(total_bonus + trial_bonus, 2) # if trial_bonus != stored_bonus: # current_app.logger.warning( # "bonus mismatch for {} on stim {} with sequence {}: {:f} (json) vs {:f} (js)".format( # uniqueid, stim, sequence, trial_bonus, stored_bonus)) user.bonus = total_bonus db_session.add(user) db_session.commit() resp = { "uniqueId": uniqueid, "bonusComputed": "success", "bonusAmount": total_bonus } except: current_app.logger.error("error processing bonus for {}".format(uniqueid)) current_app.logger.error(traceback.format_exc()) resp = { "uniqueId": uniqueid, "bonusComputed": "failure", "bonusAmount": total_bonus } current_app.logger.info(str(resp)) return jsonify(**resp)