软件工程 2020软件工程作业
作业要求 https://edu.cnblogs.com/campus/zswxy/software-engineering-2017-1/homework/10494
作业目的 实现一个命令行程序,不妨称之为Sudoku
作业正文 如下
其他参考文献 https://www.runoob.com/python3/python3-tutorial.html
https://github.com/changorz/work/tree/master/20177583/src
https://blog.csdn.net/qq_40871196/article/details/89431987

Github项目地址: https://github.com/zxw0621/demo/tree/master/20177596/src

PSP表格

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

思路描述


审题

  1. 按照数独游戏的规定,给一张含有若干的数字随机分布在网格的图,在每个位置上的数在列和行上不能重复出现,在4、6、8、9阶的数独表中,每个小宫格内不能有重复的数出现。
  2. 用cmd命令行的形式读出写入文件,并传入参数。
  3. 要实现多个九宫格一起处理。
  4. 要求用java和c++,这里顺便学习下python(从大一刚学那会就学习过一点点,后来忙于学习学校安排的课程后没怎么学了,以后还想接触些脍炙人口的新鲜事物,比如某些大佬开口就是什么大数据,云计算,人工智能的)

功能模块设计

  1. 定位模块
def new_locate(_x_, _y_, _a_, _b_):  #上面的版本是学习小邓同学的定位
    '''
    新版定位
    :param _x_:
    :param _y_:
    :return:
    '''
    if M % 3 == 0:   #通过向下取整计算出 大的九宫格能分成几行几列的小九宫格
        _c_ = 3
        _r_ = int(M / 3)
    elif M % 2 == 0:
        _c_ = 2
        _r_ = int(M / 2)
    _a_ = int(_x_ // _c_ * _c_)
    _b_ = int(_y_ // _r_ * _r_)c_:_r_
    return _a_, _b_, _c_, _r_   #这里返回 _a_: 当前元素所在的小九宫格 左上角的横坐标
                               #         _b_: 当前元素所在的小九宫格 左上角的纵坐标
                               #         _c_: 大九宫格被分成了 c行 r列的小九宫格
                               #         _r_:


# def locate(_x_, _y_, _a_, _b_):     #莽夫判断  respect阿传
#     '''
#     确定当前元素所在九宫格位置
#     :param _x_:
#     :param _y_:
#     :param a:
#     :param b:
#     :return:
#     '''
#     if 0 <= _x_ < 3 and 0 <= _y_ < 3:
#         _a_ = 0
#         _b_ = 0
#
#     if 3 <= _x_ < 6 and 0 <= _y_ < 3:
#         _a_ = 3
#         _b_ = 0
#
#     if 6 <= _x_ < 9 and 0 <= _y_ < 3:
#         _a_ = 6
#         _b_ = 0
#
#     if 0 <= _x_ < 3 and 3 <= _y_ < 6:
#         _a_ = 0
#         _b_ = 3
#
#     if 0 <= _x_ < 3 and 6 <= _y_ < 9:
#         _a_ = 0
#         _b_ = 6
#
#     if 3 <= _x_ < 6 and 3 <= _y_ < 6:
#         _a_ = 3
#         _b_ = 3
#
#     if 3 <= _x_ < 6 and 6 <= _y_ < 9:
#         _a_ = 3
#         _b_ = 6
#
#     if 6 <= _x_ < 9 and 3 <= _y_ < 6:
#         _a_ = 6
#         _b_ = 3
#
#     if 6 <= _x_ < 9 and 6 <= _y_ < 9:
#         _a_ = 6
#         _b_ = 6
#     return _a_, _b_
  1. 行列无重复判断模块
def fun(_x_, _y_):
    '''
    确定行列上不重复
    :param inde__x_:
    :param _y_:
    :param num:
    :return:
    '''

    for _i_ in range(M):
        if _i_ != _x_ and DATA[_i_][_y_] == DATA[_x_][_y_]:#遍历行
            return 0
    for j in range(M):
        if j != _y_ and DATA[_x_][j] == DATA[_x_][_y_]:#遍历列
            return 0
    _a_ = 0
    _b_ = 0
    _a_, _b_, _c_, _r_ = new_locate(_x_, _y_, _a_, _b_) 
    for _i_ in range(_a_, _a_ + _c_):
        for j in range(_b_, _b_ + _r_):
            if _i_ != _x_ and j != _y_ and DATA[_i_][j] == DATA[_x_][_y_]:#遍历小九宫格
                return 0
    return 1
  1. 深度优先搜索模块
def dfs(_x_, _y_):
    '''
    深搜
    :param _x_:
    :param _y_:
    :return:
    '''
#这里就相当于给没填数字的格子 尝试可能填的数
    if _x_ > M - 1:
        disp()
    elif DATA[_x_][_y_] != 0:
        if _y_ == M - 1:
            dfs(_x_ + 1, 0)
        else:
            dfs(_x_, _y_ + 1)
    else:
        for _i_ in range(1, M + 1):
            DATA[_x_][_y_] = _i_  #从1到M 赋值尝试
            if fun(_x_, _y_) == 1:
                if _y_ == M - 1:
                    dfs(_x_ + 1, 0)
                else:
                    dfs(_x_, _y_ + 1)
        DATA[_x_][_y_] = 0  #回溯
  1. 文件的写入读出
for line in FP.readlines(): #读出
    arr = line.strip().split(" ")
    if arr[0] >= '0':
        int_arr = list(map(int, arr))
        DATA.append(int_arr)
#分行读出 每隔一个空格读一个数  map函数用于将读取到的内容转int整型 保存成列表数组List
写入有个write函数就完事了
  1. 命令行输入
python命令行输入用 import sys
 然后用sys.argv[x]数组输入
sys.argv[0]表示的是你的py文件名   用sys.argv[1......]  按你输入的顺序赋值给你要的参数变量

命令行输入图片

性能改进


改进了定位模块 上文有提到 实现3-9阶九宫格都可以定位

心路历程


一拿到题目的时候,我是拒绝的。彭琛老师发布的作业也太快了,妈妈再也不用担心我手指不灵活了,妈妈再也不用担心我会出门花钱了,妈妈再也不用担心洗发水用的完了,这算法 题,我裂开,这怎么做,算法我学了啥。大一:彭琛老师教给我们冒泡排序法。大二:数据结构课上,冒泡排序法,我一气呵成,老师说我这发量还不行。大三:算法课上,各种指针嵌套递归回溯,一到实验课,冒泡排序法信手捏来。预测大四:《论冒泡排序法的基本思想》朱旭炜20177596.doc。其实没有老师发布的作业,我真不会接触算法这些东西,既然发布了,还是先端正下态度哈。完成代码编写的过程也是十分艰辛,在CSDN上也看了一些其他大佬的实现思路,结合作业的要求完成。

​ 关于《构建之法》:

下次我一定看! 滑稽

单元测试


import unittest

from sudoku import new_locate

class MyTestCase(unittest.TestCase):
    def test_fun(self):
        test_num=new_locate(5,8,0,0)
        self.assertEqual(test_num,(3,6,3,3))


if __name__ == '__main__':
    unittest.main()
#计算新定位模块是否能正常计算出_a_,_b_,_c_,_r_

静态检测(工具:PyLint)


​ 刚完成的代码那会,点pylint,出来好多啊,结合上次作业出现的问题总结下:

  1. 写完代码前,点击Code – > Reformat Code, 在pycharm最上面那条找得到,这个效果是整理代码,点完这个都能消除很多提醒和警告
  2. 变量命名的方法,提醒你大写你就全大写,提醒snake命名就写成_name_ 像这样的,当然我也不知道这样规范不,请大佬教育下我
  3. def函数块里面要写注释,这个提醒也太人性化了,怕别人看你的代码时候看不懂,不然就C0116提醒了,这个搞了我好久,专门折磨我这种强迫症,类似的不写注释还有C0114,写在最上面就好了,告诉别人你这整个代码干嘛用的
  4. 还有就是要简化 i f 判断,特别是多个并列条件的判断
  5. 还有减少else后面不必要的return ,不要写else: 这样的,第一个判断里面有return的话,程序都出去了,没必要再else:return return x
  6. 暂无其他问题了,以后碰到会继续补充,也请大佬们指指点点下

总结


​ 虽然没做过算法题,通过自己查资料,咨询大佬后还是对问题的解答有所思路的,python挺好用的。希望彭琛老师发布作业的速度可以慢点,顶不住,早点开学吧,我太难了。

giao

版权声明:本文为RCJames原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/RCJames/p/12529492.html