zoukankan      html  css  js  c++  java
  • 第二次结对编程作业

    1.相关链接

    [结对同学博客连接]
    https://www.cnblogs.com/panther0416/p/11754419.html
    [本作业博客连接]
    https://www.cnblogs.com/lylinyi/p/11768104.html
    [Github项目地址]
    https://github.com/panther0416/13water

    2.具体分工

    潘松波:负责前端实现、博客撰写
    林逸:负责后端算法、接口编写

    3.PSP表格

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

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

    网络接口的使用

    调用 requests库中的get/post函数实现get/post请求,把如登录、注册等等操作所需要的请求封装成 不同函数放在一个api.py文件下,使用时导入此文件就可以起飞了。
    requests基本用法简单方便,易于上手。
    下面以获取对战详情为例

    def get_detail(token, id):
        url = "http://api.revth.com/history/{}".format(id)
        header = {
            "X-Auth-Token": token,
        }
        response = requests.get(url, headers=header)
        print(response.text)
        re_js = response.json()
        if re_js["status"] == 0:
            return re_js
        else:
            return False
    

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

    • 后端算法代码组织与内部实现设计

    • 前端代码组织与内部实现设计
      利用qt dersigner 将设计好的界面自动转化为py文件,每张界面都有对应的py文件,再自己编写运行窗口和连接服务器的代码,将各界面的代码模块结合在一起,并进行修改、美化。

    说明算法的关键与关键实现部分流程图

    • 算法关键
      • 普通牌型的判断算法(部分):
        def is_tpair(self):
        cnt = 0
        max_num = -1
        for i in range(len(self.cnt_num)):
            if self.cnt_num[i] == 2:
                cnt += 1
                max_num = (i if (i > max_num) else max_num)
        if cnt == 2:
            return max_num
        return False
        
        
        def is_triple(self):
            for i in range(len(self.cnt_num)):
                if self.cnt_num[i] == 3:
                    return i
            return False
        
        
        def is_straight(self):
            for i in range(len(self.card) - 1):
        
                if self.card[i][1] + 1 != self.card[i + 1][1]:
                    return False
            return self.card[len(self.card) - 1][1]
        
        def is_TongHua(self):
            for i in self.cnt_color:
                if i == 5:
                    return max(self.card, key=takeSecond)[1]
            return False
        
      • 遍历算法
        max = -1
        ans = []
        iterator = itertools.combinations(card_list, 5)
        for iter in iterator:
            card1 = list(iter)
            tmp_card = card[:]
            for c in card1:
                tmp_card.remove(c)
            iterator2 = itertools.combinations(tmp_card, 5)
            for iter2 in iterator2:
                card2 = list(iter2)
                tmp_card2 = tmp_card[:]  
                for c in card2:
                    tmp_card2.remove(c)
                card3 = tmp_card2
                n1 = get_weight(2, card1)
                n2 = get_weight(1, card2)
                n3 = get_weight(0, card3)
                if (n1 > n2 and n2 > n3):
                    if(n1[2] + n2[2] + n3[2] > max):
                        ans = card3 + card2 + card1
                        max = n1[2] + n2[2] + n3[2]
        

    5.关键代码解释

    • 后端:

      • 牌型判断放在pattern.py文件中,每次判断牌型创建一个Card对象,并对该对象进行初始化,cnt_color存放花色,cnt_num存放牌的数值。避免了每次判断牌型时的重复计算。
      • 遍历算法没啥特别的地方,主要就是排列组合遍历三墩所有可能的牌组,再计算每一种牌组获胜概率,三墩获胜概率之和最大的就是最优结果。这里用到了itertools库来遍历牌的所有组合。
    • 前端

      • 利用分别用各界面的代码模块新建窗口类,需要跳转到某个窗口时再实例化,新建对象,显示在主窗口上。

    6.性能分析与改进

    改进的思路

    原先算法经过服务器的测试发现得分情况一般,后来又看了下十三水得分规则,根据不同牌型的得分情况不同,对权值计算进行了优化。

    对于一部分不需要遍历的情况做了跳过处理。

    性能分析图和程序中消耗最大的函数


    由图可见solve函数消耗最大,程序的时间主要都花在牌型的遍历以及计算权值上。

    7.单元测试

    • 下图是测试用到的函数,代码比较长,限于篇幅不全展开

      • 主要代码展示

        import unittest
        from pattern import Card
        class TestCard(unittest.TestCase):
            def test_is_tcpair(self):
                cards = [(1, 2), (1, 2), (1, 3), (0, 3), (2, 5)]
                c = Card(cards)
                self.assertEqual(c.is_tcpair(), 3)
        
            def test_is_pair(self):
                cards = [(1, 2), (1, 2), (1, 3), (0, 4), (2, 5)]
                c = Card(cards)
                self.assertEqual(c.is_pair(), 2)
                cards2 = [(1, 2), (1, 9), (1, 3), (0, 4), (2, 5)]
                c = Card(cards2)
                self.assertFalse(c.is_tcpair())
        
            def test_is_triple(self):
                cards = [(1, 2), (1, 2), (1, 2), (0, 5), (3, 8)]
                c = Card(cards)
                self.assertEqual(c.is_triple(), 2)
        
        if __name__ == '__main__':
            unittest.main()
        
        
      • 测试结果:

    8.Github的代码签入记录

    9.遇到的困难及解决方法

    困难描述 解决尝试 是否解决 有何收获
    界面开发工具的选择 先是学习了html和css,但是后来由于我队友先用python写好后端,该路pass,听团队的小伙伴说qypt5可以自动转为py文件,就确定用该工具 qypt5通过拖拽形成ui文件,并且可以通过PYUIC转为py文件,这个非常方便,不用狂打代码
    QT dersigner 全英文 寻找汉化包 or 自我适应 汉化包很多需要money,下载了一个不用money,但是配置一直出问题。最后就是提高英语水平
    排行榜、历史战局、登录注册要从服务器得到数据并展示 查找资料、询问大佬、求助队友 这部分我感觉是前端部分最吃力的,要自己写,问题很多,但我对如何从服务器获取数据有了更加深入的了解
    如何设计算法实现最优牌型的选择 第一想法是贪心,但是后来仔细想想贪心并不能保证最优,只能接近最优,后来想到组合数,并尝试解决 学习了组合数算法,但是没有自己造出轮子,有点遗憾,不过不得不说py确实方便,调个itertools库,直接起飞

    10.评价队友

    • 评价人:潘松波
      • 值得学习的地方:无时无地不在学习新知识并敲代码

      • 需要改进的地方:无,真的挺好的了

    • 评价人:林逸
      • 值得学习的地方 : 很强,学习新知识的速度很快

      • 需要改进的地方 : 太强了让人太有压力

    11.学习进度条

    • 潘松波
    第N周 新增代码(行) 累计代码(行 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 10 10 对项目的需求分析和原型设计的了解更深,学习使用原型分析工具
    2 0 0 5 15 学习pyqt5基本知识
    3 323 323 10 25 学习使用qtdesigner,着手设计界面
    4 554 877 15 40 深入学习pyqt5,完善设计界面,尝试从服务器获取数据,修改代码
    • 林逸
    第N周 新增代码(行) 累计代码(行 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 10 10 对项目的需求分析和原型设计的了解更深,学习使用原型分析工具
    2 0 0 5 15 构思算法
    3 382 382 45 60 学习py,初步实现特殊牌型的判断算法
    4 733 1105 45 90 通过对牌型的组合比较,实现普通牌型的最优判断算法
  • 相关阅读:
    上周热点回顾(5.9-5.15)团队
    上周热点回顾(5.2-5.8)团队
    上周热点回顾(4.25-5.1)团队
    .NET跨平台之旅:升级ASP.NET Core示例站点团队
    上周热点回顾(4.18-4.24)团队
    上周热点回顾(4.11-4.17)团队
    如何在Eclipse中正确安装Jetty插件并初步使用(图文详解)
    Spark Mllib里如何采用保序回归做回归分析(图文详解)
    机器学习概念之梯度下降算法(全量梯度下降算法、随机梯度下降算法、批量梯度下降算法)
    程序代码里出现illegal character 'ufeff' 和 expected class or object definition的解决办法(图文详解)
  • 原文地址:https://www.cnblogs.com/lylinyi/p/11768104.html
Copyright © 2011-2022 走看看