Skip navigation
All Places > Canvas Admins > Blog > Author: Gerald Q. Maguire

Canvas Admins

6 Posts authored by: Gerald Q. Maguire

In one of the courses that I have been responsible for there is a final oral presentation with formal opponents who have previously written an opposition report. During the final oral presentation, I have found it very useful to have a spreadsheet with the presentations sorted into time order - and with columns ready to take notes on the presentation, on the oral oppositions, etc. Now that another teacher is going to take over the responsibility for this course I have been showing other teachers how to organize things to make it easier for them in this course. I realized when showing my spreadsheet to the new person that will take over the course that I have been stupid and should have made more of this directly in the gradebook. The result is that I made a program to add the desired custom columns to the gradebook for the teacher to write their notes during the presentation and to populate the columns with the material that is known (in this case the scheduled date and time for the presentation and the names of the opponent(s) for each student (these were peer reviewers of a draft of the report). I have separately added a column that contains the name of the project group that each student is in. The resulting program can be found at:

https://github.com/gqmaguirejr/Canvas-tools/blob/master/add-columns-for-II2202-final-presentation.py

 

Still to be done is to extract the title of the project from the draft report that was submitted by the project group and possibly a compressed version of the grading and feedback on the written opposition.

 

In any case, the program shows what can be done with the API to get the users in a course, the groups in a course, the members of each group, calendar events for the course, etc.

Recently two courses had actual enrollments that exceeded the physical capacity of the classrooms where they were scheduled. I am thinking about writing a tool that would use the student registration data for each Canvas course to compare against the seating capacity of the classrooms that have been assigned to this course.

 

The basic idea is to use the Canvas API to get the enrollment data, then get the scheduling information (from TimeEdit), then get the classroom data via a local API that gives information about each classroom (including seating capacity for classes and exams). Ideally, this should be able to notify the responsible teacher and the scheduling office when there are too many students for the planned classroom. [Yes, I am aware that many universities avoid this problem either with very good pre-registration systems or via setting caps on the number of students who can enroll in a course. Unfortunately, locally the first is unavailable - scheduling happens almost 6 months before the course, while the latter is possible - it is undesirable.]

 

Has anyone already used Canvas in this way?

 

The above is a potential tool that I am considering for a potential project "More tools for Canvas: Helping to simplify the life of students and teachers" - my goal is to devote ~50% of my time for a year (2019) to create tools to support e-learning activities at my university.

 

A first subproject in the above project is a tool to provide an interactive quiz to collect data for students planning to start a degree project, with the goals: (1) eliminate a paper form, (2) ask only the minimal set of questions necessary, (3) automatically enter this data into custom columns of a gradebook, (4) greatly simplify life for students, teachers, and administrators, and (5) as a part of a process to streamline the entire process from a student submitting a proposal for a topic to the student completing their thesis (with oral presentation and final approved thesis).

In my recent efforts to migrate data into Canvas from another reporting system one of the things that I found useful was to enroll all the users into the course and set their state as active, but for students who should not have access to the course (because they have taken a leave, quit, have an administrative hold on course participation, ...) - after adding their data to the gradebook - simply set their state to inactive (deactivate the student).

The code below shows how to do this in python:

def deactivate_user(course_id, enrollment_id):     global Verbose_Flag     #Request Method: POST     # DELETE /api/v1/courses/:course_id/enrollments/:id     # Scope: url:DELETE|/api/v1/courses/:course_id/enrollments/:id     # Conclude, deactivate, or delete an enrollment. If the task argument isn't given, the enrollment will be concluded.      url = baseUrl + '%s/enrollments/%s/?task=deactivate' % (course_id, enrollment_id)     if Verbose_Flag:        print("url: " + url)      r = requests.delete(url, headers = header)     if Verbose_Flag:            write_to_log("result of put of reactivate: " + r.text)     if r.status_code == requests.codes.ok:        page_response=r.json()        if Verbose_Flag:               print("deactivated {0} in course {1}".format(enrollment_id, course_id))        return True     else:        if r.status_code == 404: # "404 Not Found"               write_to_log("status code: " + str(r.status_code))        else:               write_to_log("status code: " + str(r.status_code))     return False 

One surprise in doing the above is that one has to use the student enrollment_id and not their user_id. One can find this enrollment_id with:

def active_user_in_course_by_user_id(course_id, user_id):        # Use the Canvas API to get the list of users enrolled in this course        #GET /api/v1/courses/:course_id/enrollments        # user_id string     Filter by user_id (only valid for course or section enrollment queries). If set to the current user's id, this is a way to determine if the user has any enrollments in the course or section, independent of whether the user has permission to view other people on the roster.         url = baseUrl + '%s/enrollments' % (course_id)        if Verbose_Flag:               print("url: " + url)         extra_parameters={'user_id': user_id,                          'enrollment_type[]': 'StudentEnrollment,TeacherEnrollment,TaEnrollment,DesignerEnrollment,ObserverEnrollment',                          'state[]': 'active'        }        print("extra_parameters={}".format(extra_parameters))        r = requests.get(url, params=extra_parameters, headers = header)        if Verbose_Flag:               write_to_log("result of getting enrollments: " + r.text)         if r.status_code == requests.codes.ok:               page_response=r.json()               return page_response        return None

In conjunction with migrating users from one source to another (such asMigrating grades from one Canvas course to another ). I found it useful to be able add users based on their SIS ID and to be able set them to inactive or reactivate them.

The results are python programs to enroll a user:

enroll_person_in_course_by_SISID.py course_id SISID role

and a program to inactivate or reactivate the user:

set_enrollment_state_of_SISID_person_in_course.py course_id SISID state

 

Examples with pictures and code are at activating and reactivating users: Chip sandbox 

Notes

Initially I was enrolling the user with a given state, but this has the undesirable side effect of putting them in the default section and not just changing their state (if they are already enrolled). Looking at what the GUI sends when deactivating and reactivating a user let me to the solution adopted in the two programs above. The main gotcha was that you have to use the enrollment_id and not the sis_id or user_id, this means that given the user's SIS ID you first have to lookup the user to find their enrollment_id. Unfortunately, the GET /api/v1/courses/:course_id/enrollments state[] parameter does not seem to support an array of values, but rather has to be a string with one of the values; this means that one has to lookup inactive users separately from active users. It would be desirable if the state could be a vector of values or is there was synthetic state "all". Even more confusing as the parameter name is state[] , which to me suggests that it has an array value.

 

Background

Now what caused me to do the above? A question came up about what to do with users that could be migrated, but whose status was that they had interrupted their studies in the course or for some other reason could not complete the course.  I would like to thank Brian Neporadny for his answer in When do you archive / remove / disable users and content?  that lead to exploring the idea of adding these users, adding their grades, and then setting their state to inactive. In this way the instructor can see the grades of the student for those assignments that did have a reported result, while not allowing the student access to the course. [For testing purposes it was useful to be able to reactivate a user after setting them inactive.]

My recent attempt to migrate users' grades for assignments from a pre-Canvas course to Canvas starts by adding the users to a Canvas course, then adding the assignments, and then finally adding each student's grade for each assignment.

 

Of course such a program requires testing. This testing creates lots of enrollments for users. In order to run the program again it is very convenient to remove these users. Similarly there is a need to remove the created assignments. Hence I wrote two scripts:  (1) to remove users (except for myself) and (2) to remove all assignments.

 

You can find the code for them at Removing other users and assignments: Chip sandbox .

 

One of the small gotchas that I found is that to remove a user from enrollment in a course you need to use the user's enrollment_id and not their canvas_id.

In the first several year of using Canvas I spent a lot of time moving content (especially quizzes) from the prior LMSs, but this is my first major attempt to move state information for students. Has anyone else addressed such a migration?

 

In this migration effort, I need to move records of students' grades from another system into Canvas. Many of these students have partially completed an earlier course round (a specific session of the course) prior to the introduction of Canvas and now need to complete the remainder of the requirements for the course (for which they will have to register for a new course round that will be in Canvas).

 

One difficulty was that these grades were from a number of different grading systems (more than a dozen of them). One of my colleagues suggested a grading standard that would capture all of the different grades (a unified grading standard), so that when looking at grades in the gradebook for each assignment you would see the original grades. In this way a teacher could see which parts had already been completed by the student and which parts remain, and then act accordingly.

 

I was pleasantly surprised at how easy it was to add the new grading standard, but do not yet know what unexpected repercussions will occur by using it. For those who are interested in examples and the program that puts the new grading standard into a course or account, see Grading standard: Chip sandbox .

 

As a side question is there anyone who has used an ECTS A-F and Fx grading standard or the corresponding Pass/Fail grading standard for their institution? I am a bit surprised that both of these do not come as predefined grading standards for an LMS used in Europe. 

 

In a subsequent blog post I will report on my migration effort via experiments in enrolling students into a Canvas course, adding each of the assignments from the earlier course round, and then populating the gradebook with grades.

Filter Blog

By date: By tag: