作为程序员,我们经常会被客户问的一个问题一定是不是说很容易么,为什么花了这么长时间。不得不说,程序员可能是最糟糕的计划者,按时按点按计划完成的软件项目永远是下一个项目。一个项目的延期,有很多这样那样的原因,其中不得不说的一个原因就是很多代码想起来很容易,但是真的写起来,细节里全是魔鬼。在这个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. 我的学习之路_第二十七章_jQuery

    jQueryjs类库 把常用对象或者方法封装起来,让我们写代码效率更高 1.jQuery 2.extjs [jQuery入门] jQuery的引入: 通过script标签的src属性引入 入门: 获取 ...

  2. HTML5 服务器推送事件(Server-sent Events)

    服务器推送事件(Server-sent Events)WebSocket 协议的一种服务器向客户端发送事件&数据的单向通讯.目前所有主流浏览器均支持服务器发送事件,当然除了 Internet ...

  3. updateByPrimaryKey和updateByPrimaryKeySelective insert和insertSelective

    这两个update都是使用generator生成的mapper.xml文件中,对dao层的更新操作 updateByPrimaryKey对你注入的字段全部更新(不判断是否为Null) updateBy ...

  4. c++调用python系列(1): 结构体作为入参及返回结构体

    最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给 ...

  5. 51nod_1417:天堂里的游戏

    题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1417 假设 ans=n/m,C=(A+B)/2 若出正面 ...

  6. Hadoop-2.7.2集群的搭建——集群学习日记

    前言 因为比赛的限制是使用Hadoop2.7.2,估在此文章下面的也是使用Hadoop2.7.2,具体下载地址为Hadoop2.7.2 开始的准备 目前在我的实验室上有三台Linux主机,因为需要参加 ...

  7. java 笔记 Thread.currentThread().getContextClassLoader() 和 Class.getClassLoader()区别

    查了一些资料也不是太明白两个的区别,但是前者是最安全的用法 打个简单的比方,你一个WEB程序,发布到Tomcat里面运行.首先是执行Tomcat org.apache.catalina.startup ...

  8. Java-认识变量、注释并能及时发现错误

    package com;//变量的演示public class VarDemo { public static void main(String[] args) { /* * 1)题目不用抄 2)注释 ...

  9. 【SpringMVC】静态资源访问的问题

    在项目中经常会用到一些静态的资源,而一般我们在配置SpringMVC时会让SpringMVC接管所有的请求(包括静态资源的访问), 那么我们怎样才能最简单的来配置静态资源的访问呢? 一,在web.xm ...

  10. 解决div里面img的缝隙问题(转)

    图片IMG与容器下边界之间有空隙怎么办?这里介绍3中简单的解决方法. 第一,给图片img标签display:block. img{display:block} 第二,定义容器里的字体大小为0. div ...