笑哭了!电视剧里的代码真能运行吗?
我是柠檬哥,专注编程知识分享。
欢迎关注@程序员柠檬橙,编程路上不迷路
私信发送 1024 打包下载10个G编程资源学习资料
私信发送 001 获取阿里大神LeetCode 刷题笔记
私信发送 002 获取获取谷歌公司编程代码规范
私信发送 003 获取10个精美简历模板PDF和Word版
私信发送 004 获取100道精选 C++ 面试题和答案word版
私信发送 005 获取获取谷歌LeetCode算法笔记
最近有一部关于程序员的电视剧,里边有一段关于期中考试要用程序画一个爱心的桥段。仔细看了一下,发现槽点还不少。
今天就给大家分析下剧中出现的"爱心"代码,并且来复刻一下最后男主完成的酷炫跳动爱心。
剧中代码赏析
1. 首先是路人同学的代码:
虽然剧中说是"C 语言期中考试",但这位同学的代码名叫 draw2.py,一个典型的 Python 文件,再结合截图中的 pen.forward、pen.setpos 等方法来看,应该是用 turtle 海龟作图库来画爱心。那效果通常是这样的:
import turtle as t
t.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 = 10
for 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, cos
import matplotlib.pyplot as plt
no_pieces = 100
dt = 2*pi/no_pieces
t = 0
vx = []
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 += dt
plt.plot(vx, vy)
plt.show()
效果:
代码中循环时用到的 2π 是为了保证曲线长度足够绕一个圈,但其实长一点也无所谓,即使 π=100 也不影响显示效果,只是相当于同一条曲线画了很多遍。所以剧中代码里写下 35 位小数的 π,还被女主用纸笔一字不落地抄写下来,实在是让程序员无法理解的迷惑行为。
但不管写再多位的 π,上述两段代码都和最终那个跳动的效果差了五百只羊了个羊。
跳动爱心实现
下面就来挑战一下用 Python 实现最终的那个跳动爱心的效果。
1. 想要绘制动态的效果,必定要借助一些库的帮助,不然代码量肯定会让你感动得想哭。这里我们将使用 pgzero 库。然后结合最后那个极坐标爱心曲线代码,先绘制出曲线上离散的点。
import pgzrun
from math import pi, sin, cos
no_p = 100
dt = 2*3/no_p
t = 0
x = []
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 = 0
def 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
合在一起,搞定!
总结一下,就是在原本的基础爱心曲线上加上一个正态分布的随机量、一个随时间变化的正弦函数和一个跟距离成反比的系数,外面再套一层更大的随机爱心,就得到类似剧中的跳动爱心效果。
但话说回来,真有人会在考场上这么干吗?
除非真的是超级大学霸,不然就是食堂伙食太好,吃太饱撑的……
如何拥抱星星的孩子自闭症的儿童护理要点如何拥抱星星的孩子自闭症的儿童护理要点儿童自闭症也叫孤独症,属于广泛性发育障碍疾病,男童患病率要高于女童,发病时患者处于婴幼儿期。患儿在患有自闭症后会伴有精神发育迟滞的症状,部分患
服用呕吐怎么办?吃多了怎么办?今天回答粉丝问题儿童感服用奥司他韦呕吐怎么办?吃多了怎么办?关于奥司他韦。答粉丝问在后台收到很多粉丝在问服用奥司他韦时遇到的一些情况要如何处理?我就挑一些比较有代表性的回答一下。第一,孩子不愿意喝药怎么
为你喝彩治疗儿童癌症之王,这项检查至关重要!神经母细胞瘤,是目前威胁儿童生命的主要肿瘤之一,但由于这种肿瘤恶性程度较高进展快,很容易早期转移到其他器官,所以一旦确诊几乎就是晚期,一度被人们称为儿童癌王。这种疾病往往要根据不同
那些让你感到孩子长大的瞬间数日来阴雨绵绵,潮湿,这是广东最著名的回南天。来到小区对面的小咖啡馆,老板非常用心的在每张桌上插了鲜花。看见这些美丽的花儿,心中立刻敞亮起来,也有了灵感。赶快记录孩子的成长。最近孩
如果你正担负着家庭教育的责任,不妨关注小美,直播间为你家庭教育,需要自我成长。传统的家庭,很多都是男主外女主内。妈妈在家庭教育中,付出的相对更多一些。男人事业有成当然很令人钦佩。其实育儿成才的妈妈,一点儿都不比爸爸逊色。培养一个孩子,
每个人都是自己生活的烹饪师!用这组插画开启你的全新一周吧生活的甜酸苦辣,我们每天都在品尝。每个人都是自己生活的烹饪师,想要那香甜的味道,记得收好这个配方加一点包容豁达,少一点攀比焦虑。把欲望的火调得小小的,将善良的底料加得足足的,最后记
探访龙潭坪走进白竹坪绿野仙居位于武陵山脉北麓桑植县龙潭坪镇的白竹坪村,是一个有着桑植小桂林之称的人间秘境。历经岁月的六县联合政府旧址,为这里刻上了红色文化的印记错落有序的丘陵群峰,在云雾的掩映下见证着一代又一
追光丨海陆空!体育和自贸港更配哟刚结束的博鳌亚洲论坛让亚洲和世界的目光再次聚焦海南这座美丽的宝岛提起海南你还会想起什么?自贸港碧海黄沙蓝天而所有这些都跟体育息息相关在博鳌论坛前举办的中国(海南)体育用品和装备进口
萌娃上街卖报志愿服务在行动3月是学雷锋月。31日上午,海峡教育报联合石狮市快乐贝林幼儿园开展了一场别开生面的我是卖报小行家公益志愿服务活动。卖报啦卖报啦,叔叔阿姨们要买报纸吗?我们会把挣到的钱拿来献爱心。在
因姑姑无权签字,两岁幼儿急性肠炎转肠梗阻,延误抢救高烧身亡对于很多家长来说,有了孩子意味着失去自由。不仅不能像谈恋爱时那样快乐地度过二人世界,而照顾孩子的琐碎生活也重重压在了肩膀上。河北高阳县的小冯一家便是这样。自打有了孩子,平常酷爱旅游
自律与不自律的孩子,10年后怎么样了?父母再忙也应该看看在这个内卷的时代,人才辈出。为了让孩子更优秀,我们从小把他们被送进各种补习班兴趣班学校为了学生考试取得好成绩,被迫多布置家庭作业,搞题海战术。孩子被学校老师父母鞭策着前行,一直以来