作为程序员,我们经常会被客户问的一个问题一定是不是说很容易么,为什么花了这么长时间。不得不说,程序员可能是最糟糕的计划者,按时按点按计划完成的软件项目永远是下一个项目。一个项目的延期,有很多这样那样的原因,其中不得不说的一个原因就是很多代码想起来很容易,但是真的写起来,细节里全是魔鬼。在这个Epic Fail的系列中,我会记录一些在我平常写代码的过程中遇到的那些本来很简单却花了很长时间的有趣问题。这个系列会不定时更新,不断记录我写代码中的糗事,希望我永远不用更新:)。
 
作为开篇,记录一个花了我1个多小时的python脚本。故事的背景是这样的,我有个测试数据,分散在几个csv中,我想把它们合并到一个csv中。作为程序员,让我手动把每个csv文件打开,复制粘贴到另外一个文件里这种没技术含量的方法当然不会做。而且将来我要是有很多文件要合并呢?我还能真的一个一个拷啊。其实我只要合并4个文件,手动的方式可能是更快的方法,这当然是后话。
 
作为一个“精于”python又不会诸如sed一般的神奇unix命令的我,自然打开python写下了下面的代码:
import os

def merge_all(path, output_file):
output = open(os.path.join(path, output_file), 'w')
header_writen = False
for f in os.listdir(path):
full_name = os.path.join(path, f)
if os.path.isfile(full_name) and f.endswith('.csv'):
input = open(full_name)
header = input.readline()
if not header_writen:
output.write(header)
header_writen = True
input.readline()
input.readline()
line = input.readline()
while line:
output.write(line)
line = input.readline()
input.close()
output.close()
这段代码平淡无奇,我不到5分钟就一挥而就。整体的逻辑就是遍历文件夹,打开所有的csv文件,对header只输出一次,第二行和第三行跳过,因为这两行的数据我不需要,然后把下面的每行写入输出文件。
 
运行脚本,数据合并一切正常,但是数据的header,却没有。这种时候,作为程序猿第一反应就是再运行一遍,由于脚本偷懒,我把输出文件写在了输入文件夹中,我手动把生成的输出文件删了,重新运行了一次。还是一样的结果,数据都合并了,但是还是没有文件头。这个时候,作为程序猿的第二反应就是再运行一遍,无奈还是一样的结果。
 
这时,我不得不面对上面的代码有问题的结论。这也是程序员最郁闷的时候,因为我对问题一点头绪都没有。这时自己手动在生成的文件中加上头行应该是最好的选择,但是作为程序员是很难接受这种做法的。
 
开始排错,既然是header没写,那么一定是我的header_writen的逻辑有问题,可这个代码咋看也看不出有啥问题啊。经过多次纠结后,我加入了一行日志代码:
if os.path.isfile(full_name) and f.endswith('.csv'):
print 'Processing ' + full_name + '…'
这时问题的症结终于出现了,那就是第一个被遍历的csv文件是我生成的输出文件!
 
发现了问题解决起来就很容易了:
for f in os.listdir(path):
if f == output_file:
continue
在循环中加入这个简单的逻辑,问题就解决了。这个小小的细节,竟然花了我这么长时间。
 
反思这个问题,如果不是我的输出文件名在listdir中排在第一个我可能会遇到更大的问题,在生成的文件中出现重复数据。而这个问题很可能被我忽略。
 
这个问题又如何避免呢?我认为最好的方法就是我不应该图省事把数据输出文件写入读取文件夹。这个决定完全是为了省事,但是也就破坏了输入文件夹的状态,而这个状态是我完全没意识到的。 

程序员的Epic Fail [0]的更多相关文章

  1. 野生程序员对.NETFramework 4.0 ThreadPool的理解

    ThreadPool 类 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 命名空间:   System.Threading程序集:  mscor ...

  2. 35岁老半路程序员的Python从0开始之路

    9年的ERP程式开发与维护,继而转向一年的售前,再到三年半的跨行业务,近4的兜兜转转又转回来做程式了,不过与之前不同的,是这次是新的程序语言Python, 同时此次是为了教学生而学习! 从今天开始,正 ...

  3. 程序员的长安十二时辰:Java实现从Google oauth2.0认证调用谷歌内部api

    最近公司在做一个app购买的功能,主要思路就是客户在app上购买套餐以后,Google自动推送消息到Java后端,然后Java后端通过订单的token获取订单信息,保存到数据库. Java后端要获取订 ...

  4. Java 程序员技能导图 1.0

    做Java开发已经一年,并非科班出身,在毕业工作三年后毅然决然辞职,参加培训机构从零开始.在这期间迷茫.失望.绝望时常伴我左右,但是在不断自我提高与努力中渐渐看到一些小小的成果使我不断坚信自己的选择并 ...

  5. 0~5年一个Java程序员的晋升之路

    在程序界流行着一种默认的说法叫“黄金5年”,也就是一个程序员从入职的时候算起,前五年的选择直接影响着整个职业生涯中的职业发展方向和薪资走向,如何走好这5年,彻底从一个刚入行的菜鸟蜕变成可以以不变应万变 ...

  6. NEL程序员专用轻钱包 进入0.01状态了

    这个轻钱包能干什么,现在就能在测试网看个余额,转个帐,调用个合约. 而且功能非常程序员化 你会说是不是没啥用   但是他有非常有用,因为他可以很容易的拼出NEOGUI拼不出来的交易 比如参与ICO交易 ...

  7. 黑马程序员面试宝典(Java)Beta6.0免费下载

    场景 JavaSE基础 面向对象特征以及理解 访问权限修饰符区别 理解clone对象 JavaSE语法 java有没有goto语句 &和&&的区别 如何跳出当前的多重嵌套循环? ...

  8. 2020Java程序员架构师面试宝典,学习后面试必过,震惊,本人通过这篇教程,拿到了0个offer

    1. 引言 Java后端学习路线 <吐血整理>顶级程序员工具集 https://github.com/AobingJava/JavaFamily 跟上Java8 经历阿里.头条.腾讯等知名 ...

  9. gevent程序员指南

    gevent程序员指南 由Gevent社区编写 gevent是一个基于libev的并发库.它为各种并发和网络相关的任务提供了整洁的API.   介绍 本指南假定读者有中级Python水平,但不要求有其 ...

随机推荐

  1. (转载)Java自带的GUI性能监控工具Jconsole以及JisualVM简介

    原文链接:http://blog.csdn.net/chendc201/article/details/22905503 1 Jconsole 1.1 简介以及连接 JConsole是一个基于JMX的 ...

  2. VB6之截图

    今天先把主要逻辑写出来,如果有时间就实现一个真正的截图工具. Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC ...

  3. VB6之CRC32

    翻译篇:http://www.cnblogs.com/duzouzhe/archive/2009/08/05/1539543.html Private Declare Function GetTick ...

  4. js如何获取样式?

    在某个项目中,我们经常会需要来获取某个元素的样式,比如说获取一个div的color:这样,新的问出现了, var style = box.style.width;console.log(style); ...

  5. HDU 1325,POJ 1308 Is It A Tree

    HDU认为1>2,3>2不是树,POJ认为是,而Virtual Judge上引用的是POJ数据这就是唯一的区别....(因为这个瞎折腾了半天) 此题因为是为了熟悉并查集而刷,其实想了下其实 ...

  6. 设置TrackMouseEvent捕获WM_MOUSEHOVER和WM_MOUSELEAVE消息

    WM_MOUSEHOVER(非客户区消息为WM_NCMOUSEHOVER)消息表示鼠标在客户区悬浮消息,WM_MOUSELEAVE(非客户区消息为WM_NCMOUSELEAVE)为鼠标离开客户区消息, ...

  7. 单片机C语言基础编程源码六则2

    1.某单片机系统的P2口接一数模转换器DAC0832输出模拟量,现在要求从DAC0832输出连续的三角波,实现的方法是从P2口连续输出按照三角波变化的数值,从0开始逐渐增大,到某一最大值后逐渐减小,直 ...

  8. windows下安装DB2数据库以及使用Aqua Data Studio链接数据库

    本文只是作为自己的心得体会,不具有一般性! 1.其实安装DB2数据库还是比较简单的,一般都是直接下一步下一步就可以了,只是有些地方需要注意.我安装的DB2数据库版本如下图所示: 2.拿到数据库的版本之 ...

  9. 怎么在linux ubuntu 上的nginx 绑定域名

    前一篇介绍了,如果在ubuntu上运行nodejs,毕竟访问的时候都是用ip地址+端口号,但是上production 环境都需要域名的,IP地址当然不行 读过上一篇的朋友知道了,如果在upstart ...

  10. 文本处理常用命令--sort,uniq,cut,wc

    #文本处理命令--sort,cut,wc及其他 文本处理命令还有其他常用的,比如:sort,cut,wc 1.cut命令的用法 cut命令: cut - remove sections from ea ...