Example #1
0
def calculate_idr_average(param):
    """
    A function to get the average idr of
    the items:
    It gets a list of each item's idr, and
    then calculates the average.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a float: the average idr
    """
    service_key = get_service_config(11)
    catch_error = get_error(param)
    if catch_error[0]:
        return {service_key: catch_error[1]}
    inp = update_input(param)
    idr_dict = list(calculate_idr(inp).values())[0]
    if idr_dict == get_keyword_value("bad_mean"):
        return {service_key: get_keyword_value("bad_mean")}
    idr_list = list(list(idr_dict.values()))
    num_items = len(idr_list)
    idr_avg = sum(idr_list) / num_items
    idr_avg = round(idr_avg, 3)

    return {service_key: idr_avg}
Example #2
0
def get_group_list(param):
    """
    A function to get all the groups
    of students taking the exam:
    It iterates through every student's information
    adding their group to a list if it 
    exists and isnt already in the list.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: list of strings: a list containing 
             all listed groups
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    student_list = get_student_list(inp)
    group_list = []

    for i in student_list:
        curr_group = i[get_keyword_value("group")]
        for k in curr_group:
            if k not in group_list:
                group_list.append(k)

    if len(group_list) == 1:
        return get_keyword_value("no_group")

    group_list.sort()

    return group_list
Example #3
0
def get_item_ids(param):
    """
    A function to get a list of all the item ids 
    used in the exam:
    It iterates through a list of all the items a
    student responded to, and then adds that item's
    id to the id list if it isn't already in it.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: list of strings: a list containing all item ids
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    student_list = get_student_list(inp)
    id_list = []
    response_list = []

    for i in student_list:
        response_list.append(i[get_keyword_value("item_responses")])

    for i in response_list:
        for k in i:
            curr_id = k[get_keyword_value("item_id")]
            if curr_id not in id_list:
                id_list.append(curr_id)

    id_list.sort()

    return id_list
Example #4
0
def get_sorted_responses(param):
    """
    A function to sort every student's response
    to an item based on its item id:
    It calls the get_item_ids function and then
    creates a dictionary with the item ids as keys.
    Then it iterates through every students' responses
    adding each item response to its corresponding key
    in the dictionary. It then creates a now sorted 
    list of each student's responses based on its 
    index in the dictionary.


    :param: a json in the Reliabilty Measures
            standard json format
    :return: list of lists of ints: a list containing 
             all students' responses in order of item id
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    student_list = get_student_list(inp)
    num_students = len(student_list)
    id_list = get_item_ids(inp)
    response_list = []
    responses = {}

    for i in student_list:
        response_list.append(i[get_keyword_value("item_responses")])

    for i in id_list:  # Create a dictionary with the item IDs as keys
        responses[i] = []

    for i in response_list:  # For each student response list i
        checklist = id_list.copy()
        for k in i:  # For each question k
            for j in responses:  # For each item ID j
                # If item IDs match, add response to dictionary
                if k[get_keyword_value("item_id")] == j:
                    responses[j].append(k[get_keyword_value("response")])
                    checklist.remove(j)

        if len(checklist) != 0:
            for i in checklist:
                responses[i].append(0)

    sorted_resp = []
    for i in range(0, num_students):  # For each student
        student_responses = []
        for k in responses:  # For every item ID
            # Create a list of the students responses sorted by item ID
            student_responses.append(responses[k][i])
        sorted_resp.append(student_responses)

    return sorted_resp
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}
Example #6
0
def get_assumptions(param):
    """
    A function to get the items for which a
    student was assumed to have a response
    of 0:
    It gets a list of all item ids listed from
    every student's responses, then iterates
    through every student. If a student doesn't
    have a response for an item in the id list,
    then that item is assumed to have a response
    of 0 for that student.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a dictionary of dictionaries:
             a dictionary with student ids as keys
             and a list of item ids as values
    """
    service_key = get_service_config(13)
    catch_error = get_error(param)
    if catch_error[0]:
        return {service_key: catch_error[1]}
    inp = update_input(param)
    student_list = get_student_list(inp)
    id_list = get_item_ids(inp)
    assumptions_dict = {}

    for i in student_list:  # For each student i
        checklist = id_list.copy()
        dupes = []
        for k in i[get_keyword_value("item_responses")]:  # For each question k
            for j in id_list:  # For each item ID j
                if k[get_keyword_value("item_id")] == j:  # If item IDs match
                    if j in checklist:
                        checklist.remove(j)
                    else:
                        dupes.append(j)
        if dupes:
            assumptions_dict[i[get_keyword_value("id")]] = {}
            assumptions_dict[i[get_keyword_value("id")]][get_keyword_value(
                "dupes")] = dupes

        if len(checklist) != 0:
            assumptions_dict[i[get_keyword_value("id")]] = {}
            assumptions_dict[i[get_keyword_value("id")]][get_keyword_value(
                "assumed")] = checklist.copy()

    if not assumptions_dict:
        return {service_key: get_keyword_value("no_assumptions")}

    return {service_key: assumptions_dict}
def calculate_topic_rights(param):
    """
    A function to calculate the number of
    correct responses in every topic for each
    student:
    It gets a list of every topic with its
    corresponding item id. If a student gets
    that item correct, then the number of right
    responses for that topic increases.

    :param: a json in the Reliability Measures
            standard json format
    :return: a dictionary of dictionaries:
             a dictionary with student ids as keys
             and a list of topics and their number
             of right responses
    """
    service_key = get_service_config(15)
    catch_error = get_error(param)
    if catch_error[0]:
        return {service_key: catch_error[1]}
    inp = update_input(param)
    student_list = get_student_list(inp)
    check_topics = get_item_topics(inp)
    topic_rights = {}

    if check_topics == get_keyword_value("no_topics"):
        return {service_key: get_keyword_value("no_topics")}

    for i in student_list:
        topic_trees = get_item_topics(inp)
        stud_id = i[get_keyword_value("id")]
        responses = i[get_keyword_value("item_responses")]
        for k in responses:
            item_id = k[get_keyword_value("item_id")]
            item_resp = k[get_keyword_value("response")]
            for j in range(0, len(topic_trees)):
                topic_ids = topic_trees[j][get_keyword_value("topic_ids")]
                if item_resp == 1 and item_id in topic_ids:
                    topic_trees[j][get_keyword_value("topic_rights")] += 1

        for k in range(0, len(topic_trees)):
            del topic_trees[k][get_keyword_value("topic_ids")]

        topic_rights[stud_id] = topic_trees

    return {service_key: topic_rights}
Example #8
0
def get_scoring_method(param):
    """
    A function to get the scoring method
    of an exam:
    Returns the "scoring_method" object from the json
    and its factor for scaled scoring.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a string: containing the scoring method. 
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    scoring_method = inp[get_keyword_value("exam")][get_keyword_value(
        "scoring_method")]
    factor = inp[get_keyword_value("exam")][get_keyword_value("scaled_factor")]

    return (scoring_method, factor)
Example #9
0
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}
Example #10
0
def calculate_topic_averages(param):
    """
    A function to calculate the average number of
    correct responses in every topic:
    It gets the total number of right responses
    per topic and then divides them by the total
    number of students.

    :param: a json in the Reliability Measures
            standard json format
    :return: a list of dictionaries, a list of
             each topic and its average number
             of right responses
    """
    service_key = get_service_config(16)
    catch_error = get_error(param)
    if catch_error[0]:
        return {service_key: catch_error[1]}
    inp = update_input(param)
    topic_avgs = get_item_topics(inp)
    topic_responses = calculate_topic_rights(inp)[get_service_config(15)]
    num_topics = len(topic_avgs)
    num_students = len(topic_responses)
    check_topics = get_item_topics(inp)

    if check_topics == get_keyword_value("no_topics"):
        return {service_key: get_keyword_value("no_topics")}

    for i in range(0, num_topics):
        avg_rights = 0
        for k in topic_responses:
            rights = topic_responses[k][i][get_keyword_value("topic_rights")]
            avg_rights += rights
        avg_rights /= num_students
        avg_rights = round(avg_rights, 3)
        topic_avgs[i][get_keyword_value("topic_rights")] = avg_rights

    for i in range(0, num_topics):
        del topic_avgs[i][get_keyword_value("topic_ids")]

    return {service_key: topic_avgs}
Example #11
0
def get_error(param):
    """
    A function to get the errors from an input:
    It checks whether the param is already an error
    message (from a previous update_input() call).
    If not, then it calls update_input() and checks again.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a tuple with the first value a bool
             of whether or not there was an error, and the
             second value the error message.
    """
    if param == get_keyword_value("bad_data") or param == get_keyword_value(
            "bad_num_items"):
        return (True, param)
    inp = update_input(param)
    if inp == get_keyword_value("bad_data") or inp == get_keyword_value(
            "bad_num_items"):
        return (True, inp)

    return (False, inp)
Example #12
0
def get_exclude_recos(param):
    """
    A function to get a recommendation of
    items to exclude from the exam based on
    their idr values:
    It get every item's idr, and if it's less than
    0.09, it adds it to the exclude recommendations.
    If the number of recommendations is greater
    than half the number of items, only recommend
    items with idr values less than 0.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a list of strings: a list of item ids
    """
    service_key = get_service_config(9)
    catch_error = get_error(param)
    if catch_error[0]:
        return {service_key: catch_error[1]}
    inp = update_input(param)
    idr_dict = list(calculate_idr(inp).values())[0]
    if idr_dict == get_keyword_value("bad_mean"):
        return {service_key: get_keyword_value("bad_mean")}
    exclude_list = []
    for i in idr_dict:
        if idr_dict[i] <= get_keyword_value("exclude_threshold_1"):
            exclude_list.append(i)
    
    if len(exclude_list) >= len(idr_dict)*get_keyword_value("exclude_length_1"):
        exclude_list = []
        for i in idr_dict:
            if idr_dict[i] < get_keyword_value("exclude_threshold_2"):
                exclude_list.append(i)
    
    # if len(exclude_list) >= len(idr_dict)*get_keyword_value("exclude_length_2"):
    #     return {service_key: get_keyword_value("bad_exam")}
        
    return {service_key: exclude_list}
Example #13
0
def get_student_list(param):
    """
    A function to get the list of students from
    the Reliabilty Measures standard json format.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: list of student information: a list
             containing every student's item responses,
             id, and group if given
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    student_list = list(inp[get_keyword_value("student_list")])

    return student_list
Example #14
0
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}
Example #15
0
def get_student_ids(param):
    """
    A function to get a list of all the student ids:
    It iterates through every student and adds their
    id to a list.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: list of strings: a list containing all student ids
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    student_list = get_student_list(inp)
    student_ids = []

    for i in student_list:
        curr_id = i[get_keyword_value('id')]
        student_ids.append(curr_id)

    return student_ids
Example #16
0
def analyze_groups(param):
    """
    A function to get an exam's analysis by 
    students' group:
    It groups all students by group and 
    then iterates over the groups, calling
    every service used to analyze an exam. 

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a dictionary of nested dictionaries:
             a dictionary with groups as
             keys and the exam analysis as values
    """
    service_key = get_service_config(14)
    catch_error = get_error(param)
    if catch_error[0]:
        return {service_key: catch_error[1]}
    inp = update_input(param)
    assumptions_key = get_service_config(13)
    assumptions = get_assumptions(inp)[assumptions_key]
    students_dict = sort_students_by_group(inp)
    group_list = get_group_list(inp)
    group_analysis = {}

    if group_list == get_keyword_value("no_group"):
        return {service_key: get_keyword_value("no_group")}

    for i in students_dict:
        curr_students = students_dict[i]
        catch_error = get_error(curr_students)
        if catch_error[0]:
            group_analysis[i] = catch_error[1]
            continue
        student_list = get_student_list(curr_students)

        val_kr20 = calculate_kr20(curr_students)
        val_idr = calculate_idr(curr_students)
        val_difficulty = calculate_difficulty(curr_students)
        val_scores = calculate_scores(curr_students)
        val_average = calculate_average(curr_students)
        val_weighted_s = calculate_weighted_scores(curr_students)
        val_weighted_avg = calculate_weighted_average(curr_students)
        val_excludes = get_exclude_recos(curr_students)
        val_diff_avg = calculate_difficulty_average(curr_students)
        val_idr_avg = calculate_idr_average(curr_students)
        val_num_correct = calculate_num_correct(curr_students)
        val_topic_rights = calculate_topic_rights(curr_students)
        val_topic_avgs = calculate_topic_averages(curr_students)

        curr_assumptions = {}
        for k in assumptions:
            for j in student_list:
                if k == j[get_keyword_value("id")]:
                    curr_assumptions[k] = assumptions[k]
        val_assumptions = {assumptions_key: curr_assumptions}

        result = {
            'overall_quiz': {
                'average': val_average['average'],
                'kr20': val_kr20['kr20'],
                'weighted_avg': val_weighted_avg['weighted_avg']
            },
            'overall_items': {
                'diff_avg': val_diff_avg['diff_avg'],
                'idr_avg': val_idr_avg['idr_avg']
            },
            'item_analysis': [],
            'student_scores': []
        }

        for k in val_difficulty['difficulty']:
            curr_idr = val_idr['idr']
            if curr_idr is not str:
                curr_idr = val_idr['idr'][k]
            result['item_analysis'].append({
                'item_id':
                k,
                'difficulty':
                val_difficulty['difficulty'][k],
                'idr':
                curr_idr,
                'num_correct':
                val_num_correct['num_correct'][k]
            })

        for k in val_scores['scores']:
            result['student_scores'].append({
                'student':
                k,
                'score':
                val_scores['scores'][k],
                'weighted_score':
                val_weighted_s['weighted_scores'][k]
            })

        items = [
            val_excludes, val_assumptions, val_topic_rights, val_topic_avgs
        ]
        for item in items:
            result.update(item)

        group_analysis[i] = result

    return {service_key: group_analysis}
Example #17
0
def sort_students_by_group(param):
    """
    A function to sort students into a dictionary 
    with the groups as keys:
    It calls the get_group_list function and
    then creates a dictionary with the years as keys.
    Then it iterates through every student and adds 
    their responses to the dictionary of their
    corresponding year.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: dictionary of responses: a dictionary
             with groups as keys and
             student responses as values in the
             Reliabilty Measures standard json format
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = update_input(param)
    student_list = get_student_list(inp)
    group_list = get_group_list(inp)
    id_list = get_item_ids(inp)
    responses_by_group = {}

    if group_list == get_keyword_value("no_group"):
        return get_keyword_value("no_group")

    for i in group_list:
        responses_by_group[i] = {
            (get_keyword_value("student_list")): [],
            get_keyword_value("item_topics"):
            inp.get(get_keyword_value("item_topics"))
        }

    for i in group_list:
        for k in range(0, len(student_list)):
            curr_item_ids = []
            curr_responses = student_list[k][get_keyword_value(
                "item_responses")]
            curr_group = student_list[k][get_keyword_value("group")]
            for j in curr_responses:
                curr_item_ids.append(j[get_keyword_value("item_id")])
            for j in id_list:
                if j not in curr_item_ids:
                    student_list[k][get_keyword_value(
                        "item_responses")].append({
                            get_keyword_value("item_id"):
                            j,
                            get_keyword_value("response"):
                            0
                        })
            for j in curr_group:
                if j == i:
                    responses_by_group[i][get_keyword_value(
                        "student_list")].append(student_list[k])

    return responses_by_group
Example #18
0
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}
Example #19
0
def get_item_topics(param):
    """
    A function to get the hierarchy of all topics
    per item:
    It iterates through every items topic info and
    creates a hierarchy for each item's topics.

    :param: a json in the Reliabilty Measures
            standard json format
    :return: a list of dictionaries:
             a list of dictionaries containing a
             topic hierarchy, its corresponding item id,
             and a placeholder number of rights.
    """
    catch_error = get_error(param)
    if catch_error[0]:
        return catch_error[1]
    inp = inp = update_input(param)
    topics = inp.get(get_keyword_value("item_topics"))

    if not topics:
        return get_keyword_value("no_topics")

    item_ids = []
    for i in topics:
        item = i.get(get_keyword_value("item_id"))
        if item:
            if item not in item_ids:
                item_ids.append(item)

    tree_dict = {}
    index = 1
    for i in topics:
        item = i.get(get_keyword_value("item_id"))
        if not item:
            while str(index) in item_ids:
                index += 1
            item = str(index)
            item_ids.append(str(index))
        tree_dict[item] = []
        tags = i.get(get_keyword_value("tags"))
        if tags:
            for k in tags:
                if k.get(get_keyword_value("scored"), "Y") != "Y":
                    continue
                curr_tree = k.get(
                    get_keyword_value("topic_tree"),
                    inp[get_keyword_value("exam")][get_keyword_value("name")])
                curr_levels = k.get(
                    get_keyword_value("topic_branch_hierarchy"))
                curr_topic = k.get(get_keyword_value("topic_tagged"),
                                   get_keyword_value("unknown"))

                level_list = []
                if curr_levels:
                    for i in curr_levels:
                        level_list.append(int(i))
                    level_list.sort(reverse=True)

                hier_level = {}
                hier_level[0] = curr_tree
                if curr_levels:
                    for i in range(1, level_list[0] + 2):
                        hier_level[i] = curr_levels.get(
                            str(i - 1), get_keyword_value("unknown"))
                    hier_level[level_list[0] + 2] = curr_topic
                else:
                    hier_level[1] = curr_topic

                tree_dict[item].append(hier_level)

    tree_list = []
    for i in tree_dict:
        for k in tree_dict[i]:
            if k not in tree_list:
                tree_list.append(k)

    tree_tuple = {}
    for i in tree_list:
        tree = tuple(sorted(i.items()))
        tree_tuple[tree] = []
        for k in tree_dict:
            for j in tree_dict[k]:
                if j == i:
                    tree_tuple[tree].append(k)
    tree_tuple = tuple(tree_tuple.items())

    final_trees = []
    for i in tree_tuple:
        tree_object = {}
        ids = i[1]
        tree = i[0]
        tree_object[get_keyword_value("topic_ids")] = ids
        tree_object[get_keyword_value("topic_hierarchy")] = tree
        tree_object[get_keyword_value("topic_rights")] = 0
        final_trees.append(tree_object)

    return final_trees
Example #20
0
def update_input(param):
    """
    A function to update the information of
    a json in the Reliabilty Measures standard 
    json format:
    If the json does not contain student ids, a
    default of 1-n is used. If no item ids are given.
    a default of 1-n is used. If a student or item is
    included in an exclude list, they are removed from
    the json.
    :param: a json in the Reliabilty Measures
            standard json format
    :return: a json in the Reliabilty Measures
            standard json format
    """
    inp = param
    exclude_students = list(
        param.get(get_keyword_value("exclude_students"), []))
    exclude_items = list(param.get(get_keyword_value("exclude_items"), []))
    student_list = list(param.get(get_keyword_value("student_list"), []))

    # If no student data was given, return with message
    if not student_list or len(student_list) <= 1:
        return get_keyword_value("bad_data")

    # If a student does not have responses, give him an empty response list
    for i in range(0, len(student_list)):
        curr_responses = student_list[i].get(
            get_keyword_value("item_responses"))
        if not curr_responses:
            student_list[i][get_keyword_value("item_responses")] = []

    # If all response lists are empty or only has one item, return with message
    valid_items = False
    for i in student_list:
        curr_responses = i[get_keyword_value("item_responses")]
        if len(curr_responses) > 1:
            valid_items = True
    if not valid_items:
        return get_keyword_value("bad_num_items")

    # If no exam object is given or it does not contain any info, update it with "unknown"
    exam_info = param.get(get_keyword_value("exam"))
    if not exam_info:
        inp[get_keyword_value("exam")] = {
            get_keyword_value("name"): get_keyword_value("unknown"),
            get_keyword_value("scoring_method"): get_keyword_value("unknown")
        }
    else:
        exam_name = exam_info.get(get_keyword_value("name"))
        scoring_method = exam_info.get(get_keyword_value("scoring_method"))
        factor = exam_info.get(get_keyword_value("scaled_factor"))
        if not exam_name:
            inp[get_keyword_value("exam")][get_keyword_value(
                "name")] = get_keyword_value("unknown")
        if not scoring_method:
            inp[get_keyword_value("exam")][get_keyword_value(
                "scoring_method")] = get_keyword_value("unknown")
        if not factor:
            inp[get_keyword_value("exam")][get_keyword_value(
                "scaled_factor")] = 1

    # If a student does not have an id, assign it a new id
    # If the student is given a group, assign it the group "unknown"
    student_ids = []
    for i in student_list:
        curr_stud = i.get(get_keyword_value("group"))
        if curr_stud:
            if curr_stud not in student_ids:
                student_ids.append(curr_stud)
    for i in range(0, len(student_list)):
        curr_stud = student_list[i].get(get_keyword_value("id"))
        curr_group = student_list[i].get(get_keyword_value("group"))
        new_id = 1
        if not curr_stud:
            while str(new_id) in student_ids:
                new_id += 1
            student_list[i][(get_keyword_value("id"))] = str(new_id)
            student_ids.append(str(new_id))
        if not curr_group:
            student_list[i][(get_keyword_value("group"))] = [
                get_keyword_value("unknown")
            ]

    # If an item in a student's response list does not have an id, assign it a new id
    # If an item in a student's response list does not have a response, assign it a value of 0
    item_ids = []
    for i in range(0, len(student_list)):
        curr_responses = student_list[i][get_keyword_value("item_responses")]
        for k in range(0, len(curr_responses)):
            curr_item_id = curr_responses[k].get(get_keyword_value("item_id"))
            if curr_item_id:
                if curr_item_id not in item_ids:
                    item_ids.append(curr_item_id)
    for i in range(0, len(student_list)):
        curr_responses = student_list[i][get_keyword_value("item_responses")]
        new_id = 1
        curr_new_ids = []
        for k in range(0, len(curr_responses)):
            curr_item_id = curr_responses[k].get(get_keyword_value("item_id"))
            curr_item = curr_responses[k].get(get_keyword_value("response"))
            if not curr_item_id:
                while str(new_id) in item_ids or str(new_id) in curr_new_ids:
                    new_id += 1
                student_list[i][get_keyword_value("item_responses")][k][
                    get_keyword_value("item_id")] = str(new_id)
                curr_new_ids.append(str(new_id))
            if not curr_item:
                student_list[i][get_keyword_value("item_responses")][k][
                    get_keyword_value("response")] = 0

    # If a student's id is in the exclude list, exclude them from the data
    remove_students = []
    for i in student_list:
        if i[get_keyword_value("id")] in exclude_students:
            remove_students.append(i)
    for i in remove_students:
        student_list.remove(i)

    # If an item's id is in the exclue list, exclude it from the data
    for i in range(0, len(student_list)):
        remove_items = []
        curr_responses = student_list[i][get_keyword_value("item_responses")]
        for k in curr_responses:
            curr_item = k[get_keyword_value("item_id")]
            if curr_item in exclude_items:
                remove_items.append(k)
        for k in remove_items:
            curr_responses.remove(k)
        student_list[i][get_keyword_value("item_responses")] = curr_responses

    inp[get_keyword_value("student_list")] = student_list

    # Re-check data
    student_list = list(inp.get(get_keyword_value("student_list"), []))
    if not student_list or len(student_list) <= 1:
        return get_keyword_value("bad_data")

    valid_items = False
    for i in student_list:
        curr_responses = i[get_keyword_value("item_responses")]
        if len(curr_responses) > 1:
            valid_items = True
    if not valid_items:
        return get_keyword_value("bad_num_items")

    return inp