MATLAB 单元测试
学习一下关于 MATLAB 单元测试的内容,为了维护一份健壮的代码库,单元测试是必不可少的,参考官方文档。 MATLAB 提供的测试主要包括三种风格: 基于脚本 基于函数 基于类 基于脚本的单元测试 可以通过一个脚本对指定功能进行测试,脚本名称必须以 test 开头或结尾,不区分大小写,否则测试文件可能被忽略。 每一代码节(%%)作为一个测试单元,随后的文本视作测试单元的名称,否则MATLAB会提供一个默认名称。 如果脚本中不含代码节,那么整个文件会被视作一个测试单元,测试单元的名称为脚本名称。 在测试单元中主要通过 assert 语句进行检查。 在第一个代码节之前的内容是测试的初始化代码,可以用于配置测试环境,如果这部分出现错误,会导致所有测试单元失败。 执行单元测试的流程为:在每次开始时执行初始化代码,然后跳转到某个测试单元执行,执行结束即退出,不会执行多个测试单元,无论成功或失败。 这种执行方式可以保证一个测试单元的失败不会导致整个测试中断,不同测试单元使用的变量不会相互影响。 但是由于脚本仍然是一个合法的MATLAB文件,我们还是可以直接运行整个文件,这意味着依次执行...
MATLAB 帮助系统
这篇笔记只为了解决两个问题:如何基于命令行使用MATLAB的帮助文档系统?如何让自己编写的代码(函数和类)适配MATLAB的帮助系统? 获取帮助 doc & docsearch 打开 MATLAB 文档浏览器(最新版已经改成使用系统浏览器),显示帮助中心对应的完整页面。 打开帮助中心首页 1doc 打开abs对应的页面 1doc abs 在帮助中心搜索关键字 1docsearch abs 这两个命令都是完全基于离线版的MATLAB帮助中心,和在线的MATLAB帮助中心几乎一致(除了版本和语言可能不同),通常不支持对用户自定义代码的帮助。 help help 命令可以在命令行中显示简要帮助信息。 help name 会显示 name 指定的功能的帮助文本,例如函数、方法、类、工具箱、变量或命名空间。 help 则会显示与先前操作相关的内容。 例如查找函数的帮助信息 1help abs 输出内容如下 123456789abs Absolute value. abs(X) is the absolute value of the elements of X. ...
MATLAB 踩坑记录
记录一下 MATLAB 踩过的小坑,MATLAB的各种内置函数的用法实在是太奇怪了,一个小细节就可以搞出各种问题。 矩阵元素个数 除了最常见的size(A)可以获取数组的尺寸,还有如下函数: numel(A) 可以获取(任意维度数组)所有元素个数; length(A) 可以获取向量的长度(也就是元素个数),但是扩展到高维数组的行为是非常反直觉的——返回最大维数长度,相当于max(size(A))。 矩阵偏移 函数 circshift 可以用于向量或矩阵的循环偏移,不会修改原始数据。 向量偏移 123456A = [1, 2, 3, 4, 5];circshift(A, 1)% [5, 1, 2, 3, 4]circshift(A, -1)% [2, 3, 4, 5, 1] 矩阵的偏移就比较复杂了,按照前面的做法会以行为整体进行偏移!!! 1234567A = [1 2 3; 4 5 6; 7 8 9];circshift(A, 1);% 7 8 9% 1 2 3% 4 5 6 如果希望以列进行...
Cpp 多态方案对比——回字的四种写法
虽然C++没有直接提供interface,但是却提供了虚函数、模板类型等各种语法,使得我们可以用各种方式实现多态,这里我们不区分动态多态和静态多态,而是从设计一个框架的角度,分别使用四种方案实现: 虚函数(最简单直接的方式) std::function CRTP(最晦涩的方式) deducing this(可以视作CRTP的简化,不再需要将派生类作为模板参数传递,要求C++23) 需求 我们考虑这样一个需求: 基类A包括:(不可实例化) 主方法run:调用func1,func2和func3 实现方法func1 实现方法func2(多态,允许子类修改) 实现方法func3(多态,子类必须实现) 派生类B1:继承A 实现方法func3(多态,允许子类修改) 派生类B2:继承A 实现方法func3(多态,允许子类修改):调用func4 实现方法func4(多态,允许子类修改) 具体类C1:继承B2 实现方法func4 具体类C2:继承B2 实现方法func3 最终我们直接通过各种对象自身来调用run方法,达到如下效果: 12345678Running B1 ...
解读一份极其晦涩的c++代码
事先声明,下面的各种语法技巧都是炫技式的,刻意降低代码的可读性,只是写着玩,在实际应用中是不会允许这么乱写的。 先来几个开胃菜。 开胃菜 (1) 嵌入网址? 下面这段代码看起来是在c++中直接嵌入了一个网址 1234567#include <iostream>int main(){ https://www.zhihu.com std::cout << "Hello World!" << std::endl; return 0;} 它确实是合法的c++代码,但是含义却并不是网址: 左半部分https: 是一个标签,可以通过goto跳转; 右半部分由于//的存在,就是一个注释,直接被忽略了。 下面的代码就更利于理解了 123456789#include <iostream>int main() {label: // 这是注释 std::cout << "Hello World!" << std::endl; ...
Jupyter notebook 本地和远程部署
整理一下 jupyter notebook 的各种使用方式。 本地部署 直接在本地主机上启动 jupyter notebook 服务是最简单的用法 1jupyter notebook 需要说明的是: jupyter服务默认监听本机的 8888 端口,如果本机的 8888 端口已经被占用,在启动时会自动递增,例如改为 8889 端口等,也可以使用--port选项指定; jupyter 在启动时会尝试打开本地浏览器,或者手动通过http://localhost:8888/访问即可,可以加上选项阻止自动开启浏览器 --no-browser; 默认只允许接收来自localhost的请求,可以使用 --ip 选项指定,例如--ip=0.0.0.0代表允许所有的ip访问; 默认的工作目录是执行命令时所处的目录,可以在后面加上工作目录作为位置参数,例如jupyter notebook /path/to/notebooks,还可以使用 --notebook-dir 选项指定,例如--notebook-dir=/path/to/notebooks。 除了直接在前台运行,在Linux中还可以使用...
Python 包下载和虚拟环境管理
分成如下几个部分: pip:包下载安装 venv:虚拟环境管理 conda:包下载安装和 conda 环境管理 这些内容在不同的系统(Windows/Linux)中的实现细节各有不同,在不同的 shell(pwsh/bash/fish)中,对应的脚本实现也有差异,下面以 Linux + bash 为主,也会考虑 Windows + pwsh 的情况。 为了便于区分,本文中的虚拟环境特指使用 venv 创建的虚拟环境,conda 创建的虚拟环境则称为 conda 环境。 pip 基本使用 使用 pip 可以安装 Python 包,常见形式为 1pip install <package_name> 例如安装进度条工具 tqdm 1pip install tqdm pip 会自动处理包的版本要求和依赖关系,依赖关系在不同系统下可能存在差异,例如: 在 Linux 上只会安装 tqdm 自身; 在 Windows 上会自动安装两个包:colorama, tqdm,前者是 tqdm 的依赖。 但是 pip 在卸载时并不能自动处理这种依赖关系,而是采用了非常保守的策略:...
星期算法
学习一下如何根据指定的年月日快速计算星期几,由于公历的规律性很强,将所有规律整理并不断简化就可以得到这种简便算法,有很多不同的变形算法,例如蔡勒公式,康威裁决日算法等,本文主要学习蔡勒公式。 公历 简要回顾一下公历:每年12个月,每个月可能有28、29、30、31天。 区分普通的年和闰年,非闰年有365天,闰年有366天,年份满足以下情况时为闰年: 年份除以100的余数不为0,除以4的余数为0 年份除以100的余数为0,并且除以400的余数为0 非闰年的12个月的天数依次为: 28天:2月 30天:4月、6月、9月、11月 31天:1月、3月、5月、7月、8月、10月、12月 闰年的12个月的天数依次为: 29天:2月 30天:4月、6月、9月、11月 31天:1月、3月、5月、7月、8月、10月、12月 由于公历于1582年10月正式建立,在这段时间以及更早的年份可能存在日期修正,细节比较复杂,不作讨论。 蔡勒公式 公式如下 \[ w = \left( y + \left[ \frac{y}4 \right] + \left[ \frac{c}4 \...
Docker 入门笔记
简单学习一下 Docker。 基本概念 Docker 是一种轻量级的容器化技术,与传统虚拟机相比,它更加高效,能够快速部署和运行应用程序。传统虚拟机需要完整的操作系统,每个虚拟机通常占用多个 GB,而 Docker 容器共享宿主机内核,镜像通常只有 MB 级别,占用更少的资源,启动速度更快。 首先需要区分 Docker 的两个核心概念: Docker Image(镜像):Docker 镜像是一个只读的模板(实质是宿主系统中的一个文件),包含了运行应用程序所需的所有文件和环境(包括代码、运行时、依赖项、系统工具等)。镜像可以被用来创建容器,基于一个镜像可以创建多个容器。 Docker Container(容器):容器是基于镜像创建的运行实例(实质是宿主系统中的一个进程),它提供了一个隔离的轻量级 Linux 环境,可以在其中独立运行应用程序。 容器可以被创建、启动、暂停、停止、删除等,多个容器可以在同一个主机上运行,并且它们彼此之间是相互隔离的。容器在运行过程中产生的更改通常不会影响外部系统(除非使用专门的方式,包括数据卷和绑定宿主目录等),更不会影响镜像文件。 镜像的构造过...
Linux Socket 编程入门
关于计算机网络以及Socket编程相关的概念性知识,可以参考相关资料,这里只列举了常见函数的用法,以及两个简单的例子。 Socket 相关函数 socket 函数 创建socket(套接字) 123#include <sys/socket.h>int socket(int family, int type, int protocol); 参数: family:协议族,通常取 AF_INET(IPv4) 或 AF_INET6(IPv6) type:套接字类型,通常取 SOCK_STREAM(TCP) 或 SOCK_DGRAM(UDP) protocol:协议,可以取IPPROTO_TCP、IPPTOTO_UDP,但是更建议直接取0,表示自动使用默认的协议 返回值: 创建成功:返回一个新的套接字文件描述符sockfd 创建失败:返回 -1,通过errno获取错误信息 因此最常见的两种用法以及错误处理如下 12345678910111213// TCPint sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd &l...