320 likes | 432 Views
E-grades– Building Block Replaces Bubble Sheets Tracy (Ting-Hong) Tan Analyst/Programmer California State University, East Bay (formerly CSU Hayward). Overview. Show the old paper grade process Show the new E-grades process Why choose a Blackboard building block
E N D
E-grades– Building Block Replaces Bubble Sheets Tracy (Ting-Hong) TanAnalyst/Programmer California State University, East Bay (formerly CSU Hayward)
Overview • Show the old paper grade process • Show the new E-grades process • Why choose a Blackboard building block • How we implement it and the technical considerations we have to make • Usage and feedback from instructors • Issues that stop us from developing import from Blackboard Grade book to E-grades
Reason to implement online grading • While students can register for classes, view grades, view classes/schedule/catalog online, or even take online courses, instructors still need to pick up a paper grade roster, use a pencil to fill in a bubble sheet, then turn it in to the department office. Moving this grading process online makes their life a lot easier and makes the grading process less painful. • Paper grade process is time consuming and tedious, a lot of errors could happen. • Students could view their grades a lot sooner, once we go 100% E-grades.
Paper Grade E-Grade
Why choose a Blackboard Building Block? Blackboard contains the most current course roster and contains valid users group - considered to be the best platform on campus to implement this service. In addition, instructors are already familiar with how to logon to Blackboard and familiar with its user interface. Our update schedule: Course enrollment – snapshot control, updated once a day Users – snapshot control, updated twice a day from campus Identity Management system. Users get enabled/disabled based on the status in IMS.
Design concept • Simple and easy to use • Make it foolproof, instructors can only pick the grades which are acceptable for their course. • Instructors are not required to use Blackboard course management - they can login to fill out grades only. • Familiar user interface in the Blackboard environment • Accessibility
Select Regular university or Continuing Education course to grade Select Regular University or Continuing Education
Select the course to grade Select the course for grading.
Using Tag Libraries to create the User Interface <%@ taglib uri="/bbData" prefix="bbData"%> <%@ taglib uri="/bbUI" prefix="bbUI"%> ... ... <bbUI:step title="Select a Course" number="1"> <bbUI:instructions> Welcome to the CSU Hayward Online Grade Submission program.<br> <label for="CourseSelection"> Please select a course: </label> <br> </bbUI:instructions> <bbUI:stepContent> <form action="<%=PlugInUtil.getUri("csuh", "grades", "module/edit_grades.jsp")%>" method="post"> … … </bbUI:stepContent> </bbUI:step> <bbUI:stepSubmit title="Go to the Grade Roster" instructions="Click \"Submit\" to continue to the next step." number="2" cancelUrl="/"/>
Select grade for each student Based on Grade rule/type, show different grade options
Click “Save” button to save grades; “Cancel” will bring them back to courses selection page <bbUI:stepSubmit title="Save Grades" instructions="<%=instruction%>" number="2" cancelUrl="courses.jsp?termtype=reg" submitButton="save" />
Review the grade rosterNote: If a grade is not selected, the default grade of “WU” will be inserted. Click “Modify” button to go back and modify the grades for this course; “Return” to continue grading other courses
To see grades for completed courses, first select a course from the View Grade Only section on the E-Grades module. To see grades for completed courses, select a course from the View Grade Only section.
View Grade PageA “Printer Friendly” version is available so that a copy can be printed for filing. Printer Friendly version Can be sort by Student’s Name or NetID
View grade page can be sort, using Tag library – <bbUI:list> <% GenericFieldComparator stuName = new GenericFieldComparator(BaseComparator.ASCENDING,"getFamilyName",User.class); stuName.appendSecondaryComparator(new GenericFieldComparator(BaseComparator.ASCENDING,"getGivenName",User.class)); GenericFieldComparator netID = new GenericFieldComparator(BaseComparator.ASCENDING,"getUserName",User.class); //pre sort the list Collections.sort(SortedList,stuName); %> <bbUI:list collection="<%=SortedList%>" objectId="s" className="User" resultsPerPage="-1"> <bbUI:listElement label="Name" name="name" comparator="<%=stuName%>"> <%=s.getFamilyName()%>, <%=s.getGivenName()%> </bbUI:listElement> <bbUI:listElement label="NetID" name="netID" comparator="<%=netID%>"> <%=s.getUserName()%> </bbUI:listElement> <bbUI:listElement label="Grade" name="grade"> <% //get the grade value of student stustatus = (String) currGrades.get(s.getBatchUid()); if(stustatus != null) out.print(stustatus); stustatus = null; %> </bbUI:listElement> </bbUI:list> Show all data in one page Can be sorted by student name Can be sorted by NetID
CSUH_GRADES_LOGS PK1 COURSE_ID USER_ID LASTUPDATED IP CSUH_GRADES_CYCLES PK1 TERM START_DATE END_DATE CSUH_GRADES PK1 BATCH_UID COURSE_ID GRADE UPDATED CRS_MERGE PK1 BATCH_UID BB_COURSE_ID SAIL_COURSE_ID GRD_TYPE PK1 COURSE_ID GRADETYPE GRADERULE CSUH_GRADES_CRNC_INFO PK1 COURSE_ID BATCH_UID SPECIAL_GRD_TYPE E-grades custom tables Where do we store the data? Oracle database, create a new schema to store custom data we have
Using JDBC connections for E-grades related data <%ConfigurationService bbconf = BbSM.getConfigurationService(); String dbhost = bbconf.getBbProperty("bbconfig.database.bbadmin.machine.machinename"); Connection dbConn1 = null; Connection dbConn2 = null; boolean jdbcAvailable = false; String currqtr = null; try { Class.forName("oracle.jdbc.driver.OracleDriver"); dbConn1 = DriverManager.getConnection("jdbc:oracle:thin:@" + dbhost +":1521:BB60", "bb_bb60", “password"); dbConn2 = DriverManager.getConnection("jdbc:oracle:thin:@" + dbhost + ":1521:BB60", "csuh_custom", “password"); jdbcAvailable = true; } catch (Exception e) { System.out.println(e.toString()); jdbcAvailable = false; } %>
Technical considerations • Only show the course(s) taught by currently logged in user • Make sure only the instructor can grade the course • Only enrollments that come from SIS+ will show up in the grade roster • Based on grade rule/type information from SIS+, help limit the grade options on the grade roster - make it foolproof. • De-merge the courses before we send the grade file back to SIS+
Get list of courses taught by current user <%User user = bbContext.getUser();%> … … <SELECT NAME="CourseID" id="CourseSelection"><OPTION VALUE="noneselected">Select a Course</OPTION> <%//Get list of courses teach by current login user CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); BbList courseList = cLoader.loadByUserIdAndCourseMembershipRole(user.getId(), CourseMembership.Role.INSTRUCTOR); if (courseList.size() > 0) { String buffer = ""; Object[] courses = courseList.toArray(); for (int i = 0; i < courses.length; i++) { Course course = (Course)courses[i]; //Not showing system DSK courses, manual merged course, and ‘NG’ courses if (course.getDataSourceId().toExternalString().indexOf("_2_",0)== -1 && course.getCourseId().startsWith(qtr) && !course.getCourseId().endsWith("MRG") && !NGcourses.containsKey(course.getCourseId()) ) { String CourseTitle = course.getTitle(); %><OPTION VALUE="<%=course.getCourseId()%>"><%=course.getTitle()%></OPTION><% } //end if } //end for loop } //end if %> </SELECT>
Make sure only instructors can grade their courses <% User user = bbContext.getUser();UserDbLoader userDbLoader = UserDbLoader.Default.getInstance(); CourseMembershipDbLoader cmLoader = CourseMembershipDbLoader.Default.getInstance(); CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); Course course = cLoader.loadByCourseId(courseid); BbList courseMembershipList = cmLoader.loadByCourseId(course.getId()); //make sure the user currently login is one of the instructors of this course CourseMembershipRoleFilter getInstructor = new CourseMembershipRoleFilter(CourseMembership.Role.INSTRUCTOR); BbList instructorList = courseMembershipList.getFilteredSubList(getInstructor); for (Iterator i=instructorList.iterator(); i.hasNext(); ) { CourseMembership cm_instructor = (CourseMembership) i.next(); Id cm_inctructor_id = (Id)cm_instructor.getUserId(); try { User t = userDbLoader.loadById(cm_inctructor_id); if(user.getUserName().equals(t.getUserName())) { isInstructor = true; } } catch(Exception e) { isInstructor = false; } } %>
Only enrollments which come from SIS+ will show up in the grade roster <%//get student enrollment list CourseMembershipRoleFilter getStudent = new CourseMembershipRoleFilter(CourseMembership.Role.STUDENT); BbList studentList = courseMembershipList.getFilteredSubList(getStudent); Object[] stuArray = studentList.toArray(); CourseMembership cm = null; Id StuId = null; String DSKey = null; User student = null; BbList SortedList = new BbList(); for (int i = 0; i < stuArray.length; i++) { boolean disabled = false; cm = (CourseMembership)stuArray[i]; //not show any user who's on system DSK (system DSK = 2) DSKey = cm.getDataSourceId().toExternalString(); if(cm.getIsAvailable() && DSKey.indexOf("_2_",0)== -1) { StuId = cm.getUserId(); try { student = userDbLoader.loadById(StuId); } catch (Exception e) { disabled = true; } if (!disabled) { SortedList.add(student); } } } %>
Based on grade rule/type information from SIS+, limit the grade options on the grade roster - make it foolproof. <select name="stu<%=s.getUserName()%>" <% if((rownum%2) == 0) out.print("class='bLight'"); %> id="StudentName<%=s.getUserName()%>" > <option value=" "<%if (stustatus == null) out.print(" SELECTED");%>>Please select a grade</option> <% if( gradetype.equals("CN") || graderule.equals("CN") ) {%> <option value="CR"<%if (stustatus != null && stustatus.equals("CR")) out.print(" SELECTED");%>>CR</option> <option value="NC"<%if (stustatus != null && stustatus.equals("NC")) out.print(" SELECTED");%>>NC</option> <option value="I"<%if (stustatus != null && stustatus.equals("I")) out.print(" SELECTED");%>>I</option> <option value="RP"<%if (stustatus != null && stustatus.equals("RP")) out.print(" SELECTED");%>>RP</option> <% } else if((graderule.equals("UR") && gradetype.equals("NB")) || (graderule.equals("U") && gradetype.equals("SU"))) {%> <option value="A"<%if (stustatus != null && stustatus.equals("A")) out.print(" SELECTED");%>>A</option> <option value="A-"<%if (stustatus != null && stustatus.equals("A-")) out.print(" SELECTED");%>>A-</option> … … <option value="NC"<%if (stustatus != null && stustatus.equals("NC")) out.print(" SELECTED");%>>NC</option> <% } else {%> <option value="A"<%if (stustatus != null && stustatus.equals("A")) out.print(" SELECTED");%>>A</option> <option value="A-"<%if (stustatus != null && stustatus.equals("A-")) out.print(" SELECTED");%>>A-</option> <option value="B+"<%if (stustatus != null && stustatus.equals("B+")) out.print(" SELECTED");%>>B+</option> <option value="B"<%if (stustatus != null && stustatus.equals("B")) out.print(" SELECTED");%>>B</option> <option value="B-"<%if (stustatus != null && stustatus.equals("B-")) out.print(" SELECTED");%>>B-</option> <option value="C+"<%if (stustatus != null && stustatus.equals("C+")) out.print(" SELECTED");%>>C+</option> … … <option value="WU"<%if (stustatus != null && stustatus.equals("WU")) out.print(" SELECTED");%>>WU</option> <option value="I"<%if (stustatus != null && stustatus.equals("I")) out.print(" SELECTED");%>>I</option> <option value="RP"<%if (stustatus != null && stustatus.equals("RP")) out.print(" SELECTED");%>>RP</option> <% } /* End Grade rule, Grade Type checking */%> </select>
De-merge the merged courses What is a merged course? Example: cross-listed courses (Math and Computer Science) have two records in our Student Information System (SIS+), but only one instance in Blackboard. In SIS+, students can be enrolled in either course, so those enrollments need to be separated before submitting final grades back to SIS+. De-merge information (which enrollments belong to which SIS+ courses) is sent by our SIS+ programmers, and at the end of the grading cycle, we use SQL to separate the grades for transfer back to SIS+.
SQL to generate file to update SIS+ SELECT '45B'||rpad(csuh_grades.BATCH_UID,9,' ')||'PST'||rpad(CASE WHEN instr(crs_merge.sail_course_id,'_') > 0 THEN rpad(substr(crs_merge.sail_course_id,1,instr(crs_merge.sail_course_id,'_')-1),9,' ') || substr(crs_merge.sail_course_id,instr(crs_merge.sail_course_id,'_')+1) ELSE crs_merge.sail_course_id END ,23,' ') || lpad( CASE WHEN (GRADE = ' ' AND graderule = 'UR' AND gradetype = 'NB' ) THEN 'NC' WHEN GRADE = ' ' AND not ( graderule = 'UR' AND gradetype = 'NB') THEN 'WU' ELSE GRADE END ,2,' ') ext, sail_course_id course_id FROM csuh_custom.csuh_grades, csuh_custom.crs_merge, csuh_custom.grd_type WHERE csuh_grades.course_id = crs_merge.bb_course_id AND csuh_grades.batch_uid = crs_merge.batch_uid AND (updated = 'N' or updated is null) AND trim(grd_type.course_id) = csuh_grades.course_id AND substr(csuh_grades.course_id, 1, 5) = '20052'
Positive Feedbacks from Instructors: Using E-Grades was so fast and easy. I was completely finished in less than one hour. No more filling in the bubbles. My fingers used to get so tired! Thanks for streamlining the grading process! Patricia LohmanhawkAssistant Professor, Department of Communicative Sciences & Disorders Just one last "THANK YOU" to everyone who worked on the e-grading forms. I've just finished entering my grades in 1/5 the time it would have taken me using paper forms. And, I'm in LA while doing - on a vacation that I really, really needed. You folks are my heroes. May everything go smoothly in grade processing, and may all of you take a well deserved rest sometime soon! Best regards, Carol Moore Carol Moore Lecturer, Department of Management and Finance This is the first time I used an on-line grade reporting system. It was great! Everyone should use it. Peter Wilson Dean, Contra Costa Campus Great System! A vast improvement over the old paper process. David St. Clair Professor, Department of Economics
Feedbacks from Instructors: The pull-down style of entering each grade is not a good choice. The original demo had a much better choice of checking the appropriate grade box. Giving the user a choice should be easily programmable for you or the vendor. Please consider doing this and saving instructors lots of time and frustration. Donald WolitzerProfessor, Mathematics & Computer Science Please give us a second user interface option for entering grades. At my age it's far easier for me to type in the grades rather than selecting from a pull-down list for each student. And I find my occasional random mouse clicks quite disruptive as I have to check (and sometimes change) several previously-entered grades. Thanks. Tony LimaProfessor, Department of Economics I LOVE being able to submit my grades electronically. Now, why not make it so that we can simply export our Blackboard gradebook grades rather than having to reenter them? Reed, Catherine Professor , Department of Teacher Education
Issues that stop us from developing import from Blackboard Grade book to E-grades • Setting up the column correctly in the Bb Gradebook requires the user to correctly fill out several fields: Name, Category, Description, Date, Points Possible, Display, Availability, and Include Item in GB Calculations. These fields are critical to the way Blackboard’s gradebook tool calculates and displays grades. If any one of the variables are set up improperly, the import could produce incorrect results. • Blackboard may rewrite the gradebook in the future – if this happens, E-Grades import would have to be rewritten • “Final” grade is a calculated field. Faculty members have very little control over how this field is calculated, so we would have to create a “best guess” algorithm to calculate the final grade. • Grade fields can be letters, numbers, and can be defined by faculty-created ranges of numbers. There are too many possibilities provided, therefore any calculation would only be a “best guess”, which is not acceptable for grading.
Questions? Contact Information: Tracy Tan tracy.tan@csueastbay.edu