def payment(request): # Grab the profile profile = request.user.get_profile() # Grab the user's payment trial payment_trial = profile.payment_trial trial_object = TrialAnswer.objects.filter(user = request.user, question = payment_trial)[0] # Reconstruct the trial from builds.build_trials import trial problem = trial(trial_object.incomes.split(","), trial_object.interests.split(",")) # Get the responses, the wags, and, the optimal food profile, and the # totals. days_to_show = problem.days responses = trial_object.responses.split(',') wags = [calculate_wags(float(food)) for food in responses] optimum = problem.calculate_optimum() optimum_wags = map(calculate_wags, optimum) totals = {"wags": reduce(lambda x, y: x + y, wags, 0), "optimum": reduce(lambda x, y: x + y, optimum_wags, 0)} # The difference between the optimum solution and the subject's solution # is involved in the payment calculation. So is the value b, which # is a scaling parameter b = 0.01 dif = totals["optimum"] - totals["wags"] payment = round(40 - b * (dif**2), 2) # Set the payment profile.payment = payment profile.save() # Add on the proper suffix. suffix = {2: "nd", 3: "rd", 4: "th", 5: "th", 6: "th", 7: "th", 8: "th", 9: "th", 10: "th", 11: "th", 12: "th", 13: "th", 14: "th", 15: "th", 16: "th", 17: "th"} payment_trial += 1 payment_trial = str(payment_trial) + suffix[payment_trial] # Collect all of the info to show. days = [{"day": days_to_show[index], "response": responses[index], "wags": wags[index], "optimum": optimum[index]} for index in range(len(days_to_show))] context = {"user": request.user, "days": days, "totals": totals, "payment": payment, "trial": payment_trial} return render_to_response("payment.html", context)
def training_review(request): # Grab the user's profile profile = request.user.get_profile() # We want to grab the most recent answer. from builds.build_trials import trial current_problem_index = profile.trials_done - 1 trial_object = TrialAnswer.objects.filter(user = request.user, question = current_problem_index)[0] trial = trial(trial_object.incomes.split(','), trial_object.interests.split(',')) days_to_show = trial.days responses = trial_object.responses.split(',') wags = [calculate_wags(float(food)) for food in responses] optimum = trial.calculate_optimum() optimum_wags = map(calculate_wags, optimum) totals = {"wags": reduce(lambda x, y: x + y, wags, 0), "optimum": reduce(lambda x, y: x + y, optimum_wags, 0)} # Update the user's finished_training variable if necessary. if profile.trials_done == 2: next_url = "experiment" done = True else: next_url = "training" done = False # Collect all of the info to show. days = [{"day": days_to_show[index], "response": responses[index], "wags": wags[index], "optimum": optimum[index], "optimum_wags": optimum_wags[index]} for index in range(len(days_to_show))] context = {"user": request.user, "days": days, "totals": totals, "url": next_url, "done": done} return render_to_response("training_review.html", context)
def process_input(form, user, training): profile = user.get_profile() # Grab all of the non-meaningless fields. responses = filter( lambda x: x != "None", map(str, [ form.cleaned_data["Monday"], form.cleaned_data["Tuesday"], form.cleaned_data["Wednesday"], form.cleaned_data["Thursday"], form.cleaned_data["Friday"], form.cleaned_data["Saturday"], form.cleaned_data["Sunday"] ])) # Before we can submit the responses, we need to confirm that they're # legal responses given the trial's incomes and interests. To do that, # send the incomes, interests and responses over to our other helper. problem_index = profile.trials_done trial_object = TrialAnswer.objects.filter(user=user, question=problem_index)[0] from builds.build_trials import trial problem = trial(trial_object.incomes.split(","), trial_object.interests.split(",")) # Add the responses to the trial object. trial_object.add_response(user, responses) # Check if we're done with the trial. If the user is static, this is # automatically true. If they're dynamic, we need to check that the # current day is the last day of their trial. First we need to get the # trial itself to confirm this. problem_index = profile.trials_done trial_object = TrialAnswer.objects.filter(user=user, question=problem_index)[0] done_with_trial = profile.user_class == "static" or \ (profile.user_class == "dynamic" and profile.day == problem.days[-2]) # If we're done with the trial, update the trials_done counter # and check if we're now done with the training session or the # experiment itself. if done_with_trial: profile.trials_done = profile.trials_done + 1 profile.day = "Monday" # Validate the responses trial_object.validate() # If there are 2 trials completed, we just finished the training. if profile.trials_done == 2: profile.finished_training = True elif (profile.user_class == "static" and profile.trials_done == 17) or \ (profile.user_class == "dynamic" and profile.trials_done == 5): profile.finished_experiment = True # If we're NOT done with the current trial, then we can infer that # we are a dynamic user, and we need to update the day variable. else: # If the user is dynamic, update their day variable automatically. next_day = { "Monday": "Tuesday", "Tuesday": "Wednesday", "Wednesday": "Thursday", "Thursday": "Friday", "Friday": "Saturday", "Saturday": "Sunday", "Sunday": "Monday" } profile.day = next_day[profile.day] # Save the profile, and we're done! profile.save() trial_object.save() return
def experiment(request): # Get the profile profile = request.user.get_profile() # If the user has finished the training session, redirect them. if profile.finished_experiment: return HttpResponseRedirect("/diagnostics/") elif not profile.finished_training: return HttpResponseRedirect("/training/") # If the trial form has been submitted, let's check the inputs. if request.method == "POST": form = DogForm(request.POST) if form.is_valid(): process_input(form, request.user, True) # Check to see if they're now done with the experiment if request.user.get_profile().finished_experiment: return HttpResponseRedirect("/diagnostics/") # Load the form. form = DogForm(auto_id = "whatever") # Grab the problem. profile = request.user.get_profile() problem_index = profile.trials_done trial_object = TrialAnswer.objects.filter(user = request.user, question = problem_index)[0] # Reconstruct the trial from builds.build_trials import trial problem = trial(trial_object.incomes.split(","), trial_object.interests.split(",")) days_to_show = problem.days[:-1] if profile.user_class == "static" \ else [profile.day] days_inputs = calculate_days(problem, request.user) user_class = profile.user_class # Create the info for the dynamic users. today_index = problem.days.index(profile.day) # If they're dynamic, we'll want to show how much they've spent # per day. spendings = trial_object.responses if spendings: spendings = map(float, spendings.split(',')) spendings.extend(["-"]*(len(problem.days) - len(spendings))) else: spendings = ["-"]*len(problem.days) # We want to inform them how much money they can spend today. To do # so, we'll tell them how much money they actually have, plus how much # they can borrow from future days. First, calculate how much money they # have currently. incomes = map(float, problem.incomes) interests = map(float, problem.interests) carry_over = 0 for index in range(today_index): carry_over += incomes[index] - spendings[index] carry_over *= (interests[index] / 100. + 1) today_money = round(carry_over + incomes[today_index], 2) # Now calculate how much they can borrow. borrowable = float(incomes[-1]) for day in reversed(range(today_index, len(interests))): borrowable = borrowable / (1 + interests[day] / 100.) + (incomes[day] if day != today_index else 0) borrowable = round(borrowable, 2) # The amount of cash we can spend today is how much we have physically # plus how much we can borrow spendable = today_money + borrowable # Fill up the dictionary with all the info we'll need. dynamic_info = {"money": today_money, "borrowable": borrowable, "spendable": spendable, "spendings": spendings} context = {"user": request.user, "problem": problem, "days": days_to_show, "days_inputs": days_inputs, "form": form, "dynamic": dynamic_info, "class": profile.user_class} return render_to_response("experiment.html", context)