用Python来实现2024年春晚刘谦魔术
简介
这是新春的第一篇,今天早上睡到了自然醒,打开手机刷视频就被刘谦的魔术所吸引,忍不住用编程去模拟一下这个过程。
首先,声明的一点,大年初一不学习,所以这其中涉及的数学原理约瑟夫环大家可以找找其他的教程看看,我这块只是复现它魔术里面的每个步骤。
魔术的步骤
总而言之,可以分为以下8个步骤:
Step 1: 将四张4张牌撕成两半,直接将两堆叠放;
Step 2: 假设姓名为n个字,重复n次,将堆在最上的牌放到最下面;
Step 3: 将牌堆最上的3张拿出,不改变顺序,并随机插入牌堆中间;
Step 4: 将牌堆最上方的牌拿走,放在一旁;
Step 5: 按照南/北/不知道是南或者北方地区,判断自己属于哪一地区,并分别将牌堆最上的1/2/3,不改变顺序,并随机插入牌堆中间;
Step 6: 按性别男/女,从牌堆最上方拿走1/2张牌,一边念口诀:“见证奇迹的时刻”,每念一个字,将牌堆最上方的牌放到牌堆最下;
Step 7: 念口诀“好运留下米”时,将牌堆最上的牌放到牌堆最下;念“烦恼扔出去”时,将牌堆最上方的牌移除。重复这两句口诀,直到手中只有一张牌;
Step 8: 最后留下的牌和Step 4拿走的牌是一样的。
过程拆开分来其实就是对列表进行一个简单的操作了
用python实现其中的过程
0. 模拟扑克牌打乱并抽取的过程;
import random
import itertools
import copy
# 定义扑克牌
suits = ['红桃', '方块', '梅花', '黑桃']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
jokers = ['小王', '大王']
deck_of_cards = list(itertools.product(suits, ranks)) + jokers
random.shuffle(deck_of_cards) # 模拟打乱的操作
print(f"随机生成的{len(deck_of_cards)}扑克牌:", deck_of_cards)
selected_cards = random.sample(deck_of_cards, 4)
print("随机抽取其中的四张牌:", selected_cards)
随机抽取其中的四张牌: [('红桃', '9'), ('黑桃', '8'), ('黑桃', 'A'), ('黑桃', 'K')]
1. 将四张4张牌撕成两半,直接将两堆叠放;
def split_and_stack(cards):cards_copy = copy.copy(cards)merged_cards = cards + cards_copyreturn merged_cardssplit_cards = split_and_stack(selected_cards)
print("撕成两半后堆叠:", split_cards)
撕成两半后堆叠: [('红桃', '9'), ('黑桃', '8'), ('黑桃', 'A'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', '8'), ('黑桃', 'A'), ('黑桃', 'K')]
2. 假设姓名为n个字,重复n次,将堆在最上的牌放到最下面;
def repeat_name(cards, name):name_length = len(name)for _ in range(name_length):# 取出堆在最上的牌,放到最下面top_card = cards.pop(0) cards.append(top_card) return cardssplit_cards_repeated = repeat_name(split_cards, name)
print(f"{name} 重复姓名字数次后的牌堆:", split_cards_repeated)
夏天是冰红茶 重复姓名字数次后的牌堆: [('黑桃', 'A'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', '8'), ('黑桃', 'A'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', '8')]
3. 将牌堆最上的3张拿出,不改变顺序,并随机插入牌堆中间;
def take_top_and_insert(cards):top_three_cards = cards[:3] # 取出最上面的3张牌remaining_cards = cards[3:] # 剩下的牌insert_index = random.randint(1, len(remaining_cards))shuffled_cards = remaining_cards[:insert_index] + top_three_cards + remaining_cards[insert_index:]return shuffled_cardsshuffled_cards = take_top_and_insert(split_cards_repeated)
print("牌堆最上的3张拿出,随机插入后的牌堆:", shuffled_cards)
牌堆最上的3张拿出,随机插入后的牌堆: [('黑桃', '8'), ('黑桃', 'A'), ('黑桃', 'A'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', '8')]
4. 将牌堆最上方的牌拿走,放在一旁;
def take_top_card(cards):top_card = cards.pop(0) # 取出最上方的牌return top_cardtop_card = take_top_card(shuffled_cards)
print("拿走的牌:", top_card)
print("剩余的牌:", shuffled_cards)
拿走的牌: ('黑桃', '8')
剩余的牌: [('黑桃', 'A'), ('黑桃', 'A'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', '8')]
5. 按照南/北/不知道是南或者北方地区,判断自己属于哪一地区,并分别将牌堆最上的1/2/3,不改变顺序,并随机插入牌堆中间;
def insert_cards_based_on_region(cards, region):if region == "南":insert_count = 1elif region == "北":insert_count = 2else:insert_count = 3top = cards[:insert_count]remaining_cards = cards[insert_count:]insert_index = random.randint(0, len(remaining_cards)-1)shuffled_cards = remaining_cards[:insert_index] + top + remaining_cards[insert_index:]return shuffled_cardsshuffled_cards_region = insert_cards_based_on_region(shuffled_cards, region)
print(f"{region}方地区插入后的牌堆:", shuffled_cards_region)
南方地区插入后的牌堆: [('黑桃', 'A'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'K'), ('黑桃', 'A'), ('红桃', '9'), ('黑桃', '8')]
6. 按性别男/女,从牌堆最上方拿走1/2张牌,一边念口诀:“见证奇迹的时刻”,每念一个字,将牌堆最上方的牌放到牌堆最下;
def take_and_chant(cards, gender, chant="见证奇迹的时刻"):take_count = 0if gender == "男":take_count = 1elif gender == "女":take_count = 2else:print("未知性别")remaining_cards = cards[take_count:] # 剩下的牌print(remaining_cards)# 念口诀过程for c in chant:remaining_cards.append(remaining_cards.pop(0)) # 将最上方的牌放到牌堆最下return remaining_cardsremaining_cards= take_and_chant(shuffled_cards_region, gender, chant)
print(f"剩余的牌堆:", remaining_cards)
[('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'K'), ('黑桃', 'A'), ('红桃', '9'), ('黑桃', '8')]
剩余的牌堆: [('红桃', '9'), ('黑桃', 'K'), ('黑桃', 'A'), ('红桃', '9'), ('黑桃', '8'), ('黑桃', 'K')]
7/8. 念口诀“好运留下米”时,将牌堆最上的牌放到牌堆最下;念“烦恼扔出去”时,将牌堆最上方的牌移除。重复这两句口诀,直到手中只有一张牌;最后留下的牌和Step 4拿走的牌是一样的。
def chant_and_modify(cards):iter = 1while len(cards) > 1:chant_good_luck = "好运留下米"chant_throw_away = "烦恼扔出去"print(f"\n第{iter}轮口诀开始:")cards.append(cards.pop(0))print(f"口诀{chant_good_luck}结束后手上的牌:", cards)cards.pop(0)print(f"口诀{chant_throw_away}结束后手上的牌:", cards)iter += 1return cards[0]final_card = chant_and_modify(remaining_cards)
print(f"\n最终留下的牌:{final_card}, Step 4:{top_card}")
第1轮口诀开始:
口诀好运留下米结束后手上的牌: [('黑桃', 'K'), ('黑桃', 'A'), ('红桃', '9'), ('黑桃', '8'), ('黑桃', 'K'), ('红桃', '9')]
口诀烦恼扔出去结束后手上的牌: [('黑桃', 'A'), ('红桃', '9'), ('黑桃', '8'), ('黑桃', 'K'), ('红桃', '9')]
第2轮口诀开始:
口诀好运留下米结束后手上的牌: [('红桃', '9'), ('黑桃', '8'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'A')]
口诀烦恼扔出去结束后手上的牌: [('黑桃', '8'), ('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'A')]
第3轮口诀开始:
口诀好运留下米结束后手上的牌: [('黑桃', 'K'), ('红桃', '9'), ('黑桃', 'A'), ('黑桃', '8')]
口诀烦恼扔出去结束后手上的牌: [('红桃', '9'), ('黑桃', 'A'), ('黑桃', '8')]
第4轮口诀开始:
口诀好运留下米结束后手上的牌: [('黑桃', 'A'), ('黑桃', '8'), ('红桃', '9')]
口诀烦恼扔出去结束后手上的牌: [('黑桃', '8'), ('红桃', '9')]
第5轮口诀开始:
口诀好运留下米结束后手上的牌: [('红桃', '9'), ('黑桃', '8')]
口诀烦恼扔出去结束后手上的牌: [('黑桃', '8')]
最终留下的牌:('黑桃', '8'), Step 4:('黑桃', '8')
完整的代码
import random
import itertools
import copy
# 定义扑克牌
suits = ['红桃', '方块', '梅花', '黑桃']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
jokers = ['小王', '大王']
deck_of_cards = list(itertools.product(suits, ranks)) + jokers
random.shuffle(deck_of_cards) # 模拟打乱的操作
print(f"随机生成的{len(deck_of_cards)}扑克牌:", deck_of_cards)
selected_cards = random.sample(deck_of_cards, 4)
print("随机抽取其中的四张牌:", selected_cards)# 模拟性别为男的情况
name = "夏天是冰红茶"
gender = "男"
chant = "见证奇迹的时刻"
region = "南"# step 1: 将四张4张牌撕成两半,直接将两堆叠放;
def split_and_stack(cards):cards_copy = copy.copy(cards)merged_cards = cards + cards_copyreturn merged_cardssplit_cards = split_and_stack(selected_cards)
print("撕成两半后堆叠:", split_cards)# Step 2: 设你的姓名为n个字,重复n次,将堆在最上的牌放到最下面;
def repeat_name(cards, name):name_length = len(name)for _ in range(name_length):# 取出堆在最上的牌,放到最下面top_card = cards.pop(0)cards.append(top_card)return cardssplit_cards_repeated = repeat_name(split_cards, name)
print(f"{name} 重复姓名字数次后的牌堆:", split_cards_repeated)# Step 3: 将牌堆最上的3张拿出,不改变顺序,并随机插入牌堆中间
def take_top_and_insert(cards):top_three_cards = cards[:3] # 取出最上面的3张牌remaining_cards = cards[3:] # 剩下的牌insert_index = random.randint(1, len(remaining_cards))shuffled_cards = remaining_cards[:insert_index] + top_three_cards + remaining_cards[insert_index:]return shuffled_cardsshuffled_cards = take_top_and_insert(split_cards_repeated)
print("牌堆最上的3张拿出,随机插入后的牌堆:", shuffled_cards)# Step 4: 将牌堆最上方的牌拿走,放在一旁
def take_top_card(cards):top_card = cards.pop(0) # 取出最上方的牌return top_cardtop_card = take_top_card(shuffled_cards)
print("拿走的牌:", top_card)
print("剩余的牌:", shuffled_cards)# Step 5: 按照南/北/不知道是南或者北方地区,判断自己属于哪一地区,并分别将牌堆最上的1/2/3,不改变顺序,并随机插入牌堆中间
def insert_cards_based_on_region(cards, region):if region == "南":insert_count = 1elif region == "北":insert_count = 2else:insert_count = 3top = cards[:insert_count]remaining_cards = cards[insert_count:]insert_index = random.randint(0, len(remaining_cards)-1)shuffled_cards = remaining_cards[:insert_index] + top + remaining_cards[insert_index:]return shuffled_cardsshuffled_cards_region = insert_cards_based_on_region(shuffled_cards, region)
print(f"{region}方地区插入后的牌堆:", shuffled_cards_region)# Step 6: 按性别男/女,从牌堆最上方拿走1/2张牌,一边念口诀:“见证奇迹的时刻”,每念一个字,将牌堆最上方的牌放到牌堆最下。
def take_and_chant(cards, gender, chant="见证奇迹的时刻"):take_count = 0if gender == "男":take_count = 1elif gender == "女":take_count = 2else:print("未知性别")remaining_cards = cards[take_count:] # 剩下的牌print(remaining_cards)# 念口诀过程for c in chant:remaining_cards.append(remaining_cards.pop(0)) # 将最上方的牌放到牌堆最下return remaining_cardsremaining_cards= take_and_chant(shuffled_cards_region, gender, chant)
print(f"剩余的牌堆:", remaining_cards)# Step 7: 念口诀“好运留下米”时,将牌堆最上的牌放到牌堆最下;念“烦恼扔出去”时,将牌堆最上方的牌移除。重复这两句口诀,直到手中只有一张牌;
def chant_and_modify(cards):iter = 1while len(cards) > 1:chant_good_luck = "好运留下米"chant_throw_away = "烦恼扔出去"print(f"\n第{iter}轮口诀开始:")cards.append(cards.pop(0))print(f"口诀{chant_good_luck}结束后手上的牌:", cards)cards.pop(0)print(f"口诀{chant_throw_away}结束后手上的牌:", cards)iter += 1return cards[0]# Step 8: 最后留下的牌和Step 4拿走的牌是一样的。
final_card = chant_and_modify(remaining_cards)
print(f"\n最终留下的牌:{final_card}, Step 4:{top_card}")
大家可以自己去试一试,在步骤6后男生拿走的牌总是会在对应的第5位,女生拿走的牌总是会在对应的第3位。
结语
其实说实话,这种数学魔术在我小时候买的书里就曾经看到过许多。虽然现在了解了其中的数学原理,但当时的惊奇与欢乐感觉依然难以忘怀。刘谦老师在表演中展现了非凡的技艺,不仅仅是数学的巧妙运用,更是他善于抓住观众的好奇心,创造出让人难以置信的奇迹。

相关文章:
用Python来实现2024年春晚刘谦魔术
简介 这是新春的第一篇,今天早上睡到了自然醒,打开手机刷视频就被刘谦的魔术所吸引,忍不住用编程去模拟一下这个过程。 首先,声明的一点,大年初一不学习,所以这其中涉及的数学原理约瑟夫环大家可以找找其…...
TestNG基础教程
TestNG基础教程 一、常用断言二、执行顺序三、依赖测试四、参数化测试1、通过dataProvider实现2、通过xml配置(这里是直接跑xml) 五、testng.xml常用配置方式1、分组维度控制2、类维度配置3、包维度配置 六、TestNG并发测试1、通过注解来实现2、通过xml来…...
###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
前言:感谢您的关注哦,我会持续更新编程相关知识,愿您在这里有所收获。如果有任何问题,欢迎沟通交流!期待与您在学习编程的道路上共同进步。 一. 两个主要软件的介绍 1.KeiluVision5软件 Keil uVision5是一款集成开发…...
Android 9.0 任务栏中清除掉播放器的进程,状态栏仍有音乐播放器状态问题的解决
1.概述 在9.0的rom定制化开发中,在点击系统自带的播放器以后,播放音乐的时候,在最近任务栏recents列表中,点击全部清除,发现音乐播放器还在播放音乐,导致出现bug,完整的 解决方法,肯定是需要点击全部清除以后,音乐播放器也被杀掉进程,接下来分析下这个移除任务栏流程…...
【笔记】Helm-5 Chart模板指南-13 调是模版
调试模板 调试模板可能很棘手,因为渲染后的模板发送了kubernetes API server,可能会以格式化以外的原因拒绝YAML文件。 以下命令有助于调试: 1、helm lint 是验证chart是否遵循最佳实践的首选工具。 2、helm template --debug在本地测试渲…...
Gateway反向代理配置
前言 一般而言,反向代理都是在Nginx中来实现的,其实Gateway也可以作为反向代理服务,不过一般不会这么做,只不过最近的项目,在通过Nginx反向代理之后,iPhone手机访问接口代理地址会异常,安卓手机…...
HiveSQL——共同使用ip的用户检测问题【自关联问题】
注:参考文章: SQL 之共同使用ip用户检测问题【自关联问题】-HQL面试题48【拼多多面试题】_hive sql 自关联-CSDN博客文章浏览阅读810次。0 问题描述create table log( uid char(10), ip char(15), time timestamp);insert into log valuesinsert into l…...
猫头虎分享已解决Bug || 修改mongodb3.0副本集用户密码遇到 BeanDefinitionParsingException
博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …...
如何将ChatGPT升级到4.0版本?如何充值?
如何将ChatGPT升级到4.0版本? 在人工智能的世界里,每一个升级都可能带来革命性的变革。ChatGPT的4.0版本无疑是当前最炙手可热的话题之一,那么如何进行升级,体验到这一版所带来的全新特性呢?以下是一步一步的指南。 …...
conda 相关命令
创建并激活环境:打开终端,并创建一个新的conda环境,以确保安装的软件与M1芯片兼容。运行以下命令: conda create -n myenv python这将创建一个名为"myenv"的新环境,并安装Python。然后,激活该环境…...
探索现代Web前端开发框架:选择最适合你的工具
在当今快速发展的Web开发领域,前端开发框架的选择显得尤为关键。这些框架可以帮助我们更高效地构建出交互性强、性能卓越的用户界面。本文将带你了解几个当前最受欢迎的Web前端开发框架,并帮助你根据自己的需求选择最合适的工具。 1. React React由Fac…...
记录一下,我使用stm32实现pwm波输入,以及对频率和占空比的计算,同时通过串口输出(实现-重要)
1,首先看下半物理仿真 看下我的配置: 看下计算方法以及matlab的仿真输出的数据: timer3的ch2是选择高电平,计算频率 timer3的ch1是选择的是低电平,用来计算周期 其中TemPIpre表示的是CH2输出的值, TemPI…...
Spring Cloud使用ZooKeeper作为注册中心的示例
简单的Spring Cloud应用程序使用ZooKeeper作为注册中心的示例: 1.新建模块: 2.勾选依赖: 3.在pom.xml文件中做出部分修改及添加Spring Cloud Zookeeper 依赖版本: 完整pom文件 <?xml version"1.0" encoding&q…...
【项目日记(九)】项目整体测试,优化以及缺陷分析
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:项目日记-高并发内存池⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你做项目 🔝🔝 开发环境: Visual Studio 2022 项目日…...
JavaScript 设计模式之外观模式
外观模式 我们为啥要使用外观模式呢,其实我们在使用各种 js 库的时候常常会看到很多的外观者模式,也正是这些库的大量使用,所以使得兼容性更广泛,通过外观者模式来封装多个功能,简化底层操作方法 const A {g: functi…...
一、基础数据结构——2.队列——3.双端队列和单调队列2
参考资料:《算法竞赛》,罗勇军 郭卫斌 著 本博客作为阅读本书的学习笔记,仅供交流学习。 建议关注 罗勇军老师博客 3. 单调队列与最大子序和问题 不限制子序列长度问题——贪心法或动态规划 HDOJ 1003 MAX SUM Max Sum Time Limit: 2000/10…...
Stable Diffusion 模型下载:Samaritan 3d Cartoon(撒玛利亚人 3d 卡通)
本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十...
【软件工程导论】实验二——编制数据字典(数字化校园系统案例分析)
数字化校园系统案例分析 问题定义实验内容编制内容1数据项数据流处理逻辑数据存储 2外部实体 问题定义 数字化校园系统期望以数字化信息和网络为基础,在计算机和网络技术上建立起对教学、科研、管理、技术服务、生活服务等校园信息的收集、处理、整合、存储、传输和…...
耳机壳UV树脂制作私模定制耳塞适合什么样的人使用呢?
耳机壳UV树脂制作私模定制耳塞适合以下人群使用: 对音质要求高的人:私模定制耳塞能够完美契合用户的耳朵形状,减少漏音和外部噪音的干扰,提供更好的音质体验。需要长时间佩戴耳机的人:私模定制耳塞能够提高佩戴舒适度…...
第三百一十回
我们在上一章回中介绍了"再谈ListView中的分隔线",本章回中将介绍showMenu的用法.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在第一百六十三回中介绍了showMenu相关的内容,它主要用来显示移动PopupMenu在页面中的位置…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
