[小程序]PPG式心率测量模块

最近有空把之前想做的心率测量进行了开发和研究,最终选择了运动手环上面普遍采用的PPG式心率测量,载体则继续使用之前开发的”活力健身房”小程序。

什么是PPG式心率测量?

PPG是通过光电手段在活体组织中检测血液容积变化的一种无创检测方法。

测量的原理是啥?

原理:血液会吸收光纤,心跳时血液流量会规律性变化,进而产生规律性变化,进而产生规律性的光信号。

Demo视频

小程序码

使用方法

  1. 扫描小程序码
  2. 点击”我”
  3. 点击进入”心率测量”模块
  4. 阅读使用注意事项,点击下一步
  5. 开始测量,当剩余时间倒数至零时,即会生成测试结果

引用

  1. https://www.richtek.com/Design%20Support/Technical%20Document/AN057?sc_lang=zh-CN
  2. https://blog.csdn.net/QQ576494799/article/details/105024692/

ES6中的箭头函数()=>与function的区别

  1. 写法不同
  2. this指向不同
  3. 构造函数
  4. 变量提升

1.写法不同

//function
function x(a, b){
  return a + b;
}
//箭头函数
const x = (a, b)=>{
  return a + b;
}

2.this指向不同

使用function定义的函数,this的指向随着调用环境的变化而变化的,而箭头函数中的this指向是固定不变的,一直指向的是定义函数的环境。

function x(a, b){
  console.log(this);
}
const obj = ()=>{
  test: 7gugu,
}
x(); //Window
obj.test(); //obj { test: 7gugu }

使用function定义的函数中this指向是随着调用环境的变化而变化的

//使用箭头函数定义函数 
var foo = () => { console.log(this) };
var obj = { aa:foo };
foo(); //Window
obj.aa(); //Window

明显使用箭头函数的时候,this的指向是没有发生变化的。

3.构造函数

//使用function方法定义构造函数 
function Person(name, age){     
  this.name = name;   
  this.age = age; 
} 
var lenhart =  new Person(lenhart, 25);
console.log(lenhart); //{name: 'lenhart', age: 25}
//尝试使用箭头函数 
var Person = (name, age) =>{     
  this.name = name;   
  this.age = age; 
}; 
var lenhart = new Person('lenhart', 25); //Uncaught TypeError: Person is not a constructor

function是可以定义构造函数的,而箭头函数是不行的。

4.变量提升

由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!

foo(); //123
function foo(){     
  console.log('123');
}  
arrowFn(); //Uncaught TypeError: arrowFn is not a function 
var arrowFn = () => {     
  console.log('456'); 
};

转载自:https://blog.csdn.net/github_38851471/article/details/79446722

Vue Production环境中Proxy无效的解决思路&方法

问题

最近上线Vue项目到服务器,上传之后就出现了,代理404的问题。Dev环境中的代理是工作正常的,这点让我很疑惑,但这恰巧是我的一个误解,下面是这次的解决思路。

解决思路

一开始,我以为vue.config.js中的,devServer中的proxy是在路由(Router)层面做的数据转发,所以在这上面花了一些时间进行研究。后续通过查阅官方文档发现,devServer配置的是一个nodejs的测试服务器参数,而不是路由参数后,恍然大悟。(这就是我的误解所在)

解决这个proxy的方向,应该是关注于配置自身的HTTP服务器的代理上面,如果是Nginx,就要配置Nginx的路由转发;我这里用的是Apache作为我的HTTP服务器,所以应该配置的是对应的代理参数。

配置步骤

HTTP服务器部分

1.打开Apache的httpd.conf,开启以下两个proxy拓展,保存

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so 

2.在https.conf中配置监听接口,保存

3.打开httpd-vhost.conf如下图配置即可

4.此时HTTP服务器部分就配置完成了,此时仅需重启Apache服务器即可生效。

Vue部分

因为是使用了History模式的路由,所以为了正确路由到相关的页面,还需要配置相关的PathRewrite才能正确路由。

1.在vue生成生产环境文件的文件夹中,添加.htaccess文件(我使用的是默认参数,所以就在dist文件夹中)

2.配置以下参数即可。(参数参考官方文档进行配置)

3.至此Vue部分配置完成,重新访问404的问题就消除了。

参考文献

  1. vue项目使用history模式打包应该注意的地方
  2. 前端用vue 上传项目,apache服务器 成功中转接口代理
  3. Apache的ProxyPass简单使用
  4. vue项目上线apache反向代理配置跨域
  5. apache proxy作用——ProxyRequests

Vue import不识别 Unexpected Token (xx:xx)

Bug出现

最近在给工作室打工的时候,Vue做了个静态路由懒加载。

然后编译的时候死活不认这个import,截图如下,完全没有解决的思路。

解决思路

  1. 同事编译莫得问题,遂排除是代码问题
  2. 清除node_module,重新npm install,无效,排除是Node的问题
  3. 因为其他位置的import工作正常,遂排除babel未启用
  4. 最后通过下载安装”syntac-dynamic-import”,在配置后,问题解决

[回溯法] 迷宫问题

问题

思路

代码

#include "pch.h"
#include 
struct Point{
	int x;
	int y;
};

int main()
{
	int max_x = 0, max_y = 0;
	int maze_arr[100][100] = { 0 };
	scanf("%d %d", &max_x, &max_y);

	if (max_x * max_y <= 0) {
		printf("Wrong input!\n");
		return 0;
	}

	if (max_x * max_y == 1) {
		printf("No solution!\n");
		return 0;
	}

	for (int i = 0; i < max_x; i++) {
		for (int j = 0; j < max_y; j++) {
			scanf("%d", &maze_arr[i][j]);
		}
	}
	
	printf("\n");
	//第一个参数是控制行,第二个参数才是控制列
	

	int x = 0, y = 0;
	int k = 0;//步数索引
	int round = 0;

	Point path[100];//路径
	int flag[100][100];//是否走过
	int dir[100] = { 0 }; //搜索方向
	Point delta[4];//偏移量
	flag[0][0] = 1;
	while (true) {
		//0,0 第一列第0行
		//左边 0,-1 第0行第1列
		//右边 0,1 第0行第1列
		//上边 -1,0 第-1行第0列
		//下边 1,0 第1行第0列
		round = 0;//重置遍历次数
		//左方 0
		delta[0].x = x;
		delta[0].y = y - 1;
		//上方 1
		delta[1].x = x - 1;
		delta[1].y = y;
		//右方 2
		delta[2].x = x;
		delta[2].y = y + 1;
		//下方 3
		delta[3].x = x + 1;
		delta[3].y = y;
		for (int i = 0; i < 4; i++) {
			//不超出迷宫边界,即不小于0,不大于行/列
			if (delta[i].x >= 0 && delta[i].y >= 0 && delta[i].x < max_x && delta[i].y < max_y) {
				//不是墙,即所在格子值不为1
				
				if (maze_arr[delta[i].x][delta[i].y] != 1) {
					//没走过,即所在格子的flag值不为1
					if (flag[delta[i].x][delta[i].y] != 1) {
						
						//将偏移量delta加到当前坐标上
						x = delta[i].x;
						y = delta[i].y;
						path[k].x = x;
						path[k].y = y;
						//记录当前的搜索方向dir
						dir[k] = i;
						k++;
						//将当前位置的flag值标为1,表示已走
						flag[x][y] = 1;
						//是否最后一步
						if (x == max_x - 1 && y == max_y - 1) {
							//输出坐标
							printf("<0,0>\n");
							for (int j = 0; j < 100; j++) {
									if (path[j].x >= 0) {
										printf("<%d,%d>\n", path[j].x, path[j].y);
									}
							}
							return 0;
						}
						break;
					}
				}
			}
			round++;
		}
		
		if (round == 4) {
			//将当前坐标的搜索方向dir重置为0
			dir[k] = 0;
			path[k].x = 0;
			path[k].y = 0;
			//将当前坐标回退到上一步
			
			switch (dir[k-1]) {
			case 0:
				y++;
				break;
			case 1:
				x++;
				break;
			case 2:
				y--;
				break;
			case 3:
				x--;
				break;
			}
			if (k - 1 < 0) {
				printf("No solution!\n");
				break;
			}
			//令上一步的搜索方向加1(不然会重复上一次的方向)
			dir[k - 1]++;
			//回退到上一步,即让k减1
			k--;
		}

	}
	return 0;
}

运行截图

无解决方案
有解决方案

来源

华南理工大学广州学院 – 林煜东 linyd@gcu.edu.com

[小程序] 活力健身房

简介

一款基于手机加速度传感器的跑步记录小程序。
用步伐丈量世界,在活力健身房记录你的跑步轨迹,助你更快达成你的跑步目标。
运动海报,记录每一天的变化,分享好友相互勉励,在活力健身房健身不再是孤独的坚持。

小程序码

截图

仓库地址

PS

这次开发的这个小程序其实就是Lebu的升级版本,算法上升级到了2.0,计算算法更加准确且高效。加入了轨迹图,逐公里的配速曲线以及逐公里的海拔曲线。还支持运动信息海报生成。终于是把在Lebu上没实现的功能都开发完成了,开心owo

PPS

第一次参加只能当个混子,拿个三等奖了。希望明年能够有更好的成绩吧!

[小程序] 大头菜估价

简介

一个简易的大头菜估价小程序,除了可以基于你的历史价格数据,给出接下来一段时间的价格,还能给出一些出手的建议,实属卖菜利器。

小程序码

截图

近况

上岛了这么久,其实我很少机会去卖菜,基本上都是在钓鱼ing,由于选在了南半球,所以快把图谱开完了,就一直没去买卖大头菜了。如果你想找我玩的话,欢迎通过邮箱联系我,交换SW码owo

GuFilm – Vol.1

拍摄设备: 武士X3半幅照相机

胶卷: 柯达金胶卷

人民公园 & 北京路

陈家祠 & 百合

荔湾花市

桔子🍊树 (粤语音同吉, 摆在家中寓意吉利)

桃花 & 牡丹

荔湾湖公园 & 中山八路

永庆坊

粤剧博物馆 & 馆中的金鱼池

奶油草莓🍓

地铁🚇 & 麒麟阁(已经有30年的老饭店, 现在顺应潮流, 变成了茶餐厅😂)

太古仓 & 游艇码头 (码头提供游艇培训, 只要2w就能学习如何开游艇)

木棉花(广州市花)

[笔记] 设计模式 面向对象设计原则

  • 课程目标
    • 面向对象设计原则
  • 原则概述
    • 可维护性
      • 指的是软件可以很方便的理解、改正、适应和拓展的难易程度
      • 就是方不方便修改了的意思
    • 可复用性
      • 指的是软件能被重复使用的难易程度
    • 指导性原则
    • 用于评价一个设计模式的使用效果的重要指标之一
    • 为支持可维护性复用诞生
  • 单一职责原则
    • 一个类制作一件事
    • 作用
      • 用于控制一个类的粒度
      • 保证一个类里面不用实现所有的功能,仅仅需要实现单一职责即可
    • 定义
      • 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中
    • 就一个类而言,应该仅有一个引起变化的原因
  • 开闭原则
    • 不修改源代码,只添加代码
    • 定义
      • 软件实体只能增加功能,尽量不修改功能
      • 尽可能只是拓展代码来增加新功能/修改原有功能
    • 关键
      • 抽象化
    • 具有稳定的抽象层+灵活的具体层
    • 修改配置文件,增加类,这个些操作都符合开闭原则
  • 里氏代换原则
    • 父类对象可被子类对象代替,且程序将不会产生任何错误和异常(因为子类把父类的一些方法重载了)
    • 在程序中尽可能使用基类类型来对对象进行定义
  • 依赖倒转原则
    • 编程使用配置文件,仅仅是接受对象操作对象,在外部进行创建对象注入
  • 接口隔离原则(网络上的那种API接口)
    • 一个接口尽可能做少的事情
    • 把接口都拆开来
  • 合成复用原则
    • is-a继承复用  has-a组合/聚合复用
    • 就是类似于把mysql的obj反射出来,然后再操作
  • 迪米特原则
    • 减少对象之间的交互
    • 两个对象不应该发生任何直接的相互作用
    • 通过”第三者”转发这个调用
    • 引入一个合理的”第三者”来降低现有对象之间的耦合度