Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move list element position, based on values

I am trying to create a web based view of our schools timetable for staff and students. I am using Django 1.8 to output this onto a table, if that makes any difference.

Sample Student CSV File: http://pastebin.com/Jf8My0RH Sample Teacher CSV File: http://pastebin.com/ie3qeT3R

All data is stored in multiple CSV files. I have the student timetables working fine, using the code below:

def get_timetable(StudentCode):
    timetable = []

    with open(TT_BASE_DIR + 'NStudTT.txt') as student_timetable:
        reader = csv.DictReader(student_timetable, fieldnames=("StudentName","StudentCode","DayNo","PeriodNo","ClassCode","TeacherCode","RoomCode","RollClassCode","LessonType"))

    for row in reader:
        if row['StudentCode'] == StudentCode:
            for day in range(11):
                if int(row['DayNo']) == day:
                    timetable.append(row)

return(timetable[x:x+10] for x in range(0, len(timetable),10))

This returns a list of 10 lists, each with 10 dictionary items which I can output into a table.

I want to do the same for teachers, however they don't always have a full timetable. This is the code I am using to get the data out of the CSV file:

def get_teacher_timetable(TeacherCode):

    timetable = []

    with open(TT_BASE_DIR + 'NTRTimeT.txt') as teacher_timetable:
        reader = csv.DictReader(teacher_timetable, fieldnames=("TeacherCode", "RoomCode", "DayNo", "PeriodNo", "RollClassCode", "ClassCode"))

    for row in reader:
        if row['TeacherCode'] == TeacherCode:
            for day in range(11):
                if int(row['DayNo']) == day:
                    timetable.append(row)
    return(temp_timetable)

I can get it to return all the items, in a single list of dictionaries. What I need to be able to do is group the dictionaries by DayNo, then insert each group into a new list. However I want to insert the entries into the list according to PeriodNo. So if there was a spare in Period 4, it would create an element of NULL, or "", etc. At the end I should have a list of 10 lists, with 10 lessons / null in each one.

Is what I want to do possible?

like image 473
Gavin W Avatar asked Sep 25 '26 17:09

Gavin W


1 Answers

Looking at your sample data, it seems like the data will be in sorted order by TeacherCode, DayNo, PeriodNo so my solution is likewise.

To simplify, first filter the reader data structure so that it only contains relevant rows.

Use 2 for loops to loop over each day and time slot. If there is a corresponding row, add that row to the schedule. If there isn't, create a new dictionary with appropriate blank spaces and add it to the schedule.

Instead of compiling the list of lists when returning, I used a list to append all the time slots for one day, then appended that list to the full timetable after each day.

Here's the code:

def get_teacher_timetable(TeacherCode):

    timetable = []

    with open(TT_BASE_DIR + 'NTRTimeT.txt') as teacher_timetable:
        reader = csv.DictReader(teacher_timetable, fieldnames=("TeacherCode", "RoomCode", "DayNo", "PeriodNo", "RollClassCode", "ClassCode"))

    rows = iter([row for row in reader if row['TeacherCode'] == TeacherCode])
    row = next(rows,None)

    for day in range(1,11):
        day_schedule = []
        for period in range(1,11):
            if row and int(row['DayNo']) == day and int(row['PeriodNo']) == period:
                day_schedule.append(row)
                row = next(rows,None)
            else:
                new_row = {"TeacherCode":TeacherCode, "RoomCode":"", "DayNo":day, "PeriodNo":period, "RollClassCode":"", "ClassCode":""}
                day_schedule.append(new_row)
        timetable.append(day_schedule)

    return(timetable)

If there is a better way to iterate through the data, please let me know.

like image 157
Hayley Guillou Avatar answered Sep 27 '26 07:09

Hayley Guillou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!