极限初排结果显示


!/usr/local/bin/python3

# encoding=utf-8
# 用于显示算法质量生成结果脚本
import psycopg2
import cgi
import decimal
form = cgi.FieldStorage()

G_NUMBER = form.getvalue("n")
G_TYPE = form.getvalue("type")

# G_NUMBER = 100
# G_TYPE = "多产品far2.5"

class GetData():
    def __init__(self):
        self.conn = psycopg2.connect(database="unittest", user="postgres", password="Mz9A85vmP5wSxxeNbGBrjv86L9bJoX",
                                     host="10.0.0.17", port="5432")
        self.cur = self.conn.cursor()
        self.far_pass = 0
        self.far_fail = 0
        self.not_generated = 0
        self.coverage_pass = 0
        self.coverage_fail = 0
        self.run_time_pass = 0
        self.run_time_fail = 0
        self.score_sum = 0
        self.result_info_dict = {"多层": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多层大数据": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "小高11F": {"far_flag": {"green": 0, "red": 0},"coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "小高11F大数据": {"far_flag": {"green": 0, "red": 0},"coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "小高18F_T3": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "小高18F_T3大数据": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "小高18F_T4": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "小高18F_T4大数据": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "叠拼": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "叠拼大数据": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多产品": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多产品far2.0": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多产品far2.5": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多产品far2.8": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多产品far1.5": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         "多产品far3.0": {"far_flag": {"green": 0, "red": 0}, "coverage_flag": {"green": 0, "red": 0},"score_flag":{"green": 0, "red": 0,"score":{"0-3w":[],"3-5w":[],"5-8w":[],"8w+":[]}}},
                         }
        self.order = ""
        self.order = " order by id"
        if not G_NUMBER:
            self.start = 100
        else:
            self.start = G_NUMBER
        self.build_type = ["所有","多层","叠拼","小高11F","小高18F_T3","小高18F_T4","多产品","多产品far1.5","多产品far2.0","多产品far2.5","多产品far2.8","多产品far3.0"]
        if not G_TYPE:
            self.l_type = "多层"
        else:
            self.l_type = G_TYPE
        self.ground_area = {"多层":[233,7],"小高11F":[280,11],"小高18F_T3":[350,18],"小高18F_T4":[350,18],"叠拼":[160,4],"多产品":[160,4]}
    def select(self, sql):
        u"""从数据库中获取信息"""
        if len(sql) > 0:
            self.cur.execute(sql)
            rows = self.cur.fetchall()
            return rows

    def summary_info(self):
        header_html = self.header_fill()
        jq = self.load_jquery() + self.select_script()
        style = """
        <style>
            .imgPreview {
                display: none;
                top: 0;
                width: 100%;
                height: 100%;
                position: fixed;
                background: rgba(0, 0, 0, 0.5);
            }
            .imgPreview img {
                z-index: 100;
                width: auto;
                height: auto;
                position: fixed;
                top: 50%;
                transform: translate(-50%, -50%);
                left: 50%;
            }
        </style>
            <style type="text/css">
            .red{color:red}
            .green{color:green;}
            .bold_red{font-weight: bold;color:red}
            .bold_green{font-weight: bold;color:green;}
            .bold{font-weight: bold;width:60px;}
            .bold_header{font-weight: bold;}
            </style>"""
        lines = [jq, style, header_html]
        lines.append("http://external.xkool.org:30011/cgi-bin/download.py")
        return u"""<html>{}
            <head>
            {}
            </head>
            &lt;body&gt;{}<a href="{}">下载excel报告</a>""".format(*lines)
    def header_fill(self, *kargs):
        select_html = self.select_function(*kargs)
        return u"""
            &lt;h2&gt;极限排布结果查看&lt;/h2&gt;{}
            &lt;table border="1" style="width:auto id="show_table"&gt;
            &lt;tbody&gt;""".format(select_html)

    def load_jquery(self):
        return """&lt;script src="http://external.xkool.org:30011/js/jquery.min.js"&gt;&lt;/script&gt;"""

    def select_function(self, *kargs):
        select_html = """&lt;h3&gt;请选择查看类型:&nbsp;&nbsp;&lt;select id="type" style="width:200px;height:35px;border:1px solid #ccc;"&gt;"""
        for env in self.build_type:
            if G_TYPE == env:
                select_html = select_html + """&lt;option value="{}" selected&gt;{}&lt;/option&gt;""".format(env, env)
            else:
                select_html = select_html + """&lt;option value="{}"&gt;{}&lt;/option&gt;""".format(env, env)
        select_html = select_html + """&lt;/select&gt;&lt;/h3&gt;"""

        select_html = select_html + """&lt;h3&gt;请选择显示条目数:&nbsp;&nbsp;&lt;select id="number" style="width:200px;height:35px;border:1px solid #ccc;"&gt;"""

        for service_name in ["100","500","1000","所有"]:
            if G_NUMBER == service_name:
                select_html = select_html + """&lt;option value="{}" selected&gt;{}&lt;/option&gt;""".format(service_name,service_name)
            else:
                select_html = select_html + """&lt;option value="{}"&gt;{}&lt;/option&gt;""".format(service_name, service_name)
        select_html = select_html + """&lt;/select&gt;&lt;/h3&gt;"""
        return select_html

    def select_script(self):
        js_html = """&lt;script&gt;$(document).ready(function(){
              $("#type").change(function(){
                        var data = $("#type").find("option:selected").text();
                        var data1 = $("#number").find("option:selected").val();
                    window.location.href="/cgi-bin/far.py?type="+data+"&amp;n="+data1;
              });
            });&lt;/script&gt;
            &lt;script&gt;$(document).ready(function(){
              $("#number").change(function(){
                        var data = $("#type").find("option:selected").text();
                        var data1 = $("#number").find("option:selected").val();
                    window.location.href="/cgi-bin/far.py?type="+data+"&amp;n="+data1;
              });
            });&lt;/script&gt;
        """
        return js_html

    def summary_type_info(self):
        # type 容积率、覆盖率、
        headers = """&lt;table border="1" width="800"&gt;
            &lt;tbody&gt;&lt;tr&gt;&lt;td class="bold"&gt;分组类型&lt;/td&gt;&lt;td class="bold"&gt;容积率(通过个数/总数)&lt;/td&gt;&lt;td class="bold"&gt;覆盖率(-0.03)&lt;/td&gt;&lt;td class="bold"&gt;分数(通过/总数)&lt;/td&gt;&lt;td class="bold"&gt;总分数&lt;/td&gt;&lt;/tr&gt;{}&lt;/tbody&gt;&lt;/table&gt;"""
        body = ""

        for key,v in self.result_info_dict.items():
            if v["score_flag"]["green"]+v["score_flag"]["red"] == 0:
                avg = 0
            else:
                avg = self.get_weight_average_score(v["score_flag"]["score"])
                # v["score_flag"]["score"]/(v["score_flag"]["green"]+v["score_flag"]["red"])
            lines = """
                &lt;tr&gt;&lt;td class="bold"&gt;{}&lt;/td&gt;&lt;td class="bold"&gt;{}/{}&lt;/td&gt;&lt;td class="bold"&gt;{}/{}&lt;/td&gt;&lt;td class="bold"&gt;{}/{}&lt;/td&gt;&lt;td class="bold"&gt;{:.2f}&lt;/td&gt;&lt;/tr&gt;
                """.format(key,v["far_flag"]["green"],v["far_flag"]["green"]+v["far_flag"]["red"],v["coverage_flag"]["green"],v["coverage_flag"]["green"]+v["coverage_flag"]["red"],v["score_flag"]["green"],v["score_flag"]["green"]+v["score_flag"]["red"],avg)
            if self.l_type == "所有" or self.l_type in key:
                body = body + lines

        return headers.format(body)

    def get_weight_average_score(self,kwargs:dict):
        n_ = {}
        for key,score_list in kwargs.items():
            if score_list:
                avg = sum(score_list)/len(score_list)
            else:
                avg = 0
            n_[key] = avg
        return n_["0-3w"]*0.35+n_["3-5w"]*0.28 +n_["5-8w"]*0.2+n_["8w+"]*0.17

    def get_type_result_from_sql(self,*row):
        row= list(row[0])
        if "大数据" in row[0]:
            key = "{}大数据".format(row[3])
        else:
            key = row[3]
        if key == "多产品":
            sub_key = "多产品far{}".format(row[7])
            self.result_info_dict[sub_key]["far_flag"][row[1]] = self.result_info_dict[sub_key]["far_flag"][row[1]]  + 1
            self.result_info_dict[sub_key]["coverage_flag"][row[2]] = self.result_info_dict[sub_key]["coverage_flag"][row[2]]  + 1
            self.result_info_dict[sub_key]["score_flag"][row[4]] = self.result_info_dict[sub_key]["score_flag"][row[4]]  + 1
            score = row[5]
            area = row[6]
            key_range = self.get_area_key(area,score)
            self.result_info_dict[sub_key]["score_flag"]["score"][key_range].append(score)
        # print(self.result_info_dict[key][row[1]])
        self.result_info_dict[key]["far_flag"][row[1]] = self.result_info_dict[key]["far_flag"][row[1]]  + 1
        self.result_info_dict[key]["coverage_flag"][row[2]] = self.result_info_dict[key]["coverage_flag"][row[2]]  + 1
        self.result_info_dict[key]["score_flag"][row[4]] = self.result_info_dict[key]["score_flag"][row[4]]  + 1
        score = row[5]
        area = row[6]
        key_range = self.get_area_key(area,score)
        self.result_info_dict[key]["score_flag"]["score"][key_range].append(score)

    def get_area_key(self,area,score):
        if area&lt;30000:
            return "0-3w"
        elif area&lt;50000:
            return "3-5w"
        elif area&lt;80000:
            return "5-8w"
        else:
            return "8w+"
    def header_body_fill(self):
        return u"""
            &lt;table border="1" style="width:auto"&gt;
            &lt;tbody&gt;
            &lt;tr&gt;&lt;td class="bold_header"&gt;测试分组&lt;/td&gt;&lt;td class="bold_header"&gt;用例id&lt;/td&gt;&lt;td class="bold_header"&gt;用例名称&lt;/td&gt;&lt;td class="bold_header"&gt;容积率(实际值/预期值) 误差值 误差范围&lt;/td&gt;&lt;td class="bold_header"&gt;覆盖率(实际值/预期值)&lt;/td&gt;&lt;td class="bold_header"&gt;耗时(实际值/以前该case平均耗时)&lt;/td&gt;&lt;td class="bold_header"&gt;缩略图&lt;/td&gt;&lt;td class="bold_header"&gt;测试时间&lt;/td&gt;&lt;td class="bold_header"&gt;分数&lt;/td&gt;&lt;td class="bold_header"&gt;地块面积&lt;/td&gt;&lt;/tr&gt;"""

    def get_average_run_time(self, case_id, run_time):
        sql = "select avg(runtime) from baseline_new_algorithm_result where testcase_id='{}' and fact_far!=0".format(
            case_id)
        row = self.select(sql)[0][0]
        if not row:
            row = run_time
        return row

    def get_block_area(self,testcase_id,block_type='楼型_0'):
        if "bigdata" in testcase_id:
            testcase_id = "testcase_bigdata_{}".format(testcase_id[-5:])
        elif "multi_product" in testcase_id:
            testcase_id = 'testcase_{:05d}'.format(int(block_type.split("_")[-1]))
        else:
            testcase_id = testcase_id[:14]    
        sql = "select area from testcase_area where testcase_id='{}'".format(testcase_id)

        row = self.select(sql)[0][0]
        return row

    def get_backend_average(self):
        template_html = self.header_body_fill()
        if self.l_type == "所有":
            filter_build_type = ""
        elif self.l_type in ["多层","叠拼","小高11F","小高18F_T3","小高18F_T4","多产品"]:
            filter_build_type = "where build_type='{}'".format(self.l_type)
        elif self.l_type in ["多产品far1.5","多产品far2.0","多产品far2.5","多产品far2.8","多产品far3.0"]:
            far_tmp = float(self.l_type[-3:])
            filter_build_type = "where build_type='多产品' and expect_far={}".format(far_tmp)
        sql = """SELECT DISTINCT ON (testcase_id) type,testcase_id,testcase_name,expect_far,fact_far,expect_coverage,fact_coverage,runtime,url,testdate,build_type,area_list_string
        FROM baseline_new_algorithm_result {}
        ORDER BY testcase_id, id DESC""".format(filter_build_type)
        print(sql)
        rows = self.select(sql)
        if self.start == "所有":
            self.start = len(rows)
        local_number = 0
        for index, row in enumerate(rows):
            block_type = row[0]
            case_id = row[1]
            case_name = row[2]
            expect_far = row[3] 
            fact_far = row[4]
            expect_coverage = row[5]
            fact_coverage = row[6]
            run_time = row[7]
            url = row[8]
            testdate = row[9]
            key = row[10]
            area_list_string = row[11]
            pre_run_time = self.get_average_run_time(case_id, run_time)
            area = decimal.Decimal(area_list_string.split("-")[-1])
            # key = self.get_key_from_casename(row[2])
            if key in self.l_type or self.l_type == "所有":
                local_number = local_number + 1
                if fact_far == 0:
                    self.not_generated = self.not_generated + 1
                if expect_far-decimal.Decimal(0.04) &lt;= fact_far and fact_far != 0 and (fact_far-expect_far) * area &gt;= -self.ground_area[key][0]:
                        far_flag = "green"
                        self.far_pass = self.far_pass + 1
                else:
                    self.far_fail = self.far_fail + 1
                    far_flag = "red"
                if expect_coverage &lt;= round(fact_coverage,4) and fact_coverage != 0:
                    self.coverage_pass = self.coverage_pass + 1
                    coverage_flag = "green"
                else:
                    coverage_flag = "red"
                    self.coverage_fail = self.coverage_fail + 1
                # self.get_type_result_from_sql([case_name,far_flag,coverage_flag,key])

                if run_time &lt;= pre_run_time and run_time != 1800:
                    run_time_flag = "green"
                    self.run_time_pass = self.run_time_pass + 1
                else:
                    run_time_flag = "red"
                    self.run_time_fail = self.run_time_fail + 1
                far_message = "&lt;font color='{}'&gt;{:.3f}/{:.3f} {:.2f} [-{:.2f},+∞]&lt;/font&gt;".format(far_flag, fact_far, expect_far,(fact_far-expect_far)*area,self.ground_area[key][0])
                coverage_message = "&lt;font color='{}'&gt;{:.4f}/{:.4f}&lt;/font&gt;".format(coverage_flag, fact_coverage,
                                                                                  expect_coverage)
                run_message = "&lt;font color='{}'&gt;{:.2f}/{:.2f}&lt;/font&gt;".format(run_time_flag, run_time, pre_run_time)
                if key == "多产品":
                    #100 - 300 *( 手排低层建筑面积/手排建筑面积 - 算法低层建筑面积/算法建筑面积)
                    lower_area,floor_area,fact_lower_area,fact_floor_area,net_site_area = list(map(float,area_list_string.split("-")))
                    if fact_floor_area==0:
                        score = 0
                    else:
                        score = 100 - 300*(lower_area/floor_area-fact_lower_area/fact_floor_area)
                else:
                    score = (float(fact_far - expect_far) * float(area) / self.ground_area[key][0] * (0.3 / self.ground_area[key][1]) + 1) * 100

                if score &gt; 100:
                    score = 100
                elif score &lt;=0:
                    score = 0
                self.score_sum = score + self.score_sum
                if score&lt;70:
                    score_message = """&lt;font color='red'&gt;{:.2f}&lt;/font&gt;""".format(score)
                    score_flag = "red"
                else:
                    score_message = """&lt;font color='green'&gt;{:.2f}&lt;/font&gt;""".format(score)
                    score_flag = "green"
                self.get_type_result_from_sql([case_name,far_flag,coverage_flag,key,score_flag,score,area,expect_far])    
                row_list = [block_type, case_id, case_name, far_message, coverage_message, run_message, url, testdate,score_message,area]

                #row_list = [block_type, case_id, case_name, far_message, coverage_message, run_message, url, testdate,area]
                template_html = template_html + self.fill_tr_header_info(*row_list)
            if local_number &gt; int(self.start):
                break
        return template_html

    def fill_tr_header_info(self, *header_list):
        html_model = u"""&lt;tr&gt;
            &lt;td&gt;{}&lt;/td&gt;
            &lt;td&gt;{}&lt;/td&gt;
            &lt;td&gt;{}&lt;/td&gt;
            &lt;td&gt;{}&lt;/td&gt;
            &lt;td&gt;{}&lt;/td&gt;
            &lt;td&gt;{}&lt;/td&gt;
            &lt;td&gt;&lt;img class="img" width="80" height="40" src="{}"&gt;&lt;/td&gt;
            &lt;td&gt;{}&lt;/td&gt;&lt;td&gt;{}&lt;/td&gt;&lt;td&gt;{:.2f}&lt;/td&gt;&lt;/tr&gt;""".format(*header_list)
        return html_model


if __name__ == "__main__":
    idata = GetData()
    html_template = idata.get_backend_average()
    header = idata.summary_info()
    header = header +idata.summary_type_info()
    print("Content-type:text/html\n\n")
    print()
    print()
    print('&lt;html&gt;')
    print('&lt;head&gt;')
    print('&lt;meta charset="utf-8"&gt;')
    print(u'{}'.format(header + html_template))
    print("""&lt;/tbody&gt;&lt;/table&gt;&lt;div class="imgPreview"&gt;
        &lt;img src="#" alt="" id="imgPreview"&gt;
    &lt;/div&gt;
    &lt;script&gt;
        $('.img').on('click', function () {
            var src = $(this).attr('src');
            $('.imgPreview img').attr('src', src);
            $('.imgPreview').show()
        });
        $('.imgPreview').on('click', function () {
            $('.imgPreview').hide()
        });
    &lt;/script&gt;&lt;/body&gt;&lt;/html&gt;""")