Пример #1
0
 def __call__(self):
     lecture = self.db.query(models.Lecture).get(self.lecture_id)
     tutorials = lecture.tutorials
     if self.request.method == 'POST':
         student_email = self.request.POST['student_email']
         new_tutorial = int(self.request.POST['new_tutorial'])
         try:
             student = self.db.query(models.User).filter(
                 models.User.email == student_email).one()
         except exc.NoResultFound:
             self.request.session.flash(u'Emailadresse nicht gefunden!',
                                        queue='errors')
             return {'lecture': lecture, 'tutorials': tutorials}
         tutorial = [t for t in tutorials if t.id == new_tutorial]
         if len(tutorial) != 1:
             raise HTTPForbidden(
                 'Tutorial gehoert nicht zu dieser Vorlesung!')
         tutorial = tutorial[0]
         if student in lecture.students.all():
             self.request.session.flash(
                 u'Der Student ist in diese Vorlesung bereits eingetragen!',
                 queue='errors')
         else:
             lrs = self.request.db.query(models.LectureRemovedStudent).get(
                 (lecture.id, student.id))
             if lrs:
                 self.request.db.delete(lrs)
             #ls = request.db.query(models.LectureStudent).get((lecture.id, request.user.id))
             #if ls:
             #	oldtutorial = ls.tutorial
             #else:
             ls = models.LectureStudent()
             ls.lecture = lecture
             ls.student = student
             oldtutorial = None
             ls.tutorial = tutorial
             if not ls in self.request.db: self.request.db.add(ls)
             self.request.db.commit()
             self.request.session.flash(
                 u'Der Student %s wurde in das Tutorial %s (%s) eingetragen'
                 % (student, tutorial.time.__html__(), tutorial.tutor_name),
                 queue='messages')
     return {'lecture': lecture, 'tutorials': tutorials}
Пример #2
0
def subscribe(context=None, request=None, tutorial=None, user=None, db=None):
    tutorial = request.context.tutorials[0] if tutorial is None else tutorial
    user = request.user if user is None else user
    db = request.db if db is None else db
    lecture = tutorial.lecture
    if tutorial.max_students > tutorial.students.count():
        lrs = db.query(models.LectureRemovedStudent).get((lecture.id, user.id))
        if lrs: db.delete(lrs)
        ls = db.query(models.LectureStudent).get((lecture.id, user.id))
        if ls:
            oldtutorial = ls.tutorial
        else:
            ls = models.LectureStudent()
            ls.lecture = lecture
            ls.student = user
            oldtutorial = None
        ls.tutorial = tutorial
        if not ls in db: db.add(ls)
        db.commit()
        if request is not None:
            if oldtutorial:
                sendChangesMailUnsubscribe(request,
                                           oldtutorial,
                                           user,
                                           toTutorial=tutorial)
            sendChangesMailSubscribe(request,
                                     tutorial,
                                     user,
                                     fromTutorial=oldtutorial)
            request.session.flash('Erfolgreich in Übungsgruppe eingetragen',
                                  queue='messages')
    else:
        if request is not None:
            request.session.flash('Maximale Teilnehmerzahl bereits erreicht',
                                  queue='errors')
    if request is not None:
        return HTTPFound(
            location=request.route_url('lecture_view', lecture_id=lecture.id))
Пример #3
0
def assign_student(request):
    student = request.context.student
    new_tutorial = request.context.tutorial
    lecture = new_tutorial.lecture
    lrs = request.db.query(models.LectureRemovedStudent).get(
        (lecture.id, student.id))
    if lrs: request.db.delete(lrs)
    ls = request.db.query(models.LectureStudent).get((lecture.id, student.id))
    if ls:
        pass
    #	oldtutorial = ls.tutorial
    else:
        ls = models.LectureStudent()
        ls.lecture = lecture
        ls.student = student
    #	oldtutorial = None
    ls.tutorial = new_tutorial
    if not ls in request.db: request.db.add(ls)
    request.db.commit()
    #if oldtutorial:
    #	sendChangesMailUnsubscribe(request, oldtutorial, request.user, toTutorial=tutorial)
    #sendChangesMailSubscribe(request, tutorial, request.user, fromTutorial=oldtutorial)
    return {'student': student, 'new_tutorial': new_tutorial}
Пример #4
0
def assign_student(request):
    student = request.context.student
    new_tutorial = request.context.tutorial
    lecture = new_tutorial.lecture
    lrs = request.db.query(models.LectureRemovedStudent).get(
        (lecture.id, student.id))
    if lrs:
        request.db.delete(lrs)
    lecture_student = request.db.query(models.LectureStudent).get(
        (lecture.id, student.id))
    # TODO: is this really needed?!
    if not lecture_student:
        lecture_student = models.LectureStudent()
        lecture_student.lecture = lecture
        lecture_student.student = student
    lecture_student.tutorial = new_tutorial
    if lecture_student not in request.db:
        request.db.add(lecture_student)
    request.db.commit()
    request.session.flash('{} wurde der Übungsgruppe am {} zugeteilt!'.format(
        student.name, new_tutorial.time.formatted()),
                          queue='messages')
    return HTTPFound(location=request.referrer)
Пример #5
0
    def doAllocation(self):
        if not self.lecture.mode == 'prefs':
            raise Exception('Lecture not in preference mode')
        nodes = []
        arcs = []
        # every object in our optimization problem is a 'node'
        # the first node we add is the master node. The master node
        # is the destination for all network flow
        nodes.append(
            Node(
                type='master',
                id=-1,
                time=None  ## XXX: make catalyst happy!
            ))
        # the next node is the 'ghost' node. it is a 'fake-time' which
        # is needed that our optimization problem _always_ has a solution.
        # there is always an arc from 'ghost' to 'master'.
        nodes.append(Node(type='time', id=-1, extra='ghost', time=None))
        arcs.append(
            Arc(1, 0, priority=utils.ghostcapacity, type='times=>master'))
        # we do now add nodes for all different 'times' where
        # tutorials are happening. Every time gets an arc to the
        # master node.
        times = self.lecture.prepareTimePreferences()
        for time in times:
            time_tutorials = []
            tuts = self.session.query(models.Tutorial).filter(
                models.Tutorial.lecture_id == self.lecture.id).filter(
                    models.Tutorial.time == time['time']).all()
            for tut in tuts:
                time_tutorials.append({
                    'id': tut.id,
                    'tutorial': tut,
                    'max_students': tut.max_students,
                    'act_students': 0
                })
            if time_tutorials:
                nodes.append(
                    Node(type='time',
                         time=time['time'],
                         tutorials=time_tutorials))
                arcs.append(
                    Arc(len(nodes) - 1,
                        0,
                        priority=time['max_students'],
                        type='times=>master',
                        extra=''))
        ## We do now add nodes for the students. Every preference of the
        ## student is an 'arc' from the student-node to the time-node.
        ## We do add the arcs here as well.
        time_preferences = self.lecture.time_preferences
        students = set([tp.student for tp in time_preferences])
        student_nodes = {}
        for student in students:
            nodes.append(StudentNode(student=student, id=student.id,
                                     time=None))
            student_nodes[student.id] = len(nodes) - 1
            arcs.append(
                Arc(len(nodes) - 1,
                    1,
                    priority=utils.ghostpenalty,
                    type='priority_arc',
                    extra='student=>ghost'))
            student_preferences = [
                tp for tp in student.time_preferences
                if tp.lecture_id == self.lecture.id
            ]
            for tp in student_preferences:
                for i, node in enumerate(nodes):
                    if node.type == 'time' and node.time and node.time == tp.time:
                        arcs.append(
                            Arc(len(nodes) - 1,
                                i,
                                priority=tp.penalty,
                                type='priority_arc',
                                extra='__need_to_be_filled__'))
                        break
                    elif node.type == 'student':
                        break
        if len(students) == 0:
            return {'error_value': 0, 'students_processed': 0}
        # we do now write a file in the popular dimacs format.
        inputfile = "c This is Muesli. \n"
        inputfile += "p min %i %i\n" % (len(nodes), len(arcs))
        for i, node in enumerate(nodes):
            inputfile += 'n %i ' % (i + 1)
            if node.type == 'master':
                inputfile += '-%i\n' % (len(students))
            elif node.type == 'time':
                inputfile += '0\n'
            else:
                inputfile += '1\n'
        for i, arc in enumerate(arcs):
            inputfile += 'a %i %i 0 ' % (arc.src + 1, arc.dest + 1)
            if arc.type == 'times=>master':
                inputfile += '%i 1\n' % arc.priority
            else:
                inputfile += '1 %i\n' % arc.priority

        tmpfile = tempfile.NamedTemporaryFile(prefix='muesli', mode='w')
        tmpfile.write(inputfile)
        tmpfile.flush()
        out, err = subprocess.Popen(
            [utils.lpsolve, '-rxli', 'xli_DIMACS', tmpfile.name],
            stdout=subprocess.PIPE,
            universal_newlines=True).communicate()
        tmpfile.close()
        if 'Successfully' not in out:
            raise Exception('Optimizer Error: File Format wrong')
        out = out.split('Actual values')[1].split('\n', 1)[1]
        lines = out.split('\n')
        if not len(lines) > len(arcs):
            raise Exception('Optimizer Error: File Format wrong')
        lines = reversed(lines)
        self.lecture.lecture_students.delete()
        global_happiness = 0.0
        students_unhappy = []
        students_without_group = []
        narcs = list(arcs)
        arc = narcs.pop()
        for line in lines:
            if line == '': continue
            line = line.split()[1]
            if arc.extra == '__need_to_be_filled__' and line == '1':
                sorted_tutorials = list(nodes[arc.dest].tutorials)
                sorted_tutorials.sort(key=lambda t: t['act_students'])
                ls = models.LectureStudent()
                ls.student = nodes[arc.src].student
                ls.lecture = self.lecture
                ls.tutorial = sorted_tutorials[0]['tutorial']
                self.session.add(ls)
                sorted_tutorials[0]['act_students'] += 1
                if arc.priority >= utils.students_unhappiness:
                    students_unhappy.append(nodes[arc.src].student)
                global_happiness += 1 / float(arc.priority)
            elif arc.extra == 'student=>ghost' and line == '1':
                students_without_group.append(nodes[arc.src].student)
            elif arc.type == 'times=>master':
                break
            arc = narcs.pop()
        self.session.commit()
        return {
            'error_value':
            0,
            'students_processed':
            len(students),
            'students_without_group':
            students_without_group,
            'students_unhappy':
            students_unhappy,
            'global_happiness':
            100.0 * global_happiness /
            (len(students) - len(students_without_group))
            if len(students) != len(students_without_group) else 0
        }