Exemple #1
0
def execute(state, plugin, argument):

    question = state.question
    if question == None:
        return

    statistics.question_stats()
    if question.stats.given == 0:
        return

    s = '<table><tr><td>'
    s += '<p class="given">%d</p>' % question.stats.given
    s += '<p class="view">%s</p>' % \
         absolute_and_relative(question.stats.view, question.stats.given)
    s += '</td><td>'
    s += '<p class="good">%s</p>' % \
         absolute_and_relative(question.stats.good, question.stats.given)
    s += '<p class="bad">%s</p>' % \
         absolute_and_relative(question.stats.bad, question.stats.given)
    s += '</td><td>'
    s += '<p class="indice">%s</p>' % \
         absolute_and_relative(question.stats.indice, question.stats.given)
    s += '<p class="time">%s (%s)</p>' % (
        utilities.time_format(question.student_time),
        utilities.time_format(question.student_time /
                              (0.1 + question.stats.given)))
    s += '<p class="comment">%s</p>' % \
         absolute_and_relative(question.stats.nr_comment, question.stats.given)
    s += '</td></tr></table>'

    return s
Exemple #2
0
def histogram_good(state):
    stats = statistics.question_stats()

    div = int(state.form.get("value", "10"))

    histo = [0] * (1 + stats.max_good_answers // div)
    for s in stats.all_students:
        histo[s.the_number_of_good_answers // div] += 1
    t = "<pre>"
    for h in range(len(histo)):
        t += ("%3d-%3d : " % (h * div,
                              (h + 1) * div - 1)) + "*" * histo[h] + "\n"
    t += '</pre>'

    t += '<p class="histobad"></p>'
    histo = [0] * (1 + stats.max_bad_answers // div)
    for s in stats.all_students:
        histo[s.the_number_of_bad_answers // div] += 1
    t += "<pre>"
    for h in range(len(histo)):
        t += ("%3d-%3d : " % (h * div,
                              (h + 1) * div - 1)) + "*" * histo[h] + "\n"
    t += '</pre>'

    return t
Exemple #3
0
def execute(state, plugin, argument):
    if argument == None:
        return ''

    stats = statistics.question_stats()
    nr_students = float(len(stats.all_students))

    s = []
    for question in questions.questions.values():
        norme = float(question.stats.given)
        if question.stats.given == 0:
            continue
        s.append([
            question.a_href(),
            "%6.3f" % (question.stats.given / nr_students),
            "%6.3f" % (question.stats.view / norme),
            "%6.3f" % (question.stats.good / norme),
            "%6.3f" % (question.stats.bad / norme),
            "%6.3f" % (question.stats.indice / norme),
            utilities.time_format(question.student_time / norme),
            "%6.3f" % (question.stats.nr_comment / norme),
            "%5d" % question.perfect_time,
        ])

    if s:
        plugin.heart_content = \
               utilities.sortable_table(plugin.sort_column, s,
                                  url = "%s&%s=1" % (plugin.plugin.css_name, plugin.plugin.css_name))
        state.question = None

    return ''
Exemple #4
0
def execute(state, plugin, argument):
    if not state.question:
        return
    stats = statistics.question_stats()
    columns = set()
    for s in stats.all_students:
        a = s.answer(state.question.name)
        if a.answered:
            for k in a.grades:
                if a.grades[k] != '0':
                    columns.add(k)
    columns = sorted(columns)

    table = []
    for s in stats.all_students:
        a = s.answer(state.question.name)
        if not a.answered:
            continue
        table.append([utilities.answer_format(a.answered)] +
                     [a.grades.get(c, 0) for c in columns])

    return utilities.sortable_table(plugin.sort_column,
                                    table,
                                    url=plugin.plugin.css_name,
                                    titles=['X'] + columns)
Exemple #5
0
def execute(state, plugin, argument):
    if argument == None:
        return ''

    stats = statistics.question_stats()
    
    comments = []
    for s in stats.all_students:
        for a in s.answers.values():
            q = questions.a_href(a.question).replace(' ','&nbsp;')
            for c in a.comments:
                comments.append( [
                    q,
                    cgi.escape(c[1]),
                    s.a_href(body=c[1]),
                    utilities.date_format(c[0]).replace(' ','&nbsp;')])


    plugin.heart_content = \
             utilities.sortable_table(plugin.sort_column,
                                      comments,
                                      url = "%s&%s=1" % (plugin.plugin.css_name, plugin.plugin.css_name)
                                      )
    state.question = None

    return ''
Exemple #6
0
def execute(state, plugin, argument):
    if argument == None:
        return ''

    stats = statistics.question_stats()

    too_quick = collections.defaultdict(int)
    too_quick2 = collections.defaultdict(int)
    too_quick4 = collections.defaultdict(int)
    for s in stats.sorted_students:
        for question_name, answer in s.answers.items():
            if not answer.answered:
                continue
            question = questions.questions[question_name]
            average_time = question.student_time / question.stats.given
            if answer.time_searching < average_time / 10:
                too_quick[s] += 1
            if answer.time_searching < average_time / 20:
                too_quick2[s] += 1
            if answer.time_searching < average_time / 40:
                too_quick4[s] += 1

    plugin.heart_content = utilities.sortable_table(
        plugin.sort_column, [[s.a_href(), nb, too_quick2[s], too_quick4[s]]
                             for s, nb in too_quick.items()],
        url="%s&%s=1" % (plugin.plugin.css_name, plugin.plugin.css_name))

    state.question = None

    return ''
Exemple #7
0
def execute(state, plugin, argument):
    if not state.question:
        return

    stats = statistics.question_stats()

    if state.question.stats.given > 2:
        t = state.question.student_time / state.question.stats.given
        return utilities.duration(t)
Exemple #8
0
def execute(state, dummy_plugin, dummy_argument):
    stats = statistics.question_stats()
    t = []
    for q in questions.questions.values():
        if not hasattr(q, 'autoeval_level'):
            continue
        if not getattr(q, 'stats', False):
            continue
        if q.stats.given == 0:
            continue
        if q.student_time:
            d = 'x'
            time_searching = -1
            if q is state.question:
                d = '<var class="me">x</var>'
            elif q.name in state.student.answers:
                a = state.student.answers[q.name]
                if a.answered:
                    d = '<var class="ok">x</var>'
                    time_searching = a.time_searching
                else:
                    if a.nr_asked:
                        d = '<var class="bad">x</var>'
            t.append((q.autoeval_level_average,
                      math.log(1 + q.student_time / q.stats.given), d,
                      q.name + '<script>histogram(' + repr(q.autoeval_level) +
                      ',' + repr(time_searching) + ')</script>'))

    for s in stats.all_students:
        if not hasattr(s, 'autoeval_level'):
            continue
        if s.the_number_of_given_questions == 0:
            continue
        if s.the_time_searching:
            t.append(
                (s.autoeval_level,
                 math.log(1 + s.the_time_searching /
                          s.the_number_of_given_questions),
                 s is state.student and '<var class="me">·</var>'
                 or '·', s is state.student and state.student.name or ''))

    if not len(t):
        return ''
    pos.ymin = min(i[0] for i in t)
    pos.ymax = max(i[0] for i in t)
    pos.xmin = 0
    pos.xmax = max(i[1] for i in t)

    s = []
    for i in range(int(pos.ymin), int(pos.ymax) + 1):
        s.append(pos(i, 0, ("%2d" % i).replace(' ', '&nbsp;')))
    for i in t:
        s.append(pos(*i))

    return '\n'.join(s) + '<br>' * height + '&nbsp;' * 40
Exemple #9
0
def execute(state, plugin, argument):
    if not argument:
        return ''

    stats = statistics.question_stats()
    content = []

    if stats.max_good_answers == 0:
        max_good_answers = 1.
    else:
        max_good_answers = float(stats.max_good_answers)

    if stats.max_bad_answers == 0:
        max_bad_answers = 1.
    else:
        max_bad_answers = float(stats.max_bad_answers)

    if stats.max_given_indices == 0:
        max_given_indices = 1.
    else:
        max_given_indices = float(stats.max_given_indices)

    teachers = set()
    for s in stats.all_students:
        teachers.update(s.grading_teachers())

    for s in stats.all_students:
        grades = s.grades()
        content.append((
            s.filename,
            s.the_number_of_good_answers / max_good_answers,
            s.the_number_of_bad_answers / max_bad_answers,
            s.the_number_of_given_indices / max_given_indices,
            (s.the_time_searching + s.the_time_after) / 3600.,
            s.points(),
        ) + tuple(grades.get(teacher, 0) for teacher in teachers))
    content.sort()

    header = plugin.tip.split('\\A')[1:-1]
    header.append('Points')
    header += list(teachers)
    formater = "%s" + ", %5.3f" * (len(header) - 1)

    t = [
        ','.join(header),
        ','.join(configuration.explain_grade.get(i, '') for i in header)
    ]
    for c in content:
        t.append(formater % c)

    return 'text/csv; charset=UTF-8', '\n'.join(t).encode("utf-8")
def execute(state, plugin, argument):
    if state.question == None:
        return

    teacher = state.student.filename

    if argument:
        the_student, grade = argument.split(',')
        if the_student.startswith('*'):
            the_student = the_student[1:]
            student.students[the_student].set_why(state.question.name, teacher,
                                                  grade)
        else:
            student.students[the_student].set_grade(state.question.name,
                                                    teacher, grade)
        return 'image/png', b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\x0fIDAT\x08\x1d\x01\x04\x00\xfb\xff\x00\x00\xff\x00\x02\x02\x01\x00\x0b\x0e\xaa\xaf\x00\x00\x00\x00IEND\xaeB`\x82'

    stats = statistics.question_stats()

    lines = []
    for s in stats.all_students:
        a = s.answer(state.question.name)
        if not a.answered:
            continue
        last = int(a.grades.get(teacher, '-1'))
        why = a.why.get(teacher, '')

        lines.append([
            utilities.answer_format(a.answered),
            '<span><!-- %2d -->' % last + ''.join(
                '<input name="%s" type="radio" value="%d" onclick="question_correction(event)"%s>&nbsp;%d'
                % (s.filename, i, ['', ' checked'][i == last], i) + {
                    0: '',
                    1: '',
                    2: '<br>'
                }[i % 3] for i in range(6)) + '</span>',
            '<textarea rows="2" cols="40" name="*%s" onchange="question_correction(event)">%s</textarea>'
            % (s.filename, cgi.escape(why)),
        ])

    if len(lines) == 0:
        return
    return ('<noscript>!!!!!!!JAVASCRIPT NEEDED!!!!!!</noscript>' +
            utilities.sortable_table(
                plugin.sort_column,
                lines,
                url=plugin.plugin.css_name,
                html_class="question_correction_table",
            ))
Exemple #11
0
def execute(state, plugin, argument):
    if not argument:
        return ''

    stats = statistics.question_stats()

    for s in state.steal_identity(tuple(stats.all_students)):
        for a in s.answers.values():
            if a.answered and a.question in questions.questions:
                s.writable = True  # Want to change the log
                state.question = questions.questions[a.question]
                s.check_answer(a.answered, state)
    state.question = None
    plugin.heart_content = '<p class="grade_recompute"></p>'
    return ''
Exemple #12
0
def execute(state, plugin, argument):
    if argument == None:
        return ''

    stats = statistics.question_stats()

    pairs = []
    for s in stats.sorted_students:
        for ss in stats.sorted_students:
            if id(s) > id(ss):
                try:
                    if ss.name not in s.nr_answer_same_time:
                        continue
                    after, before = s.nr_answer_same_time[ss.name]
                    pairs.append((after, before,
                                  (100 * after)
                                  / s.the_number_of_good_answers,
                                  (100 * before)
                                  / ss.the_number_of_good_answers,
                                  s, ss))
                except KeyError:
                    pass
    if len(pairs) == 0:
         plugin.heart_content = '<p class="no_pairs_found"></p>'
         return ''
    pairs.sort(key=lambda x: x[0] + x[1])
    pairs.reverse()
    average = (sum(list(zip(*pairs))[1]) + sum(list(zip(*pairs))[2])) / len(pairs)
    average2 = sum((i[1]+i[2])**2 for i in pairs) / len(pairs)
    stddev = (average2 - average*average) ** 0.5
    
    st = []
    for after, before, nn1, nn2, s1, s2 in pairs:
        st.append([s1.a_href(), s2.a_href(),
                   after, before, '%.2f' % nn1,  '%.2f' % nn2])
        if max(nn1, nn2) < average + stddev/2: # not interesting
            break
        
    plugin.heart_content = utilities.sortable_table(
        plugin.sort_column,
        st,
        url = "%s&%s=1" % (plugin.plugin.css_name, plugin.plugin.css_name))

    state.question = None

    return ''
Exemple #13
0
def execute(state, plugin, argument):
    if argument == None:
        return ''

    stats = statistics.question_stats()

    content = []
    for s in stats.all_students:
        nr_good_answers = (styles[s.warning_nr_good_answers],
                           s.the_number_of_good_answers)
        nr_bad_answers = (styles[s.warning_nr_bad_answers],
                          s.the_number_of_bad_answers)
        nr_given_indices = (styles[s.warning_nr_given_indices],
                            s.the_number_of_given_indices)
        time_after = (styles[s.warning_time_after],
                      utilities.time_format(s.the_time_after))

        line = [
            s.a_href(),
            nr_good_answers,
            s.the_number_of_given_questions,
            nr_bad_answers,
            nr_given_indices,
            s.the_number_of_comment,
            utilities.time_format(s.the_time_searching),
            time_after,
            utilities.date_format(s.the_time_first),
            utilities.date_format(s.the_time_last),
            "%3.1f" % s.nr_of_same_time_normed,
            int(s.the_time_variance),
            s.logs and s.logs[-1][1] or '?',
        ]

        # line.append('<img src="?action=question_pixel_map_see_other&student=%s">' % s.filename)

        content.append(line)

    plugin.heart_content = \
         utilities.sortable_table(plugin.sort_column,
                                  content,
                                  url = "%s&%s=1" % (plugin.plugin.css_name,
                                                     plugin.plugin.css_name))
    state.question = None

    return ''
Exemple #14
0
def execute(state, plugin, argument):
    if state.question == None:
        return

    stats = statistics.question_stats()
    
    comments = []
    for s in stats.all_students:
        for a in s.answers.values():
            if a.question != state.question.name:
                continue
            for c in a.comments:
                comments.append( [cgi.escape(c[1]),
                                  s.mailto(body=str(a.question) + "  " + c[1]),
                                  utilities.date_format(c[0])])

    if len(comments) == 0:
        return None
    return utilities.sortable_table(plugin.sort_column, comments,
                                    url=plugin.plugin.css_name
                                    )
def execute(state, plugin, argument):
    if not argument:
        p = state.plugins_dict['answered_other']
        if p.heart_content is not None:
            p.heart_content = (
                '<p><a class="delete_one" href="?action_destroy_student=' +
                state.form['answered_other'] + '">&nbsp;</a>' +
                p.heart_content)
        return ''

    stats = statistics.question_stats()

    roles = set()
    for e in stats.all_students:
        try:
            for role in eval(utilities.read(e.roles_filename)):
                roles.add(role)
        except:
            pass

    if argument == '1':
        students = [
            e for e in stats.all_students if e.the_number_of_good_answers < 2
        ]
    else:
        students = [student.student(argument)]
    s = []
    for e in students:
        if e == state.student:
            continue
        if e.filename in roles:
            continue
        s.append('%s(%s)' % (e.name, e.the_number_of_good_answers))
        e.destroy()

    plugin.heart_content = ('<p class="deleted"><br>' + '<br>\n'.join(s))
    state.question = None

    return ''
Exemple #16
0
def generate(name):
    sys.path.append(os.path.join(os.getcwd()))

    from QUENLIG import statistics
    from QUENLIG import configuration
    import main
    from QUENLIG import questions
    import cgi
    
    configuration.session = main.Session(name)
    configuration.root = os.getcwd()
    configuration.version = os.path.basename(os.getcwd())
    configuration.session.init()
    os.chdir(configuration.session.dir)

    stats = statistics.question_stats()

    ba = []
    filename = 'xxx-' + name + '.html'
    print('\nGenerate', os.path.join(os.getcwd(), filename))
    f = open(filename, 'w')
    f.write('''
<body onclick="compute();">
<style>
pre { margin: 0.1em }
td { vertical-align:top }
#rank { position: fixed ; right:0px; top: 0px; }
#rank TD { font-size: 80% }
TD.radio { white-space: nowrap ; }
table.top > TBODY > TR > TD { border-top: 1px solid black ; border-left: 1px solid black ; }
table.top { border-spacing: 0px ; border: 1px solid black; }
@media print { #rank { position: inherit ; } #rank TD { font-size: 100% ;} }
table.points { text-align: center ; }
</style>
''')

    students = list(stats.all_students)
    students.sort(lambda x,y: cmp(x.name, y.name))


    f.write("""<script><!--
var win ;
    
function compute()
{
if ( win == undefined || win.closed )
   {
   win = window.open() ;
   if ( ! win )
      return;
   win.document.open('text/html') ;
   win.document.write('Total:<div id="top"></div>');
   win.document.close() ;
   }

t = document.getElementsByTagName('input') ;
students = [] ;
for(var i = 0; i < t.length; i++)
   {
   if ( t[i].checked )
       {
       name = t[i].name.split('/')[0] ;
       if ( students[name] != undefined )
           students[name] = Number(students[name]) + Number(t[i].value) ;
       else
           students[name] = Number(t[i].value) ;
       }
   }
s = '<table border class="top">' ;
for(i in students)
   s += '<tr><td>' + i + '</td><td>' + students[i] + '</td></tr>' ;
s += '</table>' ;
win.document.getElementById('top').innerHTML = s ;
}

var note_pas = 1 ;
var note_nb = 5 ;

function radio(name, question, answer)
{
document.write('<tr><td class="radio"><table class="points"><tr>') ;
for(var i=0; i<note_nb; i++)
   document.write('<td>' + i*note_pas + '</td>') ;
document.write('</tr><tr>') ;
for(var i=0; i<note_nb; i++)
   document.write('<td><input type="radio" name="' + name + '/' + question + '" value="' + i*note_pas + '"></td>') ;
document.write('</tr></table></td><td>' + name +
               '</td><td>' + answer + '</td></tr>') ;

}


--></script>
""")
    for q in questions.sorted_questions:
        q = q.name
        f.write('<h1>' + q + '</h1>\n')
        f.write('<p>' + questions.questions[q].question('') + '</p>\n')
        f.write('<table class="top">\n')
        t = []
        for s in students:
            for a in s.answers.values():
                if a.question == q and a.answered:
                    t.append( (s.name, q,
                               cgi.escape(a.answered)
                               .replace('\r\n','\n')
                               .replace('\n','<br>')
                               .replace('\\','\\\\')
                               .replace('"', '\\"')) )
                    break
        t.sort(key=lambda x: x[2].strip().lower())
        for tt in t:
            f.write('<script>radio("%s","%s","%s");</script>\n' % tt)
        f.write('</table>')
    f.close()
Exemple #17
0
def plot_svg(url_base):
    width = 55
    height = 24
    text_height = 6
    bar_text_height = text_height / 2
    x_spacing = 3
    y_spacing = 3
    line_spacing = (height - 3 * text_height) / 4
    line_decal = text_height + line_spacing
    border_width = 1
    x_margin = width * 1.5
    x_margin += 2 * width  # Name of required and used_by list of questions
    y_margin = height * 1.4

    stats = statistics.question_stats()

    h = statistics.histogram_level()
    h.sort()

    svg = Svg(text_height, bar_text_height, border_width,
              h[-1] * (width + x_spacing) + 2 * x_margin,
              (2 + questions.sorted_questions[-1].level) *
              (height + y_spacing) + 2 * y_margin, url_base)
    barplot = BarPlot(svg, width, height, 4, bar_text_height)

    level = -1
    y = y_margin
    for q in questions.sorted_questions:
        if q.level != level:
            x = x_margin
            y += height + y_spacing
            level = q.level

        opacity = (q.stats.given + 1.) / (len(stats.all_students) + 1)
        barplot.opacity = "opacity:%5.3f;fill-opacity:%5.3f;" % (opacity,
                                                                 opacity)

        svg.g_start(x, y)
        barplot.background(border_width)

        if q.stats.given:
            barplot.bar(0, q.stats.good, q.stats.given, svg_class='good')
            barplot.bar(1,
                        q.stats.bad,
                        q.stats.given,
                        svg_class='bad',
                        pixel=2)
            barplot.bar(2, q.stats.indices, q.stats.given, svg_class='indice')
            barplot.bar(3,
                        int(q.stats.time_searching / q.stats.given),
                        300,
                        svg_class='time',
                        pixel=2)

        if q.stats.nr_comment:
            barplot.nr_comments(q.stats.nr_comment)

        t = [q.world] + split_text(q.short_name)
        barplot.textes(t, line_decal, url=q.url())

        t = q.required.names()
        barplot.textes(t,
                       bar_text_height,
                       opacity='fill-opacity:0;',
                       align='e',
                       svg_class='bar e')

        t = q.used_by
        barplot.textes(t,
                       bar_text_height,
                       opacity='fill-opacity:0;',
                       align='s',
                       svg_class='bar s')

        x += width + x_spacing
        svg.g_end()

    return svg.end()
Exemple #18
0
def execute(state, dummy_plugin, dummy_argument):
    if state.question == None:
        return
    if not state.threaded_run:
        return  # To be fast

    stats = statistics.question_stats()

    uncanonize = {}
    arcs = collections.defaultdict(lambda: collections.defaultdict(int))
    for s in stats.all_students:
        if state.question.name not in s.answers:
            continue
        for dummy in state.steal_identity([s]):
            a = s.answers[state.question.name]
            last_comment = is_first + state.question.get_question(state)
            for c_orig in a.bad_answers:
                c = state.question.canonize(c_orig, state)
                uncanonize[c] = c_orig
                commented = is_comment + re_comment.sub(
                    "\n", s.answer_commented(a.question, c_orig, state))
                arcs[last_comment][c] += 1
                arcs[c][commented] += 1
                last_comment = commented
            if a.answered:
                c = is_good + state.question.canonize(a.answered, state)
                commented = is_done + re_comment.sub(
                    "\n",
                    s.check_answer(a.answered, state)[1])
                commented = re.sub("(?s)<u:sequence.*", "", commented)
                arcs[last_comment][c] += 1
                arcs[c][commented] += 1
                uncanonize[c] = is_good + a.answered
            else:
                arcs[last_comment][a.answered] += 1

    s = '''digraph "%s" {
node[height="0.2",width="0.2",shape=rectangle, margin="0.025", label="",style="filled", fillcolor="white", fontsize="8"];
graph[charset="UTF-8", orientation="P",ranksep=0.5,sep=0,nodesep=0.05];
''' % state.question.name
    nodes = set()
    for node, others in arcs.items():
        nodes.add(node)
        for other in others:
            nodes.add(other)
    for node in nodes:
        str_node = str(uncanonize.get(node,
                                      node)).replace('\\', '\\\\').replace(
                                          '"', '\\"').replace('\n', '\\n')

        if str(node).startswith(is_comment):
            s += '%s [ label="%s"];\n' % (H(node), str_node[1:])
        elif str(node).startswith(is_good):
            s += '%s [ label="%s", style="filled",fillcolor="#88FF88" ];\n' % (
                H(node), str_node[1:])
        elif str(node).startswith(is_first):
            s += '%s [ label="%s" ];\n' % (H(node), str_node[1:])
        elif str(node).startswith(is_done):
            s += '%s [ label="%s", style="filled",fillcolor="#00FF00" ];\n' % (
                H(node), str_node[1:])
        elif node is False:
            s += '%s [ style="filled",fillcolor="#FF0000" ];\n' % (H(node), )
        else:
            s += '%s [ label="%s", style="filled",fillcolor="#FF8888"   ];\n' % (
                H(node), str_node)
    for node, others in arcs.items():
        for arc, nb in others.items():
            s += '%s -> %s [penwidth="%d"];\n' % (H(node), H(arc),
                                                  int((2 * nb)**0.5))
    s += '}'

    f = open("xxx.dot", "w")
    f.write(s)
    f.close()
    p = subprocess.Popen(["dot", "-Tsvg", "xxx.dot"], stdout=subprocess.PIPE)
    svg = p.communicate()[0].decode("utf-8")
    svg = re.sub(' (width|height)="[0-9]*pt"', '', svg)

    return '<div style="text-align:left; width: 20em" onclick="this.style.width = this.offsetWidth * 1.5 + \'px\'">' + svg + '</div>'