def satprepuserdiagnostic(self, request, tl, one, two, module, extra, prog): context = {} response, userfound = search_for_user(request, self.program.students_union()) if not userfound: return response user = response if request.method == 'POST': form = SATPrepDiagForm(request.POST) if form.is_valid(): reginfo = SATPrepRegInfo.getLastForProgram(user, prog) form.instance = reginfo form.save() return self.goToCore(tl) else: reginfo = SATPrepRegInfo.getLastForProgram(user, prog) form = SATPrepDiagForm(instance=reginfo) return render_to_response(self.baseDir() + 'satprep_diag.html', request, (prog, tl), { 'form': form, 'user': user })
def satprepinfo(self, request, tl, one, two, module, extra, prog): if request.method == 'POST': form = SATPrepInfoForm(request.POST) if form.is_valid(): reginfo = SATPrepRegInfo.getLastForProgram(request.user, prog) form.instance = reginfo form.save() return self.goToCore(tl) else: satPrep = SATPrepRegInfo.getLastForProgram(request.user, prog) form = SATPrepInfoForm(instance=satPrep) return render_to_response('program/modules/satprep_stureg.html', request, (prog, tl), {'form': form})
def get_msg_vars(self, user, key): user = ESPUser(user) if key == 'diag_sat_scores' or key == 'old_sat_scores' or key == 'prac_sat_scores': test_type = key.split('_')[0] if user.isStudent(): foo = SATPrepRegInfo.getLastForProgram(user, self.program) scores = 'Your %s SAT scores:\n' % { 'prac': 'practice', 'diag': 'diagnostic', 'old': 'original' }[test_type] for test in ['Math', 'Verbal', 'Writing']: curscore = foo.__dict__['%s_%s_score' % (test_type, test[0:4].lower())] if curscore is None or curscore < 200 or curscore > 800: scores += '%s: Not Available\n' % test else: scores += '%s: %s\n' % (test, curscore) return scores return ''
def satprep_create(self, request, tl, one, two, module, extra, prog): if request.method == 'POST': form = OnSiteSATPrepRegForm(request.POST) if form.is_valid(): new_data = form.cleaned_data username = base_uname = (new_data['first_name'][0]+ \ new_data['last_name']).lower() if ESPUser.objects.filter(username=username).count() > 0: i = 2 username = base_uname + str(i) while ESPUser.objects.filter( username=username).count() > 0: i += 1 username = base_uname + str(i) new_user = ESPUser(username=username, first_name=new_data['first_name'], last_name=new_data['last_name'], email=new_data['email'], is_staff=False, is_superuser=False) new_user.save() self.student = new_user new_user.recoverPassword() #update satprep information satprep = SATPrepRegInfo.getLastForProgram( new_user, self.program) satprep.old_math_score = new_data['old_math_score'] satprep.old_verb_score = new_data['old_verb_score'] satprep.old_writ_score = new_data['old_writ_score'] satprep.save() if new_data['paid']: self.createBit('Paid') self.createBit('Attended') if new_data['medical']: self.createBit('MedicalFiled') if new_data['liability']: self.createBit('LiabilityFiled') self.createBit('OnSite') v = GetNode('V/Flags/UserRole/Student') ub = UserBit() ub.user = new_user ub.recursive = False ub.qsc = GetNode('Q') ub.verb = v ub.save() new_user = ESPUser(new_user) return render_to_response(self.baseDir() + 'reg_success.html', request, (prog, tl), {'user': new_user}) else: form = OnSiteSATPrepRegForm() return render_to_response(self.baseDir() + 'reg_info.html', request, (prog, tl), {'form': form})
def isCompleted(self): satPrep = SATPrepRegInfo.getLastForProgram(get_current_request().user, self.program) return satPrep.id is not None
def satprep_schedulestud(self, request, tl, one, two, module, extra, prog): """ An interface for scheduling all the students, provided the classes have already been generated. """ from esp.program.modules.module_ext import SATPrepTeacherModuleInfo import string import random import copy # Get confirmation and a list of users first. if not request.method == 'POST' and not request.POST.has_key( 'schedule_confirm'): return render_to_response(self.baseDir() + 'schedule_confirm.html', request, (prog, tl), {}) filterObj, found = get_user_list(request, self.program.getLists(True)) if not found: return filterObj # Find the user's scores and put them in a python list. users = list(filterObj.getList(User).distinct()) subjects = ['math', 'verb', 'writ'] # Expire existing enrollments reg_bits = UserBit.valid_objects().filter( verb=DataTree.get_by_uri('V/Flags/Registration/Enrolled')).filter( QTree(qsc__below=prog.anchor)) """ print 'Expiring %d enrollment bits' % reg_bits.count() """ for bit in reg_bits: bit.expire() # Add scores to each user for user in users: satprepreginfo = SATPrepRegInfo.getLastForProgram( user, self.program) user.scores = {} for subject in subjects: user.scores[subject] = SATPrepAdminSchedule.getScore( satprepreginfo, subject) # Get an independently sorted list for each subject sorted_lists = {} for subject in subjects: sorted_lists[subject] = copy.deepcopy(users) sorted_lists[subject].sort(key=lambda x: x.scores[subject]) # Generate list of possible orderings def combinations(lst): if len(lst) == 1: return [lst] else: result = [] for i in range(len(lst)): other_items = [y for y in lst if y != lst[i]] result += [[lst[i]] + x for x in combinations(other_items)] return result orderings = combinations(subjects) # Divide students into orderings num_orderings = len(orderings) num_subjects = len(subjects) ordering_index = 0 subject_index = 0 def lists_non_empty(): for subject in subjects: if len(sorted_lists[subject]) > 0: return True return False ordering_lists = [[] for ordering in orderings] while lists_non_empty(): # Pull a student from the top of the list in the current subject new_student = sorted_lists[subjects[subject_index]].pop() # Put them in the list for the current ordering ordering_lists[ordering_index].append(new_student) # Remove them from the other lists for subject in subjects: if subject != subjects[subject_index]: sorted_lists[subject].remove(new_student) # Debug statement: # print 'Took %s (scores: %s) from %s list to ordering %s' % (new_student, new_student.scores, subjects[subject_index], orderings[ordering_index]) # Move to the next subject list subject_index = (subject_index + 1) % num_subjects # Move to the next ordering list ordering_index = (ordering_index + 1) % num_orderings """ # Debug statements print '--------------' for i in range(num_orderings): print 'Ordering %s: %d students' % (orderings[i], len(ordering_lists[i])) """ # Retrieve the class sections of the program, keeping track of their subject and level # in the class_list dictionary. tmi = SATPrepTeacherModuleInfo.objects.filter(program=prog) class_list = {} timeslots = prog.getTimeSlots() for timeslot in timeslots: class_list[timeslot] = {} for subject in subjects: class_list[timeslot][subject] = {} for t in tmi: section = t.section subject = t.get_subject_display().lower()[:4] cl = ESPUser(t.user).getTaughtClasses(prog) for c in cl: for s in c.get_sections(): timeslot = s.start_time() if section not in class_list[timeslot][subject]: class_list[timeslot][subject][section] = [] class_list[timeslot][subject][section].append( (s, s.room_capacity())) """ # Debug statements # print class_list """ # For each timeslot/subject combination, find the orderings that include it for timeslot_index in range(len(timeslots)): for subject in subjects: valid_orderings = filter( lambda o: o[timeslot_index] == subject, orderings) # Get a list of students in those orderings sorted by their score in the current subject # (Exclude students that have no score) timeslot = timeslots[timeslot_index] students = [] for ordering in valid_orderings: students += ordering_lists[orderings.index(ordering)] students = filter(lambda s: s.scores[subject] >= 200, students) students.sort(key=lambda s: s.scores[subject]) students.reverse() """ # Debug statement print 'Timeslot %s; subject %s: %d students' % (timeslots[timeslot_index], subject, len(students)) """ # Parcel out the spots in each level proportional to space num_students = len(students) num_spots = 0 section_dict = class_list[timeslot][subject] level_space = {} level_thresholds = {} indiv_thresholds = {} ordered_sections = section_dict.keys() ordered_sections.sort() prev_section = None for section in ordered_sections: level_space[section] = 0 for item in section_dict[section]: num_spots += item[1] level_space[section] += item[1] for section in ordered_sections: if prev_section is None: prev_threshold = 0 else: prev_threshold = level_thresholds[prev_section] section_size = level_space[section] * float( num_students) / num_spots level_thresholds[section] = prev_threshold + section_size indiv_thresholds[section] = [ section_size * item[1] / level_space[section] + prev_threshold for item in section_dict[section] ] prev_section = section """ # Debug statement # print ' -> Section %s (%d/%d students): threshold = %f, indiv = %s' % (section, level_thresholds[section] - prev_threshold, level_space[section], level_thresholds[section], indiv_thresholds[section]) """ # Assign students num_students_assigned = 0 section_index = 0 current_item = 0 for student in students: if (section_index >= len(ordered_sections)): raise ESPError(False), 'Overran number of sections' current_section = ordered_sections[section_index] if (current_item >= len( indiv_thresholds[current_section])): raise ESPError( False), 'Overran number of sections in section' target_section = section_dict[current_section][ current_item][0] if not hasattr(target_section, 'min_score'): target_section.min_score = 800 if not hasattr(target_section, 'max_score'): target_section.max_score = 200 target_section.preregister_student(student, overridefull=True) if student.scores[subject] < target_section.min_score: target_section.min_score = student.scores[subject] if student.scores[subject] > target_section.max_score: target_section.max_score = student.scores[subject] num_students_assigned += 1 """ # Debug statements print ' Assigning student %s (scores: %s) to %s' % (student, student.scores, target_section) print ' -> %d assigned (current thresholds are %f, %f)' % (num_students_assigned, indiv_thresholds[current_section][current_item], level_thresholds[current_section]) """ # Increment section if necessary if num_students_assigned > level_thresholds[ current_section]: section_index += 1 current_item = 0 # Increment item if necessary elif num_students_assigned > indiv_thresholds[ current_section][current_item]: current_item += 1 """ # Check results for section in ordered_sections: # This code assumes multiple sections per level+timeblock+subject print ' -> Section %s' % section for item in section_dict[section]: print ' (%d/%d) %s' % (item[0].num_students(), item[1], item[0]) # This code assumes one section per level+timeblock+subject item = section_dict[section][0] print ' -> Section %s (%d/%d) %s: Scores %d-%d' % (section, item[0].num_students(), item[1], item[0], item[0].min_score, item[0].max_score) """ return HttpResponseRedirect('/manage/%s/schedule_options' % self.program.getUrlBase())
def enter_scores(self, request, tl, one, two, module, extra, prog): """ Allow bulk entry of scores from a spreadsheet. This works for either the diagnostic or practice exams. """ from esp.program.modules.forms.satprep import ScoreUploadForm from esp.program.models import SATPrepRegInfo # The scores should be saved in SATPrepRegInfos with the following fields: # user, program, and lookup the rest here... reginfo_fields = { 'diag_m': 'diag_math_score', 'diag_v': 'diag_verb_score', 'diag_w': 'diag_writ_score', 'prac_m': 'prac_math_score', 'prac_v': 'prac_verb_score', 'prac_w': 'prac_writ_score' } context = {} form = ScoreUploadForm() if request.method == 'POST': data = request.POST.copy() data.update(request.FILES) form = ScoreUploadForm(data) if form.is_valid(): prefix = form.cleaned_data['test'] + '_' # Check that at least one of the input methods is being used. # Copy over the content from the text box, then the file. if len(form.cleaned_data['text']) > 3: content = form.cleaned_data['text'] elif form.cleaned_data['file'] and form.cleaned_data[ 'file'].has_key('content'): content = form.cleaned_data['file']['content'] else: from esp.middleware import ESPError raise ESPError( False ), 'You need to upload a file or enter score information in the box. Please go back and do so.' lines = content.split('\n') error_lines = [] error_reasons = [] n = 0 # Read through the input string for line in lines: error_flag = False entry = line.split(',') # Clean up a bit entry = [s.strip() for s in entry] entry = [s for s in entry if s != ""] # Test the input data and report the error if there is one if len(entry) < 3: error_flag = True error_lines.append(line) error_reasons.append( 'Insufficient information in line.') continue try: id_num = int(entry[0]) student = User.objects.get(id=id_num) del entry[0] except ValueError: student = prog.students()['confirmed'].filter( first_name__icontains=entry[1], last_name__icontains=entry[0]) if student.count() != 1: error_flag = True error_lines.append(line) error_reasons.append( 'Found %d matching students in program.' % student.count()) else: student = student[0] del entry[0:2] except User.DoesNotExist: error_flag = True error_lines.append(line) error_reasons.append('Invalid user ID of %d.' % id_num) if not error_flag: reginfo = SATPrepRegInfo.getLastForProgram( student, prog) got_some = False while len(entry) > 1: try: category = entry[0].lower()[0] score = int(entry[1]) field_name = reginfo_fields[prefix + category] reginfo.__dict__[field_name] = score got_some = True entry = entry[2:] # pop entries except KeyError, IndexError: error_flag = True error_lines.append(line) error_reasons.append( 'Invalid category name: %s.' % entry[0]) break except ValueError: error_flag = True error_lines.append(line) error_reasons.append( 'Not an integer score: %s.' % entry[1]) break if not error_flag: if got_some: # Add the student's scores into the database reginfo.save() n += 1 else: error_flag = True error_lines.append(line) error_reasons.append( 'Insufficient information in line.') # Summary information to display on completion context['errors'] = error_lines context['error_reasons'] = error_reasons context['complete'] = True context['num_updated'] = n