1

I'm writing the following code to calculate consolidated grades of student to manage their Transcript, but not getting desired output, could someone help me in this,Thanx!

def transcript(coursedetails, studentdetails, grades):
    studentdetails.sort()
    coursedetails.sort()
    grades.sort()
    result=[(student,grade,coursedetail)
            for student in studentdetails 
            for grade in grades for coursedetail in coursedetails 
            if((student[0]==grade[0])and(grade[1]==coursedetail[0]))]
    print(result)

Input I'm giving is---

transcript([("MA101","Calculus"),("PH101","Mechanics"),("HU101","English")],[("UGM2018001","Rohit Grewal"),("UGP2018132","Neha Talwar")],[("UGM2018001","MA101","AB"),("UGP2018132","PH101","B"),("UGM2018001","PH101","B")])

Actual Output---

[(('UGM2018001', 'Rohit Grewal'), ('UGM2018001', 'MA101', 'AB'), ('MA101', 'Calculus')), (('UGM2018001', 'Rohit Grewal'), ('UGM2018001', 'PH101', 'B'), ('PH101', 'Mechanics')), (('UGP2018132', 'Neha Talwar'), ('UGP2018132', 'PH101', 'B'), ('PH101', 'Mechanics'))]

Desired Output---

[('UGM2018001', 'Rohit Grewal', [('MA101', 'Calculus', 'AB'), ('PH101', 'Mechanics', 'B')]), ('UGP2018132', 'Neha Talwar', [('PH101', 'Mechanics', 'B')])]
jpp
  • 159,742
  • 34
  • 281
  • 339
Juhi
  • 11
  • 1
  • 1
    You just asked that question and we told you it was a duplicate – Olivier Melançon Mar 10 '18 at 15:20
  • Possible duplicate of ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – Anton Kazakov Mar 10 '18 at 16:25
  • I've looked over this question and I don't see resemblance to the question mentioned in the previous comment. There are not even any Default Arguments passed. – Mike Peder Mar 11 '18 at 02:16

2 Answers2

0

You may consider changing your structure from a list of tuples to a dictionary as it will be much easier to manipulate the information.

def transcript(coursedetails, studentdetails, grades):
    result = {}
    students = {}
    courses = {}
    for course, descript in coursedetails:
        courses[course] = descript
    for sid, student in studentdetails:
        students[sid] = {'name':student}
    for sid, course, grade in grades:
        details = (course, courses[course], grade)
        if not 'grades' in students[sid]:
            students[sid]['grades'] = []
        students[sid]['grades'].append(details)
    return  students

This returns a dictionary of dictionaries for your transcript where the student ids are the keys that return a dictionary holding your student's name and grades.

Test:

trans = transcript([("MA101","Calculus"),("PH101","Mechanics"),("HU101","English")],[("UGM2018001","Rohit Grewal"),("UGP2018132","Neha Talwar")],[("UGM2018001","MA101","AB"),("UGP2018132","PH101","B"),("UGM2018001","PH101","B")])

Result:

{'UGM2018001': {'name': 'Rohit Grewal', 'grades': [('MA101', 'Calculus', 'AB'), ('PH101', 'Mechanics', 'B')]}, 'UGP2018132': {'name': 'Neha Talwar', 'grades': [('PH101', 'Mechanics', 'B')]}}

If you still want this information in the Desired Output described above, then the following will create a list of tuples exactly as you needed.

list((k,v['name'], v['grades']) for k,v in trans.items())
Mike Peder
  • 728
  • 4
  • 8
0

This is possible with collections.defaultdict:

from collections import defaultdict

inputs = [("MA101","Calculus"),("PH101","Mechanics"),("HU101","English")],\
         [("UGM2018001","Rohit Grewal"),("UGP2018132","Neha Talwar")],\
         [("UGM2018001","MA101","AB"),("UGP2018132","PH101","B"),("UGM2018001","PH101","B")]

def transcript(coursedetails, studentdetails, grades):

    d = defaultdict(list)

    courses, students = dict(coursedetails), dict(studentdetails)

    for grade in grades:
        d[(grade[0], students[grade[0]])].append((grade[1], courses[grade[1]], grade[2]))

    return d

res = transcript(*inputs)

Result

defaultdict(list,
            {('UGM2018001', 'Rohit Grewal'): [('MA101', 'Calculus', 'AB'),
                                              ('PH101', 'Mechanics', 'B')],
             ('UGP2018132', 'Neha Talwar'): [('PH101', 'Mechanics', 'B')]})

If you really need a list of tuples, this is easy to transform:

res2 = [(k[0], k[1], v) for k, v in res.items()]

# [('UGM2018001', 'Rohit Grewal', [('MA101', 'Calculus', 'AB'),
#                                  ('PH101', 'Mechanics', 'B')]),
#  ('UGP2018132', 'Neha Talwar', [('PH101', 'Mechanics', 'B')])]
jpp
  • 159,742
  • 34
  • 281
  • 339