2020-04
10

判断a是不是b的幂

By xrspook @ 23:59:43 归类于: 扮IT

Think Python 2第六章的某道原题是这样的:

Exercise 4: A number, a, is a power of b if it is divisible by b and a/b is a power of b. Write a function called is_power that takes parameters a and b and returns True if a is a power of b. Note: you will have to think about the base case.

版本A的中文翻译

练习4:一个数字a为b的权(power),如果a能够被b整除,并且a/b是b的权。写一个叫做is_power 的函数接收a和b作为形式参数,如果a是b的权就返回真。注意:要考虑好基准条件。

版本B的中文翻译

习题6-4:当数字a能被b整除,并且a/b是b的幂时,它就是b的幂。编写一个叫is_power的函数,接受两个参数a和b,并且当a是b的幂时返回True。注意:你必须要想好基础情形。

研究这道题到底在说什么,我纠结了起码1个小时。什么叫做权?幂来幂去,还有“它”,你真的知道那指代的是什么?我相信翻译这本书的人都一定是编程老手,但你们真的有琢磨过中文表述是否恰当吗?幸好我没买人民邮电出版社出版的Think Python 2中文版,貌似从某些页面看来,翻译也会让我非常吐槽。

还是直接看英文原文比较好懂,那段话我会这么翻译:

如果a能被b整除,且a/b是b的幂,那么a是b的幂(例如:2**3=8,即2的3次幂等于8,a=8, b=2)。编写一个名叫is_power的函数,以a和b为形式参数接收数据,如果a是b的幂,返回True。注意:要考虑好基准条件。

研究这道题在说什么研究了好长时间,随便输入几个显而易见的测试数据也挺顺利, 但要把情况想周全貌似很不简单。a == 0的情况有人想到了,但万一作死的写了b == 0呢!测试过好几个网友的编程,b == 0几乎全部挂了…… 我承认,这样测试过分了。

1
2
3
4
5
6
7
8
9
10
11
12
def is_power(a, b):
    if a == 0 or b == 0 or a%b != 0: # a和b的特殊情况先杀死
        return False
    elif a == 1 or a == b: 
        return True
    else:        
        return is_power(a/b, b) # 被除数a为0会死循环,除数b不能为0
a = 4 # int(input('a is '))
b = 2 # int(input('b is '))
print('a =', a)
print('b =', b)
print(is_power(a, b))
2020-04
10

强大到让我瑟瑟发抖的递归

By xrspook @ 8:41:56 归类于: 烂日记

大学学习C语言的时候,基本上我不会写单独的函数,所有要解决的事都在主函数里搞定了。当时我学过判断和循环,但是,我却从来没学过递归。在解决一些简单事情的时候,循环跟递归,没什么差别。从理解程度来说,我觉得循环更简洁一些,但是,当某个东西像套娃那样一层叠一层,每层里面依然用同样的规则继续套叠,不知道要叠多少层的时候。递归就会展现它无穷的魔力。循环难以实现这个,又或者循环并非实现不了,但是递归在完全不需要体现循环的框架下,简洁的语言就已经在做着循环的事情。

昨天,我第一次在Python里见到这个恐怖的递归。外国人的书,我觉得都有一个特点。正文的时候举的例子都很简单,但是一到习题,就会把你彻底搞死。习题里面会偷偷带入一些超纲的东西。大概写书的人理所当然默认你应该知晓。这种事情我已经在学习Java的时候领略过。当时那本书之所以没法看下去,就是因为我没办法想象出作者的脑洞到底是什么。他们的习题几乎可以说大多是一些填空题,但要实现一个功能,其实未必一定就得用某种方法。你给我一个条件,给我一些目标值,我能做出来也就OK了,为啥必须走你的路呢,这非常难。之前我不觉得自己跟外国人的脑洞到底差多远,但是当我对比过自己和他们写的程序以后,我发现真的差挺远的。虽然我们都能实现某个功能,就效率而言,感觉上没差多少,因为我只是在做一些非常初级的东西。应试教育的时候,有标准答案,当然好判定成绩,但实际上,编程这种东西真心应该天马行空。给我一个效率的限制,比如说完成某件事,必须在多长时间之内解决,代码长度不能多于多少,至于我用什么办法,这是我的事。

说回递归函数这件事,在处理几个简单数字的时候,可能你感觉不到它的强大,但是,当我见识过用那个东西画出来的层级图形以后,我简直就只有站在旁边瑟瑟发抖的份儿。真的不知道是哪个神经质想出来这么强大的东西。但实际上,深究下去,那也不是很强大,那不过是不断地重复一些已经设计好的事情而已。如果要人去做那些重复,一开始还好,但是随着事情的深入,会慢慢乱套,但是计算机不会,他们会一根筋地执行我们的指令。最终出来的结果是令人惊叹的优雅,还是乱七八糟一坨屎:就得看设定规律的人的功力了。

递归现在对我来说是一个非常恐怖的东西。因为我不了解它,所以我害怕它,就像当年认识循环一样。但是,用好递归以后,我的武器库里就会增加一个杀伤性非常大的家伙。说到递归,让我联想起新冠病毒。这个东西的递归到底什么时候才是个头?我觉得这肯定不是一个死循环,自然界非常擅长递归,处处都是数学和逻辑你知道吗?!但是,到底要递归多少次,全人类才最终能看到隧道尽头的曙光呢?到底这个新冠病毒函数的递归里埋伏了多少个随机数呢?学习递归让我明白到,层级少好对付,层级一旦扩增,那就是次数级的增长,而且,说不准到达一定层级的以后就会触发某些大招炸弹,想想都心寒。

编程是一个让我重新理解自然规律的过程。

2020-04
9

转换时间戳

By xrspook @ 15:18:47 归类于: 扮IT

脑袋实在转不过来,不知道怎么把1W多天转化为月份,长短月怎么处理?????所以直接暴力地使用本来就内置的time.localtime()以及time.strftime()格式化当前时间。我完全可以把逝去的时间也这么整,但逝去时间我是有认真人肉计算过的,所以同一个时间戳,用了两种方式转化。

经过这个以后,我完全明白点点导出数据里那一串标记着的数字是什么鬼,也不能说他们这样不好,因为转化为实在人肉可读的时间格式以后万一要用其它表达方式呢?一开始就用最原始的东西,前端表达用内置的函数格式化也就可以了。所以,大概看懂的人会会心微笑,看不懂的人会骂街。作为理论上应该可读的XML文件,他们这般“原始输出”实在够姜!

1
2
3
4
5
6
7
8
9
10
11
12
13
import time
def now(num):
    mytime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(num))
    return(str(mytime))
num = int(time.time())
sec = num % 60
min = (num // 60) % 60
hour = (num // (60 * 60)) % 24 + 8 # 万恶的东八区!!!!!!!!!!
day = num // (60 * 60 * 24)
print('Time is', now(num))
print('since the epoch, ' + str(day) + ' days ' + str(hour) + ' hours ' + str(min) + ' minutes ' + str(sec) + ' seconds has gone')
# Time is 2020-04-09 15:03:41
# since the epoch, 18361 days 15 hours 3 minutes 41 seconds has gone

2020-04
9

还有更低

By xrspook @ 9:15:57 归类于: 烂日记

我一直都觉得自己是个选择困难症患者。很多时候,我都不知道自己喜不喜欢,有时,第一感觉都喜欢,但是你要我挑哪个最喜欢,我说不上。但是如果你必须要我挑选其中一个,我又发现原来很多我都不喜欢。这种感觉我不知道别人有没有,这种事经常发生在我身上。所以很多时候,我不是用喜不喜欢这个标准去挑选东西,而是用划不划算。价格是不是很低?质量是不是还可以?在买大件商品的时候,我非常看重性价比,但是买一些无关紧要的小东西的时候,我非常在乎价格。当然了,买大件东西的时候。我也很在乎口碑,当我知道一个品牌毋庸置疑是最好的时候,我不会考虑它的性价比是不是跟其它有差别。买小件东西的时候,我会非常在意能不能选到一个超低的价格。

比如说近段时间我在淘宝特价版上买了两条数据线,是分开买的,1.2米的type-c数据线,据说,能过3A的电流。我没试过,但是其中一条线,我用来在小米4c上充过电,的确是快充的,充电过程正常。现没有什么意外发生,传输文件也没有问题。那是两条软硅胶线。这两条线买的时候,我都各自用了一个红包,而这条线本身就很便宜,所以每条线才一块多。要知道小米1.2米扁的type-c线要16块多。好像这个还是特价才有的价格。如果是绿联的type-c线,一米的就要14块钱,而且这还是最便宜的那种。我不知道为什么我会那么大胆买一条便宜得让人觉得匪夷所思的USB线。我不知道线材如何,如果我够狠的话我应该剪开其中一条,看看里面什么状况。那是一条软硅胶线,跟其他线比起来柔软很多。不知道买第几个耳塞的时候,我遇到过这样的充电线。一开始我还怀疑过它们的质量,但是用过一段时间以后我觉得还行。我实在搞不懂,为什么一条数据线居然可以卖这么便宜,他们是靠什么赚钱的?而且,一块多一点的价格还是包邮的,虽然那个邮件不过是从深圳寄过来而已。我自己也寄过邮件,现在的邮费要比从前贵好多。所以这一块多还包邮的数据线他们是什么靠这个经营活下去的呢?我不只是买过一块多的数据线,我还买过5毛钱的硅胶杯垫,同样也是包邮的,而且那个还远一点,好像是从义乌寄过来的。不知道从什么时候开始,我就迷上了淘宝特价版这个东西,在淘宝上买的东西都可以在那里买。区别在于那里每天你都可以收到一个红包,以前的大一点,接近一块钱一个,大红包那天,那个红包甚至会接近两块钱。现在这些红包都打折了,大红包就只有一块钱多一点。领略过非特价活动的淘宝的人都会明白,即便很多东西上面能用淘金币,但实际上那些红包要凑一块多几乎是不可能的。淘宝特价版可以用微信上的优惠券。唯一的缺陷是链接贴回微信无法跟踪返现。特价版开到的红包已经比返现的那个数大很多,又何必那么折腾呢?

从前我觉得十几块钱买到包邮的东西很划算,后来我买过几块钱的,现在我甚至买过几毛钱的。而且这些东西还不是兑换,是真正的货品,是可以重复出现的。这个世界发生的事,我越来越不知道该如何解释了。

2020-04
8

螺旋线

By xrspook @ 20:29:37 归类于: 扮IT

人家要我去学阿基米德螺旋线,但显然我是数学渣,根本领会到不到那些精神,转换不过来,就不要装着能转换。既然习题5说“或者其他种类的螺线”于是我就选择了在我理解范围内的斐波那契螺旋线,也就是黄金螺旋线。人家要我画螺旋线,我觉得要把方框也画出来才容易验证我自己有没有搞错。

为了完成方形和圆弧的两个循环,我笨蛋地把斐波那契数列算了两次……

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
45
46
47
48
49
50
51
52
import turtle, math
def arc(t, r, angle):
    n = 20 # int(2*math.pi*r/4)+3 公式画图太细致太慢,直接赋值加速
    step_length = int(2*math.pi*r)*angle/360/n
    step_angle = angle/n
    t.lt(step_angle/2) # 据说折腾一下角度能消除像素误差?
    polygon(t, step_length, n, step_angle)
    t.rt(step_angle/2)
def polygon(t, length, n, angle):
    for i in range(n):
        t.fd(length)
        t.lt(angle)
def start(t): # 起点要先偏移一些,每次方向保持一致
    t.pu()
    t.home()
    t.goto(160,-110)
def square(t, size): # 第一个正方形
    for i in range(4):
        t.lt(90)
        t.fd(size)                
    t.rt(90)
def boxes(t, n, size): # n-1个正方形
    a = b = 1
    base = size
    for i in range(n-1):
        for i in range(6):
            t.lt(90)
            t.fd(size)
        t.rt(90)
        fibo = a+b # 计算斐波那契数列
        a = b
        b = fibo
        size = base*fibo
def spiral(t, n, size): # 第一个正方形里没有弧线,所以弧线也是n-1
    a = b = 1
    base = size
    for i in range(n-1):
        arc(t, size, 90)        
        fibo = a+b # 在算一次斐波那契数列
        a = b
        b = fibo
        size = base*fibo
bob = turtle.Turtle()
bob.pensize(2) # 笔迹粗点好看些
n = 8
size = 20
start(bob)
square(bob, size)
boxes(bob, n, size)
start(bob)
spiral(bob, n, size)
turtle.mainloop()
© 2004 - 2026 我的天 | Theme by xrspook | Power by WordPress