从python文件提取以及绘图谈其设计思想

OO~ posted @ 2013年3月28日 10:46 in python , 2043 阅读

    我最近对python特别着迷,学会爬虫抓取数据之后,接着尝试将抓取到的文件数据提取,然后绘制出走势图,后面的这个任务的完成,我用了整整一个下午的时间(不睡午觉),但是最后在代码以及变量函数命名方面做的诸多不足,下面给出我前后代码,谈谈python的设计思想

主模块:

#!/usr/bin/python
# coding = utf-8

import sys
import string
import matplotlib.pyplot as plt
import numpy as np
import getNum #获得歌曲排名,因为设计中文编码问题,单独作为一个自定义模块

def getKey(fileName, s, dist):
    f = open(fileName, "r")
    info = f.read()
    f.close()
    start = info.find(s) + dist
    info = info[start:]
    end = info.find(",")
    return info[:end]

def songDraw():
    x = np.arange(1, 8, 1)
    c = ('y', 'b', 'g', 'r', 'c', 'y', 'b', 'g', 'r', 'c')
    fileDay = ("day1.txt", "day2.txt", "day3.txt", "day4.txt", "day5.txt", "day6.txt", "day7.txt")
    for i in range(0, 10, 1):
        num = []
        tmp = str(i * 20 + 1)
        strlen = len(tmp)
        if strlen == 1:#歌曲的位数要考虑,这样每次截取得到的才是正确的
            dist = 2
        elif strlen == 2:
            dist = 3
        else:
            dist = 4
        key = getKey("day1.txt", tmp, dist)
        num.append(i * 20 + 1)
        for j in range(1, 7, 1):
            num.append(int(getNum.getY(fileDay[j], key)))
        print num
        if i < 5:
            plt.plot(x, num, color=c[i], label="Monday's rank NO."+tmp)
        else:
            plt.plot(x, num, linestyle='--', color=c[i], label="Monday's rank NO."+tmp)
#        plt.plot(x, num, color=c[i], label=u(key))
    plt.legend(loc='upper right')
    plt.title("The song's seven-day rank")
    plt.xlabel("days")
    plt.ylabel("rank")
    plt.grid(True)
    plt.show()

if __name__ == '__main__':
    songDraw()

主模块使用到的自定义模块:

#!/usr/bin/python
# -*- coding:gbk -*-

import string

def getY(fileName, key):
    f = open(fileName, "r")
    info = f.read()
    f.close()
#print s
    end = info.find(key) - 1
    if end == -2:
        return 0
    else:
	info = info[:end]
	info = info[::-1]#将字符串反转,从最后面取值
	end = info.find(",")
	info = info[:end]
#print tmp
        return info[::-1]

接下来的是修改之后的:

#!/usr/bin/python
# coding = utf-8

import sys
import string
import matplotlib.pyplot as plt
import numpy as np

def getSongName(file_name, rank):
    info = open(file_name, "r").read()
    start = info.find(rank)
    return info[start:].split(',')[1]

def getSongRank(file_name, songName):
    info = open(file_name, 'r').read()
    end = info.find(songName)
    if end == -1:
        return 201
    else:
        return int(info[:end].split(',')[-2])#使用split之后,函数反转不需要了,中文字符的查找问题也不存在了

def songDraw():
    x = np.arange(1, 8)
    c = ('y', 'b', 'g', 'r', 'c', 'y', 'b', 'g', 'r', 'c')
    fileDay = ("day1.txt", "day2.txt", "day3.txt", "day4.txt", "day5.txt", "day6.txt", "day7.txt")
    for i in range(10):
        songName = getSongName("day1.txt", str(i * 20 + 1))
        num = [getSongRank(fileDay[j], songName) for j in range(7)]#简化的一个亮点
        print num
        if i < 5:
            plt.plot(x, num, color=c[i])
        else:
            plt.plot(x, num, linestyle='--', color=c[i])
    plt.title("The song's seven-day rank")
    plt.xlabel("days")
    plt.ylabel("rank")
    plt.grid(True)
    plt.show()

if __name__ == '__main__':
    songDraw()

    可以看到,两者之间有非常明显的区别。前后代码量以及松散程度得到了很好的对比。作为一个菜鸟,感觉对python最重要的三大数据结构list,string以及字典使用的还是不到位,不过通过这个训练过程,我至少学会了如何去调试python。同时,在命名规范上,我要做到更加简洁明了。

    其实之前写的C代码多了,所以总感觉在for循环里计算的东西能放在外面就放在外面,经高人提点,python最初的设计理念就不是这样的。python作为一种解释执行的编程语言,其最大的优点之一是它使你能够专注于解决问题而不是去搞明白语言本身。作为每一个python代码的书写者,都要牢记简洁是python的一大美,简洁才能做到易读易看,简洁才能让自己的代码更加优美,不会太慵懒!在网上搜了下——python之禅:

  1. 优美胜于丑陋(Python 以编写优美的代码为目标)
  2. 明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
  3. 简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
  4. 复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
  5. 扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
  6. 间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
  7. 可读性很重要(优美的代码是可读的)

    通过这次的经历,感触还是蛮多的,在代码的技巧以及书写方面也深深觉察到自己的不足,前面的一段路还是很长啊!不过我会加油的,每天进步一点就够了!

Avatar_small
OO~ 说:
2013年3月28日 10:53

感觉有点像记流水帐啊!没办法了,greenhand的境界就只能这样了!

多行相似代码可以通过函数来简洁代码,list的操作,string的操作,中文字符编码等等问题这次都涉及了,我也收益很多!最重要的一点就是不确定,不太理解的地方可以写多个小例子来测试!

PS:小问题——matplotlib中文显示问题不太会弄!

Avatar_small
依云 说:
2013年3月28日 20:50

c = ('y', 'b', 'g', 'r', 'c', 'y', 'b', 'g', 'r', 'c') 为什么不定义成字符串?
为什么不用代码高亮插件?

Avatar_small
OO~ 说:
2013年3月29日 10:48

我觉得元组在这儿也比较符合啊!如果定义成字符串也是可以的。

后面的代码高亮插件,没怎么用过!我去查查看!本人也这代码这样搞这很丑,但是不知道你们都是用的什么,这下知道了,多谢提醒啦~yes

Avatar_small
依云 说:
2013年3月29日 10:55

@OO~: 字符串比较好写 :-)

Avatar_small
OO~ 说:
2013年3月29日 11:03

恩恩,每个人在选择方面有不同的爱好把,嘿嘿!
PS:炯炯的,原来那个高亮的,是我没设置!多谢提醒,我还一直纳闷怎么回事呢!


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter