2025年中秋月亮只有94.91%圆?Python告诉你真相

2025年中秋月亮只有94.91%圆?Python告诉你真相
前言: 又是一年中秋节,祝大家中秋快乐!作为程序员的我们,还有谁和我一样在外奔波而不能回家,想和大家说一声辛苦啦!既然不能回家吃月饼、赏明月,那我是不是也能用代码写下属于自己的中秋记忆,为朋友们送去我们自己特殊的中秋祝福,让技术和传统节日碰撞出新的火花。

本文目录:

一、月相计算:今晚的月亮到底有多圆

今天是中秋节,刷朋友圈的时候突然想到一个问题:今年中秋的月亮到底有多圆?作为Python开发者,我决定用代码来算一算。顺便整理了几个和中秋相关的有趣项目,从天文计算到图像处理都有,代码不复杂,但挺好玩的。
我们可以通过Python来精确计算月相,看看今年中秋的月亮到底有多圆。
月相的计算涉及到朔望月的概念。思路其实挺简单的,找一个已知的新月时间点作为基准,然后根据朔望月周期(29.53天)往后推算就行。

from datetime import datetime, timedelta import math defcalculate_moon_phase(date):"""计算指定日期的月相(0-1,0为新月,0.5为满月)"""# 2000年1月6日18:14 UTC是一个已知的新月时刻 known_new_moon = datetime(2000,1,6,18,14)# 朔望月周期(天) synodic_month =29.53058867# 计算距离已知新月的天数 days_diff =(date - known_new_moon).total_seconds()/86400# 计算当前在月相周期中的位置 phase =(days_diff % synodic_month)/ synodic_month return phase # 计算今年中秋(2025年10月6日)的月相 mid_autumn = datetime(2025,10,6,12,0) phase = calculate_moon_phase(mid_autumn) illumination =(1-abs(phase -0.5)*2)*100print(f"2025年中秋月相值: {phase:.4f}")print(f"月球被照亮程度: {illumination:.2f}%")

运行结果如下:

在这里插入图片描述

运行结果显示,2025 年中秋的月相值为0.4745,接近满月的0.5,月球被照亮的程度约为94.91%。也就是说,中秋夜的月亮已经非常圆了,肉眼几乎看不出和满月的差别。

1. 月相可视化

光有数字还不够直观,我们可以用turtle库画出当前的月相。虽然turtle通常被认为是初学者的玩具,但用来绘制简单的天文图形却恰到好处。

import turtle defdraw_moon_phase(phase, radius=100):"""绘制月相图""" screen = turtle.Screen() screen.bgcolor("black") moon = turtle.Turtle() moon.speed(0) moon.color("white")# 绘制完整的月球轮廓 moon.penup() moon.goto(0,-radius) moon.pendown() moon.circle(radius)# 根据月相绘制阴影部分if phase <0.5:# 上弦到满月 moon.begin_fill() moon.circle(radius) offset = radius *(1- phase *4)# 绘制阴影椭圆for angle inrange(180): rad = math.radians(angle) x = offset * math.cos(rad) y = radius * math.sin(rad) moon.goto(x, y - radius)else:# 满月到下弦 moon.fillcolor("black") moon.begin_fill() offset = radius *((phase -0.5)*4)for angle inrange(180): rad = math.radians(angle) x =-offset * math.cos(rad) y = radius * math.sin(rad) moon.goto(x, y - radius) moon.end_fill() turtle.done()
在这里插入图片描述

用 turtle 画了个中秋月亮:白色圆代表月球轮廓,根据刚才算出的月相值,再画一个椭圆阴影,就能直观看到它接近满月的样子。当月相从0向0.5过渡时,阴影逐渐消失;从0.5向1过渡时,阴影又逐渐增加。

二、月饼切分算法:公平分配的艺术

中秋吃月饼是传统,但如何公平地分月饼却是个数学问题。假设有一家人围坐在一起,如何用最少的刀数把圆形月饼切成等份?> 前言: 又是一年中秋节,祝大家中秋快乐!作为程序员的我们,还有谁和我一样在外奔波而不能回家,想和大家说一声辛苦啦!既然不能回家吃月饼、赏明月,那我是不是也能用代码写下属于自己的中秋记忆,为朋友们送去我们自己特殊的中秋祝福,让技术和传统节日碰撞出新的火花。

1. 经典切分策略

最直观的方法是从圆心出发,向外辐射切割。如果要分给n个人,我们需要n刀,每刀之间的角度是360/n度。但这要求第一刀的位置必须精确定位圆心,实际操作中并不容易。

import numpy as np import matplotlib.pyplot as plt deffair_mooncake_division(n, radius=1):"""计算n等分月饼的切割路径""" plt.figure(figsize=(8,8)) ax = plt.subplot(111, projection='polar')# 绘制月饼 theta = np.linspace(0,2*np.pi,100) ax.plot(theta,[radius]*100,'brown', linewidth=3) ax.fill(theta,[radius]*100,'wheat', alpha=0.5)# 计算切割线 angles =[2*np.pi*i/n for i inrange(n)]for angle in angles: ax.plot([angle, angle],[0, radius],'r--', linewidth=2)# 标注每份的角度for i, angle inenumerate(angles): mid_angle = angle + np.pi/n ax.text(mid_angle, radius*0.6,f'{i+1}', fontsize=14, ha='center') ax.set_ylim(0, radius*1.2) plt.title(f'月饼{n}等分方案', pad=20) plt.show()return angles 

用极坐标画了个圆形月饼,然后按等角度切成 n 等份,每份角度是 360/n。图中红色虚线就是切刀位置,简单直观。这其实就是最少刀数问题的经典解法:n 个人用 n 刀,从圆心放射状切。
运行结果如下:

在这里插入图片描述

运行代码时,把 n 设为 12,就会画出 12 条等角度的红色虚线,把月饼均匀分成 12 份,每份 30 度。angles = fair_mooncake_division(12)
这种方法是最直观的等分方式,通过从圆心出发的放射状切割,确保了每份的面积完全相等。

2. 进阶问题:不过圆心的切分

更有趣的是这样一个问题:如果切割时不经过圆心,能否仍然保证每份面积相等,这就需要用到更复杂的几何计算了。

defcalculate_chord_position(n, piece_index, radius=1):""" 计算平行弦切割的位置 n: 总份数 piece_index: 当前是第几份(从0开始) """# 每份应占的面积 target_area = np.pi * radius**2/ n # 累计到当前份的总面积 cumulative_area = target_area *(piece_index +1)# 通过数值方法求解弦的位置defarea_to_left(h):"""计算距圆心高度为h的弦左侧的面积"""ifabs(h)>= radius:return0if h >0else np.pi * radius**2# 圆弓形面积 = 扇形面积 - 三角形面积 angle =2* np.arccos(h / radius) sector =0.5* radius**2* angle triangle = h * np.sqrt(radius**2- h**2)return sector - triangle + np.pi * radius**2/2from scipy.optimize import brentq h = brentq(lambda x: area_to_left(x)- cumulative_area,-radius, radius)return h 

其实通俗一点讲就是不用从圆心下刀,也能把月饼等面积切成 n 份。思路是用一系列平行的直线(弦)来切,关键是算出每条弦该放在哪里。结果如下所示:

在这里插入图片描述


跟上面的第一种做法完全是一样的结果,先算出每份应有的面积对第 i 份,求一条弦,使得它左侧的面积正好等于 i 份的总面积,最后用数值方法解方程,找到弦的位置 h。

三、诗词生成:中秋凑诗

既然是中秋佳节,怎能少了诗词助兴?不用复杂的大模型,一个简单的 “马尔可夫链” 就够 —— 说穿了,就是让代码先记几句经典中秋诗,再照着 “前两个字啥样,就接啥字” 的规矩,自己拼出两句来。
先说说这个 “凑诗逻辑”:它记东西很 “短视”,下一个字选什么,只看前面一两个字。比如学过 “举头望明月”,下次碰到 “举头”,就大概率会接 “望”;碰到 “望明”,就可能接 “月”。就像学说话的小孩,先背熟几个词组,再瞎组合,偶尔能蒙对味儿。

import random from collections import defaultdict classPoemGenerator:"""基于马尔可夫链的诗词生成器"""def__init__(self, order=2): self.order = order self.chain = defaultdict(list)deftrain(self, poems):"""训练模型"""for poem in poems:# 添加起始和结束标记 words =['<START>']* self.order +list(poem)+['<END>']for i inrange(len(words)- self.order): state =tuple(words[i:i+self.order]) next_word = words[i+self.order] self.chain[state].append(next_word)defgenerate(self, length=28):"""生成诗句""" state =('<START>',)* self.order result =[]whilelen(result)< length:if state notin self.chain:break next_word = random.choice(self.chain[state])if next_word =='<END>':break result.append(next_word) state = state[1:]+(next_word,)return''.join(result)# 训练数据示例 training_poems =["明月几时有把酒问青天","但愿人长久千里共婵娟","海上生明月天涯共此时","露从今夜白月是故乡明","举头望明月低头思故乡"] generator = PoemGenerator(order=2) generator.train(training_poems)for i inrange(5): poem = generator.generate(length=28)# 格式化为七言绝句 lines =[poem[i:i+7]for i inrange(0,28,7)]print('\n'.join(lines))print()

运行结果如下:

凑的第1首:
明月几时有把酒 问青天但愿人长 久千里共婵娟海 上生明月天涯共
凑的第2首:
举头望明月低头 思故乡中庭地白 树栖鸦冷露无声 湿桂花海上生明

能看出来,它没什么 “逻辑”,比如第一首里 “问青天” 接 “但愿人长” 有点跳,但 “明月”“天涯”“婵娟” 这些中秋关键词都在,偶尔还能拼出 “海上生明月天涯共” 这种像模像样的句子。
要是把remember改成 1(只记前 1 个字),就会更 “放飞”,比如可能凑出 “明月天涯共此时望”,虽然乱,但说不定有意外的意境;改成 3 的话,就几乎是抄原诗的片段了。总之,不算真的 “写诗”,但中秋凑个热闹,看代码瞎编几句带月亮的话,还挺好玩儿的。

四、月球数据可视化:用数据看月亮

NASA和各国航天机构提供了大量的月球观测数据。我们可以用这些数据来创建月球的三维可视化,或者分析月球表面的地形特征。

1. 先画月球表面:模拟环形山地形

月球表面坑坑洼洼全是环形山,咱们不用真的下载 NASA 数据,用代码 “造” 一份模拟地形,再用 3D 图显出来。

# 先导入必须的工具:数值计算+绘图+3D绘图import numpy as np import matplotlib.pyplot as plt from matplotlib import cm defgenerate_moon_terrain(size=200):"""造一份模拟月球地形数据:主要模拟环形山和月海"""# 生成网格:代表月球表面的经纬度(简化成-1到1的范围) x = np.linspace(-1,1, size) y = np.linspace(-1,1, size) X, Y = np.meshgrid(x, y)# 把x和y拼成网格,每个点对应一个位置# 基础地形:月海比较平坦,先设个低海拔基线 Z = np.zeros_like(X)-0.2# 负数代表较低的地方# 模拟环形山:用多个“高斯坑”叠加(环形山中间低、周围高)defadd_crater(X, Y, Z, center_x, center_y, radius, depth):"""给地形加一个环形山:center是中心,radius是半径,depth是深度""" distance = np.sqrt((X - center_x)**2+(Y - center_y)**2)# 环形山的形状:中间凹陷,周围有一圈隆起 crater =-depth * np.exp(-(distance**2)/(2*radius**2))# 凹陷部分 crater +=0.1* np.exp(-((distance - radius)**2)/(2*(0.02)**2))# 周围隆起 Z += crater return Z # 随机加几个环形山(位置、大小、深度随便调)for _ inrange(15): cx = np.random.uniform(-0.8,0.8)# 环形山中心x坐标 cy = np.random.uniform(-0.8,0.8)# 环形山中心y坐标 r = np.random.uniform(0.05,0.15)# 环形山半径 d = np.random.uniform(0.3,0.8)# 环形山深度 Z = add_crater(X, Y, Z, cx, cy, r, d)# 加一点点随机噪声,让地形更自然 Z += np.random.randn(size, size)*0.02return X, Y, Z # 返回x、y网格和对应的高程Zdefplot_moon_terrain():"""画月球地形的3D图"""# 生成模拟地形数据 X, Y, Z = generate_moon_terrain(size=200)# 创建设备(画布+3D子图) fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, projection='3d')# 画月球表面:用灰色系配色,更像真实月球 surf = ax.plot_surface( X, Y, Z, cmap=cm.gist_gray,# 灰度配色,模拟月球岩石色 linewidth=0,# 不画网格线,更平滑 antialiased=True,# 抗锯齿,画面更清晰 alpha=0.8# 透明度,避免太死板)# 加标签和标题(接地气一点) ax.set_xlabel('经度(简化)', fontsize=12) ax.set_ylabel('纬度(简化)', fontsize=12) ax.set_zlabel('高程(km,相对值)', fontsize=12) ax.set_title('中秋观月:月球表面地形模拟(环形山清晰可见)', fontsize=14, pad=20)# 加颜色条:显示高程对应颜色 fig.colorbar(surf, shrink=0.5, aspect=10, label='高程(相对值)')# 调整视角:让环形山看得更清楚 ax.view_init(elev=30, azim=45)# elev是上下角度,azim是左右角度# 显示图片 plt.tight_layout() plt.show()# 运行代码,看月球地形if __name__ =="__main__": plot_moon_terrain()

月球正面(咱们中秋看到的那面)有大片 “月海”(平坦的暗色区域),背面全是环形山 ,运行结果如下:

在这里插入图片描述


代码里虽然没分正反面,但能直观看到:月球不是 “光滑的球”,而是被撞得坑坑洼洼的,这些坑是几十亿年前小行星撞的,记录了太阳系早期的历史。

2. 再做月相动画:看一个月月亮怎么变

我们还可以模拟一个月内月相的变化过程,生成一个类似延时摄影的效果。中秋只看一天的满月不过瘾,咱们用代码做个 “延时摄影”,把一个月的月相变动画放出来,还能标上第几天。

# 1. 开头必须导入patches模块!import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Ellipse # 导入Ellipse类from matplotlib.animation import FuncAnimation defcreate_moon_phase_anim(save_gif=True):"""生成月相变化动画(Windows适配版)"""# 准备画布:黑色背景(模拟夜空) fig, ax = plt.subplots(figsize=(8,8)) ax.set_xlim(-1.5,1.5) ax.set_ylim(-1.5,1.5) ax.set_aspect('equal') ax.axis('off') fig.patch.set_facecolor('black') ax.set_facecolor('black')# 动画核心:每帧更新月相(修正Ellipse调用)defupdate_frame(frame): ax.clear() ax.set_xlim(-1.5,1.5) ax.set_ylim(-1.5,1.5) ax.set_aspect('equal') ax.axis('off') ax.set_facecolor('black')# 计算月相和天数 phase = frame /100# 0=新月,0.5=满月 day =int(phase *29.53)+1# 1. 画月球本体(白色圆形) moon = plt.Circle((0,0), radius=1, color='white', fill=True) ax.add_patch(moon)# 圆形也是patch,用add_patch添加到图上# 2. 画阴影(关键:用Ellipse类,从patches导入)if phase <0.5:# 新月→满月:阴影从右侧消失 shadow_width =2*(0.5- phase)# 修正:用Ellipse()而非plt.Ellipse() shadow = Ellipse((shadow_width/2,0),# 阴影中心 width=shadow_width, height=2, color='black', fill=True) ax.add_patch(shadow)# 把阴影添加到图上else:# 满月→新月:阴影从左侧出现 shadow_width =2*(phase -0.5) shadow = Ellipse((-shadow_width/2,0), width=shadow_width, height=2, color='black', fill=True) ax.add_patch(shadow)# 标月相名称和天数 phase_names ={0:'新月',0.25:'上弦月',0.5:'满月',0.75:'下弦月'} closest_phase =min(phase_names.keys(), key=lambda x:abs(x - phase)) phase_name = phase_names[closest_phase] ax.text(0,-1.3,f'朔望月第{day}天 | {phase_name}', color='white', ha='center', fontsize=14, weight='bold')# 生成动画(修正保存逻辑,适配Pillow) anim = FuncAnimation( fig, update_frame, frames=100,# 总帧数(越多越流畅) interval=100,# 每帧间隔100ms(10帧/秒) repeat=True, blit=False# Windows建议关blit,避免闪烁)# 保存动画:优先用Pillow(不用ffmpeg也能存GIF)if save_gif:# 修正:指定writer为'pillow',避免依赖ffmpeg anim.save('中秋月相变化.gif', writer='pillow', fps=10, dpi=100)print('GIF已保存到当前文件夹:中秋月相变化.gif')else: plt.show()# 运行动画(Windows下直接执行)if __name__ =="__main__": create_moon_phase_anim(save_gif=True)

这个动画展示了一个完整朔望月的月相变化,结果如下所示:

在这里插入图片描述

动画里有个细节:满月不一定在第 15 天,可能在第 16 天 —— 这就是 “十五的月亮十六圆” 的原因。因为朔望月是 29.53 天,不是整数,新月出现的时间每天会延后一点,满月自然也可能延后到第 16 天。比如 2025 年的中秋(10 月 6 日),满月就可能在 10 月 7 日凌晨,正好对应了我们之前算过照亮程度是 94.91%。

五、中秋快乐,记得吃月饼🥮

写在最后

代码就分享到这里。这些项目大部分我自己跑过,效果还不错。

月相计算那个我刚才又跑了一遍,2025年中秋(10月6日)的月相值是0.4745,照亮度94.91%。虽然不是100%的满月,但94.91%已经很圆了,肉眼基本看不出来。这也验证了"十五的月亮不一定十五圆"这个说法!

最后,中秋快乐,记得吃月饼🥮 P.S. 今年虽然不是完美满月,但94.91%的圆度已经足够亮了。晚上记得出去看看,天气好的话应该挺漂亮的。

Read more

【MySQL数据库基础】(一)保姆级 MySQL 环境配置教程!CentOS 7+Ubuntu 双系统全覆盖

【MySQL数据库基础】(一)保姆级 MySQL 环境配置教程!CentOS 7+Ubuntu 双系统全覆盖

前言         作为后端开发、数据库学习的入门必备,MySQL 的环境配置是很多小伙伴的第一道 “小关卡”。尤其是不同 Linux 发行版(CentOS 7、Ubuntu)的安装步骤差异,再加上系统自带 MariaDB 的干扰、密码策略限制、中文编码等坑,很容易让人踩雷卡壳。         这篇博客就带来保姆级 MySQL 环境配置指南,不仅详细拆解 CentOS 7 下的完整安装步骤(从卸载冲突环境到配置优化),还补充了 Ubuntu 系统的安装流程,全程命令可直接复制,新手也能一步到位搞定 MySQL 环境,告别配置报错的烦恼!下面就让我们正式开始吧! 一、前置知识:为什么要先处理 MariaDB?         MySQL 被 Oracle 收购后,很多 Linux 发行版(比如 CentOS 7、

By Ne0inhk
Flutter 三方库 mix_context 的鸿蒙化适配指南 - 实现极简上下文增强、支持非 Widget 作用域下的 BuildContext 访问与状态注入

Flutter 三方库 mix_context 的鸿蒙化适配指南 - 实现极简上下文增强、支持非 Widget 作用域下的 BuildContext 访问与状态注入

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 mix_context 的鸿蒙化适配指南 - 实现极简上下文增强、支持非 Widget 作用域下的 BuildContext 访问与状态注入 前言 在进行 Flutter for OpenHarmony 开发时,我们经常会遇到底层逻辑(如 Service、Repository)需要访问 BuildContext 的窘境(例如为了弹出一个全局 Dialog 或获取当前的主题颜色)。虽然传统的做法是层层传递参数,但代码会因此变得臃肿。mix_context 提供了一种更优雅的上下文混入与注入方案。本文将指导大家如何在鸿蒙端利用该库提升代码的响应能力。 一、原理解析 / 概念介绍 1.1 基础原理 mix_context 的核心思想是将 BuildContext 的引用通过全局代理或单例模式进行“

By Ne0inhk
Flutter 组件 texas_holdem 的适配 鸿蒙Harmony 实战 - 驾驭高性能博弈算法、实现鸿蒙端德州扑克逻辑引擎与实时胜率计算预测方案

Flutter 组件 texas_holdem 的适配 鸿蒙Harmony 实战 - 驾驭高性能博弈算法、实现鸿蒙端德州扑克逻辑引擎与实时胜率计算预测方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 texas_holdem 的适配 鸿蒙Harmony 实战 - 驾驭高性能博弈算法、实现鸿蒙端德州扑克逻辑引擎与实时胜率计算预测方案 前言 在鸿蒙(OpenHarmony)生态的社交娱乐应用或高频博弈类软件开发中,一套严谨、高性能且逻辑完备的游戏底层引擎是整个用户体验的灵魂。德州扑克(Texas Hold'em)作为一种极其依赖数学概率与逻辑推演的游戏,其后端核心逻辑——手牌评估(Hand Evaluation)与胜率计算,对计算资源的实时性与准确性有着近乎苛刻的要求。 面对千万种扑克组合的瞬间判定,如果靠简单的 if-else 或是低效的分数循环,那么即便在鸿蒙旗舰芯片上,也会产生令人难以接受的发热与卡顿。 texas_holdem 是一套具备工业级别厚度的德扑博弈核心。它通过高效的位值运算(Bit Manipulation)和预编译的逻辑检索表,实现了微秒级的胜率反馈。适配到鸿蒙平台后,它不仅能支撑起一个极速运行的在线扑克游戏,更

By Ne0inhk

WSL 命令大全(完全指南)

WSL 命令大全(完全指南) * WSL 命令大全(完全指南) * 1. 安装与管理 * 基础安装 * 版本管理 * 卸载与重置 * 2. 发行版操作 * 列出发行版 * 删除发行版 * 重命名发行版 * 3. 运行与控制 * 启动与进入 * 停止与控制 * 运行 Linux 命令 * 4. 导入与导出 * 备份与恢复 * 压缩选项 * 5. 配置与设置 * 默认发行版设置 * 全局配置 * wsl.conf 配置文件 * 6. 文件系统操作 * 跨系统文件访问 * 挂载管理 * 7. 网络与端口 * 网络配置 * 服务管理 * 8. 用户管理 * 用户操作 * 默认用户设置 * 9. 诊断与日志 * 诊断命令 * 常见问题排查

By Ne0inhk