2020-07
21

改进

By xrspook @ 9:18:56 归类于: 烂日记

当我把电子书的列表从800多KB改成几个以后,整个静态网站的生成速度就从之前的120秒降为20多秒。20多秒的生成速度跟生成markdown文件没什么区别了。准确来说,生成速度更快了,因为少了一个markdown转换的过程,我猜可能是这样吧。虽然我已经绕了一个大圈又重新做了一个判断,如果我直接从点点转换成静态网站,而不是先格式化为wordpress标准的XML格式,估计速度会更快,但可以肯定的是,如果那样的话,我还是得做不少的判断,因为点点的文件里面不同类型的核心内容是不一样的。其实最简单的方法,是我生成wordpress格式文件的时候把分类继续放在分类,不把博客的名字放在分类,不把分类作为其中一个标签,相对来说这样的改动是最简单的。其实现在我绕了一个圈再回去,也没麻烦多少,因为那个标签是第1个,而我的判断是,如果找到了某个标签,就马上停止循环,所以虽然每篇日志的标签有n个,但判断第1个以后就结束了。就循环来说,没耗多少时间,只是代码会显得又长又臭。

近段时间我一直在纠结如何把手动输入的字典搞得好看些。除了好看,也要容易维护。最明白的方式当然是自己写键值对,但是那么多的引号,那么多的冒号,那么多的逗号,想想都觉得好疯狂。最整齐最不容易出错的方式是一行一个,但那样的话,好像有点奢侈了。所以有时我也搞不懂自己,到底是想节省空间,还是维护容易。

昨天晚上,我纠结一个问题,如果某个单词被我用作变量,在字典里那个单词又是一个key,同时这个单词也是个文本。有没有某个函数能把某个变量只当作是某个名字的字符串呢?如果这样,我的某句话就可以写得很简洁。否则的话,当我调用函数的时候,我就要把这个单词写一遍,当作字符串再写一遍。或者你会说,我直接把这个变量等于这个字符串不就好了吗?显然,我之所以把那个单词当作变量,肯定是因为其内涵跟字符串不一样。所以我试试是不是自己挖了个坑给自己跳呢?我明明不应该把这两个东西命名成一样。

有些时候我会问一些很弱智的问题,明明我是知道的,但是一下子就是想不起来。归根到底,我觉得是我的基础还不够扎实。在完成了静态博客的部署以后。我还没想好我是继续把Think Python那本书从我中断的地方继续看下去,还是应该从头开始,复习一遍,加深印象,因为那些很基础的东西在用着用着的时候,我觉得自己已经忘光了。所以到用的时候,我又得翻箱倒柜。那些东西,我明明应该已经掌握的。

现在的静态网站转换,我是用很低端的字符串连接整出来的。有些字符串是一成不变的,有些字符串是变量。我就在变量的之前之后把静态字符串断开,储存在某个文件里。最后就像穿珠子一样,把动态和静态的东西连在一起,最终合成一个网页。实际上,这是一种模板的思路。接下来,我要利用python的模板引擎,把静态的东西写在模板里,把动态的东西放在某些参数中。这才是我的网页转化应有的方式,但我不确定,这样的转化效率会不会比我现在的低端做法还要低。对我来说,那是一个未知的世界,我非常想,立马通过实践得出答案。

人在求知的路上会越发明白到自己的无知。

2020-06
5

随机单词扎堆成文

By xrspook @ 14:47:54 归类于: 扮IT

从某本书里随机找单词拼出句子段落。重点是把握好前缀和后缀,前缀要捆绑查找,后缀要关联对应。

Exercise 8: Markov analysis: Write a program to read a text from a file and perform Markov analysis. The result should be a dictionary that maps from prefixes to a collection of possible suffixes. The collection might be a list, tuple, or dictionary; it is up to you to make an appropriate choice. You can test your program with prefix length two, but you should write the program in a way that makes it easy to try other lengths. Add a function to the previous program to generate random text based on the Markov analysis. Here is an example from Emma with prefix length 2: He was very clever, be it sweetness or be angry, ashamed or only amused, at such a stroke. She had never thought of Hannah till you were never meant for me?” “I cannot make speeches, Emma:” he soon cut it all himself. For this example, I left the punctuation attached to the words. The result is almost syntactically correct, but not quite. Semantically, it almost makes sense, but not quite. What happens if you increase the prefix length? Does the random text make more sense? Once your program is working, you might want to try a mash-up: if you combine text from two or more books, the random text you generate will blend the vocabulary and phrases from the sources in interesting ways. Credit: This case study is based on an example from Kernighan and Pike, The Practice of Programming, Addison-Wesley, 1999. You should attempt this exercise before you go on; then you can download my solution from http://thinkpython2.com/code/markov.py. You will also need http://thinkpython2.com/code/emma.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import string
import random
from collections import defaultdict
def set_book(fin1,num):
    d = defaultdict(list) # 默认键值为列表
    l = []
    header = ()
    for line in fin1:
        line = line.replace('-', ' ')
        for word in line.rstrip().split(): # 空格换行为分割,单词存入列表
            l.append(word)
    for i in range(len(l)-num): # 以列表序号逐一推进方式建立字典
        header = (l[i-1],) # 元组header为前缀,做键
        for j in range(i,i+num-1):
            header += (l[j],)
            j += 1
        if l[i+num-1] not in d[header]:
            d[header].append(l[i+num-1]) # 列表后缀做键值
    return d
def next(start, book):
    return random.choice(book[start])
fin1 = open('emma.txt', encoding='utf-8')
prefix_num = 3 # 前缀个数
suffix_num = 100 # 后缀个数
book = set_book(fin1,prefix_num)
start = random.choice(list(book.keys())) # 随机前缀开头
final =  start
for i in range(suffix_num): # 截取最后几个单词为前缀找后缀
    final += (next(final[len(final)-prefix_num:], book),) 
for word in final:
    print(word, end=' ')
# reigns alone. A very proper compliment! and then follows the application, 
# which I think, my dear, you said you had a great deal happier if she had no 
# intellectual superiority to make atonement to herself, or frighten those 
# who might hate her into outward respect. She had never seen her look so well, 
# so lovely, so engaging. There was consciousness, animation, and warmth; 
# there was every appearance of its being all in proof of how much he was 
# in love with, how to be able to return! I shall try what I can do. 
# Harriet's features are very delicate, which makes a likeness
2020-06
5

上路

By xrspook @ 8:29:07 归类于: 烂日记

我已经不记得对上一次,写python是什么时候的事了,感觉好遥远,起码一个多月以前。具体时间,我实在记不清了,但是我依然记得,上一次我卡在了哪里,我应该在哪里重新开始。当时我看到的是第14章,但实际上第13章的内容我还没有全部消化掉,前面的那些我花的时间还多一点,后面的那些简直就是囫囵吞枣。第13章最后一道练习题,我觉得自己是无论如何不会去想的了,因为我根本不知道题目到底要我做些什么,之所以这样,大概是因为我的数学学得不好,所以我无法理解题目的意思。但是倒数第二道题目,我觉得自己还是可以做到的。

那是一道从一本书里随机的选择某些单词组成一些可能有意思的句子。随机拼凑句子语意当然乱来,但是如果能保证单词前面和后面相对稳定,那么起码单词组合起来会有某些意思,虽然可能句子的意思还是很无厘头。随着前面后面单词的整体性加强,整个句子的意思也会越发明了。这其实就是一个靠着前缀找后缀的运行模式。开始的时候默认的前缀是两个单词。由前面的两个单词找出后面一个单词,然后再利用后面的两个单词找下一个单词,如此类推。这种方法理论上可以扩展为结合前面N个单词找后面一个单词,然后再撇掉第1个单词,继续找下一个。思路不复杂,但是该用什么实现这个呢?的确是需要点心思的是Think Python那本书没有把所有方法都告诉你,在最终写出这道题目的解答之前,我看过他们的答案,但我觉得自己没看懂,因为里面加入了很多书里之前根本没说过的东西。里面默认带入了很多他们认为你必须知道,所以无需解释的东西。如果这是一本传统的教程,这简直让人日子没法过了!做这本书的习题的时候,我也吐槽过无数次,他们会无底线地超纲。但也正是因为这些说来就来的超纲,让你除了要看这本书以外,你还必须动脑筋,还必须自己手动去搜索解决方法,找那些他们觉得你一定得懂,但实际上他们又没说的东西。最终我写出了我想要的东西,至于结果跟他们的差多远,我没有比较。很多人说python是一种类似于乐高积木的编程,是一个模块叠加一个模块的。但是里面的递归却让我很头晕,所以当参考答案用上全局函数,用上递归的时候,我选择的依然是循环,依然是在主函数里输出那些东西,同时也在一句话里面嵌套了好几个我想做的事。我当然可以把我嵌套的东西单独出来定制一个函数,但是一句话能说清的事情我不想再写几行,虽然在用的时候,多写几行可能会调取得方便一些。现在我之所以不这么干,是因为我要实现的功能暂时来说还很简单。我用一句话就实现了,只不过嵌套了好几个参数而已,Excel的函数也是这么玩的。虽然有些时候,我也会狠狠地吐槽那些几万公里那么长的Excel函数公式。

我从来没想过,自己能在半天之内解决一个之前我曾经想过但是却没想出解决办法的问题。

2020-05
2

改变字典规则不香吗?

By xrspook @ 20:55:44 归类于: 扮IT

改变字典的键值规则就可以把从一本书里挑随机单词这件事轻松搞定,我真搞不懂参考答案为啥要那么折腾。在Think Python 2的第十三章里,字典的默认规则是单词是键,词频是键值。既然这道题要唯一的索引找随机单词,我把键值变成唯一序号不就完事大吉了?再来一个zip把字典的键值和键互换,random.choice()直接就到达随机单词了。我只改了生成字典的规则,耗时0.12秒,参考答案折腾了不只一点点,耗时0.42秒。之所以参考答案不修改字典规则,是因为他们要灌输python拼装模块的特性,拼装很方便,但事实证明效率不一定最高。

This algorithm works, but it is not very efficient; each time you choose a random word, it rebuilds the list, which is as big as the original book. An obvious improvement is to build the list once and then make multiple selections, but the list is still big.

An alternative is: Use keys to get a list of the words in the book. Build a list that contains the cumulative sum of the word frequencies (see Exercise 2). The last item in this list is the total number of words in the book, n. Choose a random number from 1 to n. Use a bisection search (See Exercise 10) to find the index where the random number would be inserted in the cumulative sum. Use the index to find the corresponding word in the word list.

Exercise 7: Write a program that uses this algorithm to choose a random word from the book. Solution: http://thinkpython2.com/code/analyze_book3.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import string
import random
from time import time
def set_book(fin1):
    useless = string.punctuation + string.whitespace + '“' + '”' # 标点符号、换行符全部咔嚓掉
    d = {}
    i = 1
    for line in fin1:
        line = line.replace('-', ' ') # 有-的单词全部一分为二,这样真的好吗?
        for word in line.split():
            word = word.strip(useless)
            word = word.lower()
            if word not in d:
                d[word] = i # 录入字典的时候键值就是序号
                i += 1
            # d[word] = d.get(word, 0) + 1 # 反正我不算词频,这个没必要了
    return d
fin1 = open('emma.txt', encoding='utf-8')
start = time()
book1 = set_book(fin1)
book2 = dict(zip(book1.values(), book1.keys())) # 键和键值互换,序号成了唯一索引号
print('100 random words in book')
for i in range(100):
    if i > 1 and i%8 == 0:
        print()
    print(random.choice(book2), end=' ') # 索引号找词,想多快有多快
print()
end = time()
print(end - start)
# 100 random words in book
# solicit laughing preserve inebriety elton's unimpeded effusions unselfish
# intimate connect native judges charities travel informs colours
# enigmas bragge case greensward cox's particularly unexampled promise
# prone greensward dignity maps fourth christmas creature maximum
# graver mildest pleasant corrected increased named partridge marks
# following kept gloom conjecturing parlour inheriting say consulting
# magnified abundant produces sons malt add unenforceability beautifully
# richly striking confuse greatness asleep steps humility upon
# already paper delight liberties confide appendages undecided male
# prophecies esteem unadorned likelihood shopping deeply unbiased horrors
# man's dumplings business chapter shakespeare sees counsels attentive
# silenced ventured singular double mean waltzes requisite checks
# unattended qualified blessed surmises
# 0.12100672721862793
2020-04
30

字典和递归

By xrspook @ 8:48:32 归类于: 烂日记

还记得在看微软的python入门视频的时候。我第一次接触字典这种东西。我觉得那是相当深奥的一件事,因为我搞不懂,那跟列表有什么区别,有什么牛逼的功能。之所以这样,大概是因为微软的视频里字典的录入他们用的是手动输入,显然我觉得一个一个对应太麻烦了。而且用起来的时候我也没发现有什么特别高的效率。入门终归是入门,你看不到字典的牛逼之处,当然就会对学习这东西没什么兴趣。当我在做Think Python 2习题,而且做得死去活来之后。当我用尽九牛二虎之力才终于用列表的方法以二分法搜索的方式找出某个词,而当我后来学习了字典,轻而易举就能找到某个词,效率差了一大截以后,我才明白到字典的超级牛逼之处。显然对我来说,现在我还不怎么熟悉字典这个东西。因为我只是用到了最基本的功能,还有非常多的东西我还不知道,一些它真正的用法我还没有使用到。比如现在的字典我只是停留在第一层级的程度上,通常的键和键值只是某个字符串。如果键值被换成一堆的列表呢?如果一堆列表里面还有一堆的元组呢?想想都觉得这相当恐怖,如果到达那个境界,我该用什么方法去访问那些东西呢?现在对我来说,那是个未解之谜,因为我还没遇到那种题目。

因为工作的原因,我已经放下python一两天了。这种东西一天不练就会手生,下次再重新开始的时候,大概我已经不记得某些语句该怎么写了,于是又得花一些时间去复习之前学过的东西。

还记得在接触python之前,我已经有听说有字典这种牛逼东西。在C语言里好像有,Excel VBA里好像也有,但是我都从来没有用过。因为我觉得那对我来说是非常遥远的存在。在python的学习过程中,我觉得字典就像吃饭睡觉一样,是基本的核心功能。字符串列表字典和元组就像数学里面的加减乘除。当然我这里列举了关系,并不是一一对应的,而是说明他们都是基本的功能,全部都得熟练运用。

还记得貌似是在学递归的那一章。在总结的时候,我记得那里好像说要我们学会不要在一个点上过分纠结,要有全局思维。其实递归并不需要把一个数值竟放进去,然后不断地按照程序进行不断的套用,应该从大局方面想,完成了这个操作,我应该得到什么答案,得到这个答案以后,我就可以把程序继续下去了。这说得简单,但实际上,有时我真想不到,递归最终我能得到什么答案,所以每次我都只能自己很傻地一遍一遍尝试。有些时候我图快,一下子放进去不是最基础的数字,结果就把我自己搞死了。后来才发现,原来一开始进去的东西就应该用最简单的,那才能最快地得出应该有的答案。直到现在,我还是非常难适应这种思维方式。在我没学习递归之前,我已经见识过了斐波那契数列。当时我是用循环的方法实现,但实际上更直观简单的方法是递归。还记得高中的数学里面也经常要我们把某些东西最终以某些方式表达出来,而当时他们给出的题目真是一些递归的东西。所以可能很早以前我就接触过递归了,但是当时没有学编程,也没有计算机,非常苦逼。

如果在学习的时候,能一边的学习编程一边学数学,大概当年就不会那么痛苦了。

© 2004 - 2021 我的天 | Theme by xrspook | Power by WordPress