Parsing JSON to do math?
I'd recommend using a dedicated package for calculations like pandas:
first_exam_grades = pd.DataFrame.from_dict(first_exam_results, orient='index').astype(int)second_exam_grades = pd.DataFrame.from_dict(second_exam_results, orient='index').astype(int)improvements = second_exam_grades.LastExamGrade.to_frame()improvements['Improvement'] = second_exam_grades.LastExamGrade - first_exam_grades.LastExamGrade
This will give you something that looks like this:
Now you can output it anyway you'd like
list(zip(*([improvements.index.tolist()] + [improvements[c].values.tolist() for c in improvements])))
This will give you [('Bob', 54, 9), ('Jack', 70, 12)]
as you want.
One possible solution, using coroutines. Coroutine receive_message
holds up to last two values LastExamGrade
from the message for each student and produces list of student name, last grade and improvement over last grade:
json_messages = [# 1st message:{ "Bob": { "Age": "15", "LastExamGrade": "45", }, "Jack": { "Age": "16", "LastExamGrade": "58", }},# 2nd message{ "Bob": { "Age": "15", "LastExamGrade": "54", }, "Jack": { "Age": "16", "LastExamGrade": "70", }},# 3nd message (optional){ "Bob": { "Age": "15", "LastExamGrade": "14", }, "Jack": { "Age": "16", "LastExamGrade": "20", }}]def receive_message(): d, message = {}, (yield) while True: for k, v in message.items(): d.setdefault(k, []).append(v['LastExamGrade']) d[k] = d[k][-2:] # store max last two messages message = yield [(k, *tuple(v if len(v)==1 else [v[1], str(int(v[1])-int(v[0]))])) for k, v in d.items()]receiver = receive_message()next(receiver) # prime coroutinefor msg in json_messages: print(receiver.send(msg))
Prints:
[('Bob', '45'), ('Jack', '58')][('Bob', '54', '9'), ('Jack', '70', '12')][('Bob', '14', '-40'), ('Jack', '20', '-50')]