Class: Course
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Course
- Includes:
- PeopleInACollection
- Defined in:
- app/models/course.rb
Overview
Course represents a course taught at CMU-SV.
At present, there is no distinction between sections of a course. Each team can belong to a “section” which is only a labeled text field.
Adding a Course Offering
Sometime before a new semester starts, Gerry will create all the courses for the next semester. The HUB has a deadline for updating their system with courses, once that deadline has passed, Gerry typically will update the rails system. A course can be added/removed/modified after this deadline, and the information in the rails system should be updated. When Gerry creates a course, its will the minimal necessary information. When the course is created, certain information is copied from the previous offering of the same course, where as other information must not be copied.
The CMU-SV community typically does not refer to courses by their number, where as on the Pittsburgh campus, most undergraduate courses are referred to by their number.
The system asks for the tuple (course_number, semester, and year) to create the course and then puts the user in an edit mode prompting reasonable defaults from the last time the course was offered. If nothing has changed, it’s easy for Gerry to create the next course. If the instructor has changed then it’s easy to edit that information
Notifying instructors
Whenever an instructor is added to a course, they are notified about the change, asking them to review the course options. We ask that one of the instructors confirm the settings, when this happens we consider that the faculty has “configured” the course. (Or verified it’s settings.) If this doesn’t happen, the system should periodically remind faculty about the change.)
Course has grading rules. These include grading cut_offs for grade’s like A,A-,B+ etc.
Instance Attribute Summary collapse
-
#faculty_assignments_override ⇒ Object
When assigning faculty to a page, the user types in a series of strings that then need to be processed :faculty_assignments_override is a temporary variable that is used to do validation of the strings (to verify that they are people in the system) and then to save the people in the faculty association.
Class Method Summary collapse
- .copy_courses_from_a_semester_to_next_year(semester, year) ⇒ Object
- .current_semester_courses ⇒ Object
- .first_email_on_peer_evaluation_is_today ⇒ Object
- .first_offering_for_course_name(course_name) ⇒ Object
- .for_semester(semester, year) ⇒ Object
-
.last_offering(course_number) ⇒ Object
Find the last time this course was offered.
- .next_semester_courses ⇒ Object
- .remind_about_effort_course_list ⇒ Object
- .second_email_on_peer_evaluation_is_today ⇒ Object
Instance Method Summary collapse
- #auto_generated_peer_evaluation_date_end ⇒ Object
- #auto_generated_peer_evaluation_date_start ⇒ Object
- #auto_generated_twiki_url ⇒ Object
- #copy_as_new_course ⇒ Object
- #copy_teams_to_another_course(destination_course_id) ⇒ Object
-
#course_end ⇒ Object
Return the week number of the year for the end of a course.
- #course_length ⇒ Object
-
#course_start ⇒ Object
Return the week number of the year for the start of a course.
- #current_mini? ⇒ Boolean
-
#display_course_name ⇒ Object
def to_param display_course_name end.
- #display_for_course_page ⇒ Object
- #display_name ⇒ Object
- #display_semester ⇒ Object
- #email_faculty_to_configure_course_unless_already_configured ⇒ Object
- #grade_type_points_or_weights ⇒ Object
- #invalidate_distribution_list ⇒ Object
- #nomenclature_assignment_or_deliverable ⇒ Object
- #registered_students_and_students_on_teams_hash ⇒ Object
- #registered_students_or_on_teams ⇒ Object
- #short_or_course_number ⇒ Object
- #short_or_full_name ⇒ Object
- #sortable_value ⇒ Object
- #update_email_address ⇒ Object
-
#update_faculty ⇒ Object
When modifying validate_faculty or update_faculty, modify the same code in team.rb Todo - move to a higher class or try as a mixin.
- #validate_faculty_assignments ⇒ Object
Methods included from PeopleInACollection
#added_people, #detect_if_list_changed, #map_member_strings_to_users, #remove_empty_fields, #removed_people, #update_collection_members, #validate_members
Instance Attribute Details
#faculty_assignments_override ⇒ Object
When assigning faculty to a page, the user types in a series of strings that then need to be processed :faculty_assignments_override is a temporary variable that is used to do validation of the strings (to verify that they are people in the system) and then to save the people in the faculty association.
66 67 68 |
# File 'app/models/course.rb', line 66 def faculty_assignments_override @faculty_assignments_override end |
Class Method Details
.copy_courses_from_a_semester_to_next_year(semester, year) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'app/models/course.rb', line 260 def self.copy_courses_from_a_semester_to_next_year(semester, year) next_year = year + 1 if Course.for_semester(semester, next_year).empty? Course.for_semester(semester, year).each do |last_year_course| puts last_year_course.id next_year_course = last_year_course.copy_as_new_course next_year_course.peer_evaluation_first_email += 1.year if next_year_course.peer_evaluation_first_email next_year_course.peer_evaluation_second_email += 1.year if next_year_course.peer_evaluation_second_email next_year_course.year = next_year next_year_course.save end else raise "There are already courses in semester #{semester} #{next_year}" end end |
.current_semester_courses ⇒ Object
143 144 145 146 |
# File 'app/models/course.rb', line 143 def self.current_semester_courses() return self.for_semester(AcademicCalendar.current_semester(), Date.today.year) end |
.first_email_on_peer_evaluation_is_today ⇒ Object
153 154 155 |
# File 'app/models/course.rb', line 153 def self.first_email_on_peer_evaluation_is_today Course.where(:peer_evaluation_first_email => Date.today).all end |
.first_offering_for_course_name(course_name) ⇒ Object
135 136 137 |
# File 'app/models/course.rb', line 135 def self.first_offering_for_course_name(course_name) Course.with_course_name(course_name).first end |
.for_semester(semester, year) ⇒ Object
139 140 141 |
# File 'app/models/course.rb', line 139 def self.for_semester(semester, year) return Course.where(:semester => semester, :year => year).order("name ASC").all end |
.last_offering(course_number) ⇒ Object
Find the last time this course was offered
253 254 255 256 257 258 |
# File 'app/models/course.rb', line 253 def self.last_offering(course_number) #TODO: move this sorting into the database offerings = Course.where(:number => course_number).all offerings = offerings.sort_by { |c| -c.sortable_value } # note the '-' is for desc sorting return offerings.first end |
.next_semester_courses ⇒ Object
148 149 150 151 |
# File 'app/models/course.rb', line 148 def self.next_semester_courses() return self.for_semester(AcademicCalendar.next_semester(), AcademicCalendar.next_semester_year()) end |
.remind_about_effort_course_list ⇒ Object
206 207 208 209 210 |
# File 'app/models/course.rb', line 206 def self.remind_about_effort_course_list courses = Course.where(:remind_about_effort => true, :year => Date.today.cwyear, :semester => AcademicCalendar.current_semester(), :mini => "Both").all courses = courses + Course.where(:remind_about_effort => true, :year => Date.today.cwyear, :semester => AcademicCalendar.current_semester(), :mini => AcademicCalendar.current_mini).all return courses end |
.second_email_on_peer_evaluation_is_today ⇒ Object
157 158 159 |
# File 'app/models/course.rb', line 157 def self.second_email_on_peer_evaluation_is_today Course.where(:peer_evaluation_second_email => Date.today).all end |
Instance Method Details
#auto_generated_peer_evaluation_date_end ⇒ Object
220 221 222 |
# File 'app/models/course.rb', line 220 def auto_generated_peer_evaluation_date_end return Date.commercial(self.year, self.course_start + 7) end |
#auto_generated_peer_evaluation_date_start ⇒ Object
216 217 218 |
# File 'app/models/course.rb', line 216 def auto_generated_peer_evaluation_date_start return Date.commercial(self.year, self.course_start + 6) end |
#auto_generated_twiki_url ⇒ Object
212 213 214 |
# File 'app/models/course.rb', line 212 def auto_generated_twiki_url return "http://info.sv.cmu.edu/do/view/#{self.semester}#{self.year}/#{self.short_or_full_name}/WebHome".delete(' ') end |
#copy_as_new_course ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'app/models/course.rb', line 238 def copy_as_new_course new_course = self.dup new_course.is_configured = false new_course.configured_by = nil new_course.updated_by = nil new_course.created_at = Time.now new_course.updated_at = Time.now new_course.curriculum_url = nil if self.curriculum_url.nil? || self.curriculum_url.include?("twiki") new_course.faculty = self.faculty new_course.grading_rule = self.grading_rule.dup if self.grading_rule.present? self.assignments.each { |assignment| new_course.assignments << assignment.dup } if self.assignments.present? return new_course end |
#copy_teams_to_another_course(destination_course_id) ⇒ Object
276 277 278 279 280 281 |
# File 'app/models/course.rb', line 276 def copy_teams_to_another_course(destination_course_id) #Todo: at some point, refactor teams to be an ordered list, so that we wouldn't need to reverse it here to preserve ordering. self.teams.reverse.each do |team| team.clone_to_another_course(destination_course_id) end end |
#course_end ⇒ Object
Return the week number of the year for the end of a course
197 198 199 |
# File 'app/models/course.rb', line 197 def course_end self.course_start + self.course_length - 1 end |
#course_length ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'app/models/course.rb', line 162 def course_length if self.mini == "Both" then if semester == "Summer" then return 12 elsif semester == "Fall" then return 15 else return 16 end else if semester == "Summer" then return 6 else return 7 end end end |
#course_start ⇒ Object
Return the week number of the year for the start of a course
181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'app/models/course.rb', line 181 def course_start start = AcademicCalendar.semester_start(semester, year) if semester == "Spring" then return self.mini == "B" ? start + 9 : start end if semester == "Summer" then return self.mini == "B" ? start + 6 : start end if semester == "Fall" then return self.mini == "B" ? start + 8 : start end return 0 #If the semester field isn't set end |
#current_mini? ⇒ Boolean
283 284 285 286 287 288 289 290 |
# File 'app/models/course.rb', line 283 def current_mini? case self.mini when "Both" self.year == Date.today.year && self.semester == AcademicCalendar.current_semester() else self.year == Date.today.year && self.mini == AcademicCalendar.current_mini() end end |
#display_course_name ⇒ Object
def to_param
display_course_name
end
84 85 86 87 88 |
# File 'app/models/course.rb', line 84 def display_course_name mini_text = self.mini == "Both" ? "" : self.mini result = self.short_or_full_name + self.semester + mini_text + self.year.to_s result.gsub(" ", "") end |
#display_for_course_page ⇒ Object
90 91 92 93 94 |
# File 'app/models/course.rb', line 90 def display_for_course_page # Consider this # "#{self.number} #{self.name} (#{self.short_name}) #{self.display_semester}" "#{self.number} #{self.name} (#{self.short_name})" end |
#display_name ⇒ Object
96 97 98 99 |
# File 'app/models/course.rb', line 96 def display_name return self.name if self.short_name.blank? return self.name + " (" + self.short_name + ")" end |
#display_semester ⇒ Object
117 118 119 120 |
# File 'app/models/course.rb', line 117 def display_semester mini_text = self.mini == "Both" ? "" : self.mini + " " return self.semester + " " + mini_text + self.year.to_s end |
#email_faculty_to_configure_course_unless_already_configured ⇒ Object
300 301 302 |
# File 'app/models/course.rb', line 300 def email_faculty_to_configure_course_unless_already_configured CourseMailer.configure_course_faculty_email(self).deliver unless self.is_configured? end |
#grade_type_points_or_weights ⇒ Object
313 314 315 316 317 318 319 |
# File 'app/models/course.rb', line 313 def grade_type_points_or_weights if self.grading_rule.nil? || self.grading_rule.grade_type=="points" "points" else "weights" end end |
#invalidate_distribution_list ⇒ Object
292 293 294 |
# File 'app/models/course.rb', line 292 def invalidate_distribution_list self.updating_email = true end |
#nomenclature_assignment_or_deliverable ⇒ Object
305 306 307 308 309 310 311 |
# File 'app/models/course.rb', line 305 def nomenclature_assignment_or_deliverable if self.grading_rule.nil? || self.grading_rule.is_nomenclature_deliverable? "deliverable" else "assignment" end end |
#registered_students_and_students_on_teams_hash ⇒ Object
366 367 368 369 370 371 372 373 374 375 376 377 |
# File 'app/models/course.rb', line 366 def registered_students_and_students_on_teams_hash students = Hash.new self.registered_students.each do |student| students[student.human_name] = {:hub => true} end self.teams.each do |team| team.members.each do |user| students[user.human_name] = (students[user.human_name] || Hash.new).merge({:team => true, :team_name => team.name}) end end return students end |
#registered_students_or_on_teams ⇒ Object
321 322 323 |
# File 'app/models/course.rb', line 321 def registered_students_or_on_teams self.registered_students | self.teams.collect { |team| team.members }.flatten end |
#short_or_course_number ⇒ Object
109 110 111 112 113 114 115 |
# File 'app/models/course.rb', line 109 def short_or_course_number unless self.short_name.blank? self.short_name else self.number end end |
#short_or_full_name ⇒ Object
101 102 103 104 105 106 107 |
# File 'app/models/course.rb', line 101 def short_or_full_name unless self.short_name.blank? self.short_name else self.name end end |
#sortable_value ⇒ Object
201 202 203 |
# File 'app/models/course.rb', line 201 def sortable_value self.year.to_i * 100 + self.course_end end |
#update_email_address ⇒ Object
296 297 298 |
# File 'app/models/course.rb', line 296 def update_email_address self.email = build_email end |
#update_faculty ⇒ Object
When modifying validate_faculty or update_faculty, modify the same code in team.rb Todo - move to a higher class or try as a mixin
226 227 228 229 230 231 232 233 234 235 236 |
# File 'app/models/course.rb', line 226 def update_faculty return "" if faculty_assignments_override.nil? self.faculty = [] self.faculty_assignments_override = faculty_assignments_override.select { |name| name != nil && name.strip != "" } list = map_member_strings_to_users(self.faculty_assignments_override) raise "Error converting faculty_assignments_override to IDs!" if list.include?(nil) self.faculty = list faculty_assignments_override = nil self.updating_email = true end |
#validate_faculty_assignments ⇒ Object
76 77 78 |
# File 'app/models/course.rb', line 76 def validate_faculty_assignments validate_members :faculty_assignments_override end |