def choose_card(db_conn, user, unit): """ Given a user and a unit, choose an appropriate card. Return a card instance. """ # TODO-3 simplify this method unit_id = unit['entity_id'] query = (Card.start_accepted_query().filter({ 'unit_id': unit_id }).sample(10)) # TODO-2 index # TODO-3 does this belong as a model method? # TODO-2 is the sample value decent? # TODO-2 has the learner seen this card recently? cards = [Card(d) for d in query.run(db_conn)] if not len(cards): return None previous_response = get_latest_response(user['id'], unit_id, db_conn) if previous_response: learned = previous_response['learned'] # Don't allow the previous card as the next card cards = [ card for card in cards if card['entity_id'] != previous_response['card_id'] ] else: learned = init_learned shuffle(cards) assessment, nonassessment = partition(cards, lambda c: c.has_assessment()) choose_assessment = random() < p_assessment_map[floor(learned * 10)] if choose_assessment: if not len(assessment): return nonassessment[0] for card in assessment: params = get_card_parameters({'entity_id': card['entity_id']}, db_conn) if params: values = get_card_parameters_values(params) guess = values['guess'] slip = values['slip'] correct = calculate_correct(guess, slip, learned) if 0.25 < correct < 0.75: return card else: return card return assessment[0] if len(nonassessment): return nonassessment[0] if len(assessment): return assessment[0] return None
def test_calculate_correct(): assert calculate_correct(guess=0, slip=0, learned=0.5) == 0.5 assert calculate_correct(guess=1, slip=1, learned=0.5) == 0.5 assert calculate_correct(guess=0, slip=1, learned=0.5) == 0 assert calculate_correct(guess=1, slip=0, learned=0.5) == 1 assert calculate_correct(guess=0.25, slip=0.05, learned=0.9) == 0.88 assert calculate_correct(guess=0.25, slip=0.05, learned=0.5) == 0.6 assert calculate_correct(guess=0.25, slip=0.05, learned=0.1) == 0.32
def likelihood(self, data, hypothesis): """ Given new data and one of the guess hypotheses, update the probability of that hypothesis. """ score, learned, slip = \ data['score'], data['learned'], data['slip'] return (score * calculate_correct(hypothesis, slip, learned) + (1 - score) * calculate_incorrect(hypothesis, slip, learned))
def get_slip_pmf_likelihood(data, hypothesis): """ Given new data and one of the slip hypotheses, update the probability of that hypothesis. """ score, learned, guess = \ data['score'], data['learned'], data['guess'] return (score * calculate_correct(guess, hypothesis, learned) + (1 - score) * calculate_incorrect(guess, hypothesis, learned))
def choose_scored_card(scored, all_params, learned): for card in scored: params = all_params[card['entity_id']] if params: guess = params['guess'] slip = params['slip'] correct = calculate_correct(guess, slip, learned) if 0.25 < correct < 0.75: return card return scored[0]
def likelihood(self, data, hypothesis): """ Given new data and one of the slip hypotheses, update the probability of that hypothesis. """ score, learned, guess = \ data['score'], data['learned'], data['guess'] return (score * calculate_correct(guess, hypothesis, learned) + (1 - score) * calculate_incorrect(guess, hypothesis, learned))
def slip_normal(score, guess, slip, learned): if score == 1: return calculate_correct(guess, slip, learned) if score == 0: return calculate_incorrect(guess, slip, learned)
def slip_likelihood(score, guess, slip, learned): if score == 1: return calculate_correct(guess, 1, learned) if score == 0: return calculate_incorrect(guess, 1, learned)