设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 11262|回复: 7
打印 上一主题 下一主题

新手的学习过程供一样的初学者参考,顺带提了些具体问题

[复制链接]

9

主题

0

好友

133

积分

注册会员

Rank: 2

跳转到指定楼层
楼主
发表于 2016-4-22 10:07:18 |只看该作者 |正序浏览
本帖最后由 hymyg 于 2016-4-22 10:22 编辑

  我是一个英文不好的Python新手学习者,断断续续学习了大概两个月时间,中间还有一个十来天的间隔。下面我以一个初学者的身份从非专业(很业余)的角度讲一下我的学习情况供跟我一样初学的人参考,同时附上我新写的一段程序的代码以及写这段代码的原因、经过。最重要的是代码中的一些问题还有很多疑惑,希望能得到老师们的解答。

  学习的过程主要是看Crossin老师的微博公众号中发布的课程,同时还看了一本叫做《与孩子一起学编程》书。目前为止,Crossin的编程教室的课程还没有看完,《与孩子一起学编程》也没有看完。但仍旧忍不住动手写一些东西于是自己给自己设定题目,做出来以后再不停的给这个题目增加难度,比如对用户输入的数据进行校验,看看是不是合法,应该输入数字的地方是不是包含了非数字,比如能不能让界面再好看一些等等。总觉得把一个东西做出来时的成就感是支撑学习的一个很好的动力。但毕竟只是练习,写出来的东西没有什么实际用途,也没有人去用,很期待自己能写出一个能解决实际问题的程序并且有人去用。
  前两天到财务部门去玩,财务有两个女会计休产假,剩下的两个财务人员忙的一头汗,我去的时候他们正在核对一笔的帐目。我听了一下大概明白了他们的意思,就想着能不能用程序来简化他们对帐的难度。
  先说一下大概情况,我们包含的一项业务就是把一些地方租给别人经营,我们称之为商户。商户经营我们的地方,我们会收他们的租金、押金、水电费等。商户缴费是由财务开出发票或是收据(总之是票据,我只懂点财务皮毛)给商户,这个月应收你租金5000元、押金10000元、水电费500.50元…………商户直接到银行转帐给我们,拿着银行出据的转帐凭证给财务做帐。银行出具的转帐凭证通常是合计数:即15500.50元,或者商户分两次转帐又可能出现两10000元和5500.50两笔。
  以上面的情况举例,财务就会形成下在这样一个帐目:

  序号    日期   说明                              科目                       金额       备注
         1        2015.4.20      XX商户租金、水电费、押金     银行存款                  10000.00
         2        2015.4.20      XX商户租金 、水电费、押金    银行存款                    5500.50
         3        2015.4.20      XX商户租金                             其他收入-租金           -5000.00
         4        2015.4.20      XX商户押金                             其他应付款-押金      -10000.00
         5        2015.4.20      XX商户水电费                         其他应付款-水电费       -500.50

  懂财务的人大概能明白这其实就是一笔帐:
  借:银行存款    10000.00
              银行存在     5500.50
       贷:其他收入-租金  5000.00
              其他应付款-押金  -10000.00
              其他应付款-水电费 -500.50

  在表格中把借方表达为正数,贷方表达为负方。
  上面的表格因为数据量较小且只有一家商户,所以比较清楚,实际上有几十上百家商户,可是实际过程中经常发生帐目对不上的情况,比如将XXX商户的某笔水电费记到了YY商户头上等等情况。财务在对帐的时候通常是用银行过来的转帐凭证的总计对找对应科目的金额。比如上例中用15500.50去看下面对应科目哪些数字相加等于这个数。数据量一大,他们找起来的工作量就很大。

  于是出于实战的心理,我主动提出帮他们写一段程序来处理这个问题。因为当是学了列表(list),感觉上这是列表能处理的问题。

  我的处理过程是这样子的,先让他们在几务软件中将数据导出为一个excel文件,而文件的内容和版式就如上面的例子,然后再让他们将表格中只保留“序号”和“金额”一栏,其他的内容都删除掉,最后将只包含序号和金额的excel另存为.csv逗号分隔文件。

最后形成的列表就如同下面所示:
  1. 1,-4700.00
  2. 2,4700.00
  3. 3,-105.00
  4. 4,-1780.00
  5. 5,1885.00
  6. 6,-10000.00
  7. 7,10000.00
  8. 8,-500.00
  9. 9,-4350.00
  10. 10,4545.00
  11. 11,-500.00
  12. 12,-1950.00
  13. 13,2040.00
  14. 14,-34537.00
  15. 15,34537.00
  16. 16,-11500.00
  17. 17,11500.00
  18. 18,-8060.00
  19. 19,8060.00
  20. 20,-18942.00
  21. 21,-18500.00
  22. 22,37442.00
  23. 23,-24460.00
  24. 24,24460.00
  25. 25,-7420.00
  26. 26,7420.00
  27. 27,-1116.00
  28. 28,-12792.00
  29. 29,13908.00
  30. 30,-9775.00
  31. 31,9775.00
  32. 32,-6308.00
  33. 33,6308.00
  34. 34,-513.00
  35. 35,-5880.00
  36. 36,6393.00
  37. 37,-1600.00
  38. 38,1600.00
  39. 39,-10059.00
  40. 40,10059.00
  41. 41,-740.00
  42. 42,-12692.00
  43. 43,13432.00
  44. 44,-13115.00
  45. 45,13115.00
  46. 46,-663.00
  47. 47,-7721.00
  48. 48,8384.00
  49. 49,-34670.00
  50. 50,34670.00
  51. 51,-600.00
  52. 52,-4800.00
  53. 53,5400.00
  54. 54,-867.00
  55. 55,-9925.00
  56. 56,10792.00
  57. 57,-3860.00
  58. 58,3860.00
  59. 59,-7800.00
  60. 60,7800.00
  61. 61,-2448.00
  62. 62,2448.00
  63. 63,-19160.00
  64. 64,19160.00
  65. 65,-2010.00
  66. 66,-23010.00
  67. 67,25020.00
  68. 68,-2274.00
  69. 69,-26040.00
  70. 70,28314.00
  71. 71,-2118.00
  72. 72,-18706.00
  73. 73,20824.00
  74. 74,-660.00
  75. 75,-12585.00
  76. 76,13245.00
  77. 77,-70737.00
  78. 78,-5000.00
  79. 79,-23579.00
  80. 80,99316.00
  81. 81,-6972.00
  82. 82,-26457.00
  83. 83,33429.00
  84. 84,-55908.00
  85. 85,-37000.00
  86. 86,92908.00
  87. 87,-30000.00
  88. 88,-5000.00
  89. 89,-10000.00
  90. 90,45000.00
  91. 91,-1236.00
  92. 92,1236.00
  93. 93,-23940.00
  94. 94,23940.00
  95. 95,-4503.00
  96. 96,-31535.00
  97. 97,36038.00
  98. 98,-1944.00
  99. 99,-24227.00
  100. 100,26171.00
  101. 101,-1083.00
  102. 102,-7591.00
  103. 103,8674.00
  104. 104,-37950.00
  105. 105,37950.00
  106. 106,-3081.00
  107. 107,-21582.00
  108. 108,24663.00
  109. 109,-35770.00
  110. 110,35770.00
  111. 111,-3111.00
  112. 112,-21787.00
  113. 113,24898.00
  114. 114,-300.00
  115. 115,-3600.00
  116. 116,3900.00
  117. 117,-852.00
  118. 118,-9774.00
  119. 119,10626.00
  120. 120,-15167.00
  121. 121,15167.00
  122. 122,-9000.00
  123. 123,-3000.00
  124. 124,12000.00
  125. 125,-20660.00
  126. 126,20660.00
  127. 127,-4000.00
  128. 128,4000.00
  129. 129,-2968.00
  130. 130,2968.00
  131. 131,-10000.00
  132. 132,10000.00
  133. 133,-2200.00
  134. 134,2200.00
复制代码
而我的程序代码如下(见下一楼,每楼字数有限制,所以……):

方法就是将用户的csv文件读到列表中,然后将其中的正数(借方)和负数(贷方)分为两个列表,同时为了减少运算量,将两个列表中绝对值大于用户输入的数的元素都删除。然后分别将两个列表中数字的组合列出,计算每组组合的和与用户输入数字相等的即写入到一个文件中,同时在屏幕上显示。考虑到运算量,目前设定的是两个数字组合到五个数字组合。

回复

使用道具 举报

9

主题

0

好友

133

积分

注册会员

Rank: 2

8#
发表于 2016-4-26 17:32:26 |只看该作者
关于光标位置和颜色的问题最终通过一个名子叫“Windows CONsole I/O for Python”的第三方模块解决了。
关于这个模块我也是在网上搜索到的,并没有中文介绍,后来通过百度等各翻译引擎,结果在python中的测试我自己搞了个不专业的使用说明,现在发在下面供参考。
里面可能有很多错误,请英文好或是对此插件比较熟悉的人能帮助纠正一下。谢谢!

关于Windows CONsole I/O for Python
     1、项目地址:http://newcenturycomputers.net/projects/wconio.html

     2、使用前定义:import WConio    #区分大小写

     3、WConio.error()               不是很明白,似乎是可以捕捉由WConio模块引起的错误,

     4、WConio.cgets(length)     Length是一个数字,允许用户通过键盘输入不超过”Length“指定个数的半角字符,输入时不允许左右移动光标对输入进行修改,但可以使用BackSpace键。当用户输入完成后按回车结束输入,但光标不会自动换行。
     示例:
     import WConio              
     a=WConio.cgets(10)   
     print(a)

     5、WConio.clreol()               光标位置到行的结束进行清屏。

     6、WConio.clrscr()               清除整个屏幕,相当于DOS中的cls

     7、WConio.cputs(string)      在当前光标位置打印字符串,打印结束后不换行。

     8、WConio.delline()             删除当前光标位置的一行,将该行的下一部分滚动。(不是太明白)

     9、WConio.getch()               等待用户击键,返回一个元组,显示用户击键对应的键值。

     10、WConio.getche()           功能跟WConio.getch()一样,但显示结果不换行。

     11、WConio.getkey()           以字符形式返回用户单个击键,比如你输入a,就返回'a'。

     12、WConio.gettext(left, top, right, bottom)     返回屏幕指定坐标处的字符,“left,top”分别是左上角列和行、“right,bottom”是右下角的列和行。第一列和第一行的座标都是从0开始算,如果不清屏,即使屏幕滚动,第0行0列的座标仍旧是从滚动到屏幕以外,最开始的部分算起。

     13、WConio.gettextinfo()      返回一个元组,显示一组相关信息具体如示例。官方说明中说有一些信息是不准确的。
     示例:
     >>>WConio.gettextinfo()
     (0, 69, 128, 102, 7, 7, 3, 9001, 129, 0, 99)
     说明:
     (0, 69, 128, 102, 7, 7, 3, 9001, 129, 0, 99)
     0,69,128,102:目前窗口可显示区域范围,宽度为0-129,高度为34行(102-69+1),其中69代表如果向上拖动滚动条的话,目前窗口显示区域第一行上面还有69行(从第0行开始算起)。
     7,7:应该是指当前文本的属性
     3:是指当前视频显示模式
     9001,129: 当前屏幕尺寸,宽度为129,但我不明白为什么高度是9001。

    14、WConio.gotoxy(x, y)      将光标移动到指定坐标,这一条太有用了。x代表列坐标,y代表行坐标,都从0开始算起。

     15、WConio.highvideo()      激活高亮模式显示,以条命令以后的文字都以高亮显示

     16、WConio.insline()             当前位置插入一个空行

     17、WConio.kbhit()                ??????????????????不清楚!

     18、WConio.lowvideo()           取消高亮显示,对应WConio.highvideo()

     19、WConio.movetext(left, top, right, bottom, x, y)      将窗口指定区域的内容复制到新的坐标显示

     20、WConio.normvideo()      激活正常的显示模式,功能基本上与WConio.lowvideo()一样

     21、WConio.putch(ch)           在当前位置打印一个数字或是字符

     22、WConio.puttext(left, top, right, bottom, saved)      ?????????不清楚

    23、WConio.setcursortype(n)     改变光标的外观,当n=0时不显示光标,n=1时显示正常光标,n=2是光标为游标(方块)

     24、WConio.settitle(s)                 设备控制台窗口标题,参数s不能省略。

     25、WConio.textattr(attr)           改变文本的前景和背景的颜色。attr为数字,0-255,不能省略。

     26、WConio.textbackground(color)     设置背景色而不改变前景色,color为数字,0-16,不能省略。

     27、WConio.textcolor(color)     设置前景色而不改变背景色,color为数字,但实践中似乎背景色会有变化

     28、WConio.textmode()              恢复视频显示模式到初始状态,光标位置复位,光标形状改为初始状态

     29、WConio.ungetch(ch)              将一个按键存入缓冲区,具体不太明白。

     30、WConio.wherex()                   返回当前光标的列坐标

     31、WConio.wherey()                   返回当前光标的行坐标
回复

使用道具 举报

9

主题

0

好友

133

积分

注册会员

Rank: 2

7#
发表于 2016-4-25 22:19:36 来自手机 |只看该作者
微微寻觅 发表于 2016-4-23 23:33
同是纯新手,刚发现这么个论坛~
对代码暂时提不出什么建议~
但是实际操作中,为什么不让“商户”提交转账凭 ...

实际情况比较复杂,我的说明只是为了解释程序的目的和思路,实际操作过程中受制度和人力等各种制约,不是我这个财务以外的人能说的上话的,谢谢回复!
回复

使用道具 举报

0

主题

0

好友

6

积分

新手上路

Rank: 1

6#
发表于 2016-4-23 23:33:59 |只看该作者
同是纯新手,刚发现这么个论坛~
对代码暂时提不出什么建议~
但是实际操作中,为什么不让“商户”提交转账凭证的时候,直接附上明细呢。
回复

使用道具 举报

9

主题

0

好友

133

积分

注册会员

Rank: 2

5#
发表于 2016-4-22 11:00:07 |只看该作者
crossin先生 发表于 2016-4-22 10:55
给一部分建议:
1
ansi.sys 这个我没了解过,如果单纯为了显示颜色,可以尝试用第三方的控制台软件,比如po ...

谢谢老师!老师辛苦!
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

地板
发表于 2016-4-22 10:55:08 |只看该作者
给一部分建议:
1
ansi.sys 这个我没了解过,如果单纯为了显示颜色,可以尝试用第三方的控制台软件,比如powershell之类,可以做到跟linux类似的效果。但考虑到你好像是要打包成exe运行,这个可能没法用了。
windows开发这方面不熟,其实我觉得用python做到这些会有些吃力,而且windows的控制台还是比较弱的。如果是为了显示效果,可以考虑做成GUI,或者网页版本,但这个开发复杂度就大了,只是作为工具来说,不需要搞这么复杂。

2
这个不太清楚,我之前用py2exe打包pygame的时候好像也没有做特别的修改,但必须要确保版本和位数都是一致的。如果找不到库,确认下库的代码是不是在lib里

3
python2的print不支持end=' '

4
这个我一般就直接raw_input('按回车结束程序...')

#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

9

主题

0

好友

133

积分

注册会员

Rank: 2

板凳
发表于 2016-4-22 10:08:24 |只看该作者
本帖最后由 hymyg 于 2016-4-22 10:27 编辑

  对于Python高手来说这是一个很简单的程序,但我是一个英文不好的新手,学习Python(甚至学习编程)只有断续的两个月左右的时间,在编写过程中碰到了很多问题。
  有很多问题的解决需要用到我所不知道的命令、库、函数等,碰到这些问题时,大多数时候我是通过baidu搜索我想要的答案(之所以只有Baidu,是众所周知的原因),大多数都能得到解决,但仍旧有一些解决方案或是因为太过于深奥我看不懂,或是因为里面大段的英文让我望而生畏,最终不得不放弃,重找其他的方法。在此过程中还有一两个问题通过微信公众号请教了Crossin老师,也得到了Crossin老师的解答。在此谢谢Crossin老师,以及在Internet上发布自己学习心得或是教程的我认识或不认识的朋友们,感谢他们的无私。

  目前程序在我的Windows10上面运行没有问题,但拿到财务的WindowsXP机器上运行却出现了一些问题,另外我还有一些困惑在下面一起提出来,有可能我的这些困惑会有其他初学者有共鸣的,也有可能有些问题很幼稚或是很外行。但不管怎么样,如果能有人乐意回答,我都很感谢。

  一、关于改变控制台文字颜色和光标位置
  其实有这个需求也只是希望程序运行时能稍微好看一点。过程中我搜索了baidu,里面提到了通过“\033”来转义特殊代码实际颜色变化,但基本上实现都是在Linux平台上,而我用的是Windows10操作系统。我想了一下,在网上有看过批处理里面改变文字颜色和光标位置的,查了一下,特殊代码跟Linux中的这些特殊代码是一样的。所以原理也应该是一样的,不同的时候Windows是通过一个ANSI.SYS驱动来实现的。
  在我编写代码调试的过程中发现通过“\033”确实可以部分实现Linux中的效果,且在Windows10系统中我并没有找到config.nt和ansi.sys文件。不知道Windows10对于ANSI.SYS的支持是以什么样的方式实现的,是原生支持的吧?不再需要加载ANSI.SYS驱动了?
  我在使用“\033”的时候发现有一些效果是不支持的,比如想用print('\033[5m'+'闪烁')实现文字闪烁,但是失败了,但在Windows的ANSI.SYS介绍中确实提到支持这一效果的。不知道为什么不能实现。
  目前代码中使用的“\033”效果在我的Windows10机器上都调试通过,但是拿到财务的WinXP上,这些代码都运行失败了,但并没有报错,而是将\033后面的特殊代码直接打印了出来。比如print('\033[5;31m'+u'\n路径非法或文件不存在!'+'\033[0;44m'),执行的时候直接在屏幕上显示:
  1. <span style="background-color: rgb(255, 255, 255);">[5;31m</span>
  2. <span style="background-color: rgb(255, 255, 255);">路径非法或文件不存在![0;44m</span>
复制代码
其他使用“\033”的地方也都一样,开始我以为是没有在c:\windows\system32\config.nt中加载ansi.sys驱动造成的,所以我在程序开头增加了自动判断系统版本并增加驱动,但没有用,又考虑是不是因为系统没有重启的原因,重启后还是一样没有用。希望有人告诉我原因是什么。
  既然“\033”的方法对于windows系统版本有很大的依赖性,我有尝试过寻找其他的替代方法,网上的方法我找到三种,一种是直接调用windows的dll文件来实现,但是以我目前的水平看不明白,另一种是通过Python中的curses模块来实现,但这个模块目前好像只有Linux版本上才有,而我使用的是Windows。最后一种是使用一个叫Windows Console Driver的第三方库来实现,但目前似乎只支持到Python2.6版本,而且我没有找到中文介绍,而我的英文……,算了不说了。虽然知道是奢求,但如果谁能提供一下Windows Console Driver库的简单中文说明,将不甚感激。
  或者谁能提供一个在Windows下改变光标位置、文字颜色的其他简单方法,也非常感谢。

  二、目前我使用的是py2exe来发布我的Python程序,不知道py2exe发布程序时,如果涉及到第三方库的话需要在setup.py中做什么修改呢?谢谢!

  三、我使用的是Python27 for windows 32位版本,我的系统是Windows10 X64专业版,在2.7版本中可以支持print()和print不带括号两种写法,如果要实现不换行的情况,用不到括号的写法可以最结尾添加一个逗号,但如果用带括号的写法比如print('aa',end=' ')好像不能实现,请问是我代码写错了导致不能实现吗,还是说Python27不支持这种写法?

  四、我使用os.system('puase>nul')实现程序暂停,但在WindowsXP上不能实现暂停,Windows10上没有问题。因为使用raw_input,如果用户敲字符的话会导致不好看,所以才采用了这种方法,不知道是否有其他方法吗?

  五、另外我知道做为初学者,我的代码写的可能很不好,如果能指出上一楼中的代码还有什么地方能进行优化的,将非常感谢!

  六、目前为止,这个程序运行结果都是正确的,但效果很不理想,因为如果输入一个较大的数字,会出现很多的结果,结果一多,对于财务来说这个结果就没有太大的意义,但确实不知道还有什么办法能对结果进行优化,进一步减小结果的数量,但又不漏掉正确想要的值。

  以上是我做为一个英文不好,无编程经验的初学者,初学python的一段过程,以及写一个程序的过程。希望能帮助到刚开始学的人,以及得到水平更高的老师们的指导。谢谢大家。
  蓝色文字部分是我提出的一些问题,之所以用蓝色标记出来,是因为我自己的语言表达能力不太好,说的很啰嗦,标出来是希望阅读的人能看的轻松一些。希望能得到解答,谢谢!
回复

使用道具 举报

9

主题

0

好友

133

积分

注册会员

Rank: 2

沙发
发表于 2016-4-22 10:08:07 |只看该作者
本帖最后由 hymyg 于 2016-4-22 10:11 编辑
  1. #-*-coding:utf-8-*-

  2. ######################################################################################################
  3. #程序文件名:FD_Tools\FD_tool.py For Windows                                                         #
  4. #程序目的:财务查帐过程中经常会发现帐目不平,比如借方相差N元,而这N元对应多个贷方(或者反过来)。在多#
  5. #          个贷方帐户中查找加起来等于N元的每笔帐目是实现对帐的方法,但用人工来查找工作量很大。这种情 #
  6. #          况下可以在SAP中将要查询的凭证数据卖出为csv文件(逗号分隔文件),然后用本程序来实现查找,程#
  7. #          序会将所有的可能输出到一个文件文件中。                                                    #
  8. #程序实现:读取导出的.csv文件,并将第一行数据保存到list中,然后对数据进行整理,分为正数(借方)和(贷#
  9. #          方)并要大于N的值剔除出去。对整理后的数据求组合,对每一个组合元素求和以判断其值是否等于N。#
  10. #          如果等于N,则将这一元素写入到文件中最终形成结果。                                         #
  11. ######################################################################################################

  12. import os,itertools,platform
  13. os.system('color 17')                       #设定窗口颜色
  14. os.system('mode con cols=120 lines=29')     #设定窗口大小
  15. ###检查系统版本是不是WindowsXP,如果是WindowsXP则加载ANSI.SYS驱动
  16. ver_no=platform.platform()
  17. if 'Windows-XP' in ver_no:
  18.     if os.path.exists(r'c:\windows\system32\config.NT'):
  19.         con_file=open(r'c:\windows\system32\config.NT','a')
  20.     else:
  21.         con_file=open(r'c:\windows\system32\config.NT','w')
  22.     con_file.write('\n'+r'DEVICE=c:\windows\system32\ANSI.SYS /x')
  23.     con_file.close()
  24.     #print(u'在WindowsXP系统上第一次运行,需要关闭程序后重新启动')

  25. print('\n')
  26. print(' '*13+u'╔'+u'═'*45+u'╗')
  27. print(' '*13+u'║'+' '*32+u'财务借贷对帐辅助工具 V1.02'+' '*32+u'║')
  28. print(' '*13+u'╟'+u'─'*45+u'╢')
  29. print(' '*13+u'║'+' '*21+u'联系人:XXXXXX 邮件:xxxxx@sh-mail.lottemart.cn'+' '*22+u'║')
  30. print(' '*13+u'╚'+u'═'*45+u'╝')
  31. print('*'*119)

  32. ###接受用户输入文件路径,并对用户输入的文件路径的合法性进行判断###
  33. while True:
  34.     source=raw_input(u'请输入文件路径:'.encode('gbk'))
  35.     if os.path.isfile(source)==False:
  36.         print('\033[5;31m'+u'\n路径非法或文件不存在!'+'\033[0;44m')                     #\033[x;xx;xxm通过转义字符改变输出文字颜色,下面相同
  37.         choice=raw_input(u'\n【R键重新输入】/【其他键放弃退出】\n\n请选择:'.encode('gbk'))
  38.         if choice!='r' and choice!='R':                                                  #如果用户输入的不是r或R,则退出程序
  39.             exit()                                                                              
  40.         else:
  41.             print '\033[5A'+'\033[D'+('\033[K'+'\n')*4+'\033[K'+'\033[6A'+'\033[K'+'\033[1A'
  42.     else:
  43.         break

  44. ####判断用户输入的文件路径下是否有同名的.fdt文件,如果有就删除(程序执行结果将会保存在用户输入文件同目录下,将使用相同文件名,扩展为.fdt)        
  45. dir_name,file_name=os.path.split(source)                #将用户之前输入的源文件的路径分为目录(dir_name)和文件(file_name)两部分
  46. if os.path.exists(dir_name+'\\'+os.path.splitext(file_name)[0]+'.fdt'):    #os.path.splitext()函数将文件名分为文件名和扩展名两部分
  47.     os.remove(dir_name+'\\'+os.path.splitext(file_name)[0]+'.fdt')

  48. ####对用户输入的数字的有效性进行判断
  49. while True:                                                         #判断用户输入的数据是否是负数并通过对“float(num)>0”语句的错误捕获判断用户输入的是否是数字
  50.     num=raw_input(u'请输入要查找数字的目标累加值:'.encode('gbk'))
  51.     try:
  52.         if float(num)>0:
  53.             break
  54.         else:
  55.             print('\033[5;31m'+u'\n数字必须为正数!按任意键返回。'+'\033[0;44m')
  56.             os.system("pause>nul")
  57.             print('\033[1A'+'\033[D'+'\033[K'+'\033[2A'+'\033[D'+'\033[K'+'\033[1A')  #\033[1A:光标向上移一行、\033[D:光标左移到行首、\033[K:清除光标位置到行末的字符
  58.     except ValueError:
  59.         print('\033[5;31m'+u'\n输入的数字非法(必须是数字,且只能是正数)!按任意键返回。'+'\033[0;44m')
  60.         os.system("pause>nul")
  61.         print('\033[1A'+'\033[D'+'\033[K'+'\033[2A'+'\033[D'+'\033[K'+'\033[1A')  #\033[1A:光标向上移一行、\033[D:光标左移到行首、\033[K:清除光标位置到行末的字符
  62.       
  63. num=float(num)

  64. ###读取文件,并存储到list中###
  65. my_file=open(source,'r')
  66. lines=my_file.read().split('\n')  #通过read()将文件读取为一个字符串,并通过split()以"\n"为分隔符将字符串分隔为list#
  67. my_file.close()

  68. ###将列表中正数(借方)和负数(贷方)分为两个列表###
  69. positive_list=[]
  70. negative_list=[]
  71. for i in xrange(len(lines)):     #用循环对list中的元素按个判断处理#
  72.     if float(lines[i][lines[i].find(',')+1:])>0 and abs(float(lines[i][lines[i].find(',')+1:]))<num:      ##判断每个元素逗号后面的数字是正数还是负数并分别写入
  73.         positive_list.append(lines[i])                                                                    ##positive_list表或Negative_list表,同时将绝对值大于用户
  74.     elif float(lines[i][lines[i].find(',')+1:])<0 and abs(float(lines[i][lines[i].find(',')+1:]))<num:    ##输入的数字的元素舍弃,因为这样的数字肯定不是我们需要的数字
  75.         negative_list.append(lines[i])

  76. ####让用户选择筛查方向####
  77. while True:
  78.     choice=raw_input(u'请选择筛查方向【1 借方】/【2 贷方】/【0 放弃】:'.encode('gbk'))
  79.     if choice=='0':
  80.         exit()
  81.     elif choice=='1' or choice=='2':
  82.         break
  83.     else:
  84.         print('\033[1A'+'\033[D'+'\033[K'+'\033[1A')
  85.         
  86. os.system('cls')        #清屏

  87. print(u'数据整理中...\n')

  88. ###根据用户选择(借方或贷方)将相应的list赋值给select_list变量
  89. if choice=='1':
  90.     select_list=positive_list
  91. elif choice=='2':
  92.     select_list=negative_list

  93. NO_amount=1
  94. count_no=0
  95. while NO_amount<=5:                                                 #此处通过循环决定select_list列表中的“No_amount”个数字相加的结果与用户输入的num对比
  96.     for i in itertools.combinations(select_list,NO_amount):         #通过itertools.combinations()获得select_list列表的组合迭代
  97.         element=list(i)
  98.         total=0
  99.         for j in xrange(len(element)):
  100.             total+=float(element[j][element[j].find(',')+1:])       #float(element[j][element[j].find(',')+1:])是截取列表元素逗号后面的部分
  101.         if abs(total)==num:                                         #考虑到negative_list时面的数值都是负数,最后的各也是负数,所以取绝对值与用户输入的值比较
  102.             select_num=''
  103.             if os.path.isfile(dir_name+'\\'+os.path.splitext(file_name)[0]+'.fdt')==False:    ##判断文件是否存在,如果文件不存在就新建,如果存在就用追加模式打开
  104.                 d_file=open(dir_name+'\\'+os.path.splitext(file_name)[0]+'.fdt','w')          ##  
  105.             else:                                                                                ##
  106.                 d_file=open(dir_name+'\\'+os.path.splitext(file_name)[0]+'.fdt','a')          ##
  107.             for k in xrange(len(element)):                          ##   
  108.                 select_num+=element[k]+'\t'                         ##将列表中的元素通过循环依次读取出来并连接成一个字符串方便下面write()使用
  109.             print select_num
  110.             d_file.write(select_num+'\n')       #将内容写入文件,行末加换行
  111.             count_no+=1
  112.             d_file.close()      #关闭文件
  113.     NO_amount+=1
  114. print('\n'+u'数据整理完毕,共找到%s条记录,已输出到'%count_no+dir_name+'\\'+os.path.splitext(file_name)[0]+u'.fdt文件中。\n\n按任意键退出程序。')
  115. os.system('pause>nul')
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-11-22 15:38 , Processed in 0.022843 second(s), 27 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部