def test_get_sorted_responses(self): expected = [[1, 1, 0, 1, 0, 0, 0, 1], [0, 1, 1, 1, 1, 1, 0, 0], [1, 0, 0, 0, 1, 0, 1, 0]] responses = utils.get_sorted_responses(self.data) print(responses) assert expected == responses
def calculate_weighted_scores(param): """ A function to get the weighted score of each student: For each student, it gets the weight of every item they got correct by getting its difficulty and dividing it by the sum of all items' difficulties. :param: a json in the Reliabilty Measures standard json format :return: a dictionary of floats: a dictionary with student ids as keys and their weighted score as values """ service_key = get_service_config(7) catch_error = get_error(param) if catch_error[0]: return {service_key: catch_error[1]} inp = update_input(param) student_ids = get_student_ids(inp) sorted_resp = get_sorted_responses(inp) scoring_method = get_scoring_method(inp) num_items = len(sorted_resp[0]) difficulty_list = list( list(calculate_difficulty(inp).values())[0].values()) difficulty_sum = sum(difficulty_list) weighted_scores_dict = {} for curr_id in student_ids: weighted_scores_dict[curr_id] = None j = 0 for i in weighted_scores_dict: weighted = 0 for k in range(0, num_items): if sorted_resp[j][k] == 1: weighted += difficulty_list[k] weighted /= difficulty_sum if scoring_method[0] == get_keyword_value("percentage"): weighted = round(weighted * 100, 3) elif scoring_method[0] == get_keyword_value("absolute"): weighted = round(weighted * num_items, 3) elif scoring_method[0] == get_keyword_value("scaled"): weighted = round(weighted * scoring_method[1], 3) else: weighted = round(weighted, 3) weighted_scores_dict[i] = weighted j += 1 return {service_key: weighted_scores_dict}
def calculate_scores(param): """ A function to get the score of each student: For each student, it gets the number of correct responses and divides it by the number of questions. :param: a json in the Reliability Measures standard json format :return: a dictionary of floats: a dictionary with student ids as keys and their score as values """ service_key = get_service_config(4) catch_error = get_error(param) if catch_error[0]: return {service_key: catch_error[1]} inp = update_input(param) sorted_resp = get_sorted_responses(inp) student_ids = get_student_ids(inp) scoring_method = get_scoring_method(inp) num_items = len(sorted_resp[0]) score_dict = {} for curr_id in student_ids: score_dict[curr_id] = None k = 0 for i in score_dict: num_right = sum(sorted_resp[k]) score = num_right / num_items if scoring_method[0] == get_keyword_value("percentage"): score = round(score * 100, 3) elif scoring_method[0] == get_keyword_value("absolute"): score = round(score * num_items, 3) elif scoring_method[0] == get_keyword_value("scaled"): score = round(score * scoring_method[1], 3) else: score = round(score, 3) score_dict[i] = score k += 1 return {service_key: score_dict}
def calculate_kr20(param): """ A function to get the kr20 value of an exam: First it get the number of items divided by the number of items - 1. Then it multiplies that by 1 - the summation of the product of the proportion of those who got an item right by the proportion of those who got it wrong divided by the variance of the students' scores. :param: a json in the Reliabilty Measures standard json format :return: a float: the kr20 """ service_key = get_service_config(1) catch_error = get_error(param) if catch_error[0]: return {service_key: catch_error[1]} inp = update_input(param) sorted_resp = get_sorted_responses(inp) num_students = len(sorted_resp) num_items = len (sorted_resp[0]) pq_list = [] score_std = get_score_std(inp) if score_std <= 0: return {service_key: get_keyword_value("bad_std")} for i in range(0, num_items): p = 0 for k in range(0, num_students): p += sorted_resp[k][i] p /= num_students q = 1 - p pq_list.append(p * q) pq_sum = sum(pq_list) kr20_value = (num_items /(num_items - 1)) * (1 - (pq_sum / (score_std ** 2))) kr20_value = round(kr20_value, 3) return {service_key: kr20_value}
def calculate_difficulty(param): """ A function to get the difficulty of each item on the exam: It calculates how many students got an item correct, and then divides it by the total number of students. :param: a json in the Reliabilty Measures standard json format :return: a dictionary of floats: a dictionary with item ids as keys and the difficulty as values """ service_key = get_service_config(3) catch_error = get_error(param) if catch_error[0]: return {service_key: catch_error[1]} inp = update_input(param) sorted_resp = get_sorted_responses(inp) num_students = len(sorted_resp) num_items = len(sorted_resp[0]) id_list = get_item_ids(inp) difficulty_list = [] difficulty_dict = {} for i in range(0, num_items): # For each question i numRight = 0 for k in range(0, num_students): # For each student k studentAnswer = sorted_resp[k][i] numRight += studentAnswer difficulty = 1 - numRight / num_students difficulty = round(difficulty, 3) difficulty_list.append(difficulty) k = 0 for i in id_list: difficulty_dict[i] = difficulty_list[k] k += 1 return {service_key: difficulty_dict}
def calculate_idr(param): """ A function to get the idr of each item: For every item, it calculates the mean score of students who got the answer right and subtracts it by the mean score of those who got it wrong. Then it multiplies that by the square root of the number of students who got the item right multiplied by the total of those who got it wrong. Then it divides that by the number of students multiplied by the std of the students' scores. :param: a json in the Reliabilty Measures standard json format :return: a dictionary of floats: a dictionary with item ids as keys and idr as values """ service_key = get_service_config(2) catch_error = get_error(param) if catch_error[0]: return {service_key: catch_error[1]} inp = update_input(param) sorted_resp = get_sorted_responses(inp) num_students = len(sorted_resp) num_items = len(sorted_resp[0]) id_list = get_item_ids(inp) score_std = get_score_std(inp) idr_list = [] idr_dict = {} if score_std < 0: return {service_key: get_keyword_value("bad_std")} for i in range(0, num_items): # For each question i right_list = [] wrong_list = [] num_right = 0 num_wrong = 0 for k in range(0, num_students): # For each student k if sorted_resp[k][i] == 1: # If student k gets question i correct score = sum(sorted_resp[k]) / num_items right_list.append( score) # Then add their score to the "right" list num_right += 1 elif sorted_resp[k][i] == 0: # If student k gets question i wrong score = sum(sorted_resp[k]) / num_items wrong_list.append( score) # Then add their score to the "wrong" list num_wrong += 1 if num_right == num_students or num_wrong == num_students: idr_list.append(0) continue if len(right_list) == 1: right_mean = right_list[0] elif len(right_list) > 1: right_mean = mean(right_list) if len(wrong_list) == 1: wrong_mean = wrong_list[0] elif len(wrong_list) > 1: wrong_mean = mean(wrong_list) if not right_mean or not wrong_mean: return {service_key: get_keyword_value("bad_mean")} idr = ((right_mean - wrong_mean) * sqrt(num_right * num_wrong)) / num_students * score_std idr = round(idr, 3) idr_list.append(idr) k = 0 for i in id_list: idr_dict[i] = idr_list[k] k += 1 return {service_key: idr_dict}