笑喷了!电视剧里的代码真能运行吗?

最近有一部关于程序员的电视剧,里边有一段关于期中考试要用程序画一个爱心的桥段。仔细看了一下,发现槽点还不少。

今天就给大家分析下剧中出现的“爱心”代码,并且来复刻一下最后男主完成的酷炫跳动爱心。

剧中代码赏析

1. 首先是路人同学的代码:

虽然剧中说是“C语言期中考试”,但这位同学的代码名叫 draw2.py,一个典型的 Python 文件,再结合截图中的 pen.forward、pen.setpos 等方法来看,应该是用 turtle 海龟作图库来画爱心。那效果通常是这样的:

import turtle as tt.color('red')t.setheading(50)t.begin_fill()t.circle(-100, 170)t.circle(-300, 40)t.right(38)t.circle(-300, 40)t.circle(-100, 170)t.end_fill()t.done()

而不是剧中那个命令行下用1组成的不规则的图形。

2. 然后是课代表向路人同学展示的优秀代码:

及所谓的效果:

这确实是C语言代码了,但文件依然是以 .py 为后缀,并且 include 前面没有加上 #,这显然是没法运行的。

里面的内容是可以画出爱心的,用是这个爱心曲线公式:

然后遍历一个15*17的方阵,计算每个坐标是在曲线内还是曲线外,在内部就输出#或*,外部就是-

用python改写一下是这样的:

for y in range(9, -6, -1):    for x in range(-8, 9):        print('*##*'[(x+10)%4] if (x*x+y*y-25)**3 < 25*x*x*y*y*y else '-', end=' ')    print()

效果:

稍微改一下输出,还能做出前面那个全是1的效果:

for y in range(9, -6, -1):    for x in range(-8, 9):        print('1' if (x*x+y*y-25)**3 < 25*x*x*y*y*y else ' ', end=' ')    print()

但跟剧中所谓的效果相去甚远。

3. 最后是主角狂拽酷炫D炸天的跳动爱心:

代码有两个片段:

但这两个片段也不C语言,而是C++,且两段并不是同一个程序,用的方法也完全不一样。

第一段代码跟前面一种思路差不多,只不过没有直接用一条曲线,而是上半部用两个圆形,下半部用两条直线,围出一个爱心。

改写成 Python 代码:

size = 10for x in range(size):    for y in range(4*size+1):        dist1 = ((x-size)**2 + (y-size)**2) ** 0.5        dist2 = ((x-size)**2 + (y-3*size)**2) ** 0.5        if dist1 < size + 0.5 or dist2 < size + 0.5:            print('V', end=' ')        else:            print(' ', end=' ')    print()
for x in range(1, 2*size):    for y in range(x):        print(' ', end=' ')    for y in range(4*size+1-2*x):        print('V', end=' ')    print()

运行效果:

第二段代码用的是基于极坐标的爱心曲线,是遍历角度来计算点的位置。公式是:

计算出不同角度对应的点坐标,然后把它们连起来,就是一个爱心。

from math import pi, sin, cosimport matplotlib.pyplot as pltno_pieces = 100dt = 2*pi/no_piecest = 0vx = []vy = []while t <= 2*pi:    vx.append(16*sin(t)**3)    vy.append(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))    t += dtplt.plot(vx, vy)plt.show()

效果:

代码中循环时用到的2π是为了保证曲线长度足够绕一个圈,但其实长一点也无所谓,即使 π=100 也不影响显示效果,只是相当于同一条曲线画了很多遍。所以剧中代码里写下35位小数的π,还被女主用纸笔一字不落地抄写下来,实在是让程序员无法理解的迷惑行为。

但不管写再多位的π,上述两段代码都和最终那个跳动的效果差了五百只羊了个羊。

跳动爱心实现

作为一个总是在写一些没什么乱用的代码的编程博主,当然也不会放过这个机会,下面就来挑战一下用 Python 实现最终的那个效果。

1. 想要绘制动态的效果,必定要借助一些库的帮助,不然代码量肯定会让你感动得想哭。这里我们将使用 gzero库。然后结合最后那个极坐标爱心曲线代码,先绘制出曲线上离散的点。

import pgzrunfrom math import pi, sin, cos
no_p = 100dt = 2*3/no_pt = 0x = []y = []while t <= 2*3:    x.append(16*sin(t)**3)    y.append(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))    t += dt
def draw():    screen.clear()    for i in range(len(x)):        screen.draw.filled_rect(Rect((x[i]*10+400, -y[i]*10+300), (4, 4)), 'pink')
pgzrun.go()

2. 把点的数量增加,同时沿着原点到每个点的径向加一个随机数,并且这个随机数是按照正态分布来的(半个正态分布),大概率分布在曲线上,向曲线内部递减。这样,就得到这样一个随机分布的爱心效果。

...no_p = 20000...while t <= 2*pi:    l = 10 - abs(random.gauss(10, 2) - 10)    x.append(l*16*sin(t)**3)    y.append(l*(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)))    t += dt...

3. 下面就是让点动起来,这步是关键,也有一点点复杂。为了方便对于每个点进行控制,这里将每个点自定义成了一个Particle类的实例。

从原理上来说,就是给每个点加一个缩放系数,这个系数是根据时间变化的正弦函数,看起来就会像呼吸的节律一样。

class Particle():    def __init__(self, pos, size, f):        self.pos = pos        self.pos0 = pos        self.size = size        self.f = f
    def draw(self):        screen.draw.filled_rect(Rect((10*self.f*self.pos[0] + 400, -10*self.f*self.pos[1] + 300), self.size), 'hot pink')
    def update(self, t):        df = 1 + (2 - 1.5) * sin(t * 3) / 8        self.pos = self.pos0[0] * df, self.pos0[1] * df
...
t = 0def draw():    screen.clear()    for p in particles:        p.draw()
def update(dt):    global t    t += dt    for p in particles:        p.update(t)

4. 剧中爱心跳动时,靠中间的点波动的幅度更大,有一种扩张的效果。所以再根据每个点距离原点的远近,再加上一个系数,离得越近,系数越大。

class Particle():    ...    def update(self, t):        df = 1 + (2 - 1.5 * self.f) * sin(t * 3) / 8        self.pos = self.pos0[0] * df, self.pos0[1] * df

5. 最后再用同样的方法画一个更大一点的爱心,这个爱心不需要跳动,只要每一帧随机绘制就可以了。

def draw():    ...    t = 0    while t < 2*pi:        f = random.gauss(1.1, 0.1)        x = 16*sin(t)**3        y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)        size = (random.uniform(0.5,2.5), random.uniform(0.5,2.5))        screen.draw.filled_rect(Rect((10*f*x + 400, -10*f*y + 300), size), 'hot pink')        t += dt * 3

合在一起,搞定!

总结一下,就是在原本的基础爱心曲线上加上一个正态分布的随机量、一个随时间变化的正弦函数和一个跟距离成反比的系数,外面再套一层更大的随机爱心,就得到类似剧中的跳动爱心效果。

但话说回来,真有人会在考场上这么干吗?

除非真的是超级大学霸,不然就是食堂伙食太好--

最后免费分享给大家一份Python全套学习资料,包含视频、源码,课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。在这里插入图片描述

二、Python必备开发工具

在这里插入图片描述

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 在这里插入图片描述在这里插入图片描述

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 在这里插入图片描述

五、Python练习题

检查学习结果。 在这里插入图片描述

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 在这里插入图片描述在这里插入图片描述

 

因篇幅有限,仅展示部分资料,需要的同学用vx扫描上方二维码即可获取‘

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值