郑金贤 發表於 2022-1-30 12:29:00

Python写春联(turtle版)

<section id="nice" data-tool="mdnice编辑器" data-website="https://www.mdnice.com">
<p data-tool="mdnice编辑器">Python就好比编程界的瑞士军刀,开箱即用、无所不能。这得益于Python简洁易用的语法,以及丰富的第三方库,你想在电脑上做什么,总能找到事半功倍的第三方库。比如,在这新春佳节之际,用Python来写个春联能做到吗?用Python自带的<code>turtle</code>库便可以实现。</p>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://gitee.com/wansq0211/markdownImg/raw/master/img/20220128113044.gif" alt="turtle写春联">
<figcaption>turtle写春联</figcaption>
</figure>
<h2 data-tool="mdnice编辑器"><span class="content">一、turtle库简介</span></h2>
<p data-tool="mdnice编辑器"><code>turtle</code>中的绘图是控制一只“小海龟”来实现的,海龟移动的路径便能形成图形。这种程序绘图的方式具有很强的可计算性,也涉及到许多数学几何知识。</p>
<blockquote class="multiquote-1" data-tool="mdnice编辑器">
<p><code>turtle</code>的海龟绘图很适合用来引导孩子学习编程。 最初来自于 Wally Feurzeig, Seymour Papert 和 Cynthia Solomon 于 1967 年所创造的 Logo 编程语言。</p>
</blockquote>
<h2 data-tool="mdnice编辑器"><span class="content">二、画春联背景</span></h2>
<p data-tool="mdnice编辑器">春联背景的绘制比较简单,由于上下联、横批都是矩形,且颜色都是一致的。为了便于代码的复用,可以定义可以一个画背景的函数。如下所示:</p>
<pre class="custom" data-tool="mdnice编辑器"><code>def&nbsp;drawChunLianBg(startX=0,&nbsp;startY=0,&nbsp;lenX=100,&nbsp;lenY=100):
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;设置边框色和背景填充色
&nbsp;&nbsp;&nbsp;&nbsp;color('Yellow',&nbsp;'OrangeRed')
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;抬笔,定位起点
&nbsp;&nbsp;&nbsp;&nbsp;pu()
&nbsp;&nbsp;&nbsp;&nbsp;goto(startX,&nbsp;startY)
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;落笔,绘制春联矩形框,并填充颜色
&nbsp;&nbsp;&nbsp;&nbsp;pd()
&nbsp;&nbsp;&nbsp;&nbsp;begin_fill()
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;i&nbsp;in&nbsp;range(2):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fd(lenX)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rt(90)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fd(lenY)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rt(90)
&nbsp;&nbsp;&nbsp;&nbsp;end_fill()
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;结束后抬笔
&nbsp;&nbsp;&nbsp;&nbsp;pu()
</code></pre>
<h2 data-tool="mdnice编辑器"><span class="content">三、写字</span></h2>
<h3 data-tool="mdnice编辑器"><span class="content">方法一:<code>write()</code>函数直接写字</span></h3>
<p data-tool="mdnice编辑器">关于写字,<code>turtle</code>提供了一个<code>write()</code>函数。</p>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://gitee.com/wansq0211/markdownImg/raw/master/img/20220128224735.gif" alt="使用write()函数打印文字效果">
<figcaption>使用write()函数打印文字效果</figcaption>
</figure>
<p data-tool="mdnice编辑器">优点:可以自定义汉字字体,写出漂亮的字体!</p>
<p data-tool="mdnice编辑器">缺点:无法呈现书写字的动态效果。</p>
<pre class="custom" data-tool="mdnice编辑器"><code>turtle.write(arg,&nbsp;move=False,&nbsp;align='left',&nbsp;font=('Arial',&nbsp;8,&nbsp;'normal'))
</code></pre>
<ul data-tool="mdnice编辑器">
<li>
<section>
<p>arg -- 要书写到 TurtleScreen 的对象</p>
</section>
</li>
<li>
<section>
<p>move -- True/False。 move 为真值,画笔会移至文本的右下角</p>
</section>
</li>
<li>
<section>
<p>align -- 字符串 "left", "center" 或 "right"。写到当前海龟位置。</p>
</section>
</li>
<li>
<section>
<p>font -- 一个三元组 (fontname, fontsize, fonttype)</p>
</section>
</li>
</ul>
<p data-tool="mdnice编辑器">以下是实现关键代码:</p>
<pre class="custom" data-tool="mdnice编辑器"><code>def&nbsp;writeWord(target_word,&nbsp;startx,&nbsp;starty):
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;基于坐标,打印单个汉字
&nbsp;&nbsp;&nbsp;&nbsp;color("black",&nbsp;"black")
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;抬笔定位
&nbsp;&nbsp;&nbsp;&nbsp;pu()
&nbsp;&nbsp;&nbsp;&nbsp;goto(startx,starty)
&nbsp;&nbsp;&nbsp;&nbsp;pd()
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;基于字体,打印汉字
&nbsp;&nbsp;&nbsp;&nbsp;write(target_word,&nbsp;move=False,align='left',font=('汉仪程行简',24,&nbsp;'normal'))

def&nbsp;writeWords(target_words,&nbsp;startx,&nbsp;starty,lineNum=1):
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;打印多个汉字,lineNum控制每行的汉字数,默认为1
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;向右、向下的偏移量
&nbsp;&nbsp;&nbsp;&nbsp;right_shift&nbsp;=&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;down_shift&nbsp;=&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;遍历打印汉字
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;word&nbsp;in&nbsp;target_words:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeWord(word,&nbsp;startx+right_shift*45,&nbsp;starty-down_shift*45)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right_shift&nbsp;+=&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;判断是否要换行
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;right_shift&nbsp;%&nbsp;lineNum&nbsp;==&nbsp;0:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;down_shift&nbsp;+=&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right_shift&nbsp;=&nbsp;0
</code></pre>
<p data-tool="mdnice编辑器">在<code>main()</code>函数里直接调用<code>drawChunLianBg</code>和<code>writeWords()</code>就可以画出春联和写字啦。</p>
<pre class="custom" data-tool="mdnice编辑器"><code>def&nbsp;main():
&nbsp;&nbsp;&nbsp;&nbsp;initScreen()
&nbsp;&nbsp;&nbsp;&nbsp;drawChunLianBg(-160,&nbsp;215,&nbsp;60,&nbsp;500)
&nbsp;&nbsp;&nbsp;&nbsp;writeWords(target_words="一往无前&nbsp;奔赴星辰大海",&nbsp;startx=-145,&nbsp;starty=175)
&nbsp;&nbsp;&nbsp;&nbsp;drawChunLianBg(90,&nbsp;215,&nbsp;60,&nbsp;500)
&nbsp;&nbsp;&nbsp;&nbsp;writeWords(target_words="保持热爱&nbsp;静待春暖花开",&nbsp;startx=105,&nbsp;starty=175)
&nbsp;&nbsp;&nbsp;&nbsp;drawChunLianBg(-110,&nbsp;280,&nbsp;210,&nbsp;60)
&nbsp;&nbsp;&nbsp;&nbsp;writeWords(target_words="虎虎生威",&nbsp;startx=-90,&nbsp;starty=230,lineNum=4)
&nbsp;&nbsp;&nbsp;&nbsp;pu()
&nbsp;&nbsp;&nbsp;&nbsp;goto(0,&nbsp;0)
&nbsp;&nbsp;&nbsp;&nbsp;done()
</code></pre>
<h3 data-tool="mdnice编辑器"><span class="content">方法二:利用坐标“画”汉字</span></h3>
<p data-tool="mdnice编辑器">如果要实现本文一开始的书写效果,思路便是要<strong>将汉字当作图形画出来</strong>。即需要知道每个汉字笔画中的关键坐标,让海龟根据坐标来移动,画出汉字。比如“万”这个字,我们可以这样来绘制:</p>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://gitee.com/wansq0211/markdownImg/raw/master/img/20220129200808.gif" alt="坐标画“万”字原理">
<figcaption>坐标画“万”字原理</figcaption>
</figure>
<p data-tool="mdnice编辑器">也就是说,坐标越多,画出的汉字效果会越好。但可以想象这是一个非常繁琐、耗时的工作。本想放弃的我,在知乎发现了一位大神也做过类似的尝试,并且是利用Python爬虫实现了从网上获取中文字体笔画坐标。在本人感叹其精妙的代码后,本着没有必要重复造轮子的想法,本人最终决定copy核心代码试一试,没想到竟然成功了!</p>
<p data-tool="mdnice编辑器">基本原理是这样的</p>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://gitee.com/wansq0211/markdownImg/raw/master/img/20220129202840.png" alt="爬虫+turtle画字">
<figcaption>爬虫+turtle画字</figcaption>
</figure>
<p data-tool="mdnice编辑器">关键代码:</p>
<pre class="custom" data-tool="mdnice编辑器"><code>def&nbsp;drawWords(target_words,&nbsp;startx,&nbsp;starty,&nbsp;lineNum=1):
&nbsp;&nbsp;&nbsp;&nbsp;params&nbsp;=&nbsp;(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;('font',&nbsp;gen_url_encode_words(target_words)),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;('shi_fou_zi_dong',&nbsp;'0'),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;('cache_sjs1',&nbsp;'20031908'),
&nbsp;&nbsp;&nbsp;&nbsp;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;发起网页请求
&nbsp;&nbsp;&nbsp;&nbsp;response&nbsp;=&nbsp;requests.get('https://bihua.51240.com/web_system/51240_com_www/system/file/bihua/get_0/',
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;headers=headers,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params=dict(params)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)

&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;response.content.decode('utf-8')
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;解析每个字的笔画坐标
&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;content.replace(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'hzbh.main(',&nbsp;'').split(');document.getElementById')
&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;content.split('{')[-1].split("}")
&nbsp;&nbsp;&nbsp;&nbsp;pattern&nbsp;=&nbsp;re.compile(r'\w:\[(.+?)\]')
&nbsp;&nbsp;&nbsp;&nbsp;result1&nbsp;=&nbsp;re.split(pattern,&nbsp;content)
&nbsp;&nbsp;&nbsp;&nbsp;words_order_list&nbsp;=&nbsp;{}
&nbsp;&nbsp;&nbsp;&nbsp;words_cnt&nbsp;=&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;r&nbsp;in&nbsp;result1:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sec&nbsp;=&nbsp;re.findall(r'\'.+?\'',&nbsp;r)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;len(sec):
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orders&nbsp;=&nbsp;sec.split('#')
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;order_xy_routine&nbsp;=&nbsp;[]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;order&nbsp;in&nbsp;orders:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;order_str&nbsp;=&nbsp;re.findall(r'\(\d+,\d+\)',&nbsp;order)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;order_xy&nbsp;=&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;order_xy_routine.append(order_xy)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;words_order_list['{}_{}'.format(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;words_cnt,&nbsp;target_words)]&nbsp;=&nbsp;order_xy_routine
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;words_cnt&nbsp;+=&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;setting()&nbsp;&nbsp;#&nbsp;画布、画笔设置
&nbsp;&nbsp;&nbsp;&nbsp;right_shift&nbsp;=&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;down_shift&nbsp;=&nbsp;0
&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;k,&nbsp;v&nbsp;in&nbsp;words_order_list.items():
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;lines&nbsp;in&nbsp;v:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pu()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;xy&nbsp;in&nbsp;lines:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x,&nbsp;y&nbsp;=&nbsp;xy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x,&nbsp;y&nbsp;=&nbsp;x&nbsp;*&nbsp;0.05&nbsp;+&nbsp;startx&nbsp;+&nbsp;right_shift&nbsp;*&nbsp;50,&nbsp;-y&nbsp;*&nbsp;0.05&nbsp;+&nbsp;starty&nbsp;-&nbsp;down_shift&nbsp;*&nbsp;50
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(x,&nbsp;y)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto(x,&nbsp;y)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pd()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right_shift&nbsp;+=&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;right_shift&nbsp;%&nbsp;lineNum&nbsp;==&nbsp;0:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;down_shift&nbsp;+=&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right_shift&nbsp;=&nbsp;0
</code></pre>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://gitee.com/wansq0211/markdownImg/raw/master/img/20220129202953.gif" alt="turtle写春联">
<figcaption>turtle写春联</figcaption>
</figure>
<h3 data-tool="mdnice编辑器"><span class="content">写字与画字</span></h3>
<p data-tool="mdnice编辑器">利用<code>write()</code>写字注重生成的结果,效果更好;而利用坐标“画”字注重过程,是<code>爬虫技术</code>与<code>海龟画图</code>的完美合作,更有意思,让人不禁再次感叹Python的NB,每每这时总会想起那句至理名言——“人生苦短,我用Python!”</p>
<h2 data-tool="mdnice编辑器"><span class="content">写在最后</span></h2>
<p data-tool="mdnice编辑器">本文是围绕<code>turtle</code>库来构思写春联这件事的,其实用Python写春联远不止这一种方式。比如下面这副春联也是利用Python写的,简直太酷了。</p>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://img2022.cnblogs.com/blog/2289975/202201/2289975-20220130122011708-73620859.jpg" alt="" width="800" height="218">
<p><img style="display: block; margin-left: auto; margin-right: auto" src="https://img2022.cnblogs.com/blog/2289975/202201/2289975-20220130121954910-295305700.jpg" alt="" width="800" height="218"></p>
<p id="1643516022925"></p>
<figcaption>图片库生成的春联</figcaption>
</figure>
<p data-tool="mdnice编辑器">立个小小的flag,明年就来写这样的春联吧。(望不打脸😂)</p>
<p data-tool="mdnice编辑器">最重要的话留在最后,祝大家虎年万事顺遂,保持热爱,奔赴星海!</p>
<figure style="text-align: center" data-tool="mdnice编辑器"><img style="display: block; margin-left: auto; margin-right: auto" src="https://gitee.com/wansq0211/markdownImg/raw/master/img/20220130121036.png" alt="字节杂谈">
<figcaption>字节杂谈</figcaption>
</figure>
<p style="text-align: center" data-tool="mdnice编辑器">关注公众号,回复“<strong>春联</strong>”,即可<strong>获取源代码</strong>!</p>
</section><br><br>
来源:https://www.cnblogs.com/wansq/p/15856639.html
頁: [1]
查看完整版本: Python写春联(turtle版)