vim 入门笔记——3. 进阶使用
寄存器 Vim 提供了许多寄存器⽤于存放内容,可以理解为剪贴板, ⼀个字符对应⼀个寄存器(例如a-z,0-9),不同的寄存器有对应的功能,具体细节非常复杂,下表只列举常用的寄存器。 名称 标识 内容或功能 无名寄存器 " 默认寄存器(上一次复制或删除的内容) 删除寄存器 0-9 文本复制和删除历史 小写寄存器 a-z 手动指定用于保存文本 大写寄存器 A-Z 用于追加内容到同名的小写寄存器 剪切板寄存器 + / * 系统剪贴板(需要 Vim 支持) 空寄存器 _ 删除但不存储(黑洞) 此外,还有一些存放特殊信息的只读寄存器: %:当前文件名 .:上一次插入的内容 ::上一次执行的命令 通过 :reg {register} 可以查看对应寄存器的内容,使用 :reg...
vim 入门笔记——2. 基本使用
前一篇只是 vim 的极简使用,现在正式进入 vim 的学习笔记。 参考:【Vim】可能是B站最系统的Vim教程 工作模式 vim 包括三种主要模式 Normal 模式 Insert 模式 Command 模式 以及一个临时的 Visual 模式。 启动 vim 会直接进入 Normal 模式,此时的按键不会被视作输入字符,而是视作命令,例如输入i会切换到 Insert 模式,进行正常的文本编辑状态;输入英文冒号:会切换到 Command 模式,此时光标会留在最底行,可以输入复杂的命令。 几个模式的转换如下图,Normal 模式作为转换的中枢,在其他模式中可以通过 <Esc> 键可以返回 Normal 模式,也可以使用 <Ctrl+[> 替代(默认情况下,它和<Esc>键功能完全等价)。 从 Normal 模式出发 光标移动基础 在 Normal 模式中,为了保证操作的高效连贯,我们不希望双手离开主键区,主要使用按键 hjkl...
vim 入门笔记——1. 极简使用
vim 被称为编辑器之神,学习难度很大,但是熟练掌握后可以更高效地敲代码,因此有必要学一下,但是没必要鼓捣各种插件, 为了便于内容组织,计划分成几个阶段: 极简使用 基本使用 进阶使用 第一部分的内容非常简单,只够用来临时修改一些服务器上的配置文件,但是如果不写的话,感觉笔记还是不够完整。 vim 介绍与版本 vim 是古董编辑器 vi 的升级版,在现代的 Linux 发行版中通常自带 vim,无需手动安装,虽然版本通常不是最新的,但是也足够使用。在很多发行版中都将 vi 命令链接到 vim 命令,因此 vi 命令和 vim 命令通常是等价的,都是在调用 vim 编辑器。 在 vim 中输入 :version 可以查看版本信息,例如 123VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Nov 22 2021 19:31:05)Included patches: 1-3582Compiled by...
基于 Markdown / Jupyter 生成幻灯片
Marp 简单介绍 Markdown → 幻灯片 可导出 PDF / HTML 适合讲义、科研展示、课程分享 使用方式 VS Code 安装 Marp 插件(推荐) npm 安装 Marp CLI 基本语法 基于现有的 Markdown 文件略微修改即可 使用 --- 分页,前后最好有单独空行 在头部添加元信息进行全局配置 1234567---marp: truetheme: gaiapaginate: true---... 配置 Marp 支持的配置包括全局配置和局部配置,前者出现在头部,后者出现在对应的分页。 在Markdown头部支持添加如下形式的元信息进行全局配置 12345---marp: truetheme: gaiapaginate: true--- 具体含义为: marp:true 开启 Marp 渲染(这是唯一的必选项) theme: default、gaia、uncover 几个内置主题 paginate:true、false 是否显示页码 在具体分页则可以使用html注释形式添加对应的局部配置,例如: 用大字体样式(通常用于封面)...
Numpy 学习笔记之三
NumPy 提供了比较丰富的线性代数运算功能,主要集中在 numpy.linalg 模块中,下面罗列一些基础的操作,主要针对一维和二维数组,对于其它高维数组的语义可能不太符合直觉。 重要函数 点积 np.dot np.dot() 函数可以计算两个向量的点积,最基本的用法例如 1234a = np.array([1, 2, 3], dtype=np.float64)b = np.array([4, 5, 6], dtype=np.float64)np.dot(a, b) # np.float64(32.0)# 1*4 + 2*5 + 3*6 = 32 np.dot(a, b)的完整语义需要根据两个数组的维度来区分: 第一类情况: 如果其中一个是标量,那么就是进行(逐元素的)乘法,等效于 np.multiply(a, b) 或 a * b。 第二类情况: 如果 a 是 \(N\) 维数组,b 是一维数组,那么会沿着两者的最后一个轴求和,得到 \(N-1\) 维数组。 (特例,标准情况)如果两者都是尺寸为...
Numpy 学习笔记之二
数组的拷贝 Python 本身有深拷贝和浅拷贝等复杂的概念,对于多层列表等数据结构,对应的行为差异非常明显。 但是 Numpy 的 ndarray 数组无论形状如何,在内存中始终是连续存储的,高维数组并不是数组的数组, 因此并没有深拷贝和浅拷贝的明显差异。 和其它 Python 数据一样,在函数传参过程中对 ndarray 数组的传递并不会触发任何的拷贝行为。 为了获取一个 ndarray 数组的完整拷贝,可以使用 ndarray.copy() 方法,例如 12345a = np.array([1, 2, 3])b = a.copy()b[0] = 100a # array([1, 2, 3]) 上述测试代码表明,拷贝得到的是完全独立的数组,修改不会相互影响。 也可以使用numpy.copy()函数,例如 12a = np.array([1, 2, 3])b = np.copy(a) ndarray.copy() 方法和...
Numpy 学习笔记之一
Numpy 是一个用于科学计算的 Python 扩展库,虽然不是 Python 标准库,但是已经是 Python 在科学计算、机器学习等领域毋庸置疑的基础库,很多主流的 Python 库都依赖 Numpy。 1import numpy as np 一个循序渐进的入门笔记的内容组织比较麻烦,我也并不打算这么做,这个笔记的内容会围绕一些关键点展开, 主要参考 Numpy 的官方资料。 ndarray 基本概念 np.ndarray (别名 np.array)是 Numpy 的核心数据类型,可以用于存储 n 维数组,并提供了大量相关操作方法。 它与 Python 的 list 类型类似,但是存在更多限制:只能存储同类型数据,并且尺寸是固定且规则的,即不允许各个元素长短不一的数组。 这些限制使得 ndarray 的运算非常高效(直接调用底层的 C/C++ 实现)。 但是有一点不足的是:Numpy 没有提供稀疏矩阵的数据结构,需要时可以使用其它包提供的稀疏矩阵。 我们主要关注一维数组和二维数组,例如 123array([1, 2, 3]) # shape=(3,)array([[1,...
MATLAB 高性能编程笔记
记录一些常用的MATLAB编程技巧/规范,目标是写出高效并且可维护的MATLAB代码。主要参考官方文档中的提升性能的方法。 这里的讨论只关注运算效率,假设内存总是足够的,并且不涉及并行计算和GPU。 关于代码结构 我们有很多方式执行代码:命令行 vs 脚本 vs 函数,虽然绝大多数代码在不同方式中执行都是等效的,但是考虑优化就不是一回事了,通常的运行效率关系为:命令行 < 脚本 < 函数,也就是说函数的执行速度通常是最快的。 基于模块化编程的思维,避免使用过大的单一文件,考虑将其中重复使用的功能拆分为简洁的函数文件,这种做法可以降低首次运行的成本。 优先使用局部函数而非嵌套函数,嵌套函数可以直接访问外层函数的变量(按照引用捕获),这会影响效率,更好的做法是将所有需要的变量以函数参数的形式显式传递。 关于数组操作 预分配+向量化 两个核心原则:预分配 + 向量化 预分配数组:提前分配数组大小,避免在循环中动态扩展数组。 向量化计算:尽可能使用矩阵和向量运算,避免 for 循环。 我们可以对 for 循环中的几种常见写法进行简单的对比:...
Python 理解切片的底层原理
在学习 Python 的字符串和列表所支持的切片操作,以及 Numpy 所支持的各种花式索引操作时,总是会感到非常困惑, 究其原因,就是没有理解这背后的底层原理,因此有必要专门学习一下。 __getitem__ 和 __setitem__ 方法 Python 为类型的 [] 操作提供支持的方法是 __getitem__ 方法和 __setitem__ 方法,分别提供读写的功能。 例如我们可以实现一个支持 [] 读操作的实验类型: 1234class Demo: def __getitem__(self, index): print(f"type(index) = {type(index)}") print(f"index = {index}") 尝试一下基本的索引操作 12345678910111213a = Demo()a[0]# type(index) = <class 'int'># index = 0a[-1]#...
MATLAB 单元测试
学习一下关于 MATLAB 单元测试的内容,为了维护一份健壮的代码库,单元测试是必不可少的,参考官方文档。 MATLAB 提供的测试主要包括三种风格: 基于脚本 基于函数 基于类 基于脚本的单元测试 可以通过一个脚本对指定功能进行测试,脚本名称必须以 test 开头或结尾,不区分大小写,否则测试文件可能被忽略。 每一代码节(%%)作为一个测试单元,随后的文本视作测试单元的名称,否则MATLAB会提供一个默认名称。 如果脚本中不含代码节,那么整个文件会被视作一个测试单元,测试单元的名称为脚本名称。 在测试单元中主要通过 assert...