一段奇葩的1024代码

news2024/11/26 14:48:06

入门教程、案例源码、学习资料、读者群

请访问: python666.cn

大家好,欢迎来到 Crossin的编程教室 !

10月24号那天,也就是传说中的1024程序员节,我翻开日历的时候,看到一段代码:

13b5f3708ff2596fe19099da1be76e92.jpeg

说实话,我一下子还真没看出这段代码是在干啥。

不过很明显是一段js代码,于是我就拍照、识别、修正后,放到浏览器的控制台里运行了一下:

76a12a4e0590d5e8fbd948a2272555eb.png

原来是输出1024四个字符画。

出于好奇,我仔细研究了一番,算是弄清楚这代码是怎么画出字符来的。

为了便于理解,我转了一份python版。你们要不先试试看,能看明白吗?

71862456edb05ce9777e5b0dbbfbe995.png

接下来我就逐行解读一下,讲透里面的每一个知识点。

Python代码和原版js代码原理是一样的,只是语法和调用的函数不同。

代码最后一行是整个程序核心代码的入口:

list(map(R,map(int, str(1<<10))))

这行代码,可以分解成几步来看:

>>> 1 << 10
1024

这是一个向左移位的运算位,左移1位,就相当于乘以2,1左移10位,就是1乘以2的10次方,也就是大家熟悉的 1024。

>>> str(1<<10)
'1024'

然后转成字符串。

>>> list(map(int, str(1<<10)))
[1, 0, 2, 4]

map函数是用指定函数对一个序列做映射,得到一个新的序列。

比如这里映射函数是int,序列是字符串,那就是把字符串里每个字符单独转成整数,组成新的序列。

python3里map的返回值是一个迭代器,想查看的需要遍历或转成列表。 

代码这里没有转,因为map的外面还有一层map,外层map的映射函数就是整个代码的主体:函数R

于是就很容易看出这行代码做的事情了:就是把 1 0 2 4 四个数字,分别作为参数来调用函数R。

拿其中一个数字来测试就会发现,函数R所做的事情就是绘制出参数对应的字符画:

b058f55196626bed3402f0800f8295d7.png

再来看函数R内部:

B = list(map(lambda i: i=='1', bin(n)[2:].zfill(4)))[::-1]

同样,我们来分解这行复杂的代码:

>>> bin(2)
'0b10'

bin是将整数转成二进制,以2为例,bin(2)就是0b10。

>>> bin(2)[2:]
'10'

切片去掉前面2个字符得到数字部分。

>>> bin(2)[2:].zfill(4)
'0010'

zfill是用0填充字符至指定位数。

接下来又是map,这次的映射函数是通过lambda自定义的函数,效果是返回参数是否为字符串1:

>>> list(map(lambda i: i=='1', bin(2)[2:].zfill(4)))
[False, False, True, False]

于是刚才的0010就会变成 False False True False 组成的列表。

转成列表后,再通过步长为-1的切片操作将列表逆序翻转,得到的结果赋值给B:

>>> list(map(lambda i: i=='1', bin(2)[2:].zfill(4)))[::-1]
[False, True, False, False]

遍历下 1 0 2 4 可以看到对应B的不同结果:

47b4e646366b4e324c622f36f2440a3f.png

接下来是一个for循环,里面用到了代码开头定义的M和L。

M是一串字符,L又是一个map映射。

L = list(map(lambda i: ord(i) - 97, M))

映射函数里,ord是一个用来将字符转成ascii码的函数,而小写字母a的ascii码就是97:

>>> ord('a')
97

所以这个函数就是计算一个字符在字母表中的序号。而L就是将M中每个字符转成数字序号。

这里其实是在故意绕弯子,把原本可以直接写出来一组数字,伪装成一个字符串。

而这个for循环,根据M的长度进行遍历,再按索引去L中取值的操作,也完全可以简化成直接对L中的元素进行遍历:

for l in L:
    print(l)

在每次循环中,都去调用了函数F,那这个函数又是在做什么呢?

它也是一个lambda匿名函数,如果写成这样,或许更好理解:

def F(a,b,c,d,t):
    x = [a, b, c, d, not a, not c, not d, 
        not a and not b, not a and not c, not b and not c, 
        not a and not b and not c, a or c, a or b, b or c, 
        a or b or c
    ]
    return x[t]

函数里用 a b c d 4个参数的不同逻辑组合,定义了一个很长的bool值列表,然后再根据最后一个参数t,决定返回列表中的第几个元素,结果要么是True,要么是False。

代码在这里用了解包的方式传递参数。给了*B,就相当于给了4个参数:

>>> print(*B)
False True False False

后面的 and-or 是一种约等于if-else的逻辑,如果and前面的值为True,则返回and后面的值,否则返回or后面的值。

所以,如果函数F的结果是True,前面定义好的字符串D就加上一个参数对应的字符,否则加一个空格。

下面一行也是一个and-or,效果是每隔5个字符串加一个换行。

最后把字符串D输出。

看下 len(M),M的长度,也就是循环的次数:

>>> len(M)
35

是35。每5个换一行,那就是一个5x7的矩阵,对比下输出的字符画,很明显看出,就是这里在绘制字符画。

而函数F的作用就是计算每个位置上,应该是画数字,还是留白。

在代码中加上了一点输出,让这个过程更加直观一些

d79cd7a4782e441ce6ef42f4204a789c.png

函数R里面会根据当前参数生成对应的参数序列B,再用这些参数和遍历L中的数字来调用函数F,依次计算出字符画上的35个格子应该如何绘制,最后绘制出结果。

至此,程序的逻辑我们已经清楚了。

但,还有点问题。

这其中的字符串M和函数F中的列表是怎么来的?

为什么用它们就能绘制出数字图案?

除了1024外的其他数字,也可以同样画出来吗?

测试下用0~9分别调用函数R的结果,发现只有1024是对的,说明这段代码仅针对这4个字符。

937cf076b8f009665d21384e96579110.png

我们把 1 0 2 4 分别对应的4组 a b c d,代入到函数F的列表中,计算满足每一个条件的所有可能数字,就会发现列表中的每一项分别对应这4个数字的不同组合:

738adb662bd9243acbb29fb3bd53596b.png

而对于字符画中的35个位置,每一个分别是哪种组合,就在L里记录下对应的索引序号:

29f0b1f7ab48a1ee8c3d6d7d8972fb53.png

这样就得到了这35个数字,再反推一下就有了字符串M:

2001c6e026cd4187ba0b21d453fe960c.png

好了,你现在是不是对这个代码已经完全理解了呢?

那么最后留一个问题,如果我想要输出520这三个字符画,需要怎么修改呢?

56c98718f83b65587ca64e357ba5931a.png

作者:Crossin的编程教室


Crossin的第2本书《码上行动:利用Python与ChatGPT高效搞定Excel数据分析》已经上市了。

点此查看上一本《码上行动:零基础学会Python编程》介绍

7c0c5a4ef1f34dafc04f5a67b8b88d91.jpeg

本书从 Python 和 Excel 结合使用的角度讲解处理分析数据的思路、方法与实战应用。不论是希望从事数据分析岗位的学习者,还是其他职业的办公人员,都可以通过本书的学习掌握 Python 分析数据的技能。书中创新性地将 ChatGPT 引入到教学当中,用 ChatGPT 答疑并提供实训代码,并介绍了使用 ChatGPT 辅助学习的一些实用技巧,给学习者带来全新的学习方式。

读者朋友们购买后可在后台联系我,加入读者交流群,Crossin会为你开启陪读模式,解答你在阅读本书时的一切疑问。

感谢转发点赞的各位~


_往期文章推荐_

编程教室本周视频更新

Python3.12发布,性能提升5%


【教程】: python

【答疑】: 666

更多资源点击阅读原文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1160937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CPU就绪情况及其对虚拟机性能的影响

CPU就绪是虚拟化中的一种性能度量&#xff0c;用于指示物理CPU中的潜在问题&#xff0c;作为对系统效率的度量&#xff0c;它用于跟踪性能和资源利用率&#xff0c;并避免严重错误。为了理解它在管理虚拟机中的重要性&#xff0c;我们将探讨CPU就绪作为一种性能指标的作用。 让…

HarmonyOS(二)—— 初识ArkTS开发语言(中)之ArkTS的由来和演进

前言 在上一篇文章HarmonyOS&#xff08;二&#xff09;—— 初识ArkTS开发语言&#xff08;上&#xff09;之TypeScript入门&#xff0c;我初识了TypeScript相关知识点&#xff0c;也知道ArkTS是华为基于TypeScript发展演化而来。 从最初的基础的逻辑交互能力&#xff0c;到…

Python文件上传 【出错】

文件上传时选择相应文件&#xff0c;选择不到 需求&#xff1a;实现百度上传文件 Code # 无法选择文件 import os import time # import autoit from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChainsdriver webdriver.Chrome…

什么是文件安全

文件安全就是通过实施严格的访问控制措施和完美的权限卫生来保护您的业务关键信息不被窥探&#xff0c;除了启用和监控安全访问控制外&#xff0c;整理数据存储在保护文件方面也起着重要作用。通过清除旧的、过时的和其他垃圾文件来定期优化文件存储&#xff0c;以专注于关键业…

【51单片机】数码管与LCD1602(学习笔记)

一、静态数码管 1、数码管介绍 LED数码管&#xff1a;有多个发光二极管封装在一起的"8"字型的显示器 2、数码管引脚定义 分为&#xff1a;共阴极连接&#xff08;多&#xff09;、共阳极连接 图片仅供参考&#xff0c;以图纸为准 公共端&#xff1a;接地 > 供…

【数据结构与算法】排序二叉树的创建节点的添加和删除(附代码实现与代码讲解)

首先来了解下排序二叉树的基本概念 排序二叉树&#xff1a;任意一个根节点&#xff0c;比他的左子树中的任意节点都大&#xff0c;比他的右子树中的任意节点都小 比如下面的这个树就是排序二叉树 OK&#xff0c;在了解了这个基本概念之后&#xff0c;就可以去看下面的代码了 …

车载网络测试 - UDS诊断篇 - CAN与OSI七层模型

目录 为什么会介绍OSI七层模型&#xff1f; CAN规范与OSI模型 1、Physical Layer 1 2、Data Link Layer 2 3、Network Layer 3 & Transport Protocol Layer 4 4、Transport Protocol Layer 4 5、Session Layer 5 & Presentation Layer 6 & Application Laye…

【c++Leetcode】287. Find the Duplicate Number

问题入口 思想&#xff1a;Floyds Tortoise and Hare 这个算法除了可以检测是否有环&#xff08;问题入口&#xff09;&#xff0c;还可以用来检测重复数。当然这还需要一个慢指针才能实现。具体请点击标题跳转到原视频&#xff0c;这里是把内容再梳理一遍。如果有不对的地方…

多路转接之epoll

本篇博客介绍&#xff1a; 多路转接之epoll 多路转接之epoll 初识epollepoll相关系统调用epoll的工作原理epoll服务器编写成员变量构造函数 循环函数HandlerEvent函数epoll的优缺点 我们学习epoll分为四部分 快速理解部分概念 快速的看一下部分接口讲解epoll的工作原理手写epo…

Springboot 集成 Seata

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。Seata官网 1.找到适合的Seata版本 参考&#xff1a;SpringCloudAlibaba S…

译文:我们如何使 Elasticsearch 7.11 中的 date_histogram 聚合比以往更快

这篇文章是ES7.11版本的文章&#xff0c;主要学习的是思路&#xff0c;记录在这里留作以后参考用。 原文地址&#xff1a;https://www.elastic.co/cn/blog/how-we-made-date-histogram-aggregations-faster-than-ever-in-elasticsearch-7-11 正文开始&#xff1a; Elasticsea…

美国Embarcadero产品经理Marco Cantù谈Delphi/C++ Builder目前开发应用领域

美国Embarcadero产品经理Marco Cant 日前在欧洲的一次信息技术会议上谈到了Delphi/C Builder目前开发应用领域&#xff1a;RAD Studio Delphi/C Builder目前应用于哪些开发领域&#xff1f;使用 Delphi 和 CBuilder 进行开发为当今众多企业提供了动力。 航空航天 大型数据采集 …

4.2 final关键字

思维导图&#xff1a; 4.2.1 final关键字修饰类 定义和基本概念&#xff1a; 在 Java 中&#xff0c;final关键字有“最终”或“不可改”的含义。使用final关键字修饰的元素&#xff08;类、方法或变量&#xff09;都有其特定的特性。 主要应用和注意事项&#xff1a; 修饰类&…

Spring - 手写模拟Spring底层原理

手写Spring 定义配置类AppConfig ComponentScan("com.spring.zsj") public class AppConfig {Beanpublic ApplicationListener applicationListener() {return new ApplicationListener() {Overridepublic void onApplicationEvent(ApplicationEvent event) {System…

yolov7模型轻量化改进之MobileOne骨干替换

本文在之前文章yolov7分割训练的基础上进行改进: https://blog.csdn.net/qq_41920323/article/details/129464115?spm=1001.2014.3001.5502 具体GitHub工程下载,环境安装配置,数据准备等,请借鉴之前的文章,此处只介绍如何进行改进。 MobileOne地址:https://github.com…

【算法|滑动窗口No.3】leetcode3. 无重复字符的最长子串

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

Nignx安装负载均衡动静分离以及Linux前端项目部署将域名映射到特定IP地址

目录 一、nginx简介 1.1 定义 1.2 背景 1.3 作用 二、nginx搭载负载均衡提供前后分离后台接口数据 2.1 nginx安装 2.1.1 下载依赖 2.1.2 下载并解压安装包 2.1.3 安装nginx 2.1.4 启动nginx服务 2.2 tomcat负载均衡 2.2.1 负载均衡所需服务器准备 2.2.2 配置修改 …

内网穿透入门

内网穿透 内网穿透&#xff08;英文&#xff1a;Port Forwarding&#xff09;是一种网络技术&#xff0c;用于将公共互联网&#xff08;外网&#xff09;的请求转发到私有局域网&#xff08;内网&#xff09;中的特定设备或服务。在许多情况下&#xff0c;设备或服务位于一个局…

负载均衡深度解析:算法、策略与Nginx实践

引言 如今&#xff0c;网站和应用服务面临着巨大的访问流量&#xff0c;如何高效、稳定地处理这些流量成为了一个亟待解决的问题。负载均衡技术因此应运而生&#xff0c;它通过将流量合理分配到多个服务器上&#xff0c;不仅优化了资源的利用率&#xff0c;还大大提升了系统的…

下载树莓派对应的64位Ubuntu系统步骤

说点废话&#xff1a;因为ros2需要安装在64位Ubuntu上面&#xff0c;所以安装64位最合适&#xff1b; 第一步打开https://cn.ubuntu.com/ 网站&#xff1b;选择下载--->iot----> 选择这个镜像文件下载。我觉得镜像文件是img格式的&#xff0c;跟iso文件区别是&#xff…