山东大学-VirtualJudge-总结7

在过去的几天时间里面,我主要集中精力实现Contest 的的Rank以及Status功能

Rank实现代码####

###前端
<br>
<table class="table table-bordered table-hover text-center" id = "rank_table">
    <thead>
    </thead>
    <tbody>
    </tbody>
</table>

<script type="text/javascript">
    function str_pad_left(string,pad,length) {
        return (new Array(length+1).join(pad)+string).slice(-length);
    }

    function secondsToTime(secs)
    {
        var hours = Math.floor(secs / (60 * 60));

        var divisor_for_minutes = secs % (60 * 60);
        var minutes = Math.floor(divisor_for_minutes / 60);

        var divisor_for_seconds = divisor_for_minutes % 60;
        var seconds = Math.ceil(divisor_for_seconds);

        return hours + ":" + str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);;
    }
    function refreshRankList(){
        $.ajax({
            type: "post",
            url: "/contest/" + {{ contest.id }} + "/rank/",
            dataType: "json",
            success: function(data){
                $("#rank_table tr").remove();
                thHTML = "<tr><th class=\"text-center\">Rank</th><th class=\"text-center\">ID</th><th class=\"text-center\">Solve</th><th class=\"text-center\">Penalty</th>"
                $.each(data.statsinfo, function(i, item){
                    thHTML += "<th class=\"text-center\">" + item.probid + "</th>";
                });
                thHTML += "</tr>";
                $("#rank_table thead").append(thHTML);
                rank_num = 0;
        var last_solved = -1;
        var last_penalty = -1;
        var rank_list=[];
                $.each(data, function(i, item) {
                    if (item != data.statsinfo) {
                rank_list.push(item);
            }
            });
            rank_list.sort(function(a,b){return a.solved==b.solved?a.penalty-b.penalty:b.solved-a.solved;});
                $.each(rank_list, function(i, item) {
                    if (item != data.statsinfo) {
                if(item.solved!=last_solved || item.penalty!=last_penalty)
                            rank_num += 1;
            last_solved=item.solved;
            last_penalty=item.penalty;
                        trHTML = "<tr><td style=\"align:center;\">" + rank_num +
                        "</td><td class=\"text-center\">" + item.name +
                        "</td><td>" + item.solved +
                        "</td><td>" + item.penalty + "</td>";
                        $.each(item.probs, function(i, pitem){
                            if (pitem.acNum == 0) {
                                if (pitem.failNum == 0) {
                                    trHTML += "<td></td>";
                                } else {
                                    trHTML += "<td style=\"background-color: red; color:white;\"><br><span>(-" + pitem.failNum + ")</span></td>";
                                }
                            } else {
                                if (pitem.failNum == 0) {
                                    trHTML += "<td style=\"background-color: #99FF66;\">" + secondsToTime(pitem.acTime) + "</td>";
                                } else {
                                    trHTML += "<td style=\"background-color: #99FF66;\">" + secondsToTime(pitem.acTime) + "<br><span>(-" + pitem.failNum + ")</span></td>";
                                }
                            }
                        });
                        trHTML += "</tr>"
                        $("#rank_table tbody").append(trHTML);
                    }
                });
                thHTML = "<tr><td></td><td></td><td></td><td></td>";
                $.each(data.statsinfo, function(i, item){
                    thHTML += "<td style=\"background-color: #D0D0D0;\">" + item.acNum + "/" + item.tryNum + "</td>";
                });
                thHTML += "<tr>"
                $("#rank_table tbody").append(thHTML);

            }
        });
    }




    $(document).ready(function () {
    refreshRankList();
    //setInterval(function(){refreshRankList();},10000);
    })
</script>

###后台
def contest_rank(req, cid):
    if req.is_ajax():
        contest = Contest.objects.get(id = cid)
        if contest.private:
            if req.user.is_superuser==False and req.user.info not in contest.accounts.all() :
                return JsonResponse("{}")
        rank_cache = contest.rank
        # print("rank_cache:")
        # print(rank_cache)
        status_list = Status.objects.filter(cid = cid).filter(runid__gt = contest.last_submit_id).order_by("time")
        # print("status_list")
        # print(status_list)
        rank_dict = json.loads(rank_cache)
        # print("rank_dict")
        # print(rank_dict)
        statsinfo = {}
        pos = 0
        problem_list = contest.get_problem_list()
        length = len(problem_list)

        
        if contest.last_submit_id==0:
            rank_dict["statsinfo"] = [{} for i in range(length)]
            for item in problem_list:
                rank_dict["statsinfo"][pos] = {"probid" : chr(pos + 65) ,"acNum" : 0, "tryNum" : 0}
                statsinfo[item[2].title] = {"pos" : pos}
                pos += 1
        else:
            for item in problem_list:
                statsinfo[item[2].title] = {"pos" : pos}
                pos += 1

        for item in status_list:
            if item.user.is_staff :
                continue
            name = item.user.username
            contest.last_submit_id = max(contest.last_submit_id, item.runid)
            if name not in rank_dict.keys():
                rank_dict[name] = {"name" : name, "solved":0, "penalty":0, "probs" : [{"failNum" : 0, "acNum" : 0, "acTime" : 0} for i in range(length)]}

            pos = statsinfo[item.pro.title]["pos"]

            if item.result == 3: #Waiting
                break

            if item.result == 0: #Accepted
                rank_dict["statsinfo"][pos]["acNum"] += 1
            rank_dict["statsinfo"][pos]["tryNum"] += 1

            if rank_dict[name]["probs"][pos]["acNum"] == 0:
                if item.result == 0:
                    rank_dict[name]["probs"][pos]["acNum"] += 1
                    rank_dict[name]["probs"][pos]["acTime"] = dateToInt(item.timec - contest.start_time, 1)
                    rank_dict[name]["penalty"] += 20 * rank_dict[name]["probs"][pos]["failNum"] + dateToInt(item.timec - contest.start_time, 0)
                    rank_dict[name]["solved"] += 1
                else:
                    rank_dict[name]["probs"][pos]["failNum"] += 1
        contest.rank = json.dumps(rank_dict)
        # print("contest.rank")
        # print(contest.rank)
        contest.save()
        return JsonResponse(rank_dict)

Status实现代码####

###前端
</br>
<table class="table">
    <thead>
    <tr>
        <th>RunID</th>
        <th>Problem</th>
        <th>Status</th>
        <th>Language</th>
        <th>User</th>
        <th>SubmitTime</th>
    </tr>
    </thead>
    <tbody>
    {% for item in status_list %}

        <tr
                {% ifequal item.result 'Waiting' %}
                    class="info"
                {% endifequal %}
                {% ifequal item.result 'Accepted' %}
                    class="success" 
                {% else %}
                    class="danger"
                {% endifequal %}
         >
            <td>{{ item.runid }}</td>
            <td><a href="/problem/{{ item.pro.proid}}">{{ item.pro.title }}</a></td>
            {% ifequal item.pro.isCCF True %}
                 <td>{{ item.score }}</td>
        {% else %}
            {% ifequal item.result "Compilation Error"%}
            <td><a href="/show_source?solution_id={{ item.runid }}" target="_blank">{{ item.result }}</a></td>
            {% else %}
            <td>{{ item.result }}</td>
            {% endifequal %}
            {% endifequal %}
            {% ifequal item.user.id user.id %}
                <td><a href="/show_source?solution_id={{ item.runid }}" target="_blank">{{ item.result }}</a></td>
            {% else %}
            {% ifequal user.is_staff True %}
            <td><a href="/show_source?solution_id={{ item.runid }}" target="_blank">{{ item.result }}</a></td>
            {% else %}
            <td>{{ item.lang }}</td>
            {% endifequal %}
            {% endifequal %}
            <td>{{ item.user.username }}</td>
            <td>{{ item.time | date:"Y-m-d H:i:s" }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>
<center>
<ul class="pagination">
    <script type="text/javascript">
        //$(document).ready(function () {
        function request_contest_status(pg){
            $.ajax({
                    type: 'get',
                    url: "/contest/" + {{ contest_id }} + "/status/?pg=" + pg,
                    success: function (responseData) {
                        $('#panel-status').html(responseData);
                    }
            })
        }
    </script>
    {% for id in page %}
        <li><a class="{% if pg == id %}active{% else %}disabled{% endif %}"
               href="javascript:request_contest_status({{ id }});">
            {{ id }}
            </a>
        </li>
    {% endfor %}
</ul>
</center>


###后台
def contest_status(req, cid):#has understood
    if req.is_ajax():
        contest = Contest.objects.get(id=cid)
        t = loader.get_template('contest/contest_status.html')
        status_list = Status.objects.filter(cid=cid).order_by('-time')#need change
        if contest.private:
            if req.user.is_superuser==False and req.user.info not in contest.accounts.all() :
                status_list = []
        pg = req.GET.get('pg')
        if not pg:
            pg = 1
        pg = int(pg)

        max_cnt = status_list.count() // 20 + 1
        start = max(pg - PAGE_NUMBER_EVERY_PAGE, 1)
        end = min(pg + PAGE_NUMBER_EVERY_PAGE, max_cnt)

        lst = status_list[(pg - 1) * LIST_NUMBER_EVERY_PAGE:pg * LIST_NUMBER_EVERY_PAGE]

        # content_html = t.render(Context({'status_list': lst, 'page': range(start, end + 1), 'contest_id': cid, 'user': req.user}))
        # return HttpResponse(content_html)
        return render(req,'contest/contest_status.html',{'status_list': lst, 'page': range(start, end + 1), 'contest_id': cid, 'user': req.user})
    else:
        raise Http404

功能效果截图####

contest-status
contest-rank
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,515评论 25 708
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,251评论 4 61
  • 上一章 陆亦风和林思凡到家后,张诚和罗慧敏早已等在一边,看到二人同时进门,罗慧敏暧昧道:“小两口去哪儿约会了,这么...
    狐狸九阅读 358评论 0 4
  • 我的梦里有两队马, 一队白马上天山, 一队黑马下南疆。 一队为迎亲, 一队是赶丧。 一队在途中遇到僧侣点头含笑, ...
    唐诗远阅读 1,205评论 4 13
  • 什么是三观? 人生观、世界观、价值观。(人生观就是自己为什么活着,活着要干什么;世界观就是你对世界的认识,这个东西...
    请叫我徐老师x阅读 356评论 0 1