Archive for the ‘Grade Entry Forms’ Category
The problem: grade spreadsheet columns were being sorted by name instead of maintaining the order they were added in.
Knowing nothing about Ruby, this seemed like a simple task. Preserving rubric orders was already being done. It should just be a matter of saying ‘update the database in the same order you get it’, right?
Wrong. The controller receives the parameters to update the grade entry form as a hash, :params, which is unordered. So to update the database in the right order, we are going to have to decide in the view what the order should be so that it can be sent with the params.
But before working on that, maybe we can see how rubrics get their order. It turns out that rubrics get added to already created assignments (first difference) and that they are created one at a time (second difference). Their ordering is therefore much simpler because the parent is already in the database, and then it is just a matter of saving each one individually, making sure to fill in the required attributes (name and weight) before saving. This means you can just save each new rubric with a position that is either 1 more than the previous max position, or 0 if it is the first rubric for the assignment. Unfortunately, using this method for the grade entry forms would make their creation a lot more tedious than is necessary, so this idea was scrapped.
The final solution was as follows:
- Create a migration that adds a new attribute ‘position’ to GradeEntryItems. Update GradeEntryForms to order their GradeEntryItems by position.
- The ‘add_grade_entry_item_link’ method in grade_entry_form_helper.rb is already setting the key of the new columns to be added as ‘new_####’ where #### is the timestamp. This is sent in the POST params to the grade_entry_form_controller.rb for the create and update methods.
- Create a new method ‘update_grade_entry_form_params’ in grade_entry_form_helper.rb that sorts by name all of the columns that don’t already have a position. This will put all the new columns in order because they are named by timestamp. Then based on the current highest position, it adds a position to all new columns.
- In grade_entry_form_controller.rb, create and update either successfully update the model with the new params or it fail because there was an error during validation. If an error occurs, the view reloads with the old columns in the proper order (because GradeEntryForm returns them sorted by position) but the new columns in random order. Therefore, create a new method ‘sort_items_by_position’ in grade_entry_form_helper.rb so that the view can display the forms for the items in the proper order.
- When displaying the current columns in the view, I also added that it updated each item’s position so that if any columns were deleted previously, the current ones would fill in the gaps left by them. This doesn’t ensure continuous positions completely, but the only gaps in position are now only from one round of deletions and not every round of deletions.
It was more complicated than it first seemed, but the final solution seems to work pretty well!
Edit: There is an updated (more correct) schema here
I’ve been trying to figure out the best way to update the DB schema to include saving remarked grades (as well as keeping the original ones). What seems to be best so far is to add a “remark_requested” column in the “GradeEntryStudent” table, and to add a “RemarkedGrades” table with dependencies just like the “Grades” table.
We met up with Karen last week to discuss what she had in mind, and iron out some issues such as where what goes and how. We want the students to be able to request for re-marking but not make it too easy to request. We also want them to be able to edit their request until their assignment is actually in the re-marking stage by the prof/TA. We want profs to be able to comment on the re-mark request, as well as save original marks.
Our next steps over the course of the term are:
1) Figure out what is and isn’t possible to do GUI/feature-wise (i.e. familiarize ourselves with the existing framework and GUI)
2) Create a paper prototype
3) Have prototype tested by other profs and students
4) Possibly repeat steps 2) and 3)
This semester has flown by quickly! Here’s a summary of all the things that have been added to the simple grade entry feature this semester:
- Table view – I worked on some performance issues related to the grades table. I also implemented some new features for the table.
- Instructors can now enter grades for grade entry forms and the grades are automatically saved as they are entered. Each student’s total mark is automatically updated as the grades are entered. If a valid grade is entered, the table cell’s background colour changes to blue and then fades back to white. If an error occurred, the cell’s background colour is changed to red. Since it is possible for a student to have missed a test, blank marks for questions are considered to be valid.
- The grades for all the students no longer appear on a single page. Basic pagination has been implemented. In addition, alphabetical pagination has been implemented so that an instructor can use a drop-down menu to quickly jump to a page containing a particular subset of students based on their last names.
- Both unit tests and functional tests have been written for these features.
- Student interface – Students can now see their marks for grade entry forms.
- A student’s grade entry forms now appear on his/her main page when they log in. For grade entry forms for which marks have been entered and released, a student will be able to see his/her total mark as well as the class average on the main page. The student can click on a particular grade entry form to see the question-by-question breakdown of the marks. It’s possible that a student will have missed a test for some reason. If this is the case, the student’s mark will appear as N/A.
- Both unit tests and functional tests have been written for this feature.
- Releasing/unreleasing the marks – Instructors can now specify which marks to release/unrelease.
- From the Grades page, an instructor can now release or unrelease the marks for particular students or for all the students. Once a student’s marks have been released/unreleased, the marking state column of the grades table gets updated appropriately. Both releasing and unreleasing the marks are operations that are logged for future reference.
- Both unit tests and functional tests have been written for this feature.
- Uploading/downloading the marks – Instructors can upload/download the grades as a CSV file.
- From the Grades page, an instructor can choose to download the entire grades table as a CSV file. Alternatively, an instructor can choose to upload the grades from a CSV file. In the latter case, after attempting to upload the marks, a success/error message appears on the page indicating how many updates were valid/invalid.
- A review request has been submitted for this feature. Ticket #634 has been created for the unit tests and functional tests for this feature.
- Machinist tests – This semester, many of us converted existing tests to Machinist.
- The tests for grade entry forms have been converted to Machinist and all the new tests that I wrote this semester used Machinist as well.
Current State / Future Work
Simple grade entry has come a long way since I first started working on it back in September! There are a few tickets left over for some UI-related issues. (All tickets for grade entry are tagged with “Simple Grade Entry”. They’re probably a great starting point for anyone new to MarkUs!) In addition, the work that is being done to assign TAs to specific rubric elements can probably be used in a similar fashion to assign TAs to specific questions for grade entry forms. Alternatively, TAs could be given permission to modify the entire table. (This simply requires enabling the table view for TAs as well as instructors.)
Working on the grade entry feature has been a blast! I’ve learned a lot and am really glad I got to be a part of the MarkUs team!
Back in December, I blogged about performance issues related to the first version of the grades table. Two of my concerns were that the table was difficult to navigate because all of the students were shown on a single page and that the table took a long time to load or save. Since then, the grades table has undergone a bunch of changes, in an attempt to improve performance. Pagination was implemented to reduce the number of students displayed on a page, which made the table load faster. The “Save” button for the table was removed and the grades are now automatically saved as they are being entered. A drop-down list of alphabetical categories was added to make it easier for an instructor to jump to a page containing a particular set of students. All of these changes really improved the table view itself.
But, there was still one problem: when the number of students was large and when the number of questions was large, creating a grade entry form took a very long time! This is because of all the objects that were being created when the form was created. For example, say an instructor was creating a grade entry form with
q questions and there were
s students. Then, when the GradeEntryForm was being created, (
s) Grades and
s GradeEntryStudents were also being created, all in one shot. The important thing to realize is that for a table like this, all of these objects will have to be created at some point. How else can you store the grades for all the students, for all the questions, and release the grades for a particular student? However, the key thing is to create these objects in a clever way. The solution was to create GradeEntryStudents and Grades as needed, instead of when the GradeEntryForm is being created. This means that creating the form itself takes very little time! When the grades table is first loaded, the GradeEntryStudents and Grades objects do not actually exist. They are created as the user enters the grades. For example, if the user enters a grade for “Joe Smith”, we pass the Student ID and the GradeEntryItem ID to the controller. The controller then checks to see if the corresponding GradeEntryStudent exists. If it doesn’t exist, we then create it. Next, we check if the Grade for this GradeEntryItem exists. If it doesn’t exist, we create it. Otherwise, we update it. The user doesn’t even really notice these objects are being created as they are entering the grades! So now, GradeEntryForm creation and the table view itself have been improved!
As I’ve been working on the table view for grade entry last week and this week (there are still some kinks to sort out, more on that in my next post), I’ve been noticing some performance issues that I think we might want to deal with before we let instructors use this table. One thing that I needed to decide was whether or not each table cell should be saved right as the instructor enters the mark or if the instructor should enter a bunch of marks and then hit a “Save” button. I decided to go with the “Save” button option. My initial plan was to display the entire table on a single page. However, I’m finding that:
- It’s difficult to navigate
- This page can take a long time to load or save
Severin had suggested earlier that we could implement some sort of pagination. I really like this idea. Here’s what I’m thinking:
- Maybe we could implement pagination alphabetically, by last name (eg. At the bottom of the table, we could have links like “A-D”, “E-J”, etc.). This would help to reduce the number of rows that get displayed on the page at a time. We probably wouldn’t want to implement pagination using numbers because if an instructor wanted to enter grades for a particular student, he/she would have a hard time figuring out which page contains the desired student.
Any thoughts about this?
Yesterday’s meeting got me thinking more about the database schema for the grade entry feature. Here’s what I originally had in mind: Original Grade Entry Database Schema
I had originally considered a separate Grades table, as shown in the diagram. However, it would probably be better if we could combine the Grades table and the Marks table. There are two fields in the Marks table from Scenario 4 for the new marking scheme that do not really apply to simple grade entry: criterion_id and result_id. In addition, a table which stores grades for simple grade entry would require two fields which the existing Marks table does not need: grade_entry_item_id and grade_entry_student_id. The fields both tables have in common are: grade/mark, created_at, and updated_at. Any thoughts on how we could go about combining these tables?
Karen and I met yesterday to discuss the new simple grade entry feature. We went over the ideas and questions I mentioned in my initial design proposal. Here are the changes/implementation details that we discussed:
Grade Entry Form Creation:
A grade entry form is going to be treated as an assignment. This new feature will be found under the “Assignments” tab. We are going to add a new button that says “Create New Grade Entry Form” (this means that the old creation button for assignments will need to be renamed to “Create New Assignment” and “Choose Assignment” will be renamed to simply “Choose…” for now.) The creation form will contain most of the properties I described in my last post. However, in order to specify the columns for the grade entry form, the instructor will click on something like “Add Column” and enter a column name and the total number of marks for that question. The instructor can then continue to add as many columns as desired.
Views for Instructors, TAs, and Students:
- For instructors, a grade entry form will have a properties view, a graders view, and a table view.
- From the graders view, instructors will be able to assign TAs to specific grade entry forms. TAs will be given permission to edit the entire form. We’re also going to allow multiple TAs to be assigned to a single grade entry form. This means that we might need to watch out for race conditions. However, technically, two TAs should never find themselves in a situation where they are both modifying the same table cell at the same time. But, if this does happen, then a reasonable solution is to let the last writer win.
- From the table view, the instructor should also be able to download or upload the grade entry form in CSV format.
- Grade entry forms will appear on a TA’s main page along with the assignments he/she needs to mark. The TA will be able to click on a grade entry form and then the table view will get displayed.
- Grade entry forms will appear on a student’s main page along with his/her assignments. The student’s total mark will be displayed on this page and the student will be able to click on a grade entry form to see the breakdown of the marks.
I think we now have the design details sorted out. Now, it’s time to start on the implementation!
At the code sprint, we discussed some of the considerations for the new simple grade entry feature. We decided that this new feature was going to be treated as another type of “assignment” that an instructor can create. Over the last few days, I’ve been taking a closer look at the way assignments are currently handled in MarkUs. I thought it would be a good idea to first determine how this new feature is going to look for instructors, TAs, and students.
Here are the ideas I have so far:
The UI for instructors:
Under the “Assignments” tab, there should be a new creation option – something like “Create New Spreadsheet”. An alternative would be to first select “Create New”, then select the type of assignment (i.e. a regular assignment vs. a “spreadsheet”), and then the appropriate creation form could be displayed. What do you guys think of these options?
On the new “spreadsheet” creation page, the instructor should set the following properties:
- Short Identifier (T1, L1, etc.)
- Name (Term Test 1, Final Exam, Lab 1, etc.)
- Message (a description of the test, lab, etc.)
- Date (the date the test, exam, etc. took place)
- Column Name Prefix (Q, L, etc. – the actual column names in the “spreadsheet” could then contain Q1, Q2, etc.)
- Number of Questions
After the instructor enters the number of questions, we could display a table on the creation page (the dimensions of the table would be: #questions x 2) so that the instructor can enter the total number of marks each question is out of.
Views associated with a “spreadsheet” instance:
I think there should be three views associated with a “spreadsheet” instance:
1) Properties View
This would be an “Edit Spreadsheet” page, similar to the edit page for assignments. The instructor would be able to see/modify the properties that were set during “spreadsheet” creation.
2) Graders View
I think it would be good if the instructor could assign graders to an entire “spreadsheet” instance or to individual questions in a “spreadsheet”. This way, a TA could be responsible for marking and entering the grades for all the questions or only for certain questions.
3) Spreadsheet View
This would be the table that actually contains the marks. We could have columns for the student’s user name, last name, and first name, one column for each question (each of these column names would indicate what the question is out of – eg. “Q1 /10”), and an automatically generated “total” column. This table should be able to be sorted by user name/last name to make it more convenient to enter the marks.
The UI for TAs:
A “spreadsheet” instance would show up in their list of assignments that need to be marked. From the three views I described for instructors, only the Spreadsheet View would be necessary for TAs. Perhaps we could display a message at the top of this page that indicates which question(s) the TA should enter marks for.
These are my initial thoughts for the look and feel for instructors and TAs. Let me know what you guys think.
My next post will likely be about the UI for students. Stay tuned!