Nick的琐碎日常 - 📖学习
type: channel
link: https://www.nickwald.top/category/study/
items: 【数学】提纲，三板斧
items: Alist代理下的Obsidian同步问题：Remotely Save 启用WebDav报错405 Method Not Allowed
items: Python爬虫爬取Steam商店游戏信息
items: 【数电】北邮电子宠物机设计小结
items: 【数电】计数器实验小结与启发
items: 【指南】Obsidian+Cloudreve多端同步方案
items: 【指南】GitHub从白嫖到入门
items: 【指南】manimCE使用指南（1）
items: 【指南】manimCE安装指南
items: C++类与对象初探（1）

【数学】提纲，三板斧
type: item
date: 2025-11-11T00:28:21+08:00
description: 缘起数学一直是我的弱项，最近准备研究生于是痛定思痛对以前学的数学内容做个小整理。篇幅短小是因为打latex公式太麻烦了（没错虽然笔记记录在ipad上可以导出pdf，但意识流笔记，字迹排版啥还是太抽象了，就不嫌丑发出来了QwQ）对大学数学的分类我专业比较吃数学，回顾大一到大三，基本数学学习的脉络是这样的：数学分析，高数增强版（掐人中线性代数概率论工科数学基础（复分析，场论和数学物理方法）离散数学随机过程非常惨烈的是数学知识点一般会落后于专业课，所以专业课需要超前点映一些数学的内容，这时候就会非常懵逼（啊，我吗？.JPG）当然一般专业学数学就学前三项，我一般称为“三板斧”。三板斧学好了后面学起来也不会太折磨。数分相关第一个要学的是 集合，函数 。集合是函数的操作对象，广义上说函数就是一个集合到另一个集合的对应关系（映射），当然一般我们在实分析里面默认集合就是 $R, R^2, R^3$，对应实数域，二维空间和三维空间。在此基础上我们给出 极限和连续 的定义，为高等数学提供了一个区分高中的数学抓手。函数研究的是其性态，包括 最大最小值/极大极小值，奇偶性，周期性 。在此基础上我们可以研究函数的图像，并给出几个初等函数及其经典图像。当然，基础的性态不足以完整刻画函数的特点，于是基于极限，我们进一步提出刻画的工具——导数，以及对应的三个定理：中值定理，微分等式和微分不等式。以上内容构成一元函数微分学内容。而一元函数积分学按照上面思路，给出积分的计算方法，积分等式与不等式，并顺势推广到多元函数—— 多元函数微分学和多元函数积分学 。需要注意的是， 二重积分 其实属于多元函数积分学内，但课本单独提出。而 微分方程 属于多元函数微分学和积分学的综合应用，需要按情况分类比较好（这是个坑嘛hhh）。在谈论函数时，我们应该注意到函数的离散化—— 数列 ，并通过定理将数列的求解问题转为对等价函数的求解问题。线代相关线代主要操作对象是实数域中的向量（亦即函数），通过 行列式 推出 矩阵 概念，并将矩阵概念理解为线性系统即可。理解矩阵后就可以通过矩阵运算实现线性变换，这里需要区分下 线性相关和线性无关 这两个核心概念，并基于两个概念分出后面各种衍生概念，包括极大无关组，合同矩阵，正定矩阵等。将矩阵的概念再扩大，理解矩阵向量空间，在向量空间内则包含各种函数，其几何意义需要我们关注，包括平面，线的方程，以及二次型相关曲面和曲线的标准形。对标准形变基则可以化为9种不同的基本图形。本质上，线代想要搞清的就是线性变换的问题，即给定一个函数f，如何通过线性变换让f变为g，使其简化。概率相关概率首先要明确 事件 ，然后是 概率 的内涵。注意概率对标集合，从集合的运算推出概率的运算及性质。对有限情况我们可以沿用高中学的古典概，而经典分布则为 0-1，伯努利，泊松，几何，超几何 ，这些概念是逐渐衍生推广的，对标样本点n从有限到无穷。（伯努利是0-1的n重，泊松是n趋于无穷的结果，推导要用数分知识）注意到无穷的情况，我们需要更加细密的颗粒度，即 几何概 ，其代表古典概样本趋于无穷的情况，但需要空间仍然可度量。与从一元函数到多元函数的过程类似，我们提出随机变量的概念，并将其推广到多元，那么多元如何退化为一元呢？只需要 边缘概 就好（也即消元，可以理解为条件概）几何分布的内容比离散的古典概分布丰富，最出名的当然属 高斯正态分布 ，公式放在这里了：$$ p_1(x) = \frac{1}{\sqrt{2\pi\varrho^2}}exp\{-\frac{(x-\mu)^2}{2\varrho^2}\} $$一维放了那二维还会远吗（笑），二维分布如下，注意多了 $\rho$ 表示两维的关联性。$$ p_2(x,y) = \frac{1}{2\pi\varrho_1\varrho_2\sqrt{1-\rho^2}}exp\{ -\frac{1}{2(1-\rho^2)}[(\frac{x-\mu_1}{\varrho_1})^2 + (\frac{y-\mu_2}{\varrho_2})^2 - 2\rho(\frac{x-\mu_1}{\varrho_1})(\frac{y-\mu_2}{\varrho_2})] \} $$[quote color="info"]二维公式的背诵技巧：一维乘以一维，前面系数除以 $\sqrt{1-\rho^2}$ 是为了单位化，正常乘 $\sqrt{2\pi}$ 就打开根号了。后面e指数上系数看作平方公式，打开时候系数整体多系数$1-\rho^2$表单位化，平方公式把括号打开了，有xy那项多了系数$\rho$（x平方和y平方都是自己和自己的关系，不可能存在相关系数，正常写）[/quote]考试需要会背会默。除了正态分布，还有t分布，莱斯分布，瑞利分布…

Alist代理下的Obsidian同步问题：Remotely Save 启用WebDav报错405 Method Not Allowed
type: item
date: 2025-07-15T14:53:00+08:00
description: 起因之前写过(【指南】Obsidian+Cloudreve多端同步方案)[https://www.nickwald.top/study/obsidian-cloudreve.html]这篇文章，在试图切换为Alist作为后端代理时出现问题。那么就有看官要问了，为什么不继续使用Cloudreve呢？因为自己的服务器做了初始化，之前的环境要重新配置，二来Alist支持阿里云盘Open，恰巧自己就有阿里云盘的VIP哈哈哈哈哈问题排查天大地大，权限最大如果你哪个地方报错了，不管是什么错，一定要先检查是否是权限是否足够（背后蕴含多少眼泪.jpg）。Alist使用WebDav需要确认用户已经开启了读写权限，新版本甚至还要用户本身对文件具有操作的能力。排查结果：OK啊用户权限没问题（沧桑脸.jpg）路径问题教程里提示说明网址需要添加/dav后缀，我添加了，仍然报错。。。Bing了下，发现好像绝大部分都是到这里就OK了，虽然Obsidian仍然在报错。。。等等…………注意到WebDav网址格式为：协议://域名或IP地址:端口号/路径所以单纯的/dav后面还要加上路径！（注意力惊人.jpg）所以原本路径http://example.whereami.com/dav应该修改为http://example.whereami.com/dav/so/your/path/here解决。总结很小的一个问题，如果他报错不是405 Method Not Allowed就好了，弄得我下意识以为https协议不支持路径不存在一般不是报404 Not Found或者400 Bad Request吗。。。

Python爬虫爬取Steam商店游戏信息
type: item
date: 2025-04-25T19:30:00+08:00
description: 事情起因本学期有大数据课设，选择了Steam评论情感预测方向。现在已知 appid ，要求根据 appid 爬取对应游戏的信息。数据文件的封装先写了个DataIO对底层数据文件的交互进行封装。class DataIO: """ DataIO类用于封装数据资源 Args: file_path (str): 数据文件路径 """ file_path: str = None encoding:str = 'utf-8' def __init__(self, file_path: str, encoding: str = 'utf-8'): self.file_path = file_path self.encoding = encoding def save(self, data: dict, update: bool = False): """ 保存数据到文件 Args: data (dict): 要保存的数据列表 update (bool): 是否覆盖文件中存在的同appid数据，默认为False """ if self.file_path is None: raise ValueError("文件路径不能为空") file_type = os.path.splitext(self.file_path)[-1][1:] match file_type: case 'csv': self.save_to_csv(data, update) case 'xlsx': self.save_to_xlsx(data, update) case _: raise ValueError(f"不支持的文件类型{file_type}") def save_to_csv(self, data: dict, update: bool = False): """ 保存数据到CSV文件 Args: data (dict): 要保存的数据 update (bool): 是否覆盖文件中存在的同appid数据，默认为False """ if self.file_path is None: raise ValueError("文件路径不能为空") try: if os.path.isfile(self.file_path) and update: df = pd.read_csv(self.file_path, encoding=self.encoding) if 'appid' in df.columns: mask = df['appid'] == data['appid'] if mask.any(): # 创建一个新的 DataFrame 用于更新 new_df = pd.DataFrame([data]) # 重新索引新的 DataFrame 以匹配原 DataFrame 的列顺序 new_df = new_df.reindex(columns=df.columns) # 更新匹配的行 df.loc[mask] = new_df.values else: df = pd.concat([df, pd.DataFrame([data])], ignore_index=True) else: df = pd.concat([df, pd.DataFrame([data])], ignore_index=True) df.to_csv(self.file_path, index=False, encoding=self.encoding) else: pd.DataFrame([data]).to_csv(self.file_path, index=False, encoding=self.encoding, mode='a', header=not os.path.isfile(self.file_path)) except Exception as e: print(f"保存数据到 CSV 文件时出错: {e}") def save_to_xlsx(self, data: dict, update: bool = False): """ 保存数据到Excel文件 Args: data (dict): 要保存的数据列表 update (bool): 是否覆盖文件中存在的同appid数据，默认为False """ if self.file_path is None: raise ValueError("文件路径不能为空") try: if os.path.isfile(self.file_path) and update: df = pd.read_excel(self.file_path, engine='openpyxl') if 'appid' in…

【数电】北邮电子宠物机设计小结
type: item
date: 2024-06-02T18:46:00+08:00
description: 摘要小时候可能玩过宠物孵化玩具，可以通过按键交互实现宠物的孵化，喂养等有趣的功能。本次实验尝试基于可编程器件实验板DTCE-EDA_V设计了电子宠物孵化器的系统构架与并用代码实现宠物孵化功能。基于Verilog实现了包含顶层模块EPEt，LCD1602，img，music，seg，rand，button在内的7大模块。关键词关键词 ：电子宠物孵化器，Verilog，FPGA，多模块。项目要求在数字实验板上的 8×8 点阵上模拟一个电子宠物“孵化器”的工作过程。基本要求SW7 为总开关，SW7=‘0’时，所有器件不显示，SW7 拨到‘1’时，8×8 点阵显示一只 黄色的“蛋”；SW0 为温度选择键，SW0=‘1’时，LD2（黄灯）亮，表示孵化器温度适合孵化， SW0=‘0’时，LD0（蓝灯）亮，表示孵化器温度偏低，无法孵化；BTN0 为孵化启动键，按下后如果温度合适（SW0=‘1’），8×8 点阵显示“蛋”的形状 每 2 秒钟发生一次变化，变化顺序如图 1~图 6；变化过程中，如果温度偏低 （SW0=‘1’）则变化停止，等到温度合适后继续变化，如果温度偏低持续时间超过 5 秒，则“蛋”变成绿色，表示孵化失败；当“蛋”的形状变化到图 6 后，孵化过程不再受温度影响，每 2 秒依次显示图 7、图 8 和图 9 动物图案，表示孵化成功；孵化出的动物有蛇、小鸡、海龟、恐龙 4 种，具体孵化结果为四种动物中的随机一 种，4 种动物图案如下：按下 BTN0 后开始计时，记录整个孵化时间，孵化成功或失败后计时停止，同时 用 DISP7~DISP6 两个数码管显示计时；孵化成功或失败后按动 BTN0 即可开始新的孵化过程。提高要求为相关状态和过程配加合适的音效或音乐；自拟其他功能。系统设计从整体上而言，整个系统解耦为七大模块。设计思路首先对整个系统进行初步构想：将系统视为黑盒，其输入输出应该包含：控制类电源开关“孵化”启动/重启按钮温度选择开关显示类声蜂鸣器光8*8双色LED点阵（孵化图案）数码管（总计孵化时间）发光LED阵列（左半部分提示进入下一阶段的时间，右半部分提示温度状态）LCD1602（文字提示）考虑到状态的切换问题，使用状态机来管理孵化进程是一个看起来很不错的解决方案。于是我们可以考虑设计一个寄存器变量pet_state，使用数字代替表示不同的孵化状态。另外，为了方便代码的调试管理，并且为未来可能的进一步开发提供灵活性和便捷性，应该将整个系统的功能代码解耦分离，分解为多个功能各异的模块。本次实验内，我将整个系统大致功能代码分类如下：从面向对象编程的设计原理来说，应该把显示逻辑从主逻辑中分离。于是我们应该分离出LCD1602，img，seg三大模块。这三者的显示都有扫描，译码，显示三大步骤。蜂鸣器的声波生成应该也要单独分离。随机数生成器可以作为一个单独的模块，当业务拓展时，仅需改变接口位宽即可满足发展的需求。按键消抖功能应该单独分离出一个模块。这样子就可以实现多按键时代码轻松复用。整个系统存在需要高频率的部分（8*8点阵，LCD1602，蜂鸣器），所以时钟频率选择10MHz。总体框图分块设计按键消抖模块button按键消抖模块的设计灵感来源于00-19计数器的实验。我们的目的是通过延迟计时的方式滤除不稳定的抖动，这种抖动一般在30ms之内。我们可以设计模块端口如下：module button( input wire btn, // 按钮 input wire CLK, // 时钟信号 input wire RST, // 复位信号 output reg btn_deb // 去抖后的按钮 );寄存器变量cnt负责CLK计数，产生30ms计时。寄存器变量btn_deb是消抖后的稳定输出寄存器变量stable_flag是按键稳定的标志，这个变量可以排除稳定后的长按信号，使得btn_deb的输出为长一个时钟的瞬时脉冲。在顶层模块EPet相关代码整合如下：wire btn0_deb; // 按钮0去抖后输出 /* 按钮去抖 */ button u0( .btn(btn0), .CLK(clk), .RST(rst), .btn_deb(btn0_deb) );button模块综合代码如下：/* 按钮去抖模块解读 */ module button( input wire btn, // 按钮 input wire CLK, // 时钟信号 input wire RST, // 复位信号 output reg btn_deb // 去抖后的按钮 ); parameter TIME_30MS = 'd300000; //30ms消抖 reg [18:0] cnt; // 计数器 reg stable_flag; // 稳定标志 always @(p…

【数电】计数器实验小结与启发
type: item
date: 2023-11-15T00:21:11+08:00
description: 前言最近在北邮沉迷学习数电，第一个验收的实验是实现循环自动计数的计数器。就这次实验写一个小结回顾，也希望能给后来人启发。实验要求完成一个计数值为00~19的计数器的设计和仿真，并下载到实验板上验证。要求如下：计数值每秒加1，加到19后回0BTN0 为暂停键，按一下计时停止，再按一下计时继续，要求为 BTN0 设计防抖电路在数码管 DISP1 和 DISP0 上显示计数结果BTN7 为复位键，无论何时按下计数值都回到 00实验板上时钟选择 100Hz系统分析输入输出端口设计首先，我们先设计系统的输入和输出。输入显然有两个：暂停按钮 btn0 和复位按钮 reset。输出是数码管，但是我们发现数码管共用一个输入端口，所以为了实现多位数字显示，我们需要用 扫描 的方式显示。于是我们定义输出为 seg ，位选为 cat。我们可以定义整个顶层模块如下：module segCounter ( input wire clk, input wire btn0, reset, output reg [6:0] seg, output reg [7:0] cat );系统模块设计按键消抖模块由于按键动作的时刻和按下时间长短随机，并且存在开关簧片反弹导致电平抖动，我们需要设计一个按键消抖模块。一般抖动时间小于 20ms ，所以我们只需要检测高电平持续的长度大于20ms（实验里取30ms为检测时间）时再置高电平即可。可见，btn0 是原始的按键输入波形， cnt_3 的作用是基于 clk 实现计数，每当 clk 到上升沿时，若高电平则+1，计数到3后则 stable_flag 置高电平，同时 press 产生一个周期的高电平。cnt_3 为什么要计数到3呢？因为 clk 频率是 100Hz ，频率是周期的倒数，所以简单换算如下：$$ f=\frac{1}{T} \Rightarrow T=\frac{1}{f}=\frac{1}{100}s=10ms $$每隔10ms clk 来一个上升沿， cnt_3 +1，则当 cnt_3 为3时显然时间就过去了30ms。消抖模块对应代码如下： // 消抖 always @(posedge clk or posedge reset) begin if (reset == 1'b1) begin cnt_3 <= 3'b000; end else if (cnt_3 == 3'b011) begin cnt_3 <= 3'b000; end else if (btn0 == 1'b1) begin cnt_3 <= cnt_3 + 3'b001; end else begin cnt_3 <= 3'b000; end end always @(posedge clk or posedge reset) begin if (reset == 1'b1) begin stable_flag <= 1'b0; end else if (btn0 == 1'b1 && cnt_3 == 'd3) begin stable_flag <= 1'b1; end else if (btn0 == 1'b0) begin stable_flag <= 1'b0; end end always @(posedge clk or posedge reset) begin if (reset == 1'b1) begin press <= 1'b0; end else if (stable_flag == 1'b0 && cnt_3 == 'd3) begin press <= 1'b1; end else begin press <= 1'b0; end end复位功能设计我们采用异步复位（ posedge clk or posedge reset 里面用 or ），当reset按下时就立刻执行复位操作。因为复位功能显然优先级最高，所以所有 always 块内我们都先验证 reset 的状态。数码管的显示如图，要使得共阴极数码管点亮，需要改变的是阳极的状态。而阳极是多个数码管共用的，所以我们借助人 视觉暂留 的特点，用扫描的方式显示所有数字（类似显示屏的原理）。可见，我们使用 select 区分当前显示的是十位还是个位。译码器负责转换数字到数码管阳极状态的映射关系，扫描控制电路负责控制不同位数数码管的点亮与否。代码实现最后，整个代码如下：module segCounter ( input wire clk, input wire btn0, reset, output reg [6:0] seg, output reg [7:0] cat ); reg [2:0] cnt_3; reg [6:0] cnt_100; reg stabl…

【指南】Obsidian+Cloudreve多端同步方案
type: item
date: 2023-10-16T21:55:00+08:00
description: 前言最近正在尝试使用 Obsidian 这款开源免费的笔记应用。优点在于Wiki化管理和可视化的知识联系图。但是，他本身没有联网同步功能！！！ :@(无奈) 每次在ipad上写笔记，要是都要复制一份到电脑上，那也太麻烦了。不过搜索发现，Obsidian本身丰富的第三方社区插件能帮助解决这个问题。啊那很激动哇，正好自己有服务器，就动动手就能实现多端同步了。前期准备Obsidian服务器（非必须，只要支持 WebDav 读写服务即可）重点在于 WebDav 服务，看情况可能要GitHub加速器，因为很多社区插件都托管在GitHub上，网络问题可能导致下载安装插件失败。搭建WevDav服务这里以 Cloudreve 演示。在服务器安装并启用Cloudreve让我埋个坑，后面开篇文章写XwX在Cloudreve启用WebDav首先，首页左侧菜单点击 “连接” 。接下来，在云盘创建单独的文件夹存放笔记仓库，并点击 “创建新账号” 。设置Obsidian安装插件Remotely Save打开Obsidian，新建仓库，左下角齿轮图标点击进入设置界面。[tip type="warning"]设置是仓库隔离的。若想继承其他仓库的设置，可以将其他仓库根文件夹下的 .obsidian文件夹复制到该仓库。 [/tip]左侧菜单选择 “第三方插件” ，关闭 安全模式 。打开 社区插件市场 ，搜索 Remotely Save 。安装。设置插件Remotely Save安装完成后，启用插件，并转到插件设置页。设置WebDav登录信息。[tip type="info"]强烈建议设置 自动运行 和 启动后运行 。 [/tip]大功告成！ :@(得意)

【指南】GitHub从白嫖到入门
type: item
date: 2023-10-15T23:52:00+08:00
description: [tip type="warning"]本指南不保证时效性，实际操作可能因相关软件升级而更新，请以官方文档为准。[/tip]前言当项目体量变大，从个人到团体的开发模式势必会有极大的更改，而Git作为代码开发的管理工具，目前已被许多大厂和开发者采用。下面让我们从白嫖到入门，了解如何使用Git，并充分利用GitHub平台管理我们的代码吧。要点Git工具的安装GitHub注册与教育优惠基本的Git指令仓库管理与基本操作GitHub Page：来点开发文档吧GitHub Action：CI自动化与人类解放剩下的东西……Section 1: Git工具的安装（仅以Windows为例）官方参考：https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git进入Git官网，点选右侧Download for Windows点击Click here to download获取安装包后，（以管理员方式）运行，选择安装路径，安装即可。安装完成后检查 Git Bash 是否已安装。接下来打开cmd（Win键+R键），输入指令git -v，若出现版本信息即为安装成功。Section 2: GitHub注册GitHub Docs（中文）：https://docs.github.com/zh[DSUCCESS title="提示" font="darkgreen" bg="r" border="darkgreen"]由于地理位置，网络环境等复杂原因，GitHub经常出现掉线问题。请选择合适的加速器或者使用魔法访问。[/DSUCCESS]首先，我们需要打开GitHub官网【左Ctrl按住点选可以自动在新建页面打开哦】右上角有两个选项，若已有账户请选择Sign in，否则请选择Sign up创建账户。按照提示完善个人信息（邮箱，用户名，密码等等）之后，我们会来到个人界面。右上角点击头像，弹出右菜单。其中，Your profile是个人首页。但是我们先不打开这个，而是选择SettingsSection 3: 白嫖教育优惠（以北京邮电大学为例）北邮关于邮箱注册的说明：https://nic.bupt.edu.cn/info/1013/1482.htm首先申请学校邮箱，你会得到以@bupt.edu.cn结尾的邮箱继续回到GitHub的Settings界面，点选Emails添加你的学校邮箱，通过验证码激活。接下来打开教务系统，导出在读证明。你的邮箱会收到一份pdf，打开，查看自己的英文名。在设置里修改自己的姓名【不能少一个字母，也不能变换大小写】GitHub打开申请页面，这时候要【关闭】加速器或者魔法（他会获取你的位置，点同意），选择【Student】，填写表单。[tip type="error"]有些电脑无法获取位置的解决办法：https://zhuanlan.zhihu.com/p/643398611?utm_id=0，北邮的地理位置：东经:116.358103、北纬:39.961554[/tip]接下来会要求你提供证明，要求拍照，这时候你用手机打开那个PDF文件，让拍摄到的画面大致是这样子。提交，等待审核通过。【通过会收到邮件提示，而且会有pro的权限在Highlights】Section 4: Git的基本入门菜鸟教程-Git入门：https://www.runoob.com/git/git-tutorial.html更简明的教程：https://www.runoob.com/manual/git-guide/

【指南】manimCE使用指南（1）
type: item
date: 2023-02-28T08:53:00+08:00
description: 视频效果[video src="https://www.nickwald.top/usr/uploads/2023/02/3165716385.mp4" loop="loop" poster="https://www.nickwald.top/usr/uploads/2023/02/607553714.png" height="" width=""]代码一览from manim import * class Beginning(Scene): def construct(self): title = Text("胡说数学",font="ipix_12px",font_size=DEFAULT_FONT_SIZE*2) subtitle_vol = Text("第一集",font="ipix_12px") subtitle = Text("从数羊开始的数字",font="ipix_12px") author = Text("By Nickwald",font="ipix_12px") l = Line(UP,DOWN) subtitle_vol.next_to(title,RIGHT+DOWN*0.8,buff=-2) subtitle.next_to(title,RIGHT+UP*0.7,buff=-2) l.next_to(title,RIGHT,buff=-2.5) author.next_to(l,DOWN,buff=LARGE_BUFF) titleWriteIn = [ Write(subtitle_vol), Write(subtitle) ] titleFadeOut = [ FadeOut(title), FadeOut(subtitle_vol), FadeOut(subtitle), FadeOut(l), FadeOut(author) ] self.play(Write(title)) self.play(title.animate.shift(LEFT*3)) self.play(Create(l)) self.play(AnimationGroup(*titleWriteIn)) self.play(Write(author)) self.wait() self.play(AnimationGroup(*titleFadeOut)) self.wait()代码讲解固定格式首先，使用manim制作视频时，都需要在开头添加manim库：from manim import *接下来，我们便需要创建一个场景：class YourSceneName(Scene): def construct(self):需要注意的是，一个代码文件中可以存在多个场景，看起来可能是这样的：class SceneName1(Scene): def construct(self): //Your code here... class SceneName2(Scene): def construct(self): //Your code here...如果有多个场景，在使用manimCE渲染时，需要你选择要渲染的场景。一般文字(Text对象)[tip type='info']manimCE中的Text对象说明：说明文档 [/tip]注意到之前的代码中有这样一行：title = Text("Section 1:从数羊开始……",font="ipix_12px",font_size=30).to_corner(UL)这行代码做了两件事：创建Text对象设置Text位置我们逐个分析。[tabs][item title="创建Text对象"]首先，我们创建了Text对象，并将其赋给 title变量。下面是一些对Text对象的说明。# 一般用法 varName = Text("Some text here...")事实上，manim提供了极高的定义属性支持，完整声明如下：class Text(text, fill_opacity=1.0, stroke_width=0, *, color='#FFFFFF', font_size=48, line_spacing=- 1, font='', slant='NORMAL', weight='NORMAL', t2c=None, t2f=None, t2g=None, t2s=None, t2w=None, gradient=None, tab_width=4, height=None, width=None, should_center=True, disable_ligatures=False, **kwargs)我们仅仅就其中几个最常用的属性进行说明。color：颜色，支持诸如RED，YELL…

【指南】manimCE安装指南
type: item
date: 2023-02-27T20:00:00+08:00
description: manim是什么如果你没有看过B站UP主 3Blue1Brown 的视频，那么，你可以先在b站上观看他的视频。[BiliVideo][/BiliVideo]manim就是其为了做视频而开发的基于Python的可视化引擎。manimCE和manim的区别manimCE是manim的社区版本。作为社区版，manimCE更加活跃，开发文档也更完善。事实上，你可以从manimCE的 官方网站 上更深入地了解它。更方便的是，manimCE完善了依赖的安装方式，安装流程上自动化更高，出错率也更少。因为manimCE目前还没有中文版本支持，所以这里简单的对manimCE安装过程做个教程，方便更多人使用上这个强大的视频制作引擎。本教程仅仅说明Windows系统，其他系统的安装方式可以自行阅读开发文档。本次安装所用设备参数，仅供参考（manimCE对设备要求不高）：系统版本：Windows11 x64cpu：11代i7内存：16G安装安装ChocolateyChocolatey是Windows平台上的包管理器，通过它可以集中安装、管理、更新各种各样的软件。类似apt-get，可以一条命令自动抓取更新，省心省力自动化高。Chocolatey安装文档：戳我首先，可以打开Windows的开始菜单，在搜索栏中搜索 powershell ，右键，以管理员身份运行。运行 Set-ExecutionPolicy AllSigned ，升级权限。再运行Get-ExecutionPolicy，如果显示Restricted，则说明权限无效，需要：检查是否以管理员身份运行了powershell多次运行Set-ExecutionPolicy AllSigned，重复检查复制粘贴以下代码，然后运行：Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))安装结束后，运行choco，如果最后显示消息如下，则安装Chocolatey成功。 由于国内网络环境原因，如果安装失败，可以按上面的步骤多试几次，或者通过网络代理，更换安装源等方式改善网络。安装manimCE到这一步，安装就简单了。对于Chocolatey，我们仅仅需要一条命令：choco install manimceChocolatey就会自动安装包括manimCE在内的所有依赖。同Chocolatey一样，因为国内网络环境，可能会出现安装失败的情况。多次尝试即可。安装完成后，运行manim，应该同样会弹出版本信息。安装VSCode（可选）VSCode官网：戳我直接点击首页的Download for Windows即可。因为网络原因，下载不了的可以网上寻找安装包。安装VSCode拓展（可选）安装完VSCode后，可以从拓展中搜索Manim SideView拓展，安装。之后即可直接在VSCode中使用manimCE。 manimCE升级仅仅需要一行命令：choco upgrade manimce

C++类与对象初探（1）
type: item
date: 2022-11-30T16:53:00+08:00
description: 楔子最近学校学到了面向对象，觉得挺有意思的。以前编程觉得单纯看变量名就好，学习后才发现自己以前是面向过程的编程思维，小程序没问题，一旦工程变大，弊端就显露无疑。恰好学校雏燕计划也开始了，用上了面向对象的编程方法。觉得有必要留下点笔墨，记录下自己学习的过程，以供参考。一切的开始从第一次接触编程，变量永远是绕不开的话题。这个变量在哪里改变了值，在哪里被引用……编程绕着变量转，一切似乎都已经完美。这就是上一代程序员的感觉，他们把这种围绕变量，函数转的流程称为 面向过程 。早期软件开发面临的问题较为简单，认清问题问题到代码实现并不是太困难的事情。随着计算机的普及和应用领域的发展，计算机处理的事情越来越复杂，规模和复杂度空前扩大。人们忽然发现面向过程不太好使了。面向对象？面向对象！20世纪60年代，一场“软件危机”席卷了整个编程界。事实上，随着计算机发展，原本通常是一个人完成的工作需要更多人合力完成。虽然“人多力量大”听起来很美好，但是出于编程习惯的差异，代码版本控制缺失等问题，软件开发人员失望的发现，他们已经无法控制住软件的错误了……很要命，程序员想。可能很难理解，一个自己亲手开发的程序，为什么会落得无法控制错误的地步。可以想象下，两个无助的人漂流到荒岛，做一个简陋的茅草屋可能绰绰有余，然而，当问题变成如何建造一个100层的高楼，程序员就蚌埠住了。复杂到一定程度，面对上千上万行的庞大代码，也只能有心无力。虽然随之而来的Git代码管理，驼峰命名法等大杀器成功缓解了“有码难编”的困境，但是程序员最终发现，真正的问题出于面向过程本身。面向对象 出现了，程序员看到了新的救星。类，数据成员，成员函数让我们从生活中寻找灵感。糖果可以作为一个庞大的类（Class），我们发现，首先，糖果是有很多颜色的，其次，糖果还可以有不同的口味。我们可以定义一个新的类了。class Candy{ private: string color; string taste; };但是，结构体（Struct）依然可以替代类：struct Candy{ string color; string taste; };但是，类可以看做是结构体的一次大升级：class Candy{ public: void Set(string, string); void AskTaste(); void AskColor(); private: string color; string taste; }; void Candy::Set(string Color, string Taste){ color = Color; taste = Taste; } void Candy::AskTaste(){ cout<<"The Candy taste like "<<taste; } void Candy::AskColor(){ cout<<"The Candy is "<<color; }类不仅包括变量（数据成员 Data Members），还可以包括函数（成员函数 Member Functions）！面向对象更加符合人的认知规律，将数据和操作封装在一起。类相当于一种新的自定义数据类型，地位等同int，float，struct等等。因此在C++中，可以通过类名 对象名的方式创建一个属于类的对象。下面是一个创建对象的具体代码片段：class Candy{ //Define }; int main(void){ class Candy c1;//class可以省略 //Your Code }我们将Define部分称之为 类的声明 ，而其中的成员有三种访问属性：public为 公有性成员 ，外部可访问，作为接口protected为 保护性成员 ，外部不可访问，主要在类的继承和派生中起作用。private为 私有成员 ，外部不可访问[tip type="note"]若未声明访问属性，默认为private类型。[/tip]面向对象的优点事实上，面向对象真正促进了软件体系的重构。我们知道，需求是不断变化的，我们无法预知需求的变化，但是可以预测需求变化的位置。这样就给我们可乘之机，能够通过封装的方式将新代码和旧代码隔离，减少维护成本。面向对象通过继承和映射关系，把接口，包等等概念的实现变得简单，这也为后面设计模式的推行奠定了至关重要的基础。