• 第二次结对编程作业


    1. 地址

    本次博客链接
    结对同学博客链接
    github项目地址

    2. 分工

    童景霖:完成AI的实现
    黄永福:完成UI的实现

    3. PSP表格

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    · Planning · 计划 30 20
    · Estimate · 估计这个任务需要多少时间 20 20
    · Development · 开发 240 300
    · Analysis · 需求分析 (包括学习新技术) 200 600
    · Design Spec · 生成设计文档 30 30
    · Design Review · 设计复审 20 20
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 10
    · Design · 具体设计 60 80
    · Coding · 具体编码 200 240
    · Code Review · 代码复审 30 30
    · Test · 测试(自我测试,修改代码,提交修改) 30 40
    · Reporting · 报告 40 60
    · Test Repor · 测试报告 20 15
    · Size Measurement · 计算工作量 20 25
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 20 20
    · 合计 970 1510

    4. 解题思路描述与设计实现说明

    网络接口的使用

    • 采用API文档中“注册与绑定”里的代码样例实现注册和绑定,其他功能也基本类似,将函数中的参数进行修改即可
    • 将API返回的数据格式转换,利用json.load()转换成字典对象,再对字典进行处理获得所需要的数据

    代码组织与内部实现设计(类图)

    关键部分流程图

    5. 关键代码解释

    代码的关键部分

    • AI_Part:
    def find_card(c_list):
        s1 = 0
        s0 = 0
        for x0 in itertools.combinations(c_list, 5):
            list1 = c_list.copy()
            x0 = list(x0)
            a = gets_core(x0, 5)
            if a < 20 :
                continue
            for y0 in x0:
                list1.remove(y0)
    
            for x1 in itertools.combinations(list1, 5):
                list2 = list1.copy()
                x1 = list(x1)
                for y1 in x1:
                    list2.remove(y1)
                x2 = list2
    
                b = gets_core(x1,5)
                c = gets_core(x2,3)
    
                if (a >= b) and (b >= c):
                    s1 = a + 1.5*b + 2*c
                    if s1 > s0:
                        s0 = s1
                        global card
                        card.clear()
                        # 3 x2
                        str2 = get_str(x2,3)
                        # 5 x1
                        str1 = get_str(x1,5)
                        # 5 x0
                        str0 = get_str(x0,5)
                        card.append(str2)
                        card.append(str1)
                        card.append(str0)
    
    
    • 利用itertools迭代器的combinations函数从13张牌中抽取5张作为后墩,判断后墩牌型,若为散牌则直接跳过;再从剩下的8张牌中抽取5张做为中墩,判断中墩牌型,若比后墩大,则直接跳过,重新搜索中墩;剩下的3张牌为前墩。
      将各种牌型赋予一定的分数值,将前中后墩的牌型分数相加得到总分,总分最高的牌即为最终牌型,并返回。

    • UI_Part:

    class IndexDetail(QtWidgets.QDialog, history_detail.Ui_Dialog):
        def __init__(self, parent=None, *args, **kwargs):
            super().__init__(parent, *args, **kwargs)
            self.setupUi(self)
            self.res = API.history(MainWindow.TokenMine, IndexHistory.pid)
            print(self.res['status'])
            if self.res['status'] == 0:
                self.res = self.res['data']
                self.res = self.res['detail']
                self.label_name.setText(str(self.res[0]['name']))
                self.label_score.setText(str(self.res[0]['score']))
                self.label_card.setText(str(self.res[0]['card']))
                self.label_name_2.setText(str(self.res[1]['name']))
                self.label_score_2.setText(str(self.res[1]['score']))
                self.label_card_2.setText(str(self.res[1]['card']))
                self.label_name_3.setText(str(self.res[2]['name']))
                self.label_score_3.setText(str(self.res[2]['score']))
                self.label_card_3.setText(str(self.res[2]['card']))
                self.label_name_4.setText(str(self.res[3]['name']))
                self.label_score_4.setText(str(self.res[3]['score']))
                self.label_card_4.setText(str(self.res[3]['card']))
            else:
                self.label_card.setText('status:'+str(self.res['status']))
    
        def back(self):
            self.close()
            w = IndexHistory(window)
            w.show()
    
    
    • 战局列表界面利用接口函数获取该局PID记录为类成员,在详情界面使用战局列表类成员PID来调用接口获取详情,并显示在GUI上,(如遇对局未完成等情况,显示返回的Status)

    6. 性能分析与改进

    性能分析图


    程序中消耗最大的函数

    改进思路

    • 程序中消耗最大的函数是利用itertools迭代器,使用组合数列出13张牌能组成的所有牌型,再通过对每种情况的牌型进行评分,将分数最高的牌型输出。从13张牌中抽取5张,再从剩下的8张拍中抽取5张,最后剩下3张牌,这样组成牌的前、中、后墩。由于十三张牌能组成的牌型过多导致花费的时间很长。
    • 由于每个人有13张牌,所以后墩必定不可能是散排(如果是散排则为一条龙),因此可以对后墩前进行判断,如果是散牌则可以直接跳过,考虑下一种情况;同样的也可以对中墩进行判断,如果中墩大于后墩,则跳过这种情况,但此时应保持后墩不变,改变中墩。其他的改进思路暂时还没想到。

    7. 单元测试

    def getnum(a):
        return a.num
    
    
    def tonghuashu(dun_b):
        lista = []
        listb = []
        listc = []
        listd = []
    
    #分类
        for s in dun_b:
            if s.color == "#":
                lista.append(s)
            elif s.color == "$":
                listb.append(s)
            elif s.color == "&":
                listc.append(s)
            elif s.color == "*":
                listd.append(s)
    #排序
        lista.sort(key=getnum)
        listb.sort(key=getnum)
        listc.sort(key=getnum)
        listd.sort(key=getnum)
    
        if len(lista) == 5:
            liste = lista
        elif len(listb) == 5:
            liste = listb
        elif len(listc) == 5:
            liste = listc
        elif len(listd) == 5:
            liste = listd
        else:
            liste = []
    
    
        l = len(liste)
        i = 1
    
        if l == 5:
            flag = True
            while i < l:
                if liste[i].num != liste[i-1].num+1:
                    flag = False
                    break
                i = i+1
        else:
            flag =False
    
        if flag is True:
            return liste[0].num
        else:
            return 0
    
    a = tonghuashu(list)
    print(a)
    
    • 这是测试传入的中墩或者后墩是否为同花顺的代码
    • 传入的牌事先经过处理以类的形式存放于列表s中,先将他们根据不同的花色进行分类,若某一种花色的数量达到5,再将其按牌的大小进行排序,检查是否是连续的牌型,是则为同花顺。

    8. GitHub代码签入记录

    9. 遇到的代码模块异常或结对困难及解决方法

    问题描述

    • AI_Part:
      • 不会使用api
      • 不懂得如何制作UI界面
      • 数据类型直接的转换老是弄乱,对于一些函数的返回值类型不熟悉
      • 使用迭代器模块时一直出现错乱
    • UI_Part:
      • QTDesigner网上教程资源过少(多为C++教程或者代码实现教程)
      • .ui->.py 需要借助Pyuic工具,而我下的最新版的anaconda找不到Pyuic.exe的路径
      • 右键.ui文件使用Pyuic进行.ui->.py时 点错成主模块即我的UI.py造成了整个UI.py代码丢失
      • 调用显示继承来的窗口发生跳出

    做过的尝试

    • AI_Part:
      • 百度查找相关资料以及到视频网站查找相应的教学视频
      • 询问同学
      • 不断测试,增加了很多测试点寻找问题
    • UI.Part:
      • 百度精确检索Pyqt5该关键词项
      • 寻找原生的python文件里带该工具
      • 发现有历史记录这个工具英语水平过低未及时发现,经大佬提醒
      • 发现继承来的窗口未定义自定义槽函数,一经调用,立马跳出!

    是否解决

    • AI_Part:
    • UI_Part:

    收获

    • AI_Part:
      • 对API的使用更加熟练了
      • 能更加熟练的使用python,对python的了解也更多了
      • 学习使用了python的itertools模块和time模块
      • 简单掌握了pyqt5的使用,能用pyqt5做出一些简单的程序界面
    • UI_Part:
      • 熟悉API的使用,并能够根据所给的接口写模块
      • 对python自带的工具栏更加熟悉
      • 对python附加工具更加熟悉
      • 对Pyqt5及QtDesigner熟练应用,并初步认识使用QtCreator
      • 对GUI的Init有一定了解

    10. 评价队友

    值得学习的地方

    • 有耐心
    • 学习能力强

    需要改进的地方

    • 效率有待提高

    11. 学习进度条

    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    6 0 0 8 8 学习并能简单使用墨刀、ps等软件
    7 800 800 12 20 学习python
    8 1200 2000 12 32 学习python和pyqt5
  • 相关阅读:
    Linux 用户 quote 配置 说明
    Linux 用户和用户组 配置说明
    ORA-00600: [kck_rls_check must use (11,0,0,0,0) or lower] 故障解决
    Oracle Data Guard PING[ARC2]: Heartbeat failed to connect to standby ''. Error is 12514 故障分析
    Oracle 11g RAC OCR 与 db_unique_name 配置关系 说明
    Data Guard 奇葩的 ORA-16191: Primary log shipping client not logged on standby 问题
    Oracle 11gR2 RMAN Duplicate 触发PLS-00201: identifier 'DBMS_RCVCAT.GETDBID' must be declared 错误
    RMAN RAC 到 单实例 duplicate 自动分配通道 触发 ORA-19505 错误
    Secure CRT 自动记录日志 配置 小记
    VBox fdisk 不显示 添加的硬盘 解决方法
  • 原文地址:https://www.cnblogs.com/tjll/p/11729982.html
Copyright © 2020-2023  润新知