页面载入中...
首页 » 编程心得

《HeadFirst Python》第一章学习笔记

对于Python初学者来说,舍得强烈推荐从《HeadFirst Python》开始读起,这本书当真做到了深入浅出,HeadFirst系列,本身亦是品质的保证。这本书舍得已在《Python起步:写给零编程基础的童鞋》一文中提供了下载。为了方便大家的学习,舍得特意制作了Jupyter Notebook格式的笔记,文章末尾舍得提供了笔记的下载地址。

读《HeadFirst Python》的同时,最紧要的是及时做练习,你甚至可以在快速浏览过一章后,便拿起练习来做。

做练习的时候,切记,不要用书中建议的Python自带的IDLE。作为过来人,舍得的建议是使用Jupyter Notobook。具体的安装方法舍得已在Python起步:写给零编程基础的童鞋》中讲得很清楚了,每次你要练习的时候,运行jupyter-notebook.exe,便可以在程序打开的浏览器页面中进行代码输入了。Jupyter Notobook与Python自带的IDLE相比,有着巨大的优势:

  • 增强版的代码自动补全:输入代码过程中,可尝试按Tab键,程序会提示相应的代码;
  • 每次录入的代码程序会自动替你保存下来,这就相当于你自己的学习笔记,你可以在代码的前或后加入注释,注释前面用一个“#”+一个空格(空格可以不加,但舍得建议从一开始便养成良好的写代码习惯,#后带空格是Python代码规范-PEP8的要求)就可以了;
  • Notebook给你保存的笔记,你可以随时打开,点RUN按钮(或用Alt+Enter快捷键)便可以运行选择中的某一段代码,这是Python自带的IDLE根本无法做到的事情;
  • 在Notebook中你可以极为方便地输入多行代码,而Python自带的IDLE在这方面有极大的限制;
  • 对于颜控来说,Notebook的代码着色看起来更加舒服一些;
  • ……

舍得会将书中每一章中提到的大部分练习,收录到笔记中,你可以在看完一章后,拿舍得给你的笔记,在Jupyter Notebook中进行练习。当然你也可以在看到书出给出一段代码时,立刻在Jupyter Notobook中输入并运行。

舍得提供的笔记是ipynb格式(ipy是指ipython, Notebook是用ipython来实现的。而nb则是notebook的缩写),当你下载了笔记之后,请将其放到“你的python安装文件夹(默认是c:\python34)\Scripts”文件夹下,然后刷新一下浏览器中Jupyter Notebook的首页,便可以看到这个笔记,点击该笔记,就可以浏览了。

SNAG-0140

如果你在Jupyter Notebook首页中已经点击过“New->Python 3”, 那么你可以使用菜单”File->Open“回到首页选择舍得提供的笔记。

SNAG-0143

下面舍得开始讲解第一章的要点。

文中”[in]:“后面的内容,表示我们在Jupyter Notebook中输入的代码和注释,内容中以”# “开头的,是舍得的注释。

[out]:“后面的内容,则是代码执行后的输出结果。

舍得在注释中,标明了该段代码的页码,方便你对照书本进行练习。书中有些内容的讲解比舍得更详细。

舍得对部分代码进行了改写,但不影响代码的最终效果。

[in]:

    # 熟愁一下打印命令.
    # 第一章 p4
    # 内容前面加一个#号表示注释, python会自动忽略#号后面的内容
    if 43 > 42:
        print("Don’t panic!")

[out]:

    Don’t panic!
   

[in]:

    # 创建简单的Python列表
    # 第一章 p8
    # 标识符:movies, 你给这个列表起的名字
    # 操作符:=,把列表赋给标识符
    # 列表格式:两端用中括号;列表中每一项用逗号隔开;电影名称两边加引号;
    movies = ["The Holy Grail",
             "The Life of Brian",
             "The Meaning of Life"]
    print(movies)

[out]:

    [‘The Holy Grail’, ‘The Life of Brian’, ‘The Meaning of Life’]
   

[in]:

    # 用中括号记法访问列表
    # 第一章 p9
    # 打印列表中第2个数据(第1个为0)
    print(movies[1])

[out]:

    The Life of Brian
   

[in]:

    # 列表深入学习:len
    # 第一章 p10
    # len:获取列表长度,即列表有几个数据项
    cast = ["Cleese", ‘Plain’, ‘Jones’,"Idle"]
    print(cast)
    print(len(cast))
    print(cast[0])  # 0表示第一个数据项, 你可以自己换不同的数字尝试一下

[out]:

    [‘Cleese’, ‘Plain’, ‘Jones’, ‘Idle’]
    4
    Cleese
   

[in]:

    # 列表深入学习:append
    # 第一章 p10
    # append:在列表末尾增加一项数据
    cast.append("Gillianm")
    print(cast)

[out]:

    [‘Cleese’, ‘Plain’, ‘Jones’, ‘Idle’, ‘Gillianm’]
   

[in]:

    # 列表深入学习:pop
    # 第一章 p10
    # pop:从列表末尾删除数据
    cast.pop()

[out]:

    ‘Gillianm’

[in]:

    # 再打印一下,看看有何变化
    print(cast)

[out]:

    [‘Cleese’, ‘Plain’, ‘Jones’, ‘Idle’]
   

[in]:

    # 列表深入学习:extend
    # 第一章 p10
    # extend:在列表末尾增加一个列表(两个列表合并)
    cast.extend(["Gillianm", "Chapman"])
    print(cast)

[out]:

    [‘Cleese’, ‘Plain’, ‘Jones’, ‘Idle’, ‘Gillianm’, ‘Chapman’]
   

[in]:

    # 列表深入学习:remove
    # 第一章 p10
    # remove:在列表中找到并删除一个特定的数据项
    cast.remove("Chapman")
    print(cast)

[out]:

    [‘Cleese’, ‘Plain’, ‘Jones’, ‘Idle’, ‘Gillianm’]
   

[in]:

    # 列表深入学习:insert
    # 第一章 p10
    # insert:在列表中特定的位置前增加一个数据项
    cast.insert(0, "Chapman")  # 0表示插入在最前面,你可以试试其它的数字
    print(cast)

[out]:

    [‘Chapman’, ‘Cleese’, ‘Plain’, ‘Jones’, ‘Idle’, ‘Gillianm’]
   

[in]:

    # 习题
    # 第一章 p13
    # 把每部电影的出品年代加到列表中
    # 象下面这样: [‘The Holy Grail’, 1975, 1975, 1979,
    # ‘The Life of Brian’, 1979, ‘The Meaning of Life’, 1983, 1983]
    # 把数字放进列表的时候,数字不用加引号
    movies.insert(1, 1975)  # 第1个插入到第2个列表项前
    movies.insert(3, 1979)  # 第2个插入到第4个列表项前(好好想想为什么用3)
    movies.append(1983)  # 最后一个追加到末尾就行
    print(movies)

[out]:

    [‘The Holy Grail’, 1975, ‘The Life of Brian’, 1979, ‘The Meaning of Life’, 1983]
   

[in]:

    # 列表: 迭代
    # 第一章 p15
    # 迭代: 用一个for循环,把列表中所有的项逐个打印出来
    # for … in …表示取这个列表的每一个数据
    for i in movies:  # 这里的i随便用哪个(一个或多个)字母都行
        print(i)  # 只要两个i保持一致.你可以试试用不同的字母

[out]:

    The Holy Grail
    1975
    The Life of Brian
    1979
    The Meaning of Life
    1983
   

[in]:

    # 列表: 迭代
    # 第一章 p16
    # 迭代: 用一个while循环,把列表中所有的项逐个打印出来
    # 效果和for循环一样
    # while xx < xxx表示:只要xx < xxx,就一直执行下去, 直到这个条件不成立
    count = 0
    while count < len(movies):  # 前面刚学过的len用法
        print(movies[count])  # 前面刚学过的中括号记法
        count += 1  # 和书本上的count = count + 1相同, 表示让count自增1

[in]:

    # 列表:在列表中储存列表
    # 第一章 p18
    # 我们用movies这个列表来记录一部电影的数据. The Holy Grail这部电影全名叫
    # 《Monty Python and the Holy Grail》(巨蟒与圣杯),1975年出品,两个Terry是导演,
    # 同时也参加了演出。影片时长为91分钟,Chapman是编剧(同时也是主演)。Michael这
    # 一伙人既是编剧,亦是配角。这帮人真是玩嗨了,自编自导自演。
    movies = ["The Holy Grail", 1975, "Terry Jones & Terry Gilliam", 91,
              ["Graham Chapman", ["Michael Palin", "John Clseese",
                                "Terry Gilliam", "Eric Idle", "Terry Jones"]]]
    print(movies)

[out]:

    [‘The Holy Grail’, 1975, ‘Terry Jones & Terry Gilliam’, 91, [‘Graham Chapman’, [‘Michael Palin’, ‘John Clseese’, ‘Terry Gilliam’, ‘Eric Idle’, ‘Terry Jones’]]]
   

[in]:

    # 用for循环处理这个列表
    for i in movies:
        print(i)

[out]:

    The Holy Grail
    1975
    Terry Jones & Terry Gilliam
    91
    [‘Graham Chapman’, [‘Michail Palin’, ‘John Clseese’, ‘Terry Gilliam’, ‘Eric Idle’, ‘Terry Jones’]]
   

[in]:

    # 列表:在列表中查找列表
    # 第一章 p20
    # isinstance: 判断标识符的类型
    names = [‘Michael’, ‘Terry’]
    isinstance(names, list)  # 判断它是不是列表(list)类型
   

[out]:

    True

[in]:

    # 列表:在列表中查找列表
    # 第一章 p20
    # isinstance: 判断标识符的类型
    # 换个方式
    num_names = len(names)
    isinstance(num_names, list)

[out]:

    False

[in]:

    # 列表:在列表中查找列表
    # 第一章 p21
    # 习题: 把上面那个movies列表中的每一个数据项都打印出来
    # 用if … else …模式
    # 结合isinstance
    for i in movies:
        if isinstance(i, list):  # 先判断i是不是列表
            for j in i:  # 是的话用for循环
                if isinstance(j, list):  # 还要再往下挖一层, 因为还有一个嵌套的列表
                    for k in j:
                        print(k)
                else:  # 每一对if…else…要对齐
                    print(j)
        else:  # 不是列表就直接打印
            print(i)
    # 如果再来一层嵌套的列表, 怎么办?

[out]:

    The Holy Grail
    1975
    Terry Jones & Terry Gilliam
    91
    Graham Chapman
    Michail Palin
    John Clseese
    Terry Gilliam
    Eric Idle
    Terry Jones
   

[in]:

    # 函数
    # 第一章 p30
    # 使用函数可以简化刚才写的那段代码, 再多来几层列表咱也不怕啦!
    # def关键字是define的缩写,python看到def就知道这个是函数
    def print_lol(the_list):  # print_lol就是我们定义的函数名,尽可能把名字起得有意义一点
        for i in the_list:
            if isinstance(i, list):
                print_lol(i)  # 如果是列表, 那么调用"自己"再次处理这个列表
            else:
                print(i)

[in]:

    # 函数
    # 第一章 p30
    # 我们来用print_lol这个函数来打印我们的列表movies
    print_lol(movies)  # 看看,代码是不是精简了很多?

[out]:

    The Holy Grail
    1975
    Terry Jones & Terry Gilliam
    91
    Graham Chapman
    Michail Palin
    John Clseese
    Terry Gilliam
    Eric Idle
    Terry Jones

   

第一章完。

本文笔记下载地址:

链接:http://pan.baidu.com/s/1eR4iJoI 密码:t72j

本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:舍得
首发:舍得新浪博客

标签:

《配音小丫》诞生记

很久以前,舍得就想做这样一款软件。那是在2013年,舍得学苑开启“视频月”活动,当时要发布一连串的视频。辣么问题来了,视频好做,配音却不好搞。虽然舍得在北方呆过蛮久的时间,但普通话自认还不够标准。怎么办呢?

以前接触过TTS语音,当时便想用TTS来做,用文本直接合成语音。中文的语音合成,最牛x的自然是讯飞。2010年舍得制作视频的时候,配音用的就是科大讯飞的InterPhonic 5.0。不过最近几年讯飞发展挺快,还专门搭建了一个讯飞开放平台。InterPhonic 5.0和现在最新的语音技术相比,已经不可同日而语了。

2014年舍得注册了个讯飞的账号,下载了它的SDK,硬着头皮用其它现成的C++源代码改出一个自己用的小程序来,当时的程序是酱紫滴:

001K43yhzy6Opg1bojg02&amp

用法也很粗糙,在最上方的文本框中输入要合成的文本,然后点击开始合成就OK了。

不过这样还是不大理想……舍得做视频的时候,往往是先写好要配音的脚本,到配音的时候,能不能把这个脚本交给程序,让它自动生成一连串音频文件呢?

要不然,这样一行行往里输入,得多慢啊!

于是乎就有了今天的《配音小丫》。

从界面上讲,小丫似乎比原来的程序还退步了……因为,她根本就没有图形界面。

小丫工作时是酱紫滴:

SNAG-0138

我在她所在的文件夹下放了一个叫source.txt的文档,文档内放的正是我写的配音脚本。

然后打开小丫,她就腾腾腾开始合成,输出的文件是按1、2、3、4、5……这样的顺序来的,而且是wav格式,直接就可以用。

等小丫把脚本里每一行文本合成完毕,按个“任意键”就可以让她收工了。

虽然样子简陋了一点,但效率可不止高了一点点。

以后有时间,还是要给小丫加个图形界面滴。

最后,上个小丫的“身份证明”:

SNAG-0139

本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:舍得
首发:舍得新浪博客

标签:

Python主流IDE对比:Eric&nbsp;VS.&nbsp;PyCharm

IDE, 全称是Integrated Development Environment,翻译过来就是集成开发环境。Python的开发从2010年5月算起,不知不觉中,到现在已经是第七个年头。

这六年里,舍得最常用的IDE是Eric6(一开始是5.x版本),也试用过圈内闻名的PyCharm、WingIDE和Eclipse(+PyDev插件),算是有些心得。今天,着重对Eric6和PyCharm 2016.3作一下简单的评测。

颜值

Eric6是基于PyQt开发的,程序运行甚至只用一个BAT文件来调用,界面相对而言略丑。PyCharm基于Java开发,自带的主题很漂亮,风格比较统一。在颜值这一点上,无疑是PyCharm胜出。

顺带提一下WingIDE,虽然它也带了很多款主题,但整个窗口中有些部位是不受主题控制的。举个栗子,当你选择深色的主题时,窗口左下角往往会有一块白色的控件,忒刺眼。

速度和内存开销

从启动到打开一个项目,舍得掐着秒表测试了这几款IDE,数据如下:

  • 最慢的是PyCharm,平均需要18-20秒左右。就算把插件干掉只剩两个,再将Xms和Xmx参数适当调整,跑出最快的成绩是16秒5;
  • Eric平均只用11秒;
  • 最快的是WingIDE, 只用7秒;

内存开销上,PyCharm是大户,动辄就是吃掉你300-400MB的内存。机子内存小的童鞋要当心了!

UI和资源编译

开发过程中难免要对UI和资源文件进行调整,所以IDE中自然需要将这两项的编译工作集成进来。

Eric6是原生支持UI和资源文件编译的,它的开发者早就想到了我们需要这项功能。

PyCharm作为一个专业的Python IDE,在这方面无疑略显不足。要实现UI和资源编译,你必须手工在外部工具设置中添加它们(具体操作请自己去问度娘),虽然设置好之后和Eric6比也没啥区别,但总是开发者欠考虑。

不过PyCharm这个外部工具的设计还是值得赞赏的,你可以直接把打包命令(我通常用cx_freeze)直接整合进去,这样就方便多了。

调试

IDE中应当配备调试模块。舍得以前常在DOS命令行下运行开发中的程序,发现错误再切回IDE。现在想想实在是浪费了IDE自带的调试模块。

使用调试模块,首先带来的好处是你不必手工输入命令,也不必在DOS命令行和IDE间切来切去;其次,当遇到错误时,IDE的调试模块会直接显示出错误所在的位置,你不必再去手动寻找。当然调试模块的功能不止于此,具体如何,童鞋们可以自己去深入体会。

在调试方面,Eric6做得更好一些,在遇到错误时,它会自动跳到最终让你出错的位置,省时省力。PyCharm做法略嫌保守,它是在底部的“运行”窗口显示一系列出错的位置,每一个位置带有链接,点击链接即可跳到相应的行。舍得认为,不如在保留链接功能的前提下,自动跳到最后一行出错的位置,通常这一行是问题的关键。如果程序能够做得更智能一些则更好。

智能缩进

在Python的语法中,缩进是非常重要的一项。开发过程中,缩进若能更智能化一点,自然写代码的速度也会快一些。

在这方面,做得最优秀的是Eric6。它的牛x之处在于,无论你的光标键在哪个位置,只要你按TAB键,程序就会根据上面的代码选择合适的缩进位置。

PyCharm亦有类似的设计。它的智能缩进操作英文名叫Emacs Indent(建议将快捷键TAB设置给它),国内的汉化莫名其妙地翻译成了“宏选项卡”,这一定是外行人干的。

但Emacs Indent在处理整块缩进的时候略显无力,当我们要将整块代码往前移的时候,只能使用另一项叫作“取消缩进内容”的操作,而Eric6只要一个TAB键就足够了。

字体缩放

虽然我们可以在设置中给IDE的编辑器设一个特定的字号,但在实际开发中,还是免不了要适当缩放字体。尤其是大屏幕,字体适当放大一些,眼睛不至于那么遭罪。

字体的缩放这两款IDE都有。只不过,Eric6是早已设置好快捷键的(用Ctrl+=/-,或Ctrl+滚轮),而在PyCharm中,你必须手动设置这个快捷键。

这一轮,算打成平手好了。

自动补空格

PEP8的规范要求在逗号、运算符号之类的内容后面加一个空格,这一点Eric做得不错,在你输入一个逗号后,它会自动给你补一个空格,而PyCharm显然考虑得没有那么周到。你不得不手动一个个敲空格,或留着到最后使用Reformat File功能来纠正。

代码自动补全和代码规范化

两款IDE的代码自动补全做得都挺好。硬要挑出一个更好的来,我会把票投给PyCharm, 它的智能化程度似乎(我没法给出更精确的评价,建议自行体会)更高一些。

PyCharm除了自动补全,还会用类似拼写检查的方式检查你的代码,当你输入的代码不符合PEP8之类的规范时,PyCharm会适时提醒并对该部分代码作出标记。这个功能确实很贴心,我有理由相信用PyCharm会帮助我们将代码写得更加规范。

此外,PyCharm还会对当前方法下所用的变量进行检查,当有变量出现未使用、不一致、输入错误等情形时,PyCharm亦会将其一一标出,让你一目了然。

版本控制

版本控制也可算是IDE的标配了吧!Eric6和PyCharm都有版本控制的模块,不过舍得认为,PyCharm在这一块做得更细一些,和GibHub结合得很好,舍得用得很趁手。

数据库连接、查看

这项功能只能算是可选配置了。两款IDE都带有数据库内容浏览的功能,它的方便之处在于,我们要查看数据库中某项数据时,可以不必打开专用的数据库管理工具(比如SQLite的SQLite Expert, PostGreSQL的PG Admin,MySQL的PHPMyAdmin等),直接在IDE内查看。

Eric6自带一个内建的SQL浏览器,界面相对简陋,而且每次打开都必须重新设置,不够方便。

PyCharm是通过Database Tools and SQL这款插件来实现数据库连接和查看的功能,用来临时查看一下数据是足够了。

书签

在开发过程中,我们经常需要在一个文档中不同的位置间切换,此时书签功能会给我们带来很大的便利。

两款IDE都有书签功能,PyCharm做得更好一点,它的书签不会因为你退出程序而清除。而Eric6则会在你每次退出程序时,清空你的书签设置。

TODO

舍得在堆代码的时候,想到一些下一步要完善的功能之类的内容时,往往会在文档中插入一行,行首写上“# todo,”,然后把当时的想法写进去。这样日后就能根据todo的标记和内容来逐渐完善自己所开发的软件。

两款IDE都支持Todo功能,它们会把你在当前项目中的每一行标有todo的内容都搜集起来,以供你随时查看。只是在功能的完善性上,略有差距:

  • PyCharm在你输入“# todo,”的时候就将这一行进行高亮处理,让它变得非常醒目,Eric6默认是不会对“# todo,”作高亮处理的;
  • PyCharm的todo支持大小写,Eric6默认只支持大写,要想支持不同的格式,需要单独设置;

相比之下,PyCharm以微弱的优势胜出。

帮助文档

Eric6自带一个WebKit内核的帮助浏览器,当你设置好Python/PyQt/Pyside/Qt等帮助文档的路径后,可以在帮助菜单中直接点击这些文档的链接,Eric6就会调用帮助浏览器来显示这些文档。

PyCharm虽然有一个外部文档的设置和对应的菜单命令,但功能实在太弱比,应该好好完善一下才是。

另外PyCharm虽然提供了一个Search EveryWhere的“强大”功能,但由于搜索结果匹配往往不能尽如人意,使得此功能形如鸡肋。

结语

通过上面的比较和分析,相信大家自会得出自己的答案。简单说一下舍得的观点:

  • 如果你是个颜控,请选择PyCharm;
  • 如果你的电脑配置略低(尤其是内存),跑PyCharm感觉慢、卡,请选择Eric6;
  • 大多数功能,这两款IDE都大同小异。舍得最介意的是,PyCharm没法在逗号后居然不能自动补空格,希望开发者能在后续的版本中进一步完善;
  • 至于很多仍在使用非IDE(比如用vim、emacs、sublime text之类的编辑器)的童鞋,舍得的建议是,IDE可以让你的开发效率更高。看上去你用这些编辑器也能完成大部分工作,但别忘了,你费尽九牛二虎之力搞定各种插件的同时,IDE上这些功能早就已经非常成熟了,何必自己再去造轮子呢?

 

本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:舍得
首发:舍得新浪博客

标签:

Python主流IDE对比:Eric VS. PyCharm

IDE, 全称是Integrated Development Environment,翻译过来就是集成开发环境。Python的开发从2010年5月算起,不知不觉中,到现在已经是第七个年头。

这六年里,舍得最常用的IDE是Eric6(一开始是5.x版本),也试用过圈内闻名的PyCharm、WingIDE和Eclipse(+PyDev插件),算是有些心得。今天,着重对Eric6和PyCharm 2016.3作一下简单的评测。

颜值

Eric6是基于PyQt开发的,程序运行甚至只用一个BAT文件来调用,界面相对而言略丑。PyCharm基于Java开发,自带的主题很漂亮,风格比较统一。在颜值这一点上,无疑是PyCharm胜出。

顺带提一下WingIDE,虽然它也带了很多款主题,但整个窗口中有些部位是不受主题控制的。举个栗子,当你选择深色的主题时,窗口左下角往往会有一块白色的控件,忒刺眼。

速度和内存开销

从启动到打开一个项目,舍得掐着秒表测试了这几款IDE,数据如下:

  • 最慢的是PyCharm,平均需要18-20秒左右。就算把插件干掉只剩两个,再将Xms和Xmx参数适当调整,跑出最快的成绩是16秒5;
  • Eric平均只用11秒;
  • 最快的是WingIDE, 只用7秒;

内存开销上,PyCharm是大户,动辄就是吃掉你300-400MB的内存。机子内存小的童鞋要当心了!

UI和资源编译

开发过程中难免要对UI和资源文件进行调整,所以IDE中自然需要将这两项的编译工作集成进来。

Eric6是原生支持UI和资源文件编译的,它的开发者早就想到了我们需要这项功能。

PyCharm作为一个专业的Python IDE,在这方面无疑略显不足。要实现UI和资源编译,你必须手工在外部工具设置中添加它们(具体操作请自己去问度娘),虽然设置好之后和Eric6比也没啥区别,但总是开发者欠考虑。

不过PyCharm这个外部工具的设计还是值得赞赏的,你可以直接把打包命令(我通常用cx_freeze)直接整合进去,这样就方便多了。

智能缩进

在Python的语法中,缩进是非常重要的一项。开发过程中,缩进若能更智能化一点,自然写代码的速度也会快一些。

在这方面,做得最优秀的是Eric6。它的牛x之处在于,无论你的光标键在哪个位置,只要你按TAB键,程序就会根据上面的代码选择合适的缩进位置。

PyCharm亦有类似的设计。它的智能缩进操作英文名叫Emacs Indent(建议将快捷键TAB设置给它),国内的汉化莫名其妙地翻译成了“宏选项卡”,这一定是外行人干的。

但Emacs Indent在处理整块缩进的时候略显无力,当我们要将整块代码往前移的时候,只能使用另一项叫作“取消缩进内容”的操作,而Eric6只要一个TAB键就足够了。

字体缩放

虽然我们可以在设置中给IDE的编辑器设一个特定的字号,但在实际开发中,还是免不了要适当缩放字体。尤其是大屏幕,字体适当放大一些,眼睛不至于那么遭罪。

字体的缩放这两款IDE都有。只不过,Eric6是早已设置好快捷键的(用Ctrl+=/-,或Ctrl+滚轮),而在PyCharm中,你必须手动设置这个快捷键。

这一轮,算打成平手好了。

自动补空格

PEP8的规范要求在逗号、运算符号之类的内容后面加一个空格,这一点Eric做得不错,在你输入一个逗号后,它会自动给你补一个空格,而PyCharm显然考虑得没有那么周到。你不得不手动一个个敲空格,或留着到最后使用Reformat File功能来纠正。

代码自动补全和代码规范化

两款IDE的代码自动补全做得都挺好。硬要挑出一个更好的来,我会把票投给PyCharm, 它的智能化程度似乎(我没法给出更精确的评价,建议自行体会)更高一些。

PyCharm除了自动补全,还会用类似拼写检查的方式检查你的代码,当你输入的代码不符合PEP8之类的规范时,PyCharm会适时提醒并对该部分代码作出标记。这个功能确实很贴心,我有理由相信用PyCharm会帮助我们将代码写得更加规范。

此外,PyCharm还会对当前方法下所用的变量进行检查,当有变量出现未使用、不一致、输入错误等情形时,PyCharm亦会将其一一标出,让你一目了然。

版本控制

版本控制也可算是IDE的标配了吧!Eric6和PyCharm都有版本控制的模块,不过舍得认为,PyCharm在这一块做得更细一些,和GibHub结合得很好,舍得用得很趁手。

数据库连接、查看

这项功能只能算是可选配置了。两款IDE都带有数据库内容浏览的功能,它的方便之处在于,我们要查看数据库中某项数据时,可以不必打开专用的数据库管理工具(比如SQLite的SQLite Expert, PostGreSQL的PG Admin,MySQL的PHPMyAdmin等),直接在IDE内查看。

Eric6自带一个内建的SQL浏览器,界面相对简陋,而且每次打开都必须重新设置,不够方便。

PyCharm是通过Database Tools and SQL这款插件来实现数据库连接和查看的功能,用来临时查看一下数据是足够了。

书签

在开发过程中,我们经常需要在一个文档中不同的位置间切换,此时书签功能会给我们带来很大的便利。

两款IDE都有书签功能,PyCharm做得更好一点,它的书签不会因为你退出程序而清除。而Eric6则会在你每次退出程序时,清空你的书签设置。

TODO

舍得在堆代码的时候,想到一些下一步要完善的功能之类的内容时,往往会在文档中插入一行,行首写上“# todo,”,然后把当时的想法写进去。这样日后就能根据todo的标记和内容来逐渐完善自己所开发的软件。

两款IDE都支持Todo功能,它们会把你在当前项目中的每一行标有todo的内容都搜集起来,以供你随时查看。只是在功能的完善性上,略有差距:

  • PyCharm在你输入“# todo,”的时候就将这一行进行高亮处理,让它变得非常醒目,Eric6默认是不会对“# todo,”作高亮处理的;
  • PyCharm的todo支持大小写,Eric6默认只支持大写,要想支持不同的格式,需要单独设置;

相比之下,PyCharm以微弱的优势胜出。

帮助文档

Eric6自带一个WebKit内核的帮助浏览器,当你设置好Python/PyQt/Pyside/Qt等帮助文档的路径后,可以在帮助菜单中直接点击这些文档的链接,Eric6就会调用帮助浏览器来显示这些文档。

PyCharm虽然有一个外部文档的设置和对应的菜单命令,但功能实在太弱比,应该好好完善一下才是。

另外PyCharm虽然提供了一个Search EveryWhere的“强大”功能,但由于搜索结果匹配往往不能尽如人意,使得此功能形如鸡肋。

结语

通过上面的比较和分析,相信大家自会得出自己的答案。简单说一下舍得的观点:

  • 如果你是个颜控,请选择PyCharm;
  • 如果你的电脑配置略低(尤其是内存),跑PyCharm感觉慢、卡,请选择Eric6;
  • 大多数功能,这两款IDE都大同小异。舍得最介意的是,PyCharm没法在逗号后居然不能自动补空格,希望开发者能在后续的版本中进一步完善;
  • 至于很多仍在使用非IDE(比如用vim、emacs、sublime text之类的编辑器)的童鞋,舍得的建议是,IDE可以让你的开发效率更高。看上去你用这些编辑器也能完成大部分工作,但别忘了,你费尽九牛二虎之力搞定各种插件的同时,IDE上这些功能早就已经非常成熟了,何必自己再去造轮子呢?

 

本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
作者:舍得
首发:舍得新浪博客

标签:

Python:起步

Hi,我是舍得。

六年前,我为了给SuperMemo设计一个辅助工具,无意中撞进Python这个圈子,从此,一发不可收拾。

当时,我的编程知识几乎可算是零基础。真要认真滴追根溯源的话,嗯嗯,我在2000年左右开始接触asp,做过几个网站,然后慢慢学了点PHP,直到2009年,建了一个叫“舍得学苑”的网站。然而,毫不客气的讲,这些对于我后来学习编程,帮助真的不大。

都说学编程最好有不错的英语基础。这倒不假。你若能有一定的英语阅读能力,在Python的学习中,可以直接去查看各种英文文档。

不要被”英语基础“这四个字吓倒。舍得的英语基础并不好,当年在读技校的时候是没有英语这门课的。so,我的“原始”英语基础仅仅是初中水平。能读英文文档,完全是后来慢慢一步步积累起来的。我能做到的,你自然也能。

为什么选Python?

这个嘛,我还真没办法告诉你一个完全正确的答案。

我只能很唯心滴讲几点自己的看法:

  • 简单,学习成本低:连我这零基础的都学得会,六年间,开发了转换精灵、课程助手、课程编辑器等软件,自然是因为Python的学习成本够低;
  • 开发速度够快:写几行代码,随时可以运行一下看到效果;
  • 大量的库可用:你不必自己去造轮子。自带的标准库不必再说了,读写excel有xlrd/xlwt,数据分析有pandas,数据库工具可选用sqlalchemy,打包可以用cx_freeze……

    至于图形界面的开发,可以使用PyQt,同样非常的方便。

    如何开始?

    俗话说,万事开头难。这个一点不假。

    难在哪里?

    难在刚开始的时候容易碰到各种卡到你的问题,这确实是一件让人扫兴的事情。所以,若能让学习之路变得更好走一些,让学习的曲线更平坦一些,无疑会帮助我们更快地度过学习的起步阶段。

    那么,从哪开始呢?

  • 给自己的电脑上装上python,舍得根据目前的Python的现状,推荐安装Python3.4.x。3.3及以前的版本,有些常用的库慢慢地不再支持,而3.5及以后的版本呢,也有一部分的库还来不及支持它,所以当下最适合的版本是3.4.x。舍得会在文末放出相应的下载地址,当然,你也可以去官方下载;
  • 阅读《Head First Python》。刚学Python时不要去读太多书!最好的学习方式是边读书,边敲代码来验证、来获得最直观的体验,代码执行的结果会让你明白,哦,原来书中讲的是就是这个!我们不需要知道为什么写这个代码可以获得这样的结果,我们只要记住,这个代码可以让你实现这种效果,下次这么去用就行了。《Head First Python》是Python入门类书籍中的佼佼者,舍得竭诚推荐优先食用;
  • 使用一些工具,来加快学习过程,提升学习效率。这个呆会舍得再细讲;

    之后怎么学习?

    严格地讲,这个话题应该留到以后。不过舍得觉得,先预告一下也无妨:

    • 进一步完善开发环境:安装PyQt4、Eric6,还有一些常用的库;
    • 从PyQt4的官方范例入手学习:这是最快的学习方式之一。官方范例大多短小精悍,你可以像舍得一样,走”修改流“路线,把它们修修改改,跟捏橡皮泥一样,最后捏出的东西跟你自己的作品一样。这个跟刚开始学自行车一样,一开始有人帮忙扶着、看着,骑得熟了,慢慢不用扶,不用看了,你就学会骑车了;

    如何用工具来提升学习速度?

    前面舍得讲到,我们要在看书的同时,做相应的练习。这个练习,可以用Python自带的Shell来完成。但老话说的好,工欲善其事,必先利其器。用自带的Shell来做练习,太过原始了。现在,我们可以有更好的办法。

    方法一:安装ipython。这是一个python的交互式的shell,比自带的强太多了。下面舍得直接讲安装办法(注意,以下所用到的安装包均会在文末提供下载,操作系统为windows-win7或win8,示例用的Python默认安装路径为”C:\Python34”):

    1. 先将舍得提供的ipython-5.1.0-py2.py3-none-any.whl文件解压到Python34\Scripts文件夹下;

    2. 打开命令提示符窗口,转到python下的Scripts文件夹下:

      • 按Win+X组合键,从弹出的快捷菜单中选择“命令提示符(管理员)”;
      • *如果你的系统盘和Python安装位置并不在同一分区,比如你将python装在“D:\Python34”下,而系统盘是C,那么需要输入“D:”再敲回车;
      • 输入“cd\Python34\Scripts”,然后敲回车, 就会进入Scripts文件夹下;

    3. 输入“pip install ipython-5.1.0-py2.py3-none-any.whl”,再敲回车;

    4. 如果没有出现错误提示的话,你可以Scripts文件夹下找到“ipython3.exe”这个文件,用鼠标右键点击它,然后从弹出的菜单中选择“发送到->桌面快捷方式”,以后只要运行它,就可以在这个ipython的窗口下敲敲代码来学习了!

    SNAG-0127

    方法二:安装notebook。这是一种更高级、用起来更爽的方式,舍得以后发的部分文章,会发布相应的notebook文档。这个需要安装多个包,下面一一讲解:

    1. 将下面用到的whl文件解压到Python34\Scripts文件夹下;

    2. 打开命令提示符窗口,转到python下的Scripts文件夹下,具体方法详见方法一;

    3. 输入“pip install pyzmq-16.0.2-cp34-cp34m-win32.whl”,再敲回车;

    4. 输入“pip install Jinja2-2.8-py2.py3-none-any.whl”,再敲回车;

    5. 输入“pip install tornado-4.4.2-cp34-cp34m-win32.whl”,再敲回车;

    6. 输入“pip install notebook-4.2.3-py2.py3-none-any.whl”,再敲回车。理论上3-5步可以不做,直接做第6步也行,但那样靠它自已去获取相应的依赖包(就是3-5中的这仨),下载速度可能会比较慢,有时甚至会安装中断,推荐这样逐个安装;

    7. 以上工作完成后,你可以Scripts文件夹下找到“jupyter-notebook.exe”这个文件,用鼠标右键点击它,然后从弹出的菜单中选择“发送到->桌面快捷方式”,当然你可以双击它直接运行;

    8. 双击运行jupyter-notebook.exe,程序会在你的浏览器(推荐在系统内安装chrome,如果你还在用IE系列的浏览器,辣么,是时候告别它了)中打开Jupyter的页面。这是jupyter-notebook利用tornado这个web框架搭的一个本地服务器——如果你对这些名词不熟悉,先别管它,你只要知道,执行这个程序,你就可以在浏览器中敲代码来学习。

    9. 在Jupyter的页面右侧找到并点击”New“按钮,从下拉菜单中选择”Python3”:

    SNAG-0129

    10. 我们可以在接着打开的页面中输入代码,输入到前面带“In”字样的文本框内即可,然后点击SNAG-0131按钮,就可以看到代码执行后的效果。

    SNAG-0130

    11. 每天用Jupyter notebook一一敲完当天所学、所用过的代码后,你可以点击左上角的”File”按钮,然后从菜单中选择“Download as->Notebook”,可以把当天的学习成果存成”ipynb”格式的文档,供以后回顾、复习使用。这个,就是ipython所不能提供的功能,更不用说python自带的shell了。

    还有什么高效的工具?

    要想快速度过起步时的困难阶段,缩短“新手期”,降低学习成本,将新学到的知识点牢牢记住是最佳的选择。

    而记住这些知识点,靠什么?一是反复地练习,二是有目的、有针对性地去复习。

    舍得建议大家使用SuperMemo UX来帮助自己复习每天新学到的知识点。这个软件的使用并不难,具体的使用方法,舍得会撰写专文讲解。在后续的话题展开过程中,舍得也会制作一些相应的SuperMemo课程,来帮助大家提高学习效果。

     

    好了,Python的起步部分就先介绍到这里。顺便提供本文中讲到的一些工具的下载:

    一、Python 3.4.4.msi

    链接:http://pan.baidu.com/s/1kVDbPyf 密码:oqba

    二、《Head First Python》中文版,pdf格式,相应的阅读器请自行下载,推荐使用百度阅读器。

    链接:http://pan.baidu.com/s/1c1O5g7A

    三、Python推荐安装包:

    链接:http://pan.baidu.com/s/1dFHrKK5 密码:so4k

     

    本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:舍得
    首发:舍得新浪博客

  • PyQt程序编译后的数据库驱动问题

    舍得按:这个问题困住舍得蛮长的一段时间了。在用cx-freeze对写完的程序进行编译的时候,舍得发现,程序居然无法正常打开数据库!直到今晚,按脑中突然冒出的一个念头试了一下,发现解决问题的方法竟然是如此滴简单。

    先介绍一下问题的背景:在舍得写的这个程序中要用到Qt自带的MySQL驱动,在本地调试的时候,一切正常,数据可以随心所欲滴读取、写入。可一旦用cx-freeze对程序进行编译后,杯具发生,数据库就再也打不开了。

    难道是cx-freeze出了错?

    还是,根本没法酱紫调用数据库?那写好的程序只能带着Python的环境运行了?

    舍得有一个优点是会去想各种各样的“可能”的解决办法,然后一一尝试。哪怕可能性很低很低,只要尝试的成本没有超出舍得的忍耐程度,那——还是会去试。

    就这样一个个方案试过去,直到找到答案:

    你要调用哪个数据库的驱动,先在程序目录下新建一个叫”sqldrivers“的文件夹,然后把那个驱动(通常放在"Python安装目录\Lib\site-packages\PyQt4\plugins\sqldrivers下,例如舍得要用到MySQL的驱动,就复制qsqlmysql4.dll")复制过来,放到这个文件夹下。然后就没有然后了,直接运行编译好的程序,你会发现数据库正常了。

     

    本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:
    舍得
    首发:舍得@学习力博客

    从SuperMemo UX课程中提取源文本的基本思路

    之前舍得在转换精灵中提供过将SuperMemo UX课程转换为源文本的功能,但由于SuperMemo UX中题型变化较多,常见的有拼写(填空)题、选择题、匹配题等,碰到这些题型,用之前的思路转换得到的文本将无法直接阅读,因此在新版的转换精灵中已将此功能去除。

    近日在研究官方课程的时候,用到转换精灵的一个新模块来处理这些文本,发现效果不错。考虑到此模块不大可能出现在近期几个版本中,因此将处理的思路简单介绍一下,一可供有一定动手能力的童鞋研究,二来亦算是为自己的操作做一下简单的记录。

    要得到源文本,首先要考虑的是两大方面的问题:

    1.Item文件列表从哪来?

    2.如果将Item文件转成源文本?

    熟悉SuperMemo UX的童鞋想来很快能够得出第一个问题的答案:course.xml。用Python处理这个文件相对比较简单:

    1.用BeatifulSoup模块提取course.xml中的elment标签;

    2.取出符合条件的ID和Keywords属性,存入一个字典;

    没错,用这两步就可以搞定,注意最好对这个字典进行一下排序处理。

    第二个问题处理起来显然比较复杂。好在新版转换精灵的实时预览模块已经对item文件进行了一番解构,将其中的Question、Answer等元素一一分离,且对各个题型进行了分别的处理:

    1.分离出Question、Answer等标签,用BeatifulSoup模块会比较简单;

    2.用正则表达式对各个题型进行处理,重点是拼写题、选择题、匹配题、提示题和排序题,其它如是非题、改错题之类的相对用的较少,可以暂且放过;

    处理时注意转换,比如我们要处理拼写题,item文件中的代码如下:

    ‘Where <spellpad correct="are">a</spellpad> the children?’ – ‘They’re outside in the garden.’

    处理后的源文本最好是下面这个样子:

    ‘Where ____ the children?’ – ‘They’re outside in the garden.’ (TAB空格)are

    当然也可以是:

    ‘Where are the children?’ – ‘They’re outside in the garden.’ (TAB空格)are

    再比如选择题,代码如下:

    ‘Where <droplist>
    <option correct="true">are</option>
    <option>live</option>
    <option>follow</option>
    <option>look</option>
    <option>ruin</option>
    </droplist> the children?’ – ‘They’re outside in the garden.’

    处理后的源文本最好是下面这样:

    ‘Where ____ the children?’ – ‘They’re outside in the garden.'(TAB空格)are(TAB空格)live(TAB空格)follow(TAB空格)look(TAB空格)ruin

    按照这种思路得到的源文本,你就可以利用转换精灵,自由地制作成自己想要的课程。

     

    本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:
    舍得
    首发:
    舍得@学习力博客

     

    Python字典排序一例

    舍得在处理SuperMemo的course.xml文件时,需要将每个元素的ID和keywords成对取出,存入字典。但由于Python的字典是无序的,因此,当储存工作完成后,需要对字典进行排序。

    原始的字典像下面这个样子:

    {(‘213’, ‘I’),  (‘262’, ‘they’), (‘206’, ‘it’), (‘220’, ‘or’)}

    我们要将它排成:

    {(‘206’, ‘it’), (’213′, ‘I’),(‘220’, ‘or’), (‘262’, ‘they’)}

    经过试验,最简单的方法是采用OrderedDict来处理,方法如下:

    itemDict = {(‘213’, ‘I’), (‘262’, ‘they’), (‘206’, ‘it’), (‘220’, ‘or’)}

    from collections import OrderedDict
    recordDict = OrderedDict(sorted(itemDict.items(), key=lambda t: int(t[0])))

    这个recordDict 便是我们所要的结果。

     

    本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:
    舍得
    首发:
    舍得@学习力博客

    SuperMemo UX数据库中的日期格式转换

    打开SuperMemo UX的数据库,我们会发现其中的日期并没有用常见的"年-月-日"的格式,而是用了一个int值,这个值通常是5位数左右,它表示从1970年1月1日起的天数,对UX程序来讲,这样的储存方式便于计算时间间隔,而当你要以日期格式来表现的时候,只要处理一下就可以了。

    舍得以python为例,讲解一下日期的格式转换:

    比如我们要转换15517这个值,这里要用到fromordinal这个函数,下面是代码

    def getdate(self,  date):
        __s_date = datetime.date(1970, 1, 1).toordinal()   #取1970年1月1日的ordinal值
        d = datetime.date.fromordinal(__s_date + date)   #加上传进来的以int表示的日期
        return d.strftime("%Y-%m-%d")   #返回"年-月-日"格式的日期

    这样我们只要调用getdate就可以得到日期,如:

    print(self.getdate(15517))

    结果为:

    >>>2012-06-26

     

    本文版权归舍得学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:
    舍得
    首发:
    舍得@学习力博客

    [编程心得]PyQt中让按钮保持按下状态

    近日舍得在开发SuperMemo转换精灵体验版的时候遇到了一个问题,舍得需要左侧一个竖排的工具栏,工具栏中的按钮点下后高亮为蓝色,而且点击后一直保持这种高亮状态.直到另一个按钮按下,把它替换掉为止,就象下面这个效果:

    SNAG-0043

    在实际使用的时候发现了问题:当鼠标在主窗口的其它位置点击的时候,这个蓝色高亮状态就消失了,舍得尝试了很多种方法,什么信号槽啊,事件啊啥的,一直找不到一个妥善的解决方案,这几乎已经成为舍得心头的一根刺了。

    直到今天,在度娘的帮助下,找到了一篇文章《Qt保持状态的Button》,直觉告诉我这个可以解决,马上动手测试,终于把这根刺给干掉了。

    下面是解决的方案:

    在按钮中应用下面的函数:

            self.scriptBtn.setCheckable(True)
            self.scriptBtn.setAutoExclusive(True)

    像舍得上面这幅图中总共5个按钮,需要一一设置。

    然后在QSS样式表中设置:

    QPushButton::checked,QToolButton::checked{
        background: #3C79F2;
        border-color: #11505C;
        font-weight: bold;
        font-family:"Microsoft YaHei";
    }

    就完成了舍得预期的效果,每个按钮点中后高亮,直至另一个按钮被点击;鼠标即使在非按钮区点击,高亮效果仍然保留.

     

    本文版权归舍得英语魔法学苑所有,欢迎转载,转载请注明作者和出处。谢谢!

    作者:
    舍得

    首发:
    舍得@学习力博客

    [编程心得]用Python给汉字加上带音调的拼音

    作为一个南方人,拼音没学好那似乎已是一件非常正常的事。什么卷舌音、鼻音,也只有在近几年才算是分清了一部分。但尴尬的事情仍在继续,发短信的时候,总有些字拼得不准;说话的时候,总有些字没有卷舌、或忘了加鼻音……痛定思痛,于是有了一个用SuperMemo来强化拼音的训练方案。

    要实现这个方案,得具备两个条件,一是选定汉字范围——舍得选的是一级国标汉字,共计3700余个;二是利用程序将这些汉字转化为拼音,要求拼音带上音调,这个就需要对转换精灵进行适度的改造。

    舍得以HzqGhost(小强)童鞋的代码为蓝本,进行了如下的改造:

    1. 编码部分采用这份码表:下载地址
    2. 源代码为python2.x的,改造为python 3.x;
    3. 在给韵母添加声调的部分代码,原代码有个别地方出现错误,在我家傻妹的提醒下,舍得修复了这一错误;

    下面是相关的部分代码,分段描述:

    1、读入码表文件,转成dict:

            fileName = './Mandarin.dat'
            self.dict = {}
            for line in open(fileName):
                k, v = line.split('\t')
                self.dict[k] = v

    2、然后对传入的中文字符串进行处理:

            self.yunmu = ( 'ang','eng','ing','ong','an','en','in','un','ai','ei','ao','ou','iu','er','en','a','o','e','i','u', 'v')
            self.sheng = {'a':'ā á ǎ à','o':'ō ó ǒ ò','e':'ē é ě è','i':'ī í ǐ ì','u':'ū ú ǔ ù', 'v':'ǖ ǘ ǚ ǜ'}
            result = []
            for char in chars:#chars为传入的中文字符串
                key = "%X" % ord(char)#将汉字转为utf16编码,“码表”文件中用的是这个编码
                try:
                    py = self.dict[key].split(" ")[0].strip().lower()#只取查到的拼音第一个值(当有多音字的时候),同时将结果转为小写
                    for ym in self.yunmu:
                        if re.search(ym, py):#匹配
                            py = getPy(py, ym)
                            break#只取第一个结果
                    result.append(py)
                except:
                    result.append(char)
            return " ".join(result)


    原来的self.yunmu设置不合理,在碰到’ui’,’iu’,’ie’,’ue’四个韵母时,音调会标在第一个字母上,舍得在元组中去除了’ui’,’ie’,’ue’这三个值,这样在匹配时根据a,o,e,i,u的顺序,这三个韵母的音调才会落在第二个字母上。而对于’iu’这个韵母,则需在下面的getPy里作一个特殊的处理:

    3、给匹配到的韵母标上音调:

            def getPy(py, ym):
                t = py[-1:].encode('ascii','ignore')#‘码表’中返回的拼音字符串最后一位是数字,表示音调值
                t2 = "%d" % ord(t)
                t3 = (int(t2) - 48)%4 -1
                py2 = py[:-len(ym)-1]#声母
                if ym == "iu":#如果韵母是iu
                    letter = self.sheng[ym[1]].split(' ')[t3]#音调字母要标在u上
                    ym = ym[0] + letter
                else:                
                    letter = self.sheng[ym[0]].split(' ')[t3]#其它情况,音调标在第一个字母上
                    ym = letter + ym[1:]
                py = py2 + ym
                return py


    最终完整的代码如下:

        def cnCode(self, chars):
            def getPy(py, ym):
                t = py[-1:].encode('ascii','ignore')#‘码表’中返回的拼音字符串最后一位是数字,表示音调值
                t2 = "%d" % ord(t)
                t3 = (int(t2) - 48)%4 -1
                py2 = py[:-len(ym)-1]#声母
                if ym == "iu":#如果韵母是iu
                    letter = self.sheng[ym[1]].split(' ')[t3]#音调字母要标在u上
                    ym = ym[0] + letter
                else:                
                    letter = self.sheng[ym[0]].split(' ')[t3]#其它情况,音调标在第一个字母上
                    ym = letter + ym[1:]
                py = py2 + ym
                return py
                
            fileName = './Mandarin.dat'
            self.dict = {}
            for line in open(fileName):
                k, v = line.split('\t')
                self.dict[k] = v
    
            self.yunmu = ( 'ang','eng','ing','ong','an','en','in','un','ai','ei','ao','ou','iu','er','en','a','o','e','i','u', 'v')
            self.sheng = {'a':'ā á ǎ à','o':'ō ó ǒ ò','e':'ē é ě è','i':'ī í ǐ ì','u':'ū ú ǔ ù', 'v':'ǖ ǘ ǚ ǜ'}
            result = []
            for char in chars:#chars为传入的中文字符串
                key = "%X" % ord(char)#将汉字转为utf16编码,“码表”文件中用的是这个编码
                try:
                    py = self.dict[key].split(" ")[0].strip().lower()#只取查到的拼音第一个值(当有多音字的时候),同时将结果转为小写
                    for ym in self.yunmu:
                        if re.search(ym, py):#匹配
                            py = getPy(py, ym)
                            break#只取第一个结果
                    result.append(py)
                except:
                    result.append(char)
            return " ".join(result)

    调用的时候,只要这样就可以了:

            chars = "舍得英语魔法学苑"
            print(self.cnCode(chars))

    返回的结果如下图所示:

    拼音

    不过舍得通常会读取当前文本,然后按换行符分割,再逐个传入,得到拼音,最后拼成TAB文本,这样就可以利用转换精灵制作成课程了。这里边的细节就不再一一叙述了。

    附上最终完成的课程:

    国标汉字拼音课程

     

    本文版权归舍得英语魔法学苑所有,欢迎转载,转载请注明作者和出处。谢谢!

    作者:
    舍得

    首发:
    舍得@学习力博客

    [编程心得]PyQt中“明天”的表示法

    话说学苑有童鞋抱怨,说一直在看舍得的博客,希望舍得能多介绍一些SuperMemo和Tell Me More方面的使用技巧。这个要求估计比较难满足。倒不是因为SuperMemo和Tell Me More方面已经没什么好写——这绝对不是事实,只要将SuperMemo官网上的文章翻译翻译,再适度延伸一下,一篇文章就出来了,但舍得不想为了交任务而写东西。博客嘛!写下自己最想写的内容才是最佳的选择。这不,现在写上了编程方面的内容。

    Qt用的人不少,不过PyQt的就略微少一些。但没关系,舍得用惯了就好。在这里所写的一些东西,都是舍得在实际编程的过程中用到的。之前舍得在学苑里有讲到,舍得向来是走实战流,更准确地讲是“改装流”。因为舍得从来不去探究代码背后的种种原理,往往满足于“我知道这段代码干什么用的”、“这里放这样的代码应该能解决问题”。由于非科班出身,代码难免写得难看点,执行效率多少会低一些,好在舍得的满足点比较低,只要“能用”就行了,这一点倒与不求上进的腾讯有些相似。

    下面介绍的是在PyQt中“明天”的表示法,这是最近写的一个HR程序中用到的,先来看看今天怎么表示,比如说我们有一个DateEdit控件,叫做beginDayDateEdit,要给它赋上“今天”这个值就可以这样写:

    beginDayDateEdit.setDate(QtCore.QDate.currentDate())

    那明天呢?咋办办?

    舍得看了看PyQt官方的说明文档,从中找到了一个方法,就是将currentDate先用toJulianDay转成数值形式,然后加1,再用fromJulianDay转回来就可以了,具体的代码如下:

    tomorrow = QtCore.QDate.currentDate().toJulianDay() + 1
    beginDayDateEdit.setDate(QtCore.QDate.fromJulianDay(tomorrow))

    后天、大后天就可以依此类推,不再赘述。

    不过在处理DateTimeEdit的控件会有所差异,此时用的不是toJulianDay和fromJulianDay,而是toTime_t和fromTime_t,我们来看看:

    tomorrow = QtCore.QDateTime.currentDateTime().toTime_t() + 86400
    self.beginDayDateEdit.setDateTime(QtCore.QDateTime.fromTime_t(tomorrow))

    注意,由于控件改变了,setDate也变成了setDateTime,toTime_t把当前时间转成了从1970年1月1日00:00:00到现在的总秒数,要加1天的话,加上86400秒就行了。

     

     

    本文版权归舍得英语魔法学苑所有,欢迎转载,转载请注明作者和出处。谢谢!
    作者:
    舍得
    首发:
    舍得@学习力博客

    [编程心得]用python取汉字首字母

    近日给兄弟公司编写一个HR管理软件,其中需要用到这样一个功能:当用户在窗口中输入员工姓名时,能够自动取出姓名中的拼音首字母,作为"助记码",以便用于后续的查询。

    尝试了几种不同的方案以后,最终参考水木社区中的Roy兄提出的方案,用Python+Sqlite的方式来完成此项工作。

    软件环境如下:

    Python 3.2.2

    PyQt 4.9.1

    Sqlite 3

    在文件头部需先导入sqlite3:

    import sqlite3

     

    然后来看getFirstLetter段代码:

       1:      def getFirstLetter(self, text):
       2:          pinyinlist=[]
       3:          for i in range(len(text)):
       4:              hanziSql = 'select pinyin from hanzi where hanzi = "'\
       5:                              + text[i] + '"'
       6:              pinyinlist.append([])
       7:              result = self.execSql(hanziSql)
       8:              for pinyin in result:                    
       9:                  pinyinlist[i].append(pinyin[0][0])#数据库中查到的是整个拼音,用pinyin[0][0]则指定返回首字母
      10:          poslist=[-1]*len(text)
      11:          i=0
      12:          results=[]
      13:          n=0
      14:          while (i>=0):
      15:              poslist[i]=poslist[i]+1
      16:              if (poslist[i]>=len(pinyinlist[i])) :
      17:                  poslist[i]=-1
      18:                  i=i-1
      19:                  continue
      20:              if i==len(text)-1:
      21:                  results.append('')
      22:                  for t in range(len(text)):
      23:                      results[n]=results[n]+pinyinlist[t][poslist[t]]
      24:                  n=n+1
      25:              else :
      26:                  i=i+1
      27:          return results 
     
    里面调用到的execSql段代码如下:
       1:      def execSql(self, sql):
       2:          cxn = sqlite3.connect(db)
       3:          cur = cxn.cursor()
       4:          cur.execute(sql)#执行查询
       5:          return cur.fetchall()
       6:          cxn.close()
     
    execSql这一段当然可以直接并到getFirstLetter中,不过舍得在其它地方要调用它,所以单独列出.
     
    具体使用的方法如下,比如我们要查"舍得学苑"的拼音首字母:

            easyCode = self.getFirstLetter("舍得学苑")
            if len(easyCode) > 0:
                print(easyCode[0])#返回的结果中有多音词 ,只取第一个


     

    本文用到的数据库可到这里下载:华为网盘下载
     

    本文版权归舍得英语魔法学苑所有,欢迎转载,转载请注明作者和出处。谢谢!

    作者:
    舍得

    首发:
    舍得@学习力博客