Python实战:用Python程序实现春晚刘谦魔术

刘谦春晚魔术是一个让人叹为观止的魔术表演,其中涉及到了数学、编程和创意的结合。看了春晚魔术的朋友们,是不是好奇春晚刘谦的魔术是怎么变的。

在这篇文章中,我们将通过 Python 程序实现春晚刘谦魔术,让读者对这个魔术有更深入的了解。

一、导入库

import random
from collections import deque

二、跟着刘谦的步骤写程序

1、打乱13张牌

用一个 cards 列表存放 13 张不一样的牌 [“2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “10”, “J”, “Q”, “K”, “A”]

使用random.shuffle() 函数,将列表中的元素随机打乱。这个函数会直接修改原始列表,而不是创建一个新的打乱顺序的列表。

import random
cards = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
print(f"最初的的13张牌:{cards}")
random.shuffle(cards)
print(f"打乱顺序的13张牌:{cards}")

Pycharm 控制台输出如下:

2、随机抽取4张牌

使用random.sample() 是 函数,从列表中随机抽取指定数量的元素。这个函数不会修改原始序列,而是返回一个新的包含抽取元素的列表。

from collections import deque# 随机选择4张牌
random_4_cards = random.sample(cards, 4)
print(f"随机抽出的4张牌:{random_4_cards}")

Pycharm 控制台输出如下:

3、将牌对折撕开

创建了一个名为 random_8_cards 的双端队列,其中包含 random_4_cards 的 2 倍元素。

# 对折后撕开得到8张牌
random_8_cards = deque(random_4_cards * 2)
print(f"对折后撕开得到8张牌:{random_8_cards}")

Pycharm 控制台输出如下:

4、根据名字字数得到新顺序牌

使用 collections.deque 类中的rotate() 方法,将双端队列中的元素向左或向右旋转指定的位置。这个方法接受一个参数,表示要旋转的位置数。正数表示向右旋转,负数表示向左旋转。

# 1. 根据名字有几个字,将前几张牌移到最后
name = int(input("请输入名字字数:"))
# 将双端队列中的元素向左旋转几个位置
random_8_cards.rotate(-name)
print(f"根据名字字数调整后的牌:{random_8_cards}")

Pycharm 控制台输出如下:

5、最上面3张插入剩下牌中间

# 2. 取出前三张牌并随机插入剩余牌中,不能插在第一张和最后一张
first_three = [random_8_cards.popleft() for i in range(3)]
print(f"上面3张牌是:{first_three}")
print(f"下面5张牌是:{random_8_cards}")for card in first_three:insert_position = random.randint(1, len(random_8_cards) - 2)random_8_cards.insert(insert_position, card)print(f"插入牌是:{card},随机插入位置是:{insert_position+1},新牌顺序是{random_8_cards}")
print(f"上面3张牌随机插入剩下牌中间,此时新牌顺序:{random_8_cards}")

Pycharm 控制台输出如下:

6、最上面1张牌藏起来

# 3. 把最上面的牌藏起来
remembered_card = random_8_cards.popleft()
print(f"藏起来的1张牌是:{remembered_card}")
print(f"剩下7张牌是:{random_8_cards}")

Pycharm 控制台输出如下:

7、根据南北方得到新顺序牌

# 4. 南方人取1张,北方人取2张,无法确定取3张,将这些牌随机插入剩下的牌中
location = int(input("请输入地区,南方人输入1,北方人输入2,无法确定输入3:"))
first_location = [random_8_cards.popleft() for i in range(location)]
print(f"上面地区牌是:{first_location}")
print(f"剩下牌是:{random_8_cards}")for card in first_location:insert_position = random.randint(1, len(random_8_cards) - 2)random_8_cards.insert(insert_position, card)print(f"插入牌是:{card},随机插入位置是:{insert_position + 1},新牌顺序是{random_8_cards}")
print(f"根据南北方,随机插入剩下牌中间,此时新牌顺序:{random_8_cards}")

Pycharm 控制台输出如下:

8、根据性别得到新顺序牌

# 5. 男生取1张,女生取2张,将这些牌扔掉
gender = int(input("请输入性别,男性输入1,女性输入2:"))
for i in range(gender):random_8_cards.popleft()
print(f"根据性别扔牌,此时新牌顺序:{random_8_cards}")

Pycharm 控制台输出如下:

9、见证奇迹的时刻

"见证奇迹的时刻"是 7 个字,翻译成代码就是将双端队列中的元素向左旋转 7 个位置。

# 6. 见证奇迹的时刻
# 将双端队列中的元素向左旋转7个位置
random_8_cards.rotate(-7)
print(f"见证奇迹的时刻(向左旋转7次牌),此时新牌顺序:{random_8_cards}")

Pycharm 控制台输出如下:

10、好运留下来,烦恼丢出去

# 7. 好运留下来,烦恼丢出去!
while len(random_8_cards) > 1:random_8_cards.append(random_8_cards.popleft())  # 第一张牌移到最后random_8_cards.popleft()  # 删除现在的第一张牌print(f"好运留下来,烦恼丢出去!(第一张牌移到最后,删除现在的第一张牌)此时剩余牌顺序:{random_8_cards}")
print(f"剩余最后1张牌是:{random_8_cards}")

Pycharm 控制台输出如下:

三、完整代码

完整的代码程序如下:

import random
from collections import dequecards = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
print(f"最初的的13张牌:{cards}")
random.shuffle(cards)
print(f"打乱顺序的13张牌:{cards}")# 随机选择4张牌
random_4_cards = random.sample(cards, 4)
print(f"随机抽出的4张牌:{random_4_cards}")
# 对折后撕开得到8张牌
random_8_cards = deque(random_4_cards * 2)
print(f"对折后撕开得到8张牌:{random_8_cards}")# 1. 根据名字有几个字,将前几张牌移到最后
name = int(input("请输入名字字数:"))
# 将双端队列中的元素向左旋转几个位置
random_8_cards.rotate(-name)
print(f"根据名字字数调整后的牌:{random_8_cards}")# 2. 取出前三张牌并随机插入剩余牌中,不能插在第一张和最后一张
first_three = [random_8_cards.popleft() for _ in range(3)]
print(f"上面3张牌是:{first_three}")
print(f"下面5张牌是:{random_8_cards}")for card in first_three:insert_position = random.randint(1, len(random_8_cards) - 2)random_8_cards.insert(insert_position, card)print(f"插入牌是:{card},随机插入位置是:{insert_position + 1},新牌顺序是{random_8_cards}")
print(f"上面3张牌随机插入剩下牌中间,此时新牌顺序:{random_8_cards}")# 3. 把最上面的牌藏起来
remembered_card = random_8_cards.popleft()
print(f"藏起来的1张牌是:{remembered_card}")
print(f"剩下7张牌是:{random_8_cards}")# 4. 南方人取1张,北方人取2张,无法确定取3张,将这些牌随机插入剩下的牌中
location = int(input("请输入地区,南方人输入1,北方人输入2,无法确定输入3:"))
first_location = [random_8_cards.popleft() for i in range(location)]
print(f"上面地区牌是:{first_location}")
print(f"剩下牌是:{random_8_cards}")for card in first_location:insert_position = random.randint(1, len(random_8_cards) - 2)random_8_cards.insert(insert_position, card)print(f"插入牌是:{card},随机插入位置是:{insert_position + 1},新牌顺序是{random_8_cards}")
print(f"根据南北方,随机插入剩下牌中间,此时新牌顺序:{random_8_cards}")# 5. 男生取1张,女生取2张,将这些牌扔掉
gender = int(input("请输入性别,男性输入1,女性输入2:"))
for i in range(gender):random_8_cards.popleft()
print(f"根据性别扔牌,此时新牌顺序:{random_8_cards}")# 6. 见证奇迹的时刻
# 将双端队列中的元素向左旋转7个位置
random_8_cards.rotate(-7)
print(f"见证奇迹的时刻(向左旋转7次牌),此时新牌顺序:{random_8_cards}")# 7. 好运留下来,烦恼丢出去!
while len(random_8_cards) > 1:random_8_cards.append(random_8_cards.popleft())  # 第一张牌移到最后random_8_cards.popleft()  # 删除现在的第一张牌print(f"好运留下来,烦恼丢出去!(第一张牌移到最后,删除现在的第一张牌)此时剩余牌顺序:{random_8_cards}")
print(f"剩余最后1张牌是:{random_8_cards}")# 8. 查看藏起来的1张牌
print(f"藏起来的1张牌是:{remembered_card}")

Pycharm 控制台输出如下:

四、封装函数

我们将上面的代码进行封装,定义一个 magic() 函数,把名字字数定义为随机 1-10 的数字,南北方人为随机 1-3 的数字,性别为随机 1-2 的数字。

在 main 主函数内调用 10 万次 magic()函数,看一下运行结果正确率。

import random
from collections import dequedef magic():cards = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]# print(f"最初的的13张牌:{cards}")random.shuffle(cards)# print(f"打乱顺序的13张牌:{cards}")# 随机选择4张牌random_4_cards = random.sample(cards, 4)# print(f"随机抽出的4张牌:{random_4_cards}")# 对折后撕开得到8张牌random_8_cards = deque(random_4_cards * 2)# print(f"对折后撕开得到8张牌:{random_8_cards}")# 1. 根据名字有几个字,将前几张牌移到最后name = int(random.randint(1, 10))# 将双端队列中的元素向左旋转几个位置random_8_cards.rotate(-name)# print(f"根据名字字数调整后的牌:{random_8_cards}")# 2. 取出前三张牌并随机插入剩余牌中,不能插在第一张和最后一张first_three = [random_8_cards.popleft() for _ in range(3)]# print(f"上面3张牌是:{first_three}")# print(f"下面5张牌是:{random_8_cards}")for card in first_three:insert_position = random.randint(1, len(random_8_cards) - 2)random_8_cards.insert(insert_position, card)#     print(f"插入牌是:{card},随机插入位置是:{insert_position + 1},新牌顺序是{random_8_cards}")# print(f"上面3张牌随机插入剩下牌中间,此时新牌顺序:{random_8_cards}")# 3. 把最上面的牌藏起来remembered_card = random_8_cards.popleft()# print(f"藏起来的1张牌是:{remembered_card}")# print(f"剩下7张牌是:{random_8_cards}")# 4. 南方人取1张,北方人取2张,无法确定取3张,将这些牌随机插入剩下的牌中location = int(random.randint(1, 4))first_location = [random_8_cards.popleft() for i in range(location)]# print(f"上面地区牌是:{first_location}")# print(f"剩下牌是:{random_8_cards}")for card in first_location:insert_position = random.randint(1, len(random_8_cards) - 2)random_8_cards.insert(insert_position, card)#     print(f"插入牌是:{card},随机插入位置是:{insert_position + 1},新牌顺序是{random_8_cards}")# print(f"根据南北方,随机插入剩下牌中间,此时新牌顺序:{random_8_cards}")# 5. 男生取1张,女生取2张,将这些牌扔掉gender = int(random.randint(1, 2))for i in range(gender):random_8_cards.popleft()# print(f"根据性别扔牌,此时新牌顺序:{random_8_cards}")# 6. 见证奇迹的时刻# 将双端队列中的元素向左旋转7个位置random_8_cards.rotate(-7)# print(f"见证奇迹的时刻(向左旋转7次牌),此时新牌顺序:{random_8_cards}")# 7. 好运留下来,烦恼丢出去!while len(random_8_cards) > 1:random_8_cards.append(random_8_cards.popleft())  # 第一张牌移到最后random_8_cards.popleft()  # 删除现在的第一张牌#     print(f"好运留下来,烦恼丢出去!(第一张牌移到最后,删除现在的第一张牌)此时剩余牌顺序:{random_8_cards}")# print(f"剩余最后1张牌是:{random_8_cards[0]}")# 8. 查看藏起来的1张牌# print(f"藏起来的1张牌是:{remembered_card[0]}")return [random_8_cards[0], remembered_card]if __name__ == '__main__':# 进行多次模拟,计算正确率times = 100000correct_match_times = 0for i in range(times):result = magic()if result[0] == result[1]:correct_match_times += 1match_rate = f"{(correct_match_times / times * 100)} % "print(f"运行{times}次,正确率是{match_rate}")

Pycharm 控制台输出如下:

运行 10 万次程序,正确率 100%。

五、总结

通过我们的代码实验,可以看出刘谦的这个魔术纯粹是数学原理,只要按照固定的顺序执行,就一定能拼成完成的牌。

如果您觉得这篇文章对您有所启发或帮助,请不吝点赞、转发,与您的朋友和家人分享。

本文首发在“程序员coding”公众号,欢迎关注与我一起交流学习。

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

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

相关文章

【GAMES101】Lecture 20 光场

目录 光场(Light Field / Lumigraph) 广场照相机 光场(Light Field / Lumigraph) 我们在三维的世界中从一个观测点出发看到这么一幅二维的画面 如果有这么一副画布可以完美的显示出从观察点看到的画面,那用这幅画布…

idea设置terminal为git

要在IntelliJ IDEA中设置终端为Git Bash,请按照以下步骤操作: 打开 Settings(设置)。点击 Tools(工具)选项卡。进入 Terminal(终端)界面。在 Shell Path 下选择 Browse(…

Redis发布订阅及事务管理

目录 一、发布订阅 1.1、常用命令 1.2、示例演示 二、事务管理 2.1 Multi、Exec、Discard 2.2 示例演示 2.3 事务的错误处理 2.4 事务的冲突问题 2.4.1 事务场景 2.4.2 悲观锁 2.4.3 乐观锁 2.4.4 事务解决冲突—WATCH 2.4.5 UNWATCH 2.4.6 Redis事务的三个特性 …

ES实战-book笔记1

#索引一个文档,-XPUT手动创建索引, curl -XPUT localhost:9200/get-together/_doc/1?pretty -H Content-Type: application/json -d {"name": "Elasticsearch Denver","organizer": "Lee" } #返回结果 {"_index" : "g…

尚硅谷 Vue3+TypeScript 学习笔记(中)

目录 三、路由 3.1. 【对路由的理解】 3.2. 【基本切换效果】 3.3. 【两个注意点】 3.4.【路由器工作模式】 3.5. 【to的两种写法】 3.6. 【命名路由】 3.7. 【嵌套路由】 3.8. 【路由传参】 query参数 params参数 3.9. 【路由的props配置】 3.10. 【 replace属性…

【GAMES101】Lecture 20 颜色

目录 光 颜色 加色系统 CIE RGB颜色匹配实验 颜色空间 CIE XYZ颜色空间 HSV颜色空间(Hue-Saturation-Value) CIELAB空间 减色系统:CMYK 光 光是由不同波长的光波组成的,其中可见光的波长范围在400nm到700nm 用谱功率密度(Spectral…

Low 级别反射型 XSS 攻击演示(附链接)

环境准备 如何搭建 DVWA 靶场保姆级教程(附链接)https://eclecticism.blog.csdn.net/article/details/135834194?spm1001.2014.3001.5502 测试 打开 DVWA 靶场并登录,找到反射型 XSS 页面(笔者这里是 Low 级别) 先…

图像处理之《鲁棒图像隐写术:隐藏频率系数中的信息》论文精读

一、文章摘要 隐写术是一种将秘密信息隐藏到公共多媒体对象中而不会引起第三方怀疑的技术。然而,大多数现有的工作不能提供良好的抗有损JPEG压缩鲁棒性,同时保持相对较大的嵌入容量。提出了一种基于可逆神经网络的端到端鲁棒隐写系统。该方法将秘密信息…

医学搜题神器找答案? #知识分享#职场发展

大学生必备的搜题工具,专业课本习题、电子版教材、考研资料、英语四六级等考试题目也能一并搜索,每道题目都有详细的讲解,每个都堪称大学神器。 1.题小聪 这是一个公众号 它支持文本搜索、扫码搜书、拍照搜索,不会的题目直接对…

幻兽帕鲁PalWorld服务器2024年配置选择

幻兽帕鲁PalWorld是一款备受期待的虚拟游戏,其独特的幻兽系统和丰富的世界观吸引了大量玩家。然而,随着游戏日益受到关注,服务器的配置选择成为了关键问题。2024年,随着技术不断发展,玩家对于游戏体验的需求也在不断提…

[word] word自定义编号格式怎么设置 #经验分享#职场发展#职场发展

word自定义编号格式怎么设置 在Word文档的编辑中,经常会给段落添加编号,但是在编号的使用过程中我们会遇到很多问题,今天给大家分享word自定义编号格式怎么设置,希望能帮到您! 1.如何自定义编号格式? 点击…

NAS如何成为生产力?使用绿联DX4600 Pro搭建图床并实现创作自由

NAS如何成为生产力?使用绿联DX4600 Pro搭建图床并实现创作自由 哈喽小伙伴们好,我是Stark-C~ 关注我的小伙伴都知道,我之前有分享过我的创作过程与工具,其中介绍了我个人其实一直都是使用Markdown的编辑器来进行图文创作的。 我…

如何在 Mac 上恢复永久删除的文件:有效方法

您是否错误地从 Mac 中删除了某个文件,并且确信它已经永远消失了?好吧,你可能错了。即使您认为已永久删除计算机上的数据,仍有可能将其恢复。 在本文中,您将了解如何在 Mac 上恢复永久删除的文件,并了解增…

基于微信小程序的校园失物招领小程序

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

【Web】小白友好的Java内存马基础学习笔记

目录 简介 文件马与内存马的比较 文件马原理 内存马原理 内存马使用场景 内存马分类 内存马注入方式 这篇文章主要是概念性的,具体技术细节不做探究,重点在祛魅。 简介 内存马(Memory Shellcode)是一种恶意攻击技术&…

【后端高频面试题--Mybatis篇】

🚀 作者 :“码上有前” 🚀 文章简介 :后端高频面试题 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 后端高频面试题--Mybatis篇 什么是Mybatis?Mybatis的优缺点?Mybatis的特点…

大水仙花数求解

输入位数,求解水仙花数。暴力求解,位数如果太多,会超时。 思路: (1)11333355和33331155看上去是不一样的两个数,但是它们又一样,因为相同数字出现的次数一样。 (2&…

使用navicat导出mysql离线数据后,再导入doris的方案

一、背景 doris本身是支持直接从mysql中同步数据的,但有时候,客户不允许我们使用doris直连mysql,此时就需要客户配合将mysql中的数据手工导出成离线文件,我们再导入到doris中 二、环境 doris 1.2 三、方案 doris支持多种导入…

【C语言】一道相当有难度的指针题目(某大厂笔试真题)超详解

这是比较复杂的题目,但是如果我们能够理解清楚各个指针代表的含义,画出各级指针的关系图,这道题就迎刃而解了。 学会这道笔试题,相信你对指针的理解,对数组,字符串的理解都会上一个档次。 字符串存储使用的…

使用Arduino UNO和蓝牙模块制作智能小车

目录 概述 1 硬件结构 1.1 硬件组成 1.2 蓝牙模块介绍 1.3 控制板IO引脚定义 2 机械结构 3 固件设计 4 App设计 5 参考文献 概述 本文主要介绍使用Arduino UNO作为主板,用于控制电机和接收蓝牙模块数据。蓝牙模块用于从手机App上接收控制信号,使…