一步一脚印之Python:第一步-设计目录

前言

“对于理工科非计算机专业的人来讲,如果只是在工作中利用计算机作为工具,最好的办法就是学好一些计算机的工具。”

到底该如何提高效率呢?那就是根据计算流程建立合适的目录,模块。

以前,我也总是只实现功能。一段时间后,会发现忘记代码,搞混测试内容,再次检查而浪费了大量时间。通过跟老师、师兄、同学的学习,发现合理的设计目录、能够事半功倍。️

于是,我将从一个小项目中的目录设计、各目录功能、总结三部分进行介绍。

目录设计

利用python解决平常的问题或小项目时,最好在纸上先进行规划,建立合适的目录,来确定不同目录之间的关系。一个小项目涉及到的流程是:

输入数据->数据处理->输出数据->数据可视化或利用

下面,根据我自己的理解,我说一下每一部分会遇到的问题是什么。

输入文件有这样的特点:数据来源广、数据量多、数据形式异构。来源可以是下载、文本处理、或者网络的接口等等,这就会造成了数据形式异构,杂乱数据就需要合理的保存与之后的处理。为了按照流程化的思路说,在这里,我把原始数据全部归到了输入数据。

数据处理有两方面需要考虑:一方面是根据输入数据的三个特点,需要进行预处理,具体为格式处理,时间处理。另一方面是将标准化后的数据进行之后的计算。

输出数据有三个方面的问题:需要保存的数据、保存的形式、保存的位置。原则上是根据事情的目的、目标将得到的结果进行保存,在后面会详细的介绍。

数据可视化的特点:明确展示基本要求、确定数据使用者或读者是谁。从而将结果以文本、图表、动画的形式展示出来。

现在我们再次回顾一个小项目的流程是什么:输入数据->数据处理->输出数据->数据可视化或利用。接下来,我依据这个流程,介绍一种目录结构管理的思路,如图1。注意:数据处理两个方面以及数据可视化都属于对数据进行操作,我将他们都放到了数据处理中。下面我就详细介绍每一部分在程序中要注意的问题和文件的关系。

图1 目录结构示意图

一般会依据处理的事情,以其项目名建立一个总文件夹case_name。在实际应用中,我们把原始数据存放到了input中,输出数据放到了output,而在数据处理部分的流程为:数据预处理->计算->运行程序->可视化数据

数据处理部分又包括了:常用的预处理工具、自己写的函数方法、或第三方包,这些都应该放到doms下,一些常用的工具建议放到doms/utils下;而process是按一个一级计算模块的流程将doms下的子次级计算模块进行整合,也可以将一类对象放入此中;而一件事的处理是在manage下运行,最终我们只修改mange下的运行脚本。比如有不同的研究区域或时间,都是在这里修改变量。因为本篇是介绍思路,请先往下面看。

各目录功能

现在,我根据自己的经验,叙述在处理一件事情的流程中,每一步的限制条件有什么,我又是如何应对的。

01

数据存储

【限制条件】杂,多,是否需要保存

由于一件事情、一件项目就会设计到数字内容,而数据包含多种格式,有文本、图像、动画、声音以及视频等等。同时,数据是可随时间更新或扩展。这些原始数据也应该满足被拆分重组或单独使用的需求。

当我们使用原始数据,进行有目的的处理,又会得到中间过程,结果数据。一些项目中间过程多,会在大量数据的基础上产生N倍的数据,如果遇到差值、差分的计算,数据会出现几个量级的变化。因此一个很关键的问题就是:有多少数据应该被保留?

Saving is not preserving

保存中涉及到了数据量、数据存储成本、数据再利用频次、数据备份。所以,我认为需要对于输入数据采用‘‘数据库+配置+压缩文件’ ;对于中间过程用‘字典+矩阵’ ;对于结果采用“目的需求+特殊格式”的形式来操作。

比如,我们采用mongodb数据库+json来对原始文件进行操作,利用数据库很好的存放不同格式的数据,在json文件中我们的存放需要的信息,以便调用。而数据的操作运算呢,我们可以利用dict+array来实现。

Dict的好处在于,利用key可以实现不同格式、不同字段的个性化信息录入,包含数据的信息、来源、数据质量等等。

利用array,可以对数据进行矩阵操作。矩阵要求数据是格式统一,因为数据是利用索引index进行操作的,这是与dict利用key所不同地方。

但是遇到不规则的数据,时间不连续,排列不同,我们可以采用list的方式进行处理,比如AIS数据。

02

预处理 doms

【需要解决的问题】将数据进行标准化处理;需要将确定的每一个基础计算(比如一个公式),在此实现功能。

如图1,我们将数据的预处理工具包和基本计算程序存放到了工具包doms中。数据预处理包含了数据的读取,时间转换,格式转换。而基本计算程序,是指计算流程中的每一个子过程。第三方包指的是将github、网络、自己撰写的工具,由于一些开源库我们可以用conda 等进行管理,只需要将项目的环境写入到requiremens.txt便可,不需要放入此文件。

图2 计算流程示意图

03

计算 process

【需要解决的问题】将次级计算流程规整;确定类

如图2,计算是将每一个计算流程进行连接,调用doms下的每一个次级计算过程,按照一级计算模块进行整合。合理的归纳出项目中的对象,以类的形式进行编程。

04

运算manage

【需要解决的问题】将计算流程理清楚;确定输入参数

一个项目虽然涉及到多项计算,但是每次不同的例子,往往只是时间范围、地理位置、数据来源等有所不同。在manage中我们依据需要计算的案例进行配置初始输入条件,然后进行相应的计算。运输后自动将结果输出到output中。

05

输出output

【需要解决的问题】保存如何的形式,目录如何分类。

关于中间数据:

我的建议是在之后流程中会多次利用某一步的结果,可以将该结果导出。如果是规整的矩阵,可以写入mat、Netcd4、grb2。如果是不规则的数据,写成dat、txt、json都是可以的。

保存出第一次处理的数据,因为经过第一次的数据清洗,数据量会减小、数据格式变得统一。而之后的数据不必保存,再次操作时,通过dict对第一次清洗过的数据进行不同的操作。

关于output中的log,日志是很重要的。从前期的测试、后期测试、每日检测都需要保存。前期测试,我建议的是每一个细节在脚本中进行记录,测试结果也在log中记录,记录的内容要有,测试名与测试结果,并记录调整前后的内容与时间,如图3。

图3 log日志示意图

目录如何分类:

分类有两种方式,根据一个完整的流程,将涉及到的全部的数据和配置文件存放到同一个以测试命名目录下;或将同一类属性数据放到一个目录下,比如风速、流速、潮汐分开存放。

这两个的优点各不相同,当做前期测试时,采用第一种方式,可以快速的找到相关过程文件,便于检查、改善;采用第二种方式能够很好的管理完善的系统。

06

其他,协作开发期间注意的问题

【需要注意的问题】备注规范、变量规范、函数规范、注释规范、生成文件规范。

变量规范:变量语义明确,常量大写,变量小写。由于计算过程中可能涉及到虚数i,所以我们要避免使用变量i,特别是循环时。

备注规范:关于程序中的备注,程序的备注要占到程序的1/3,包含每个模块,变量,采用的方法,以及一些修改的commit,如图4。

注意:在协作中不能够直接修改代码,首先进行粘贴复制,然后command之前的命令,记录好自己的操作。

函数规范:函数功能,参考的文献或网址,都要详细的记录对应的位置。

生成文件规范:在进行测试时,生成的文件可以加随机数或明确的测试名进行标示,一个测试用到的文件建议放到同一个目录下,进行管理,以达到有迹可循。

图4 注释示意图

总结

吴军老师在谷歌方法论中提到 “对于理工科非计算机专业的人来讲,如果只是在工作中利用计算机作为工具,最好的办法就是学好一些计算机的工具。”

我在平常的编程中,都是通过复制粘贴以往的代码来实现功能,生成的文件也是简单的进行移动。当一段时间后,由于遗忘,或混乱的保存。总是需要花费大量的时间进行复查,不便于管理做过的事情。通过与老师、师兄的学习,发现这种采用一定的结构来管理项目,会使得处理思路更清晰,办事情更高效。之后我会通过介绍一些具体的开源程序来解释这种做法的优缺点,来与大家一同学习更高效的解决思路。

所以呢,blabla半天其实就是:依据具体事情->提取出流程->动手前要进行合理的规划。

感谢导师、佰超师兄的指导与帮助。

由于缺乏经验,希望能向大家进行交流、学习

入秋了,羊肉、蟹黄汤包、老鸭汤,芋艿,毛豆、玉米、杏子、柿子…

微信号:op_programmer

分享一些个人理解和整理的物海方面有关编程技术的知识,大家一起学习一起进步。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181012G02V5600?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券