Introduction

本博客用于记录本人的想法,知识。

本人账号:r1Way (github.com)

本项目:r1Way/know

本页面由mdbook构建,并部署在github page上,有兴趣者,可点击make_github_page

111

[toc]

Git

创建仓库

git init repo_nmae

切换目录

  • cd directory

  • cd ..返回上一级

  • cd .本级

删除目录

\rm -rf directory

创建文件夹

mkdir temp

复制文件夹

cp -rf 原文件名 复制后的文件名

复制时会把版本号等都复制过去

文件

写入

echo 111 > file1.txt

echo 111 >temp/file2.txt (temp是一个文件夹)

显示

cat file1.txt

修改

vi file1.txt

退出编辑模式:wq

删除

\rm -rf file1.txt

重命名

mv old_folder_name new_folder_name

查看所有文件

  • ls

  • ls -a包含隐藏

  • ls -ltr 按照时间显示

  • git ls-files查看暂存区文件

工作区->暂存区

git add file1.txt

git add *.txt

git add . 提交所有

缓存区->仓库区

git commit file1.txt -m "first commit "

git commit -am " " 同时完成add 和commit(前提是该文件不是新建的)

查看提交记录

  • git log
  • git log --oneline

可按wq退出

回退版本

git reset --soft/hard/mixed 版本号

soft 保留工作区、暂存区

hard 均不保留

mixed 保留工作区,不保留暂存区

返回上一版本用 HEAD^

返回错了,可用git reflog查看

查看版本区别

  • 基本

git diff工作区与暂存区

git diff HEAD工作区(及暂存区)与仓库区

git diff --cached暂存区与仓库区

  • 扩展

git diff version1 version2 比较两个版本(版本2=版本1 -- ++)

git diff version1 HEAD(HEAD代表最新提交结点)

git diff version1 HEAD^git diff version1 HEAD~为与上一个版本进行比较

git diff HEAD~2 HEAD HEAD与HEAD前2个版本进行比较

git diff HEAD~3 HEAD file3.txt 仅比较 file3.txt

删除文件

  • 方法一

    rm file1.txtgit add .

  • 方法二

    git rm <file> 将文件从工作区和暂存区删除

    git rm --cached <file> 将文件仅从暂存区删除

方法一与方法二用完后,都要记得git commit -m ""

  • 方法三 删除文件夹

    git rm -r --cached <directory_name>

    然后commit,然后再push,这样远程仓库的文件夹就会被删除,但是本地的保留

忽略文件

  • 忽略某个文件

echo <file> >> .gitignore或者vi .gitignore

  • 忽略某个后缀的文件

echo *.txt >> .gitignore

  • 忽略某个文件夹

echo "temp/" >> .gitignore

无法忽略已经提交过的文件

克隆

git clone <SSH>

拉取更新(远程到本地)

git pull <SSH>

git pull <远程库别名> <远程branch>:<本地branch>

推送更新(本地到远程)

git push <remote库><本地branch>:<远程branch>

关联本地仓库和远程仓库

  • 添加远程仓库

git remote add <远程仓库别名> <远程仓库地址> (别名多为origin)

把本地main与远程main 关联

git push -u origin <本地分支名>:<远程分支名>(-u指upstream, 若本地与远程名称相同,可省略冒号以后内容)

  • 查看别名及地址

git remote -v

  • 拉取远程仓库内容

git pull <远程仓库r名> <远程分支名> :<本地分支名>

git pull默认将origin 的main与本地main合并

如果出问题了,就用git branch -m main将本地分支改个名

检查本地仓库是否是空的,或者有冲突的,然后就可以git push -m origin main

  • 有冲突时(远程有本地没有的文件)报错

     ! [rejected]        main -> main (fetch first)
    error: failed to push some refs to 'github.com:r1Way/remote-repo.git'
    hint: Updates were rejected because the remote contains work that you do not
    hint: have locally. This is usually caused by another repository pushing to
    hint: the same ref. If you want to integrate the remote changes, use
    hint: 'git pull' before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details.
    
  • 最佳实践

    关联仓库时,本地先别提交,先拉取README.md,再push

  • 删除远程库

git remote rm <remote_name>

分支

  • 创建分支

git branch <branch name>

别忘记提交

  • 查看分支

git branch

  • 切换分支

git switch <branch name>

git checkout <branch name> (不好有歧义)

不同分支的文件内容在同一文件下,但用ls只能看到当前分支的内容(新分支会包含旧分支的文件)

  • 合并分支

git merge <branch name>将该branch合并到本branch下,默认让我们进行一次提交

  • 查看分支图

git log --graph --oneline --decorate --all

当main也有新的commit后,才容易看到合并的图像

分支被合并后不会消失

  • 删除本地分支

若已经合并

git branch -d <branch name>

若未合并

git branch -D <branch name>

  • 删除远程分支

    git push origin --delete [branch_name]

image-20240605171148497

刘星池@river-away MINGW64 ~/learn-git/branch-demo (main)
$ git log --graph --oneline --decorate --all
*   b334c02 (HEAD -> main) gerge branch 'other' merge the branch other
|\
| * f0db2b0 (other) commit other1.txt
* | fc0e809 commit main4.txt
|/
* 3618250 commit from branch dev
* 6dae08c first commit

刘星池@river-away MINGW64 ~/learn-git/branch-demo (main)
$ git log --oneline
b334c02 (HEAD -> main) gerge branch 'other' merge the branch other
fc0e809 commit main4.txt
f0db2b0 (other) commit other1.txt
3618250 commit from branch dev
6dae08c first commit

解决合并冲突

  • 查看冲突文件

git status

  • 查看冲突内容

git diff

此时冲突文件中会将两冲突同时显示在文件内

image-20240606192123054

等号上方为当前branch(主干),下方为被合并的branch(侧枝)。

把左箭头,右箭头等号都去掉。然后保存后提交

  • 终止合并

git merge --abort

回退和rebase

git rebase main将本分支到公共结点的提交记录变基到另一条分支上

git checkout -b dev <版本号> 恢复被删除的分支

alias graph="git log --oneline --graph --decorate --all" 来简化我们的命令

规范

  • 版本号规则

git tab 标记版本号

image-20240607124122985

更改Git起始目录

http://t.csdnimg.cn/BhONz

原为:

目标F:\Git\Git\git-bash.exe --cd-to-home

起始位置%HOMEDRIVE%%HOMEPATH%

改为F:\Git\Git\git-bash.exe

起始位置G:\inspire\simulator

注意是右斜线(反斜杠)

Trouble Shooting

(use "git restore <file>..." to discard changes in working directory)

$ git commit -m"commit error refer to the last time"
On branch temp
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   ../project/.vs/project/v15/.suo
        modified:   ../project/.vs/project/v15/Browse.VC.db
        modified:   ../project/.vs/project/v15/ipch/AutoPCH/c8e138fe51f15a31/GATE.ipch
        modified:   ../project/project/Element.h
        modified:   ../project/project/Gate.h
        modified:   ../project/project/project.vcxproj
        modified:   ../project/project/project.vcxproj.filters
        modified:   ../project/project/project.vcxproj.user

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        ../project/project/Event.h
        ../project/project/Time.h

no changes added to commit (use "git add" and/or "git commit -a")
  • 解决

    回到上一目录(project),git add .才能将我所有的文件提交完。

打开git log --oneline后,无法退出

  • 按q

git pull后因为conflict跟本地分支merge了

  • vi 修改冲突后,add commit,后main|MERGING就消失了

  • 刘星池@river-away MINGW64 /g/know/src (main)
    $ git pull
    Auto-merging src/SUMMARY.md
    CONFLICT (content): Merge conflict in src/SUMMARY.md
    Automatic merge failed; fix conflicts and then commit the result.
    
    刘星池@river-away MINGW64 /g/know/src (main|MERGING)
    $ vi SUMMARY.md
    
    刘星池@river-away MINGW64 /g/know/src (main|MERGING)
    $ git add .
    
    刘星池@river-away MINGW64 /g/know/src (main|MERGING)
    $ git commit -m"deal merge"
    [main 66f29ba] deal merge
    
    刘星池@river-away MINGW64 /g/know/src (main)
    $ git push
    
    

! [rejected] main -> main (non-fast-forward)

  • 问题
To github.com:r1Way/work_manage.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'github.com:r1Way/work_manage.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
$ git pull origin main
From github.com:r1Way/work_manage
 * branch            main       -> FETCH_HEAD
fatal: refusing to merge unrelated histories
  • 解决

你遇到的错误信息“fatal: refusing to merge unrelated histories”通常是因为本地和远程的 main 分支并没有共同的历史记录。这种情况通常在以下几种情况下发生:

  1. 你在本地仓库里创建了一个新的 Git 仓库,而远程仓库是一个全新的仓库,没有相同的提交历史。
  2. 远程仓库被重置过(例如,进行过 git reset --hard),导致其历史与本地的不同。

合并远程分支:使用以下命令来拉取远程分支并合并:

git pull origin main --allow-unrelated-histories  

Vim

  • 按到ctrl+c退出时

shell输入fg

  • set number! 显示行号
  • split水平线分割,vsplit竖直线分割

matlab相关函数使用

matlab 多目标最优 paretosearch

%main.m
clc
clear
fun=@(x)func_temp(x);
A=[-1 0;
   0 -1];
b=[-1 ;-2];
x=paretosearch(fun,2,A,b);
plot(x(:,1),x(:,2),'m*');
xlabel('x(1)');
ylabel('x(2)');
%func_temp.m
function f=func_temp(x)
    f(1)=x(1)+x(2);
    f(2)=2*x(2)+x(2);
end

三维空间中的汉字

text(x,y,z,'string')

matlab如何在三维图形中添加汉字注释?_百度知道 (baidu.com)

绘制圆形

Matlab------在Matlab中如何画圆_matlab画圆函数-CSDN博客

让原点在右上角,x轴向左,y轴向右

set(gca, 'XDir', 'reverse');  % x 轴方向反转
set(gca, 'YDir', 'reverse');  % y 轴方向反转
set(gca, 'XAxisLocation', 'top');  % x 轴在顶部
set(gca, 'YAxisLocation', 'right');  % y 轴在右侧

要沿 x 轴和 y 轴使用长度相等的数据单位

axis equal

求函数零点

  • fzero
%fzero_test.m
function h=fzero_test(a)
    h=a^2-9;
end
%test.m
x0=[2 4];
fzero(@fzero_test,x0) % ans=3

matlab line 宽度,颜色,宽度

line([x1,x2],[y1,y2],'LineWidth', 2);

matlab利用最优化解决非线性微分方程

使用一次

x = optimvar('x');
y = optimvar('y');
x0=struct();
prob = optimproblem("Objective",peaks(x,y));

prob.Constraints.cons1 = x^2 + y^2 == 4;
prob.Constraints.cons2 = x^2 - y^2 == 0;
prob.Constraints.cons3 = x>=0;
prob.Constraints.cons4 = y>=0;
x0.x = 1;
x0.y = -1;
sol = solve(prob,x0)

约束不支持

当需要进行迭代时

x = optimvar('x');
y = optimvar('y');
x0=struct();
prob = optimproblem("Objective",peaks(x,y));

prob.Constraints.cons1 = x^2 + y^2 == 4;
prob.Constraints.cons2 = x^2 - y^2 == 0;
prob.Constraints.cons3 = x>=0;
prob.Constraints.cons4 = y>=0;
x0.x = 1;
x0.y = 0;
sol = solve(prob,x0)

%允许的
prob = optimproblem("Objective",peaks(x,y));
prob.Constraints.cons1 = x^2 + y^2 == 2;
prob.Constraints.cons2 = x^2 - y^2 == 0;
prob.Constraints.cons3 = x>=0;
prob.Constraints.cons4 = y>=0;
x0.x = 1;
x0.y = 0;
sol = solve(prob,x0)

参考

基于问题的有约束的非线性方程组 - MATLAB & Simulink - MathWorks 中国 求解优化问题或方程问题 - MATLAB solve - MathWorks 中国 求解优化问题或方程问题 - MATLAB solve - MathWorks 中国

求解非线性方程组

  • fsolve()

matlab绘制datetime与因变量关系图

clc
clear
close all
fileName1_1="attach1_1.CSV";
data=readtable(fileName1_1)
% Assuming "data" is your array with missing values
data = rmmissing(data);%清理数据,删除数据丢失的行

time=datetime(table2array(data(:,1)),'InputFormat', 'yyyy-MM-dd HH:mm:ss');
T1=table2array(data(:,2));%table转数值数组
T2=table2array(data(:,3));

figure;
plot(time,T1);%打印
hold on;
plot(time,T2);%打印
hold on;
hold off;

matlab三维路径规划绘图.md

temp_matlab_road

绘制立方体

hold on
grid on
plotcube([5 5 5],[ 2 2 2],.8,[1 0 0]);
plotcube([2 1 3],[ 10 10 10],.8,[144/256 144/256 144/256]);
axis([0 2000 0 2000 -200 600 ])   %设置图像的可视化范围

axis equal     % 图像坐标轴可视化间隔相等 
xlabel('x');
ylabel('y');

plotcube([长,宽,高],[x,y,z坐标] , 透明度0~1 , [r , g ,b 0~1] );

绘制立方柱

clc
clear
close all
hold on
grid on
rows=7;
place=randi(15,rows,2);
height=randi(15,rows,1);
for i=1:rows
    plotcube([2,2,height(i)],[place(i,:),0],0.8,[1 1 0]);
end

axis([0 2000 0 2000 -200 600 ])   %设置图像的可视化范围
axis equal     % 图像坐标轴可视化间隔相等 
xlabel('x');ylabel('y');

自由视角

命令行输入 cameratoolbar

生成随机数矩阵

randi(max,rows,cols) 生成rows *cols的1~max的随机数矩阵

GPU加速

  • gpuArray
a=[1 2 3;4 5 6 ; 7 8 9];%a在cpu里进行计算
b=gpuArray(a);%b在gpu里进行计算
  • parfor 并行循环

简单看看matlab的GPU加速

一阶微分方程

  • 代码
%deal.m
function f=deal(t,y)
    f=(y^2-t-2)/(4*(t+1));
end
%test.m
[t,y]=ode45('deal',[0,2],0);
plot(t,y);
  • 效果

4ee8d075542d410222899a1fde32f53b

  • 带参数
%直线阻尼器的阻尼系数为常数
function f=myODE(t,x,a)    %a为直线阻尼系数
    k1=1025*9.8*pi*1^2;%静力回复系数
    k2=656.3616;%兴波阻力系数
    k3=80000;%弹簧刚度
    m1=2433;%振子质量
    m2=4866;%浮子质量
    m3=1335.535;%附加质量
    w=1.4005;%入射波浪频率
    f=6250;%垂荡激励力振幅 (N)
    %{
    x1 振子位移,向上为正
    x2 浮子位移,向上为正
    x3=diff(x1)
    x4=diff(x2)
    %}
    f=[
        x(3);
        x(4);
        ( -k3*(x(1)-x(2))-a*(x(3)-x(4)) )/(m1);
        ( f*cos(w*t)-k1*x(2)-k2*x(4)+k3*(x(1)-x(2))+a*(x(3)-x(4)) )/(m2+m3);
    ];
end
%main.m
[t,x]=ode45(@(t,x)myODE1(t,x,a),[0,40*2*pi/w],[0,0,0,0]);%括号一

可正常运行

一阶微分方程组

function f=deal(t,y)
    f=[1;y(1)];
end
options = odeset('MaxStep', 1);
[t,y]=ode45('deal',[0,10],[0,0],options);
figure;
hold on;
plot(t,y(:,2));
  • 效果

2ddd1f054574b1e3d7492ae106bf0ea8

013a566a6ca71e3185bfff022f1bb03d

获取矩阵最大/最小元素及索引

[power_max,power_pos]=max(power_sum);
[maxVal, linearIndex] = max(power_sum(:));% 获取最小值和线性索引
[row, col] = ind2sub(size(power_sum), linearIndex);% 将线性索引转换为行列索引

绘制等高地形图,深度图,高度图

filename='attach.xlsx';
data=readtable(filename);

south_north=table2array(data(2:end,1));
west_east=table2array(data(1,2:end));
depth=table2array(data(2:end,2:end));

%海水深度
figure;
surf(repmat(south_north,1,201),repmat(west_east,251,1),depth);
font_size=15;
title("海水深度",FontSize=font_size+2);
xlabel("从南到北/NM",FontSize=font_size);
ylabel("从西到东/NM",FontSize=font_size);
zlabel("海水深度/m",FontSize=font_size);
shading interp;
saveas(gcf,'land_depth.png');

%海底形状
figure;
surf(repmat(south_north,1,201),repmat(west_east,251,1),-1*depth);
title("海底形状",FontSize=font_size+2);
xlabel("从南到北/NM",FontSize=font_size);
ylabel("从西到东/NM",FontSize=font_size);
zlabel("海拔高度/m",FontSize=font_size);
shading interp;
saveas(gcf,'land_shape.png');

%二维等高地平线
figure;

contourf(repmat(south_north,1,201),repmat(west_east,251,1),-1*depth);
title("海底等高地形图",FontSize=font_size+2);
xlabel("从南到北/NM",FontSize=font_size);
ylabel("从西到东/NM",FontSize=font_size);
zlabel("海水深度/m",FontSize=font_size);
colormap jet; % 设置颜色映射
colorbar; % 添加颜色图例
saveas(gcf,'land_same_height.png');

CSV导入数据,等高散点图

  • 法一
filename='attach1.csv';
data=readtable(filename, 'VariableNamingRule', 'preserve');
x=table2array(data(:,2));
y=table2array(data(:,3));
z=table2array(data(:,4));

figure;
font_size=15;
scatter3(x, y, z, 20, z, 'filled'); % 36为点的大小,z用于指定颜色
xlabel("x/m",FontSize=font_size);
ylabel("y/m",FontSize=font_size);
zlabel("z/m",FontSize=font_size);
colorbar; % 添加颜色图例
saveas(gcf,"fast.png");
  • 法二
filename='attach1.xls';
data=readtable(filename, 'VariableNamingRule', 'preserve');

wei=data.("任务gps 纬度");
jing=data.("任务gps经度");

无须再使用table2array

surf 光滑

clc;
clear;
filename='attach1.xlsx';
data=readtable(filename, 'VariableNamingRule', 'preserve');
data=table2array(data);
size=256;

surf(repmat(1:size,size,1)',repmat(1:size,size,1),data);
shading interp; % 启用插值着色

Makefile

如何编译 C++ 程序:轻松搞定 Makefile

示例

#设置编译器
CC := g++

SRCS := $(shell find ./* -type f | grep '\.cpp' | grep -v './main\.cpp')
$(warning SRCS is $(SRCS))

OBJS :=$(patsubst %.cpp, %.o,$(filter %.cpp, $(SRCS)))
$(warning OBJS is $(OBJS))

#搜索路径
INCLUDE := -I.

MAIN_SRC :=main.cpp
MAIN_OBJ :=$(patsubst %.cpp,%.o,$(MAIN_SRC))
MAIN_EXE :=main

target:$(MAIN_EXE) 
$(MAIN_EXE):$(OBJS) $(MAIN_OBJ) 
	$(CC)  -o $@ $^ $(INCLUDE) 

%.o: %.cpp
	$(CC) $(INCLUDE) -c $< -o $@

clean:
	rm -rf *.o $(MAIN_EXE) 
  • 代码

main.cpp

#include<iostream>
#include"add.h"
int main()
{
    std::cout<<"result: "<<add(3,5)<<std::endl;
    return 0;
}

add.h

#pragma once
int add(int a,int b);

add.cpp

#include"add.h"
int add(int a,int b)
{
    return a+b;
}

编译一个简单的程序

gcc

编译

源文件(.cpp)编译生成目标文件(.o)

gcc -c main.c -o main.o

链接

目标文件(.o)链接生成可执行文件

gcc main.o -o main

单命令

不生成 .o文件

gcc main.cpp -o main -lstdc++

运行

./main

链接错误

test.o:test.cpp:(.text+0x17): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
test.o:test.cpp:(.text+0x4f): undefined reference to `std::ios_base::Init::~Init()'
test.o:test.cpp:(.text+0x7f): undefined reference to `std::ios_base::Init::Init()'
test.o:test.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout]+0x0): undefined reference to `std::cout'
collect2.exe: error: ld returned 1 exit status
  • 解决方法

链接某个库

gcc main.o -o main -lstdc++

g++

编译

g++ -c main.cpp -o main.o

链接

g++ main.o -o main

单命令

g++ main.cpp -o main

区别:g++相较gcc会默认链接标准库

C++编译流程

  1. 预处理

    把#include语句以及一些宏插入程序文本中,得到*.i文件

    g++ -E main.cpp -o main.i
    
  2. 编译

    将*.i 编译成 *.s的汇编语言程序

    g++ -S main.i -o main.s
    
  3. 汇编

    将* .s翻译成机器语言的二进制指令,并打包成一种可重定位目标程序的格式,并将结果保存在*.o文件中

    g++ -c main.s -o main.o
    
    
  4. 链接

    合并全部 *.o文件,得到可执行文件。

    g++ main.o -o main
    

预处理、编译、汇编三合一

g++ -c main.cpp -o main.o

生成 .o文件时才加-c

预处理、编译、汇编、链接四合一

g++ main.cpp -o main

编译和链接错误

编译错误

为包含头文件

源代码

main.cpp

#include<iostream>

int main()
{
    std::cout<<"result: "<<add(3,5)<<std::end;
    return 0;
}

add.cpp

int add(int a,int b)
{
    return a+b;
}

运行

g++ -c add.cpp -o add.o
g++ -c main.cpp -o main.o
g++ main.o add.o -o main

g++ main.cpp add.cpp -o main

报错

main.cpp: In function 'int main()':
main.cpp:5:28: error: 'add' was not declared in this scope
     std::cout<<"result: "<<add(3,5)<<std::end;
                            ^~~
main.cpp:5:28: note: suggested alternative: 'rand'
     std::cout<<"result: "<<add(3,5)<<std::end;
                            ^~~
                            rand

解决

  • 写头文件add.h
#pragma once
int add(int a,int b);
  • 包含头文件
#include<iostream>
#include"add.h"
int main()
{
    std::cout<<"result: "<<add(3,5)<<std::endl;
    return 0;
}

链接错误

未提供实现

源代码

add.cpp为空

// int add(int a,int b)
// {
//     return a+b;
// }

报错

main.o:main.cpp:(.text+0x34): undefined reference to `add(int, int)'
collect2.exe: error: ld returned 1 exit status

解决

在add.cpp中提供实现(记得保存),重新编译。

源文件要包含头文件

  • 会检查函数定义与函数实现是否一致

头文件搜索路径

  • #include "head.h"按照相对工程的路径去找头文件

  • #include <head.h>按照头文件搜素路径去找头文件

    • 将当前路径.添加到头文件搜索路径
  g++ -I. add.cpp main.cpp -o main

-I dir 将dir添加到文件查找路径

多文件编译

  • 法一

    每个源文件生成.o文件,再链接

  • 法二

    g++ -I. add.cpp sub.cpp main.cpp -o main
    

Makefile基本功能

法一

target:
	g++ -I. add.cpp main.cpp -o main
  • target:目标名称,可以随便命名

  • g++ 前面不是空格,必须是 tab 缩进

  • Makefile 里如果有多个目标,可以通过 make加目标名称来执行指定的目标,如果不指定目标,则默认选择第一个目标执行

    make target
    

法二

target:main

main:
	g++ -I. add.cpp main.cpp -o main

tatget main表示 target 目标依赖 main 目标

  • 未指定目标
  make

默认调用第一个目标(target)的第一个目标(main)

  • 指定目标
make main

法三

target: add_o main_o main

main:
	g++ add.o main.o -o main

add_o:
	g++ -I. -c add.cpp -o add.o

main_o:
	g++ -I. -c main.cpp -o main.o 
  • target的各个目标有顺序,先进行add_o再进行main_o,最后进行main

Makefile升级用法

模式规则

target: add.o main.o main

main:
	g++ add.o main.o -o main

%.o: %.cpp
	g++ -I. -c $< -o $@
  • 说明

    • %.o:%.cpp 所有的.o文件都由相同名称的 .cpp文件编译生成
    • <表示第一个依赖值
    • ^表示所有依赖的挨个值
    • @表示所有目标的挨个值

    “<” ,“@” 被称为自动化变量

变量替换

OBJS = main.o add.o

target: $(OBJS) main

main:
	g++ $(OBJS) -o main

%.o: %.cpp
	g++ -I. -c $< -o $@

说明

  • 引用变量时,加上小括号或大括号,这样可以更安全
  • =是最基本的变量
  • :=是覆盖之前的值
  • ?=是如果没有被赋值过,就赋予等号后面的值
  • +=是添加等号后面的值

清理文件

  • PowerShell

    OBJS = main.o add.o
    
    target: $(OBJS) main
    
    main:
    	g++ $(OBJS) -o main
    
    %.o: %.cpp
    	g++ -I. -c $< -o $@
    
    clean:
    	del $(OBJS) main.exe
    
  • Bash

    OBJS = main.o add.o
    
    target: $(OBJS) main
    
    main:
    	g++ $(OBJS) -o main
    
    %.o: %.cpp
    	g++ -I. -c $< -o $@
    
    clean:
    	rm -rf $(OBJS) main
    

Makefile高级用法

文件过滤

SRCS := $(shell find ./* -type f | grep '\.cpp')
$(warning SRCS is $(SRCS))

OBJS :=$(patsubst %.cpp, %.o,$(filter %.cpp, $(SRCS)))
$(warning OBJS is $(OBJS))

target: $(OBJS) main

main:
	g++ $(OBJS) -o main

%.o: %.cpp
	g++ -I. -c $< -o $@

clean:
	rm -rf *.o main	

编译选项

SRCS := $(shell find ./* -type f | grep '\.cpp')
$(warning SRCS is $(SRCS))

OBJS :=$(patsubst %.cpp, %.o,$(filter %.cpp, $(SRCS)))
$(warning OBJS is $(OBJS))

#编译选项
CFLAGS := -g  -o2 -Wall -Werror -Wno-unused -ldl -std=c++11

#搜索路径
INCLUDE := -I.

target: $(OBJS) main

main:
	g++ $(OBJS) -o main

%.o: %.cpp
	g++ $(INCLUDE) $(CFLAGS) -c $< -o $@

clean:
	rm -rf *.o main	

Makefile 多入口编译

多入口

CC := g++

SRCS := $(shell find ./* -type f | grep '\.cpp' | grep -v './main\.cpp' | grep -v './test\.cpp')
$(warning SRCS is $(SRCS))

OBJS :=$(patsubst %.cpp, %.o,$(filter %.cpp, $(SRCS)))
$(warning OBJS is $(OBJS))

#搜索路径
INCLUDE := -I.

MAIN_SRC :=main.cpp
MAIN_OBJ :=$(patsubst %.cpp,%.o,$(MAIN_SRC))
$(warning $(MAIN_OBJ))
MAIN_EXE :=main

TEST_SRC :=test.cpp
TEST_OBJ :=$(patsubst %.cpp,%.o,$(TEST_SRC))
$(warning $(TEST_OBJ))
TEST_EXE :=test

target:$(MAIN_EXE) $(TEST_EXE)

$(MAIN_EXE):$(OBJS) $(MAIN_OBJ) 
	$(CC)  -o $@ $^ $(INCLUDE) 

$(TEST_EXE):$(OBJS) $(TEST_OBJ) 
	$(CC)  -o $@ $^ $(INCLUDE) 

%.o: %.cpp
	$(CC) $(INCLUDE) -c $< -o $@

clean:
	rm -rf *.o $(MAIN_EXE) $(TEST_EXE)
  • $(patsubst %.cpp,%.o,$(MAIN_SRC))表示将MAIN_SRC中的所有.cpp文件替换为.o的文件赋值给MAIN_OBJ

单入口模板

#设置编译器
CC := g++

SRCS := $(shell find ./* -type f | grep '\.cpp' | grep -v './main\.cpp')
$(warning SRCS is $(SRCS))

OBJS :=$(patsubst %.cpp, %.o,$(filter %.cpp, $(SRCS)))
$(warning OBJS is $(OBJS))

#搜索路径
INCLUDE := -I.

MAIN_SRC :=main.cpp
MAIN_OBJ :=$(patsubst %.cpp,%.o,$(MAIN_SRC))
MAIN_EXE :=main

target:$(MAIN_EXE) 
$(MAIN_EXE):$(OBJS) $(MAIN_OBJ) 
	$(CC)  -o $@ $^ $(INCLUDE) 

%.o: %.cpp
	$(CC) $(INCLUDE) -c $< -o $@

clean:
	rm -rf *.o $(MAIN_EXE) 

inc 、src

  • 结构图
|-inc
|  └add.h
|-src
|  └add.cpp
|-main.cpp
|-Makefile
  • 将 add.cpp 挪到 src 目录下仍然可以正常编译
  • 将 add.h、sub.h 挪到 inc目录下只需修改 INCLUDE 即可
#设置编译器
CC := g++

SRCS := $(shell find ./* -type f | grep '\.cpp' | grep -v './main\.cpp')
$(warning SRCS is $(SRCS))

OBJS :=$(patsubst %.cpp, %.o,$(filter %.cpp, $(SRCS)))
$(warning OBJS is $(OBJS))

#搜索路径
INCLUDE := -I. -I ./inc

MAIN_SRC :=main.cpp
MAIN_OBJ :=$(patsubst %.cpp,%.o,$(MAIN_SRC))
MAIN_EXE :=main

target:$(MAIN_EXE) 
$(MAIN_EXE):$(OBJS) $(MAIN_OBJ) 
	$(CC)  -o $@ $^ $(INCLUDE) 

%.o: %.cpp
	$(CC) $(INCLUDE) -c $< -o $@

clean:
	rm -rf *.o $(MAIN_EXE) 

静态库 动态库

P11 P12

【如何编译 C++ 程序:轻松搞定 Makefile】https://www.bilibili.com/video/BV1dF41117NV?p=11&vd_source=ec4e4974e1b56ed330afdb6c6ead1501

CMake

模板

cmake_minimum_required(VERSION 3.14)

project(hello)

include_directories(./ ./inc)

file(GLOB_RECURSE SOURCES "src/*.cpp")

add_executable(main ${SOURCES} main.cpp)s

参考

  • 本文件为下方链接中视频的笔记

如何编译 C++ 程序:轻松搞定 CMake

安装

  • 检验
cmake --version

[Windows下Cmake安装步骤详解(图文)_windows终端安装cmake-CSDN博客](https://blog.csdn.net/qq_42598221/article/details/121952160?ops_request_misc=%7B%22request%5Fid%22%3A%22172282160116800222890009%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=172282160116800222890009&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~top_positive~default-1-121952160-null-null.nonecase&utm_term=windows Cmake&spm=1018.2226.3001.4450)

CMake 编译流程

  1. 编写
  2. 执行 cmake PATH 生成 Makefile(PATH 为CMakeLists.txt所在目录)
  3. 执行 make 编译

编写CMakeLists.txt

add_executable(main main.cpp)

add_executable:使用指定的源文件生成目标可执行文件

生成Makefile文件

  • 一般
cmake .
  • 若未生成 Makefile文件,而是生成了一大堆其他文件

第一次

cmake . -G "Unix Makefiles"

之后

cmake .

解决【Windows】下CMake不能生成makefile的问题_cmake不生成makefile-CSDN博客

编译项目

make

修复告警

cmake_minimum_required(VERSION 3.14)

project(hello)

add_executable(main main.cpp)

cmake_minimum_required:用于设定CMake的最低版本

project:指定工程名称

语言版本

cmake_minimum_required(VERSION 3.14)

project(hello)

set(CMAKE_CXX_STANDARD 11)

add_executable(main main.cpp)

set(CMAKE_CXX_STANDARD 11):增加c++ 11

编译选项

cmake_minimum_required(VERSION 3.14)

project(hello)

set(CMAKE_CXX_STANDARD 11)

add_compile_options(-g -Wunused)

add_executable(main main.cpp)

add_compile_options:给后续的目标加上编译选项

target_compile_options(main PUBLIC -Wall -Werror)

target_compile_options:给指定的目标加上编译选项

多文件编写

代码

add.h

#pragma once
int add(int x,int y);

add.cpp

#include"add.h"
int add(int x,int y)
{
    return x+y;
}

main.cpp

#include<iostream>
#include"add.h"

int main()
{
    std::cout<<add(3,2);
    return 0;
}

单个添加

cmake_minimum_required(VERSION 3.14)

project(hello)

add_executable(main add.cpp main.cpp)

紧需将其他.cpp添加到add_executable即可

自动添加

自动把src目录下的cpp文件添加到项目里

include_directories(./)
file(GLOB_RECURSE SOURCES "src/*.cpp")

file:获取src目录下的所有.cpp文件,并将其保存到变量中

include_directories:添加头文件搜索路径

添加多个头文件搜索路径

include_directories(./ ./inc)

Trouble Shooting

Invalid argument

  • 报错
CMake Error: Target DependInfo.cmake file not found
Building CXX object CMakeFiles/main.dir/main.cpp.obj
c++.exe: error: C:/Users/錯sktop/temp/main.cpp: Invalid argument
c++.exe: fatal error: no input files
  • 解决

    路径有中文

add.h: No such file or directory

  • 报错
C:/temp/src/add.cpp:1:9: fatal error: add.h: No such file or directory
 #include"add.h"
  • 解决

    #include"add.h"为相对路径,需要将.h文件所在路径添加到搜素路径

include_directories(./)

Mysql

http://t.csdnimg.cn/MVKa7

数据库

清屏

system cls

登录数据库

mysql -u root -p

数据类型

INT:整数类型,常用于存储整数数据。 FLOAT:单精度浮点数类型,用于存储小数数据。 DOUBLE:双精度浮点数类型,用于存储大数数据。 DECIMAL:定点数类型,用于存储精确的小数数据,通常用于财务计算。 CHAR:固定长度字符串类型,最多255个字符。 VARCHAR:可变长度字符串类型,最多65535个字符。

创建数据库

create database my_database;

展示数据库

show databases;

有分号

选择数据库

use <database name>;

查看数据库默认编码

SHOW CREATE DATABASE your_database_name;

设置数据库编码

CREATE DATABASE dbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

数据表

  • 都要有ALTER TABLE <table name>

展示表

show tables;

查询表结构

desc student;

创建数据表

create table student(id int,name char(10),age int,sex char(5));

重命名数据表名

ALTER TABLE user10 RENAME TO user11;

查询数据表编码

SHOW CREATE TABLE your_table_name;

设置数据表编码

CREATE TABLE `students` (
    `id` CHAR(30) NOT NULL,
    `name` CHAR(30) NOT NULL,
    `major` CHAR(30) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

注意是反引号`而不是单引号‘

修改数据表的名字

ALTER TABLE students RENAME TABLE <table name before> TO <table name after>;

查询表结构

desc studens;

修改数据表的结构

RENAME TABLE users TO students;

ALTER TABLE students
DROP COLUMN age,
CHANGE name student_name VARCHAR(100),
ADD COLUMN student_id INT NOT NULL,
ADD COLUMN major VARCHAR(100) NOT NULL;

删除表

DROP TABLE students;

数据项

插入数据项

insert into student(name,id,major) value ("张三","001","计算机");

insert into student value ("张三","001","计算机");

删除数据项

删除若干项

delete from students where name="张三";

删除所有

delete from student

修改数据项

UPDATE students
SET student_id = 新的学号
WHERE id = 2;

展示所有数据

select * from students;

联合查询

join

mysql> SELECT class.class_id,class.name,class.description
-> from class
-> JOIN class_teacher ON class.class_id=class_teacher.class_id
-> WHERE class_teacher.teacher_id=113210;

!= 不等于

效果

+----------+-------+-------------+
| class_id | name | description |
+----------+-------+-------------+
| 10293 | 英语I | 星期二1~2节 |
+----------+-------+-------------+
1 row in set (0.00 sec)

修改多个字段

UPDATE students
SET major = 'Computer Science', age = 22
WHERE id = 1;

宣传海报设计

软件

  • 可画 网页版

公众号制作

软件

  • 秀米XIUMI

AI声音克隆

来源

你的声音,现在是我的了!- 手把手教你用 GPT-SoVITS 克隆声音!

RVC-Boss/GPT-SoVITS: 1 min voice data can also be used to train a good TTS model! (few shot voice cloning) (github.com)

流程

  1. 下载

  2. 人声伴奏分离

  3. 语音切割

    将1~2 mins的语言分割成多个单句。

  4. 打标

    让文字,标点与语音对应。

  5. 训练

  6. 微调

  7. 推理

关键路径

  • 人声伴奏分离

H:\voice_clone\GPT-SoVITS-beta\GPT-SoVITS-beta0706\output\uvr5_opt

  • 语音切割

H:\voice_clone\GPT-SoVITS-beta\GPT-SoVITS-beta0706\output\slicer_opt

  • 打标

H:\voice_clone\GPT-SoVITS-beta\GPT-SoVITS-beta0706\output\asr_opt

  • 训练后的模型

H:\voice_clone\GPT-SoVITS-beta\GPT-SoVITS-beta0706\SoVITS_weights

H:\voice_clone\GPT-SoVITS-beta\GPT-SoVITS-beta0706\GPT_weights

上面仅做参考,记得替换盘符。

说明

优点:部署简单,效果不错。

缺点:8个g,步骤有点多,占显存,推理字数多了,会有漏字的情况。

Tex

文档类型

\documentclass{article}
  • article(常用)/book/beamer(幻灯片)

Trouble Shooting

Python

for与if语句

# 定义一个数字列表
numbers = [1, 2, 3, 4, 5, 6]

# 使用for循环遍历列表
for number in numbers:
    # 使用if判断条件
    if number % 2 == 0:  # 判断数字是否为偶数
        print(number, "is even.")
    else:
        print(number, "is odd.")

复制 numpy

copy = original[1:3, 2:4].copy()

二维数组调用

if data[i,0]%2==0:

格式化输出

# 假设odd列表已经被填充了奇数元组
odd = [(1, 1.1), (3, 2.2), (5, 3.3)]

# 遍历odd列表中的每一行
for odd_item in odd:
    # 访问元组中的每个元素
    wi, di = odd_item
    print(f"WI: {wi}, DI: {di}")

记录程序用时

import time

start_time = time.time()  # 获取当前时间的时间戳
# 执行你的代码
time.sleep(2)  # 假设这是你要测量的代码
end_time = time.time()  # 获取当前时间的时间戳

print(f"程序运行时间:{end_time - start_time}秒")

生成随机数

import random
# 生成第二列:0~207的随机整数
second_column = random.randint(0, 207)
# 生成第三列:0~960的随机浮点数,精度到小数点后一位
third_column = round(random.uniform(0, 960), 1)

Adams

旋转

R

平移

T

缩放

Z

取消/显示物体坐标轴

V

codeql 使用 (C++)

架构

文件组成

.
├── cpp-database
├── incl
│   └── *.h (头文件)
├── src
│   └── *.cpp (源文件)
├── main.cpp
├── Makefile
├── query.ql
└── qlpack.yml
  1. Makefile用来构建make配置
  2. query.ql为查询包查询代码(名字可自定义)
  3. qlpack.yml为查询包配置文件,描述了query.ql的依赖库,以方便后续安装依赖库。

使用

  • 创建数据库(c++项目中)

    codeql database create <database> --language=cpp
    

    为 CodeQL 分析准备代码 - GitHub 文档

    codeql database create <database> --language=cpp --command=make
    

    为 CodeQL 分析准备代码 - GitHub 文档

  • 创建配置文件qlpack.yml

    name: my-cpp-queries
    version: 0.0.0
    libraryPathDependencies:
      - codeql-cpp
    
  • 下载依赖包

    codeql resolve qlpacks
    
  • 进行查询

    codeql database analyze <database name> <query> --format=csv --output=out.csv
    

使用 CodeQL 查询分析代码 - GitHub 文档

数据库

介绍

​ CodeQL databases contain queryable data extracted from a codebase, for a single language at a particular point in time. The database contains a full, hierarchical representation of the code, including a representation of the abstract syntax tree, the data flow graph, and the control flow graph.

About CodeQL — CodeQL (github.com)

Codeql 语法

结构示例

import cpp
from IfStmt ifstmt, BlockStmt block
where ifstmt.getThen() = block and
  block.getNumStmt() = 0
select ifstmt, "This 'if' statement is redundant."

CodeQL for C and C++ — CodeQL (github.com)

Metadata 元数据

  • 格式

    /**
     * @name Useless assignment to local variable
     * @description An assignment to a local variable that is not used later on, or whose value is always
     *              overwritten, has no effect.
     * @kind problem
     * @problem.severity warning
     * @id cs/useless-assignment-to-local
     * @tags maintainability
     *       external/cwe/cwe-563
     * @precision very-high
     * @security-severity 6.1
     */
    

Metadata for CodeQL queries — CodeQL (github.com)

codeql/docs/query-metadata-style-guide.md at main · github/codeql

Error was: Expected result pattern(s) are not present for query kind "Problem"(INVALID_RESULT_PATTERNS) · Issue #2905 · github/codeql

https://codeql.github.com/docs/writing-codeql-queries/defining-the-results-of-a-query/#adding-a-link-to-the-similar-file)

Select

[Defining the results of a query — CodeQL (github.com)](

Codeql参考

Variables

  • Free and bound variables
"hello".indexOf("l") = 1

min(float f | f in [-3 .. 3]) = -3

(i + 7) * 3 instanceof int

exists(float y | x.sqrt() = y)

Variables — CodeQL (github.com)

Codeql 重要库

CodeQL library for C and C++ — CodeQL (github.com)

QL language reference — CodeQL (github.com)

重要接口

Function

BlockStmt

Expr

Node

查询

  • conversion.ql文件与项目在同一个文件夹时

    codeql database analyze cpp-database conversion.ql --format=csv --output=results.csv
    

使用 CodeQL 包自定义分析 - GitHub 文档

待看

Trouble Shooting 报错

Expected result pattern(s)

  • 问题描述

    A fatal error occurred: Could not process query metadata for /home/riway/Documents/test2/conversion.ql.
    Error was: Expected result pattern(s) are not present for problem query: Expected alternating entity/string and string columns. [INVALID_RESULT_PATTERNS]
    
  • 解决

    最后加上--rerun

    codeql database analyze cpp-database conversion.ql --format=csv --output=results.csv --rerun
    

[Expected alternating entity/string and string columns. INVALID_RESULT_PATTERNS] · Issue #6482 · github/codeql

Error was: Expected result pattern(s) are not present for query kind "Problem"(INVALID_RESULT_PATTERNS) · Issue #2905 · github/codeql

To be finalized before running queries

  • 问题描述

    A fatal error occurred: Database at G:\research\data_race\CodeQL_test\rely\cpp-database needs to be finalized before running queries; please run codeql database finalize
    
  • 解决

    codeql database create <database> --language=cpp --command=make
    

A fatal error occurred: Exit status 1 from command

  • 问题描述

    [2024-07-12 15:58:40] [build-stdout] CodeQL C++ autobuilder
    [2024-07-12 15:58:40] [build-stdout] Working directory: G:\research\data_race\CodeQL_test
    [2024-07-12 15:58:40] [build-stdout] Attempting to locate build script
    [2024-07-12 15:58:40] [build-stderr] Error: Could not auto-detect a suitable build method
    [2024-07-12 15:58:40] [ERROR] Spawned process exited abnormally (code 1; tried to run: [G:\research\data_race\codeql_app\codeql\tools\win64\tracer.exe, G:\research\data_race\codeql_app\codeql\tools\win64\runner.exe, cmd.exe, /C, type, NUL, &&, G:\research\data_race\codeql_app\codeql\cpp\tools\autobuild.cmd])
    A fatal error occurred: Exit status 1 from command: [G:\research\data_race\codeql_app\codeql\tools\win64\runner.exe, cmd.exe, /C, type, NUL, &&, G:\research\data_race\codeql_app\codeql\cpp\tools\autobuild.cmd]
    
  • 解决

    切换到Makefile所在文件夹

    codeql database create cpp-database --language=cpp --command=make
    

示例

报告模板

查询名称查询描述问题等级说明文件位置起始行号起始列号结束行号结束列号
"Find enclosing function""A ql to find enclosing function.""recommendation""(global namespace)main call ::test1""/main.cpp"“31”“5”“31”“8”

enFunc1

  • 代码
/**
 * @name Find enclosing function
 * @description A ql to find enclosing function.
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/enFunc
 */

import cpp

from Function f1,Function f2
where f1.calls(f2)
select f1,f1.toString()+" call "+f2.toString() 
  • 报告
"Find enclosing function","A ql to find enclosing function.","recommendation","main call test1","/main.cpp","31","5","31","8"

enFunc2

  • 代码
/**
 * @name Find enclosing function
 * @description A ql to find enclosing function.
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/enFunc
 */

 import cpp

 from Function f1,Function f2
 where f1.calls(f2)
 select f1,f1.getNamespace().toString()+f1.toString()+" call "+f2.getNamespace().getName()+"::"+f2.toString() 
  • 报告
"Find enclosing function","A ql to find enclosing function.","recommendation","(global namespace)main call ::test1","/main.cpp","31","5","31","8"

enFunc3

  • 代码
/**
 * @name Find enclosing function
 * @description A ql to find enclosing function.
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/enFunc
 */

 import cpp

 from Function f1,Function f2
 where f1.calls(f2) and f1.getName()="test1"
 select f1,f1.getNamespace().getName()+f1.getName()+" call "+f2.getNamespace().getName()+"::"+f2.toString() 
  • 结果
"Find enclosing function","A ql to find enclosing function.","recommendation","test1 call std::operator<<
test1 call ::test2","/main.cpp","8","5","8","9"

enVar1

  • 代码
/**
 * @name Find enclosing variate 
 * @description A ql to find enclosing variate.
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/enVar
 */

 import cpp

 from Function f, Variable v
 where f.accesses(v)
 select f,f.getNamespace().getName()+"::"+f.toString()+" calls "+v.getNamespace().getName()+"::"+v.toString() 
 

enVar2

  • 代码
/**
 * @name Find enclosing variate 
 * @description A ql to find enclosing variate.
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/enVar
 */

 import cpp

 from Function f, LocalVariable v
 where  v.getFunction()=f
 select f,f.getNamespace().getName()+"::"+f.toString()+" calls "+v.getNamespace().getName()+"::"+v.toString() 
  • 报告
"Find enclosing variate","A ql to find enclosing variate.","recommendation","::test1 calls ::num1","/main.cpp","8","5","8","9"

flow1

  • 代码
/**
 * @name Data flow
 * @description A ql to trace dataflow
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/flow
 */

 import cpp
 import semmle.code.cpp.dataflow.new.DataFlow

 from DataFlow::Node nodeFrom, DataFlow::Node nodeTo,Parameter source,Parameter sink
 where nodeFrom.asParameter() = source and
 nodeTo.asParameter() = sink and
 DataFlow::localFlow(nodeFrom, nodeTo)
 select nodeFrom,"from "+nodeFrom.toString()+" to "+nodeTo.toString()+" source: "+source.toString()+
 " sink : "+sink.toString()

源文件1

#include<iostream>
using namespace std;

int test1(int a);
int test2(int b);

int test1(int a)
{
    cout<<"this is test 1\n";
    cout<<"a: "<<a<<endl;
    int num1=1;
    test2(a);
    return 0;
}

int test2(int b)
{
    cout<<"this is test 2\n";
    cout<<"b: "<<b<<endl;   
    return b;
}


int main()
{
    int num=1;
    test1(num);
    return 0;
}
  • 结果1
"Data flow","A ql to trace dataflow","recommendation","from b to b source: b sink : b","/main.cpp","16","15","16","15"

源文件2

#include<iostream>
using namespace std;

int test1(int &a);
int test2(int &b);

int test1(int &a)
{
    cout<<"this is test 1\n";
    cout<<"a: "<<a<<endl;
    int num1=1;
    test2(a);
    return 0;
}

int test2(int &b)
{
    cout<<"this is test 2\n";
    cout<<"b: "<<b<<endl;   
    return b;
}


int main()
{
    int num=1;
    test1(num);
    return 0;
}
  • 结果
"Data flow","A ql to trace dataflow","recommendation","from *b to *b source: b sink : b","/main.cpp","16","16","16","16"
  • 结论

DataFlow::Node能识别出地址传递还是值传递

rely

  • 代码
/**
 * @name Find expr
 * @description A ql to find expr.
 * @kind problem 
 * @problem.severity recommendation
 * @id cpp/rely
 */

import cpp

from Expr e
select e,e.toString() 
  • 报告
"Find expr","A ql to find expr.","recommendation","call to test1","/main.cpp","27","5","27","9"

Expr

"Data flow","A ql to trace dataflow","recommendation","Expr: num","/main.cpp","27","11","27","13"
"Data flow","A ql to trace dataflow","recommendation","Expr: cout","/main.cpp","18","5","18","8"
"Data flow","A ql to trace dataflow","recommendation","Expr: this is test 2
","/main.cpp","18","11","18","28"
"Data flow","A ql to trace dataflow","recommendation","Expr: endl","/main.cpp","19","21","19","24"
"Data flow","A ql to trace dataflow","recommendation","Expr: call to operator<<","/main.cpp","19","16","19","20"
"Data flow","A ql to trace dataflow","recommendation","Expr: b","/main.cpp","19","18","19","18"
"Data flow","A ql to trace dataflow","recommendation","Expr: call to operator<<","/main.cpp","19","9","19","17"
"Data flow","A ql to trace dataflow","recommendation","Expr: cout","/main.cpp","19","5","19","8"
"Data flow","A ql to trace dataflow","recommendation","Expr: b: ","/main.cpp","19","11","19","15"
"Data flow","A ql to trace dataflow","recommendation","Expr: cout","/main.cpp","9","5","9","8"
"Data flow","A ql to trace dataflow","recommendation","Expr: this is test 1
","/main.cpp","9","11","9","28"
"Data flow","A ql to trace dataflow","recommendation","Expr: endl","/main.cpp","10","21","10","24"
"Data flow","A ql to trace dataflow","recommendation","Expr: call to operator<<","/main.cpp","10","16","10","20"
"Data flow","A ql to trace dataflow","recommendation","Expr: a","/main.cpp","10","18","10","18"
"Data flow","A ql to trace dataflow","recommendation","Expr: call to operator<<","/main.cpp","10","9","10","17"
"Data flow","A ql to trace dataflow","recommendation","Expr: cout","/main.cpp","10","5","10","8"
"Data flow","A ql to trace dataflow","recommendation","Expr: a: ","/main.cpp","10","11","10","15"
"Data flow","A ql to trace dataflow","recommendation","Expr: a","/main.cpp","12","11","12","11"
"Data flow","A ql to trace dataflow","recommendation","Expr: b","/main.cpp","20","12","20","12"
"Data flow","A ql to trace dataflow","recommendation","Expr: 1","/main.cpp","26","13","26","13"
"Data flow","A ql to trace dataflow","recommendation","Expr: 0","/main.cpp","28","12","28","12"
"Data flow","A ql to trace dataflow","recommendation","Expr: 1","/main.cpp","11","14","11","14"
"Data flow","A ql to trace dataflow","recommendation","Expr: 0","/main.cpp","13","12","13","12"

个人使用.clang-format

与visual studio类似

---
Language: Cpp
# BasedOnStyle:  LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortLambdasOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
  AfterCaseLabel: false
  AfterClass: true
  AfterControlStatement: true
  AfterEnum: false
  AfterFunction: true
  AfterNamespace: false
  AfterObjCDeclaration: false
  AfterStruct: false
  AfterUnion: false
  AfterExternBlock: false
  BeforeCatch: false
  BeforeElse: true
  IndentBraces: false
  SplitEmptyFunction: false
  SplitEmptyRecord: false
  SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: "^ IWYU pragma:"
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
  - foreach
  - Q_FOREACH
  - BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
  - Regex: '^<ext/.*\.h>'
    Priority: 2
  - Regex: '^<.*\.h>'
    Priority: 1
  - Regex: "^<.*"
    Priority: 2
  - Regex: ".*"
    Priority: 3
IncludeIsMainRegex: "(Test)?$"
IndentCaseBlocks: false
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
StatementMacros:
  - Q_UNUSED
  - QT_REQUIRE_VERSION
TabWidth: 4
UseTab: Never

Verilog

板子 boolean board

芯片型号xc7s50csga324-1

板子 达芬奇xc7a35tfgg484-2

芯片型号

流程

  1. 综合分析(synthesis)
  2. 实施(implemention)
  3. 仿真
  4. generate bitstream
  5. open target

数据

二进制n,八进制o,十进制d,十六进制h

3'b010//3位二进制

其它

顶层文件名需与项目名称一致

修改总线数据类型(二进制/ascii/binary)

  • 仿真后右键,radix

仿真end time

  • settings->simulation->simulation->xsim.simulate.runtime

仿真区操作

  • 向左/右拖动 放大缩小(每格代表的时间长度,与示波器类似)

351ec9f78ac59703feb4dfe57c32acf9

  • 滑动槽可改变观看区域

wire型变量不能初始化

reg才行

initial与always执行顺序关系

仿真开始时,所有initial块按照它们在代码中出现的顺序执行一次。这意味着在任何always块执行之前,所有的initial块已经执行完毕。

计数器加满后,会置零重新加

模块内有reg

可在模块设计时初始化

`timescale 1ns / 1ps
module Lab_5_1(
input wire clk,
output reg q=0,
output reg front=0,
output reg behind=0
    );
    ······
endmodule

仿真时不要将wire赋值

module tb(
    );
    
reg clk=0;
wire q;
wire front;
wire behind;

initial begin
clk=0;
end

always #10 clk=~clk;

Lab_5_1 test(
.clk(clk),
.q(q),
.front(front),
.behind(behind)
);

endmodule

仿真的内容

只要是在testbanch中定义的东西,都会在仿真中出现

.veo文件查看ip核使用方法

initial模块一般只在仿真中使用

https://reborn.blog.csdn.net/article/details/107307958?fromshare=blogdetail&sharetype=blogdetail&sharerId=107307958&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

查看内部器件的仿真信号

https://jianght.blog.csdn.net/article/details/105813222?fromshare=blogdetail&sharetype=blogdetail&sharerId=105813222&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

仿真时需要在initial中对clk初始化

硬件图

开关

ca21a64f3cae703e7092c1633821e720

语法

module

module boolean_demo(//模块的输入输出
input [15:0] sw,
output [15:0] led
    );
    
assign led=sw;//各接口连接方式
endmodule

always

always@(*)begin
end
always #10 clk = ~clk;// 语句意味着在某些条件下会反复执行块内的代码。在这里,#10 是一种延迟控制,表示在每次执行该语句后等待 10 时间单位(可以是纳秒、皮秒等,取决于模拟的时间单位),然后再执行块内的代码。

initial

initial begin
in=3'b000;
#10;
in=3'b001;
#10;
in=3'b010;
end

case

case(in)
    3'b000: y=8'b00000001;
    3'b001: y=8'b00000010;
    3'b010: y=8'b00000100;
    3'b011: y=8'b00001000;
    3'b100: y=8'b00010000;
    3'b101: y=8'b00100000;
    3'b110: y=8'b01000000;
    3'b111: y=8'b10000000;
endcase

reg

reg a[0:3];   // 声明一个数组,包含4个元素  
initial begin  
    a[0] = 7; // 只给第一个元素赋值为 7,其他元素为 0  
end  
reg [3:0] a; // 声明一个4位的reg变量  
initial begin  
    a = 7; // 将a赋值为7  
end  

wire

wire [7:0] c;// 用于表示一个 8 位宽的单一信号,适合处理一个完整数据字。
wire c[7:0];//用于表示一个有 8 个元素的数组,每个元素是一个单比特的 wire,适合处理多个分散的信号。

仿真

module testbench();
reg[2:0] in;
wire[7:0] y;
       
Lab_2_1 test(//实例化 类名 对象名
.in(in),
.y(y)
);
    
initial begin
in=3'b000;

注意输入要用reg,输出要用wire

项目

lab1 按键控制led

  • Design sources
module boolean_demo(
input [15:0] sw,
output [15:0] led
    );
    
assign led=sw;
endmodule
  • Simulation sources
module TestBench();
    
    reg [15:0] sw;
    wire [15:0] led;
    integer i;
    
    initial begin
    sw=0;
        for(i=0;i<=15;i=i+1) begin
            sw[i]=#100 1;
        end
   end
   
   boolean_demo test(
   .sw(sw),
   .led(led)
   ); 
endmodule
  • Constrains
set_property -dict {PACKAGE_PIN V2 IOSTANDARD LVCMOS33} [get_ports {sw[0]}]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports {sw[1]}]
set_property -dict {PACKAGE_PIN U1 IOSTANDARD LVCMOS33} [get_ports {sw[2]}]
set_property -dict {PACKAGE_PIN T2 IOSTANDARD LVCMOS33} [get_ports {sw[3]}]
set_property -dict {PACKAGE_PIN T1 IOSTANDARD LVCMOS33} [get_ports {sw[4]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {sw[5]}]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {sw[6]}]
set_property -dict {PACKAGE_PIN P2 IOSTANDARD LVCMOS33} [get_ports {sw[7]}]
set_property -dict {PACKAGE_PIN P1 IOSTANDARD LVCMOS33} [get_ports {sw[8]}]
set_property -dict {PACKAGE_PIN N2 IOSTANDARD LVCMOS33} [get_ports {sw[9]}]
set_property -dict {PACKAGE_PIN N1 IOSTANDARD LVCMOS33} [get_ports {sw[10]}]
set_property -dict {PACKAGE_PIN M2 IOSTANDARD LVCMOS33} [get_ports {sw[11]}]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports {sw[12]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {sw[13]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {sw[14]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {sw[15]}]
# On-board LEDs
set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN F1 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN F2 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN E5 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
set_property -dict {PACKAGE_PIN E6 IOSTANDARD LVCMOS33} [get_ports {led[8]}]
set_property -dict {PACKAGE_PIN C3 IOSTANDARD LVCMOS33} [get_ports {led[9]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {led[10]}]
set_property -dict {PACKAGE_PIN A2 IOSTANDARD LVCMOS33} [get_ports {led[11]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {led[12]}]
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {led[13]}]
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {led[14]}]
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {led[15]}]

lab2 组合逻辑电路

译码器与编码器

  • design
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/10/02 20:17:40
// Design Name: 
// Module Name: project_2_decoder
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module project_2_decoder(
    input wire[2:0] in,
    output reg[7:0] y
    );
    
    always@(*)begin
        case(in)
        3'b000: y=8'b00000001;
        3'b001: y=8'b00000010;
        3'b010: y=8'b00000100;
        3'b011: y=8'b00001000;
        3'b100: y=8'b00010000;
        3'b101: y=8'b00100000;
        3'b110: y=8'b01000000;
        3'b111: y=8'b10000000;
        endcase
    end
endmodule
  • simulation
`timescale 1ns / 1ps
module testbench();
reg[2:0] in;
wire[7:0] y;

project_2_decoder test(
.in(in),
.y(y)
);

initial begin
in=3'b000;
#10;
in=3'b001;
#10;
in=3'b010;
#10;
in=3'b011;
#10;
in=3'b100;
#10;
in=3'b101;
#10;
in=3'b110;
#10;
in=3'b111;
end
endmodule
  • contrains
# On-board Slide Switches
set_property -dict {PACKAGE_PIN V2 IOSTANDARD LVCMOS33} [get_ports {in[0]}]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports {in[1]}]
set_property -dict {PACKAGE_PIN U1 IOSTANDARD LVCMOS33} [get_ports {in[2]}]
# On-board LEDs
set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVCMOS33} [get_ports {y[0]}]
set_property -dict {PACKAGE_PIN 
G2 IOSTANDARD LVCMOS33} [get_ports {y[1]}]
set_property -dict {PACKAGE_PIN F1 IOSTANDARD LVCMOS33} [get_ports {y[2]}]
set_property -dict {PACKAGE_PIN F2 IOSTANDARD LVCMOS33} [get_ports {y[3]}]
set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {y[4]}]
set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports {y[5]}]
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports {y[6]}]
set_property -dict {PACKAGE_PIN E5 IOSTANDARD LVCMOS33} [get_ports {y[7]}]

lab3 rgb pwm

  • design
module Lab_3_2(
output r, output g, output b, input en, input clk_100MHz
);
reg [31:0]freq=1000000;//1MHz
reg [6:0]duty_r=50;
reg [6:0]duty_g=50;
reg [6:0]duty_b=50;
reg rst=1;
reg [31:0]cnt=0;
reg [7:0]cnt2=1;
//简单的分频代码,也可以使用分频的 IP 进行分频
always@(posedge clk_100MHz) begin
if(cnt<10000000) begin //变化频率 0.1s
cnt=cnt+1;
end
else begin
cnt=0;
if(cnt2<=150) begin
cnt2=cnt2+1;
end
else begin
cnt2=1;
end
end
if(cnt2>0 && cnt2<=50) begin
duty_r<=cnt2;
duty_g<=0;
duty_b<=0;
end
else if(cnt2>50 && cnt2<=100) begin
duty_g<=cnt2-50;
duty_r<=0;
duty_b<=0;
end
else begin
duty_b<=cnt2-100;
duty_g<=0;
duty_r<=0;
end
end
Driver_PWM_0 pwm_r (
.clk_100MHz(clk_100MHz), // input wire clk_100MHz
.Freq(freq), // input wire [31 : 0] Freq
.Duty(duty_r), // input wire [6 : 0] Duty
.Rst(rst), // input wire Rst
.En(en), // input wire En
.PWM(r) // output wire PWM
);
Driver_PWM_0 pwm_g (
.clk_100MHz(clk_100MHz), // input wire clk_100MHz
.Freq(freq), // input wire [31 : 0] Freq
.Duty(duty_g), // input wire [6 : 0] Duty
.Rst(rst), // input wire Rst
.En(en), // input wire En
.PWM(g) // output wire PWM
);
Driver_PWM_0 pwm_b (
.clk_100MHz(clk_100MHz), // input wire clk_100MHz
.Freq(freq), // input wire [31 : 0] Freq
.Duty(duty_b), // input wire [6 : 0] Duty
.Rst(rst), // input wire Rst
.En(en), // input wire En
.PWM(b) // output wire PWM
);
  • constrain
create_clock -period 10.000 -name gclk [get_ports clk_100MHz]
set_property -dict {PACKAGE_PIN F14 IOSTANDARD LVCMOS33} [get_ports {clk_100MHz}]
set_property -dict {PACKAGE_PIN V2 IOSTANDARD LVCMOS33} [get_ports {en}]; #sw0
set_property -dict {PACKAGE_PIN V6 IOSTANDARD LVCMOS33} [get_ports {r}]; # RBG0_R
set_property -dict {PACKAGE_PIN V4 IOSTANDARD LVCMOS33} [get_ports {g}]; #RBG0_G
set_property -dict {PACKAGE_PIN U6 IOSTANDARD LVCMOS33} [get_ports {b}]; #RBG0_B

lab5 分频器

三分频

  • design
`timescale 1ns / 1ps

module Lab_5_1(
input wire clk,
output reg q=0,
output reg front=0,
output reg behind=0
    );

reg [1:0]count=0;

   
always@(posedge clk) begin
    if(count!=2) begin
    count=count+1;
    end
    else begin
    count=0;
    end
end

always@(posedge clk) begin
    if(count==0) begin
    front<=1;
    end
    else begin
    front<=0;
    end
end

always@(negedge clk) begin
    if(count==0) begin
    behind<=1;
    end
    else begin
    behind<=0;
    end
end

always@(posedge front)begin
    q=1;
end

always@(negedge behind)begin
    q=0;
end
endmodule
  • simulation
`timescale 1ns / 1ps

module tb(
    );
    
reg clk=0;
wire q;
wire front;
wire behind;

initial begin
clk=0;
end

always #10 clk=~clk;

Lab_5_1 test(
.clk(clk),
.q(q),
.front(front),
.behind(behind)
);

endmodule

比较两数大小

[verilog比较两个数大小 - CSDN文库](https://wenku.csdn.net/answer/2fcd241fed3c4deea194904de5ea4570#:~:text=可以使用 Veril)

车牌识别

jjejdhhd/License-Plate-Recognition-FPGA: 基于FPGA进行车牌识别 (github.com)

UART

新新新手Icer练习(八):uart的基本组成及其verilog实现

Web 开发

MDN Web Docs

上线网站

【合集完结】想上线网站?通俗易懂的网站上线部署发布教程 | 个人网站如何托管建站 | 服务器 IP DNS CDN 备案 工作原理 | 腾讯云开发静态网站托管

域名

域名注册购买_域名注册选购 - 腾讯云

域名注册 单个域名注册-注册新域名-文档中心-腾讯云

ICP 备案 如何快速备案您的网站或 APP-快速入门-文档中心-腾讯云

我的备案 - ICP备案 - 控制台

轻量应用服务器 安装和配置宝塔 Linux 面板腾讯云专享版-实践教程-文档中心-腾讯云

服务器

其它

学生云服务器_学生云主机_学生云数据库_云+校园特惠套餐 - 腾讯云

MDN Web Docs

  • 课程

全网首发AI+JavaWeb开发入门,Tlias教学管理系统项目实战全套视频教程,从需求分析、设计、前后端开发、测试、程序优化到项目部署一套搞定

CMS内容管理系统

https://blog.csdn.net/weixin_36338224/article/details/109105047?fromshare=blogdetail&sharetype=blogdetail&sharerId=109105047&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

Django

命令行

  • ./mysite下 创建应用
py magage.py startapp blog
  • 启动项目
py manage.py runserver

静态文件

如何管理静态文件(如图片、JavaScript、CSS) | Django 文档 | Django

改变模型

  1. 编辑models.py
  2. py manage.py makemigrations users 生成迁移文件
  3. py manage.py migrate应用数据库迁移

创建超级用户管理员

py manage.py createsuperuser

admin 123456

URL调度器

URL调度器 | Django 文档 | Django

Django实例

编写你的第一个 Django 应用,第 1 部分 | Django 文档 | Django

图片浮出

html

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>图片浮现效果</title>
    <link rel="stylesheet" href="script.css">
</head>
<body>
    <div class="content" style="height:200px;">
        <!-- 这里是页面内容,用于产生滚动条 -->
    </div>
    <img src="1.png" alt="浮现的图片" class="fade-in-image">
    <script src="script.js"></script>
</body>
</html>

css

/* 移除了固定定位 */
.fade-in-image {
    opacity: 0; /* 初始透明度为0 */
    /* position: fixed; 移除这一行 */
    /* bottom: 20px; 移除这一行 */
    /* right: 20px; 移除这一行 */
    transition: opacity 1s ease-in-out; /* 透明度变化过渡效果 */
}

/* 当图片进入视口时的样式 */
.fade-in-image.visible {
    opacity: 1; /* 透明度变为1 */
}

js

document.addEventListener('DOMContentLoaded', function() {
    // 获取图片元素
    var img = document.querySelector('.fade-in-image');

    // 创建一个IntersectionObserver实例
    var observer = new IntersectionObserver(function(entries, observer) {
        entries.forEach(function(entry) {
            if (entry.isIntersecting) {
                // 当图片进入视口时,添加'visible'类
                img.classList.add('visible');
            } else {
                // 当图片离开视口时,移除'visible'类
                img.classList.remove('visible');
            }
        });
    }, {
        rootMargin: '0px', // 可以设置一个边距,提前触发
        threshold: 0.4 // 当图片的40%进入视口时触发
    });

    // 开始观察图片元素
    observer.observe(img);
});

剪辑

遮罩

需要占据一层

字幕遮罩

颜色遮罩

蒙版

蒙版为某视频的一种属性,本质上就是一个选区,即每一种效果的使用范围,为了避免效果生硬,可以加上蒙版羽化

蒙版滑屏

蒙版滑屏|剪辑教学

水平翻转

效果:水平

https://baijiahao.baidu.com/s?id=1760888131837029502

色调

负片

效果:反转(通道)

lumetri

效果->lumetri调色,同时打开窗口->lumetri调色,方便调色。

若要调成只有黑白灰的那种,则将饱和度调节为0,曝光也可以通过这个效果进行调节。

显示一部分(画中画)

效果->不透明度,然后在该效果的蒙版中用钢笔(或其他方式)选择出区域

消除

人物消失

人物消失卡点 | 不是pr消除要付费

AE消除动态物体

好用的,但要注意渲染视频的时间不能长,1s差不多了。

【【AE教程】如何快速去除视频中的动态物体?99%的人都不知道!】https://www.bilibili.com/video/BV1fq421F7Vz?vd_source=ec4e4974e1b56ed330afdb6c6ead1501

消除字幕

如果为静态,直接用手机的AI消除或者PS的污点消除工具。

如果为动态,可以用中间值效果。

动态抠像

【AE教程】一键解决复杂抠像,ROTO笔刷到底多智能?明白这些效率倍增

【教程】如何进行动态抠像

ProPainter视频移除技术,让后期人员解放双手, 完美移除视频水印及人物

小技巧

  • 拖动视频时,双击 效果->位置(似乎叫这个名字),然后就可以在视窗里面拖动了,相比较与调节数值更加方便。
  • 选择右侧所有视频片段
  • 创建新的序列以使得电脑不卡

其他

项目降低版本

Pr工程文件降级工具-在线Pr项目模板降级/高低版本转换网站

格式转换

视频移除AI

绿幕

项目

双城之战

  • 需要8个画面,每个画面2秒

    1. 正常

    2. 消失

    3. 正常

    4. 反相(消失)

    5. 局部反相

    6. 消失

  • 组成

    1. 爆爆 1

    2. 本索 1

    3. 希尔科 1 最后一幕可以进行别的修改 金克斯坐在桌子上

    4. 范德尔 1

    5. 两个伙伴 左右分屏 jinx听到的杂声

    6. 丽莎

    7. 金克斯 镜子

    8. 艾克 1

  • 白色边框

    • 通过绘制矩形实现
  • 其他

    • 爆炸,时间倒流

Trouble Shooting

导入mp4后,无声音

  • 解决
    • 声音通道,需要点击两个A1,这样才能修改,当只选择一个A1时,视频的声音是没有效果的。

蒙版

灰度蒙版

曲线蒙版

调色

羽化

发光

点状

线条

添加图层样式(右下角,fx)内发光,外发光。

字体

添加图层样式(右下角,fx)内发光,外发光,字体就有颜色了。

添加调整图层(太极)->纯色,然后在蒙版中进行绘制(绘制选取),可以使用柔光笔,使得更加柔和,注意颜色。

【PS做发光字】 https://www.bilibili.com/video/BV1qX4y1g7UR/?share_source=copy_web&vd_source=ec4e4974e1b56ed330afdb6c6ead1501

小技巧

  • 觉得图层太多,且部分不再修改,可以右键图层->向下合并

需求

添加阴影

ps如何局部加深颜色_百度知道

蒙版单个图层

PS怎样蒙版调节单个图层曲线_百度知道

让边缘更自然

ps怎么让边缘过渡自然-百度经验

DDCA

课程网站

start Digital Design and Computer Architecture - Spring 2023

verilog

// You can assign partial buses
wire [15:0] longbus;
wire [7:0] shortbus;
assign shortbus = longbus[12:5];
// Concatenating is by ()
assign y = (a[2],a[1],a[o],a[e]);
Possible to define multiple copies
assign x = {a[el, a[e], a[o], a[o])
assign y = { 4(a[o]} }

赋值

8'bZ#高阻态
8'b0000_1001 # 00001001
8'bxX0X1zZ1  # XX0X1ZZ1

金融行业·大模型挑战赛

开源知识图谱:https://cpubmed.openi.org.cn/graphwiki 慢性病管理 Agent Github 地址:https://github.com/lzl-am/AM-Med-Agent 金融大模型比赛网址:https://competitions.zhipuai.cn/matchDetail?id=120241202000000003

环境

本地部署大模型

Ollama安装

基于语言模型的应用的框架

ollama

https://ollama.com/

API

只读SQL查询服务 - Swagger UI

【强化学习】Q-Learning算法详解_qlearning算法详解-CSDN博客

ideas

志愿者管理系统

EASYX

To_Do_List

cs1.6_ai图像识别自动瞄准

cs2

cs剪辑

file

multisim教程

python画图讲解

to_do_List_diary

vac视频剪辑

信息统计

像素风画图工具

光纤,解码器和编码器

制作一个vs调试的教程

医院引导

和猫住_可操控绳索

多教室打分系统

大帝+图像识别+文字提取

实验数据处理

手势识别与ppt切换

技能录像

数学建模

文档扫描

更加方便的查词器

校园接驳车定位

源码_补码生成器

物联网体验组

用遗传算法做一个小东西?

用链式结构搓一个图

盲文打印

视线跟踪台灯

训练自己文本的GPT

键盘操作与神经网络

网站相关技术

前端基础

html+css+js

全网首发AI+JavaWeb开发入门,Tlias教学管理系统项目实战全套视频教程,从需求分析、设计、前后端开发、测试、程序优化到项目部署一套搞定

帮助文档参考 MDN Web Docs

网站上线流程

【合集完结】想上线网站?通俗易懂的网站上线部署发布教程 | 个人网站如何托管建站 | 服务器 IP DNS CDN 备案 工作原理 | 腾讯云开发静态网站托管

腾讯云部署文档

域名注册购买_域名注册选购 - 腾讯云

域名注册 单个域名注册-注册新域名-文档中心-腾讯云

ICP 备案 如何快速备案您的网站或 APP-快速入门-文档中心-腾讯云

我的备案 - ICP备案 - 控制台

轻量应用服务器 安装和配置宝塔 Linux 面板腾讯云专享版-实践教程-文档中心-腾讯云

Django框架

该框架用于构建后端

Python-Django手把手从零开发个人博客

入门

编写你的第一个 Django 应用,第 1 部分 | Django 文档 | Django

CONN功能连接系列视频-01 准备工作,软件和数据 | 静息态任务态fMRI 功能连接 ALFF REHO

这个视频比较清晰

环境

matlab+CONN+SPM12

数据下载

OpenNeuro

数据处理

  1. 添加结构态与功能态至session
  2. processing
  3. 降噪 done
  4. 功能连接一阶水平分析

降噪

done

质量检查

QA_plot查看成像效果

文字匹配算法

最长公共子序列(Longest Common Subsequence, LCS)算法

https://gongweichen.blog.csdn.net/article/details/142357110?fromshare=blogdetail&sharetype=blogdetail&sharerId=142357110&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

编辑距离(Levenshtein distance)算法

https://bigcoder.blog.csdn.net/article/details/115803158?fromshare=blogdetail&sharetype=blogdetail&sharerId=115803158&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

缩略图显示

https://blog.csdn.net/Joker__123/article/details/124456107?fromshare=blogdetail&sharetype=blogdetail&sharerId=124456107&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

二值化抠图滤镜

这霓虹双胞胎滤镜也太酷了吧,老外纷纷炫技-哔哩哔哩

[图片翻译-图片翻译API文档-有道智云AI开放平台](https://ai.youdao.com/DOCSIRMA/html/trans/api/tpfy/index.html#:~:text=您只需要通过调用图片翻译API,传入图片的Base64编码,指定源语言与目标语言,通过POST请求方式,就可以识别图片中的文字并进行翻译。 图片翻译 API HTTPS地址: 调用方在集成文本翻译API时,请遵循以下规则。 调用API需要向接口发送以下字段来访问服务。,注意%3A 请先将需要识别的图片转换为 Base64 编码。 在发送HTTP请求之前需要对各字段做 URL encode。)

梅庵

网站

设计参考

  • 南京博物院 https://www.njmuseum.com/zh
  • 故宫博物院 https://www.dpm.org.cn/Home.html
  • 遵义会议纪念馆 https://zunyihy.cn/n167/index.html
  • 延安革命纪念馆 https://www.720yun.com/t/e4vkOh19sim#scene_id=57965262
  • 河南省博物馆 https://www.chnmus.net/
  • 山东省博物馆 https://www.sdmuseum.com/

框架

公众号+介绍视频+Web

梅历史

  • 梅庵相关电子资料整理

  • 背景

  • 历史

  • 相关

“梅“bug

  • Web开发过程
  • 公众号创建过程

“梅”见面

  • 团队介绍(F1赛车)
  • 梅庵讲解视频
  • 奥本海默视频

人员安排

要做的事情总共有几类

  • 写推文,写报告,写新闻

  • 排版推文,绘画

  • 公众号管理

  • 答辩

  • Web开发

  • AE制作片头

  • 树木旋转向上

    【摆摊1天赚1030元?不当博主能赚钱吗?】https://www.bilibili.com/video/BV1j8S3YdEaT?vd_source=ec4e4974e1b56ed330afdb6c6ead1501

GPT

【五分钟做一个自己的AI ChatGPT】https://www.bilibili.com/video/BV1xA46e7EbR?vd_source=ec4e4974e1b56ed330afdb6c6ead1501

批量修改名字的工具

Pytorch

CUDA Version: 12.7

Driver Version: 566.14

torch Version: 1.13.1

conda.exe地址: F:\Users\anaconda3\envs\pytorch\Scripts

环境配置

PyTorch深度学习快速入门教程(绝对通俗易懂!)

查看cuda版本

nvidia-smi

进入环境

conda activate pytorch

查看库

pip list

查看虚拟环境地址

conda env list

查看torch版本

import torch
print(torch.__version__)
print(torch.version.cuda)

检查配置是否成功

torch.cuda.is_available()

pycharm选择已有环境

setting->项目->python解释器->添加已有解释器->conda环境->使用先有环境->pytorch->应用

手写数字识别

CNN.py

构建自定义类

import torch


class CNN(torch.nn.Module):  # 继承
    def __init__(self):
        super(CNN, self).__init__()
        self.conv = torch.nn.Sequential(
            # 1.卷积(卷积层)
            torch.nn.Conv2d(1, 32, kernel_size=5,  # 卷积核有32个
                            padding=2),  # h2=(28-5+2*2)/1+1=28
            # 2.归一化(BN层)
            torch.nn.BatchNorm2d(32),
            # 3.激活层 Relu函数
            torch.nn.ReLU(),
            # 4.最大池化
            torch.nn.MaxPool2d(2)  # 池化核的大小 14*14
        );
        self.fc = torch.nn.Linear(in_features=14 * 14 * 32, out_features=10);

    def forward(self, x):
        out = self.conv(x)
        # 将图像展开成一维
        # 输入的张量(n,c,h,w) n为数 c为通道数 c
        out = out.view(out.size()[0], -1)
        out = self.fc(out)
        return out

main.py

用于训练模型

import torch
import torchvision.datasets as dataset
import torchvision.transforms as transforms
import torch.utils.data as data_utils
from CNN import CNN

##### 数据加载

train_data = dataset.MNIST(
    root="mnist",
    train=True,
    transform=transforms.ToTensor(),
    download=True
);

test_data = dataset.MNIST(
    root="mnist",
    train=False,
    transform=transforms.ToTensor(),
    download=True
);

# print(train_data)
# print(test_data)


###分批加载
train_loader = data_utils.DataLoader(dataset=train_data,
                                     batch_size=64,
                                     shuffle=True)  # 打乱下标

test_loader = data_utils.DataLoader(dataset=test_data,
                                    batch_size=64,
                                    shuffle=True)  # 打乱下标

# print(train_loader)
# print(test_loader)
cnn = CNN();

#######损失函数
loss_func = torch.nn.CrossEntropyLoss();

######优化函数
optimizer = torch.optim.Adam(cnn.parameters(), lr=0.01)

####训练过程
# epoch 通常指 一次训练数据全部训练一次
for epoch in range(10):
    for index, (images, labels) in enumerate(train_loader):
        # print(index)
        # print(images)
        # print(labels)

        # 前向传播
        outputs = cnn(images)
        loss = loss_func(outputs, labels);
        # 先清空梯度
        optimizer.zero_grad()
        # 反向传播
        loss.backward()
        optimizer.step()
        print("now round{}, it is {}/{},loss is {}".format(epoch + 1, index + 1, len(train_data) // 64, loss.item()))
        # break
    ###########测试集验证
    loss_test = 0
    rightValue = 0
    for index2, (images, labels) in enumerate(test_loader):
        outputs = cnn(images)
        # print(outputs)
        # print(labels)
        loss_test += loss_func(outputs, labels)
        _, pred = outputs.max(1)
        rightValue += (pred == labels).sum().item()
        # print(pred)
        # 把两个张量中的每一个元素进行对比
        # print((pred == labels).sum().item())
        # break;
        print("当前为第{}轮测试集验证, 当前批次为{}/{},loss为{},准确率是{}".format(epoch + 1, index2 + 1,
                                                                                   len(test_data) // 64, loss_test,
                                                                                   rightValue / len(test_data)))

# torch.save(cnn, "model/mnist_model.pkl")

mnist_test.py

使用模型

import cv2
import torch
import torchvision.datasets as dataset
import torchvision.transforms as transforms
import torch.utils.data as data_utils
from CNN import CNN

test_data = dataset.MNIST(
    root="mnist",
    train=False,
    transform=transforms.ToTensor(),
    download=True
);

test_loader = data_utils.DataLoader(dataset=test_data,
                                    batch_size=64,
                                    shuffle=True)  # 打乱下标

cnn = torch.load("model/mnist_model.pkl")
loss_func = torch.nn.CrossEntropyLoss();
loss_test = 0
rightValue = 0
for index, (images, labels) in enumerate(test_loader):
    outputs = cnn(images)
    _, pred = outputs.max(1)
    loss_test += loss_func(outputs, labels)
    rightValue += (pred == labels).sum().item()

    images = images.numpy()  # batch , c ,h ,w
    labels = labels.numpy()
    pred = pred.numpy()

    for idx in range(images.shape[0]):
        im_data = images[idx]
        im_data = im_data.transpose(1, 2, 0)  # 交换维度,将通道维度移到最后
        im_label = labels[idx]
        im_pred = pred[idx]
        print("预测值为{} 真实值为{}".format(im_pred, im_label))
        cv2.imshow("nowImage", im_data)
        cv2.waitKey(0)  # 弹出窗口时程序停止运行
print("loss为{},准确率是{}".format(loss_test, rightValue / len(test_data)))
print(cv2.__version__)

实战教学!pytorch实现手写数字识别!

Dataset

用于将数据从数据集中打包,然后分批次(batch)进行加载、训练

from torch.utils.data import  Dataset
from PIL import Image
import cv2
import  os
class MyData(Dataset):

    def __init__(self,root_dir,label_dir):
        self.root_dir=root_dir
        self.label_dir=label_dir
        self.path=os.path.join(self.root_dir,self.label_dir)
        self.img_path=os.listdir(self.path)

    def __getitem__(self, idx):
        img_name=self.img_path[idx]
        img_item_path=os.path.join(self.root_dir,self.label_dir,img_name)
        img=Image.open(img_item_path)
        label=self.label_dir
        return img,label

    def __len__(self):
        return len(self.img_path)

root_dir="train"
ants_label_dir="ants"
bees_label_dir="bees"
bees_dataset=MyData(root_dir,bees_label_dir)
ants_dataset=MyData(root_dir,ants_label_dir)

train_dataset=ants_dataset+bees_dataset

TensorBoard

用处是为了打印出loss等或者图片等,以用来监视整个训练过程

环境

pip install tensorboard

导出log

# 用处是为了打印出loss等或者图片等,以用来监视整个训练过程
from torch.utils.tensorboard import SummaryWriter
import  numpy as np
from PIL import Image

writer =SummaryWriter("logs")
image_path="train/ants/0013035.jpg"
img_PIL=Image.open(image_path)
img_array=np.array(img_PIL)#转化成能用tensorboard打开的图片格式
print(type(img_array))
print(img_array.shape)# (512,768,3)发现通道在最后,与add_image的默认不同

writer.add_image("test",img_array,1,dataformats='HWC')
# y= 2*x
for i in range(100):
    writer.add_scalar("y=2x",2*i,i)

writer.close()

打开log

终端中输入以下指令。复制链接至浏览器,终端中退出按ctrl+c

tensorboard --logdir=logs

端口选项

tensorboard --logdir=logs --port=6007

常用Transforms

是一个用于处理图像的库

  • 样例
from PIL import Image
from torchvision import transforms

# alt+7 打开structure
# ctrl+p方便查看函数参数
# ctrl+alt+l格式化代码

# tensor
img_path = "train/ants/0013035.jpg"
img_path_abs = "G:\\project\\pytorch_train\\dataset\\train\\ants\\0013035.jpg"
img = Image.open(img_path)
print(img)  # 打印图片信息

# transforms如何使用
# transforms是一个工具箱

tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)  # 将图片转为tensor
print(tensor_img)
输入PILImage.open()
输出tensorToTensor()
作用narrayscv.imread()
  • Totensor

    将图片转成tensor格式

from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter("logs")
img = Image.open("train/ants/0013035.jpg")
print(img)

# ToTensor
trans_totensor = transforms.ToTensor()  ##工具
img_tensor = trans_totensor(img)
writer.add_image("ToTensor", img_tensor)
write.close()
  • Normalize

    标准化,可以参考正太分布变为标准正太分布的过。

    writer.add_iamge()的第三个参数用于将该图片放置在第几step

from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter("logs")
img = Image.open("train/ants/0013035.jpg")
print(img)

trans_totensor = transforms.ToTensor()  ##工具
img_tensor = trans_totensor(img)

#Normalize
print(img_tensor[0][0][0])
trans_norm=transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])# 三通道 均值与标准差
img_norm=trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize",img_norm)
writer.close()
  • RandomCrop

    from PIL import Image
    from torchvision import transforms
    from torch.utils.tensorboard import SummaryWriter
    
    writer = SummaryWriter("logs")
    img = Image.open("train/ants/0013035.jpg")
    print(img)
    
    # RandomCrop
    trans_random=transforms.RandomCrop(50,100);
    trans_compose_2=transforms.Compose([trans_random,trans_totensor]) #compose为将多种transforms组合在一起
    for i in range(10):
        img_crop=trans_compose_2(img)
        writer.add_image("RandomCrop",img_crop,i)
    
    writer.close()
    

数据集的下载及使用

PyTorch Domains | PyTorch

import torchvision
from torch.utils.tensorboard import SummaryWriter

dataset_transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform,
                                         download=True)  # 作为训练集,下载数据集,并自动解压
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform,
                                        download=True)  # 作为测试集

# print(test_set[0])
# image,target=test_set[0]
# print(image)
# print(target)
# image.show()

print(test_set[0])
writer=SummaryWriter("p11")
for i in range(10):
    img,target=test_set[i]
    writer.add_image("test_set",img,i)

writer.close()

DataLoader

torch.utils.data — PyTorch 2.5 documentation

  • 样例
import torchvision.datasets
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

test_data = torchvision.datasets.CIFAR10("./dataset", False, transform=torchvision.transforms.ToTensor())

test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=True, num_workers=0, drop_last=False)
# shuffle 一轮后是否重新洗牌
# num_workers 启用子线程数量
# drop_last 余数数据是否保留
img,target=test_data[0]
print(img.shape)
print(target)

writer =SummaryWriter("dataloader")
for epoch in range(2):
    step = 0
    for data in test_loader:
        imgs,targets=data
        # print(imgs.shape)#torch.Size([4, 3, 32, 32]) 4表示batch_size
        # print(targets)# tensor([8, 7, 8, 3])
        writer.add_images("Epoch:{}".format(epoch),imgs,step)
        step=step+1

writer.close()
  • 效果

    864bf3f2f5f8c399b79f029aa3bf9fcc

nn.Module

Module — PyTorch 2.5 documentation

基础样例

import torch
from torch import nn


class Tudui(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self,input):
        output=input+1
        return output

tudui=Tudui()
x=torch.tensor(1.0)
output=tudui(x)
print(output)

卷积层

卷积核

convolution-layers

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=64)


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=0)
        # stride为步进
        # padding为四周的填充

    def forward(self, x):
        x = self.conv1(x)
        return x


tudui = Tudui()
print(tudui)

writer = SummaryWriter("./logs")
step = 0
for data in dataloader:
    imgs, targets = data
    output = tudui(imgs)
    print(imgs.shape)
    print(output.shape)
    writer.add_images("input", imgs, step)
    # 将output从6变为3个通道
    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("output", output, step)
    step = step + 1

writer.close()

最大池化层

池化层没有学习参数

pooling-layers

import torch
from torch import nn
from torch.nn import MaxPool2d

input =torch.tensor([[1,2,0,3,1],
                     [0,1,2,3,1],
                     [1,2,1,0,0],
                     [5,2,3,1,1],
                     [2,1,0,1,1]],dtype=torch.float)#默认为long,现在设置为浮点
# print(input.shape) torch.Size([5, 5])
input=torch.reshape(input,(-1,1,5,5))
# print(input.shape) torch.Size([1,1,5, 5])

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui,self).__init__()
        self.maxpool1=MaxPool2d(kernel_size=3,ceil_mode=True)#ceil 向上取整

    def forward(self,input):
        output=self.maxpool1(input)
        return output

tudui=Tudui()
output=tudui(input)
print(output)

非线性激活

import torch
import torchvision.datasets
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

#使用数据集测试
dataset = torchvision.datasets.CIFAR10("./dataset", train=True, transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=64)

#使用自定义数据测试
input =torch.tensor([[1,-0.5],
                     [-1,3]])
output=torch.reshape(input,[-1,1,2,2])

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui,self).__init__()
        self.relu1=ReLU(inplace=False)#false传形参,True传实参,默认为
        self.sigmoid=Sigmoid()
    def forward(self,input):
        output=self.sigmoid(input)#ReLU效果不明显,用sigmoid代替
        return output


tudui=Tudui()
#
# output=tudui(input)
# print(output)

writer=SummaryWriter("log__sigmoid")
step=0
for data in dataloader:
    imgs,targets=data
    writer.add_images("input",imgs,step)
    output=tudui(imgs)
    writer.add_images("output",output,step)
    step=step+1
writer.close()

Sequential

将若干层组合在一起

import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
from torch.utils.tensorboard import SummaryWriter


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.module1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

    def forward(self,x):
        x=self.module1(x)
        return x

tudui=Tudui()
print(tudui)
input=torch.ones((64,3,32,32))
output=tudui(input)
print(output.shape)
writer=SummaryWriter("logs_seq")
writer.add_graph(tudui,input)
writer.close()
  • 用tensorboard可以查看各层

    writer=SummaryWriter("logs_seq")
    writer.add_graph(tudui,input)
    writer.close()
    

650a49b4cac47aec649411d93115d1eb

损失函数

L1Loss — PyTorch 2.5 documentation

import torch
from torch import nn
from torch.nn import L1Loss,MSELoss,CrossEntropyLoss

inputs = torch.tensor([1, 2, 3],dtype=float)
targets = torch.tensor([1, 2, 5],dtype=float)

inputs = torch.reshape(inputs, (1, 1, 1, 3))
outputs = torch.reshape(targets, (1, 1, 1, 3))

##
loss =L1Loss()
result=loss(inputs,outputs)
print(result)

##方差
loss_mse=MSELoss()
result_mse=loss_mse(inputs,outputs)
print(result_mse)

##交叉熵(分类时使用)
x=torch.tensor([0.1,0.2,0.3])
y=torch.tensor([1])
x=torch.reshape(x,(1,3))
loss_cross=nn.CrossEntropyLoss()
result_cross=loss_cross(x,y)
print(result_cross)

反向传播

反向计算各权重的梯度(此时还未调整参数)

在创建的网络模型->model1->受保护的特性->_modules->某层(如卷积层)->weight,可以查看权重

import torchvision
from torch import nn
from torch.nn import Sequential,Conv2d,MaxPool2d,Flatten,Linear
from torch.utils.data import DataLoader

dataset=torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),
                                     download=True)
dataloader=DataLoader(dataset,batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.module1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

    def forward(self,x):
        x=self.module1(x)
        return x

tudui=Tudui()
loss=nn.CrossEntropyLoss()
for data in dataloader:
    imgs,targets=data
    outputs=tudui(imgs)
    result_loss=loss(outputs,targets)
    result_loss.backward()
    print(result_loss)
    break;##只是看看weight

优化器

用于更新模型里的权重

import torch.optim
import torchvision
from torch import nn
from torch.nn import Sequential,Conv2d,MaxPool2d,Flatten,Linear
from torch.utils.data import DataLoader

dataset=torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),
                                     download=True)
dataloader=DataLoader(dataset,batch_size=1)

class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.module1 = Sequential(
            Conv2d(3, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, 5, padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, 5, padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024,64),
            Linear(64,10)
        )

    def forward(self,x):
        x=self.module1(x)
        return x

tudui=Tudui()
loss=nn.CrossEntropyLoss()
optim=torch.optim.SGD(tudui.parameters(),lr=0.01)
for epoch in range(20):
    running_loss=0.0
    for data in dataloader:
        imgs,targets=data
        outputs=tudui(imgs)
        result_loss=loss(outputs,targets)
        optim.zero_grad()###初始化,千万不能忘
        result_loss.backward()
        optim.step()
        running_loss=running_loss+result_loss
    print(running_loss)

现有网络模型的使用/修改

vgg16_true = torchvision.models.vgg16(pretrained=True)#True表示未进行预训练 新版pretrained这一项似乎已经去掉了,改为了weights=None
vgg16_false = torchvision.models.vgg16(pretrained=False)
print(vgg16_false)#用来查看Module有哪些层
vgg16_true.add_module('add_linear',nn.Linear(1000,10))#给该模型添加新的模型
vgg16_false.classifier[6]=nn.Linear(4096,10)#classifier为该模型中某个模型的名字
  • print效果如下,显示各层信息

    690b9337f5426733fb11bc34bbd04240

网络模型的保存与读取

保存

import torch
import  torchvision
vgg16=torchvision.models.vgg16(weights=None)

#网络模型=结构+参数

#保存方式1 保存结构及参数
torch.save(vgg16,"vgg16_method1.pth")

#保存方式2 保存参数(官方推荐)
torch.save(vgg16.state_dict(),"vgg16_method2.pth")

加载

import  torch
import torchvision

#加载方式需与保存方式对应
#方式一加载模型
#如果为自定义模型,还需要将自定义模型class代码放在此.py里
model1=torch.load("vgg16_method1.pth")
print(model1)

#方式二加载模型(官方推荐)
vgg16=torchvision.models.vgg16(weights=None)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
print(vgg16)

小技巧

  • ctrl+p显示函数参数
  • ctrl+alt+L代码格式化
  • ctrl+鼠标左键查看源码
  • .shape查看维数

Trouble Shooting

pycharm配置anaconda环境时找不到python.exe解决办法

https://blog.csdn.net/ytusdc/article/details/137782055?fromshare=blogdetail&sharetype=blogdetail&sharerId=137782055&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

torch为cpu && print(torch.version.cuda)结果为 none

地址torch库地址 F:\Users\anaconda3\pkgs

print(torch.version.cuda)

记录一下安装Pytorch和cuda的踩坑经历 - 知乎

pycharm import cv2出错

  • 估计是权限的问题

用管理员打开anaconda prompt

切换至你的虚拟环境

输入

pip install opencv-python

在Anaconda中安装opencv库

Traceback (most recent call last):

  • 报错
Traceback (most recent call last):
  File "G:\research\number_recognition\main.py", line 2, in <module>
    import torchvision.datasets as dataset
  File "F:\Users\anaconda3\envs\pytorch\lib\site-packages\torchvision\__init__.py", line 5, in <module>
    from torchvision import datasets, io, models, ops, transforms, utils
  File "F:\Users\anaconda3\envs\pytorch\lib\site-packages\torchvision\datasets\__init__.py", line 1, in <module>
    from ._optical_flow import FlyingChairs, FlyingThings3D, HD1K, KittiFlow, Sintel
  File "F:\Users\anaconda3\envs\pytorch\lib\site-packages\torchvision\datasets\_optical_flow.py", line 9, in <module>
    from PIL import Image
  File "F:\Users\anaconda3\envs\pytorch\lib\site-packages\PIL\Image.py", line 103, in <module>
    from . import _imaging as core
ImportError: DLL load failed: 找不到指定的模块。
  • 解决
pip uninstall pillow
pip install pillow

Tensorboard无法写入

  • 解决

    注意write.close()的位置

解决tensorboard不能显示每一步的操作

  • 解决
tensorboard --logdir="<your logs>" --samples_per_plugin=images=1000

解决tensorboard每次都是从step3开始,而且不能显示每一步的操作_在网页上打开tensorboard时,为什么step间隔不是1-CSDN博客

其他

GNN

CS224W | Home

图神经网络 | BrainGNN: 用于功能磁共振成像分析的可解释性脑图神经网络

GCN

入门

FMRi

静息态fMRI功能性连接: 15分钟知识速览

LCD显示

硬件

型号:ATK-MD0430R-800480

【京东】https://3.cn/27-459X6「正点原子4.3英寸RGB屏模块800480」 点击链接直接打开

相关资料

1_【正点原子】达芬奇之FPGA开发指南 V2.2

整体介绍(更细节,包含实验展示与字符产生器,获取id)

集中展示代码

包含硬件连接图

RGB-LCD与TFT-LCD

【原创】TFTLCD和RGBLCD的区别 - 学习提问与解答专区 - 芯路恒电子技术论坛 - Powered by Discuz!

彩条实验

lcd_rgb_colorbar

顶层文件

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com 
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved                               
//----------------------------------------------------------------------------------------
// File name:           lcd_rgb_colorbar
// Last modified Date:  2019/8/07 10:41:06
// Last Version:        V1.0
// Descriptions:        LCD彩条显示顶层模块
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2019/8/07 10:41:06
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//

module lcd_rgb_colorbar(
    input                sys_clk,     //系统时钟
    input                sys_rst_n,   //系统复位

    //RGB LCD接口
    output               lcd_de,      //LCD 数据使能信号
    output               lcd_hs,      //LCD 行同步信号
    output               lcd_vs,      //LCD 场同步信号
    output               lcd_bl,      //LCD 背光控制信号
    output               lcd_clk,     //LCD 像素时钟
    output               lcd_rst,     //LCD 复位
    inout        [23:0]  lcd_rgb      //LCD RGB888颜色数据
    );                                                      
    
//wire define    
wire  [15:0]  lcd_id    ;    //LCD屏ID
wire          lcd_pclk  ;    //LCD像素时钟
              
wire  [10:0]  pixel_xpos;    //当前像素点横坐标
wire  [10:0]  pixel_ypos;    //当前像素点纵坐标
wire  [10:0]  h_disp    ;    //LCD屏水平分辨率
wire  [10:0]  v_disp    ;    //LCD屏垂直分辨率
wire  [23:0]  pixel_data;    //像素数据
wire  [23:0]  lcd_rgb_o ;    //输出的像素数据
wire  [23:0]  lcd_rgb_i ;    //输入的像素数据

//*****************************************************
//**                    main code
//*****************************************************

//像素数据方向切换
assign lcd_rgb = lcd_de ?  lcd_rgb_o :  {24{1'bz}};
assign lcd_rgb_i = lcd_rgb;

//读LCD ID模块
rd_id u_rd_id(
    .clk          (sys_clk  ),
    .rst_n        (sys_rst_n),
    .lcd_rgb      (lcd_rgb_i),
    .lcd_id       (lcd_id   )
    );    

//时钟分频模块    
clk_div u_clk_div(
    .clk           (sys_clk  ),
    .rst_n         (sys_rst_n),
    .lcd_id        (lcd_id   ),
    .lcd_pclk      (lcd_pclk )
    );    

//LCD显示模块    
lcd_display u_lcd_display(
    .lcd_pclk       (lcd_pclk  ),
    .rst_n          (sys_rst_n ),
    .pixel_xpos     (pixel_xpos),
    .pixel_ypos     (pixel_ypos),
    .h_disp         (h_disp    ),
    .v_disp         (v_disp    ),
    .pixel_data     (pixel_data)
    );    

//LCD驱动模块
lcd_driver u_lcd_driver(
    .lcd_pclk      (lcd_pclk  ),
    .rst_n         (sys_rst_n ),
    .lcd_id        (lcd_id    ),
    .pixel_data    (pixel_data),
    .pixel_xpos    (pixel_xpos),
    .pixel_ypos    (pixel_ypos),
    .h_disp        (h_disp    ),
    .v_disp        (v_disp    ),
	.data_req	   (		  ),
	
    .lcd_de        (lcd_de    ),
    .lcd_hs        (lcd_hs    ),
    .lcd_vs        (lcd_vs    ),
    .lcd_bl        (lcd_bl    ),
    .lcd_clk       (lcd_clk   ),
    .lcd_rst       (lcd_rst   ),
    .lcd_rgb       (lcd_rgb_o )
    );

endmodule

rd_id

获取id

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com 
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved                               
//----------------------------------------------------------------------------------------
// File name:           rd_id
// Last modified Date:  2019/8/07 10:41:06
// Last Version:        V1.0
// Descriptions:        读取LCD ID模块
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2019/8/07 10:41:06
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//

module rd_id(
    input                   clk    ,    //时钟
    input                   rst_n  ,    //复位,低电平有效
    input           [23:0]  lcd_rgb,    //RGB LCD像素数据,用于读取ID
    output   reg    [15:0]  lcd_id     //LCD屏ID
    );

//reg define
reg            rd_flag;  //读ID标志

//*****************************************************
//**                    main code
//*****************************************************

//获取LCD ID   M2:B7  M1:G7  M0:R7
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rd_flag <= 1'b0;
        lcd_id <= 16'd0;
    end    
    else begin
        if(rd_flag == 1'b0) begin
            rd_flag <= 1'b1; 
            case({lcd_rgb[7],lcd_rgb[15],lcd_rgb[23]})
                3'b000 : lcd_id <= 16'h4342;    //4.3' RGB LCD  RES:480x272
                3'b001 : lcd_id <= 16'h7084;    //7'   RGB LCD  RES:800x480
                3'b010 : lcd_id <= 16'h7016;    //7'   RGB LCD  RES:1024x600
                3'b100 : lcd_id <= 16'h4384;    //4.3' RGB LCD  RES:800x480
                3'b101 : lcd_id <= 16'h1018;    //10'  RGB LCD  RES:1280x800
                default : lcd_id <= 16'd0;
            endcase    
        end
    end    
end

endmodule

clk_div

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com 
//关注微信公众平台微信号:"正点原子",免费获取FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved                               
//----------------------------------------------------------------------------------------
// File name:           clk_div
// Last modified Date:  2019/8/7 10:41:06
// Last Version:        V1.0
// Descriptions:        时钟分频模块
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2019/8/7 10:41:06
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//

module clk_div(
    input               clk,          //50Mhz
    input               rst_n,
    input       [15:0]  lcd_id,
    output  reg         lcd_pclk
    );

//reg define
reg          clk_25m;
reg          clk_12_5m;
reg          div_4_cnt;

//*****************************************************
//**                    main code
//*****************************************************

//时钟2分频 输出25MHz时钟 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        clk_25m <= 1'b0;
    else 
        clk_25m <= ~clk_25m;
end

//时钟4分频 输出12.5MHz时钟 
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        div_4_cnt <= 1'b0;
        clk_12_5m <= 1'b0;
    end    
    else begin
        div_4_cnt <= div_4_cnt + 1'b1;
        if(div_4_cnt == 1'b1)
            clk_12_5m <= ~clk_12_5m;
		else
			clk_12_5m <= clk_12_5m;
    end        
end

always @(*) begin
    case(lcd_id)
        16'h4342 : lcd_pclk = clk_12_5m;
        16'h7084 : lcd_pclk = clk_25m;       
        16'h7016 : lcd_pclk = clk;
        16'h4384 : lcd_pclk = clk_25m;
        16'h1018 : lcd_pclk = clk;
        default :  lcd_pclk = 1'b0;
    endcase      
end

endmodule

lcd_driver

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com 
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved                               
//----------------------------------------------------------------------------------------
// File name:           lcd_driver
// Last modified Date:  2019/8/07 10:41:06
// Last Version:        V1.0
// Descriptions:        LCD驱动模块
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2019/8/07 10:41:06
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//

module lcd_driver(
    input                lcd_pclk,    //时钟
    input                rst_n,       //复位,低电平有效
    input        [15:0]  lcd_id,      //LCD屏ID
    input        [23:0]  pixel_data,  //像素数据
    output  reg  [10:0]  pixel_xpos,  //当前像素点横坐标
    output  reg  [10:0]  pixel_ypos,  //当前像素点纵坐标   
    output  reg  [10:0]  h_disp,      //LCD屏水平分辨率
    output  reg  [10:0]  v_disp,      //LCD屏垂直分辨率 
	output  reg          data_req,    //数据请求信号
    //RGB LCD接口
    output  reg          lcd_de,      //LCD 数据使能信号
    output               lcd_hs,      //LCD 行同步信号
    output               lcd_vs,      //LCD 场同步信号
    output               lcd_bl,      //LCD 背光控制信号
    output               lcd_clk,     //LCD 像素时钟
    output               lcd_rst,     //LCD复位
    output       [23:0]  lcd_rgb      //LCD RGB888颜色数据
    );

//parameter define  
// 4.3' 480*272
parameter  H_SYNC_4342   =  11'd41;     //行同步
parameter  H_BACK_4342   =  11'd2;      //行显示后沿
parameter  H_DISP_4342   =  11'd480;    //行有效数据
parameter  H_FRONT_4342  =  11'd2;      //行显示前沿
parameter  H_TOTAL_4342  =  11'd525;    //行扫描周期
   
parameter  V_SYNC_4342   =  11'd10;     //场同步
parameter  V_BACK_4342   =  11'd2;      //场显示后沿
parameter  V_DISP_4342   =  11'd272;    //场有效数据
parameter  V_FRONT_4342  =  11'd2;      //场显示前沿
parameter  V_TOTAL_4342  =  11'd286;    //场扫描周期
   
// 7' 800*480   
parameter  H_SYNC_7084   =  11'd128;    //行同步
parameter  H_BACK_7084   =  11'd88;     //行显示后沿
parameter  H_DISP_7084   =  11'd800;    //行有效数据
parameter  H_FRONT_7084  =  11'd40;     //行显示前沿
parameter  H_TOTAL_7084  =  11'd1056;   //行扫描周期
   
parameter  V_SYNC_7084   =  11'd2;      //场同步
parameter  V_BACK_7084   =  11'd33;     //场显示后沿
parameter  V_DISP_7084   =  11'd480;    //场有效数据
parameter  V_FRONT_7084  =  11'd10;     //场显示前沿
parameter  V_TOTAL_7084  =  11'd525;    //场扫描周期       
   
// 7' 1024*600   
parameter  H_SYNC_7016   =  11'd20;     //行同步
parameter  H_BACK_7016   =  11'd140;    //行显示后沿
parameter  H_DISP_7016   =  11'd1024;   //行有效数据
parameter  H_FRONT_7016  =  11'd160;    //行显示前沿
parameter  H_TOTAL_7016  =  11'd1344;   //行扫描周期
   
parameter  V_SYNC_7016   =  11'd3;      //场同步
parameter  V_BACK_7016   =  11'd20;     //场显示后沿
parameter  V_DISP_7016   =  11'd600;    //场有效数据
parameter  V_FRONT_7016  =  11'd12;     //场显示前沿
parameter  V_TOTAL_7016  =  11'd635;    //场扫描周期
   
// 10.1' 1280*800   
parameter  H_SYNC_1018   =  11'd10;     //行同步
parameter  H_BACK_1018   =  11'd80;     //行显示后沿
parameter  H_DISP_1018   =  11'd1280;   //行有效数据
parameter  H_FRONT_1018  =  11'd70;     //行显示前沿
parameter  H_TOTAL_1018  =  11'd1440;   //行扫描周期
   
parameter  V_SYNC_1018   =  11'd3;      //场同步
parameter  V_BACK_1018   =  11'd10;     //场显示后沿
parameter  V_DISP_1018   =  11'd800;    //场有效数据
parameter  V_FRONT_1018  =  11'd10;     //场显示前沿
parameter  V_TOTAL_1018  =  11'd823;    //场扫描周期

// 4.3' 800*480   
parameter  H_SYNC_4384   =  11'd128;    //行同步
parameter  H_BACK_4384   =  11'd88;     //行显示后沿
parameter  H_DISP_4384   =  11'd800;    //行有效数据
parameter  H_FRONT_4384  =  11'd40;     //行显示前沿
parameter  H_TOTAL_4384  =  11'd1056;   //行扫描周期
   
parameter  V_SYNC_4384   =  11'd2;      //场同步
parameter  V_BACK_4384   =  11'd33;     //场显示后沿
parameter  V_DISP_4384   =  11'd480;    //场有效数据
parameter  V_FRONT_4384  =  11'd10;     //场显示前沿
parameter  V_TOTAL_4384  =  11'd525;    //场扫描周期    

//reg define
reg  [10:0] h_sync ;
reg  [10:0] h_back ;
reg  [10:0] h_total;
reg  [10:0] v_sync ;
reg  [10:0] v_back ;
reg  [10:0] v_total;
reg  [10:0] h_cnt  ;
reg  [10:0] v_cnt  ;

//*****************************************************
//**                    main code
//*****************************************************

//RGB LCD 采用DE模式时,行场同步信号需要拉高
assign  lcd_hs = 1'b1;        //LCD行同步信号
assign  lcd_vs = 1'b1;        //LCD场同步信号

assign  lcd_bl = 1'b1;        //LCD背光控制信号  
assign  lcd_clk = lcd_pclk;   //LCD像素时钟
assign  lcd_rst= 1'b1;        //LCD复位

//RGB888数据输出
assign lcd_rgb = lcd_de ? pixel_data : 24'd0;

//像素点x坐标
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n)
        pixel_xpos <= 11'd0;
    else if(data_req)
        pixel_xpos <= h_cnt + 2'd2 - h_sync - h_back ;
    else 
        pixel_xpos <= 11'd0;
end
   
//像素点y坐标   
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n)
        pixel_ypos <= 11'd0;
    else if(v_cnt >= (v_sync + v_back)&&v_cnt < (v_sync + v_back + v_disp))
        pixel_ypos <= v_cnt + 1'b1 - (v_sync + v_back) ;
    else 
        pixel_ypos <= 11'd0;
end

//行场时序参数
always @(*) begin
    case(lcd_id)
        16'h4342 : begin
            h_sync  = H_SYNC_4342; 
            h_back  = H_BACK_4342; 
            h_disp  = H_DISP_4342; 
            h_total = H_TOTAL_4342;
            v_sync  = V_SYNC_4342; 
            v_back  = V_BACK_4342; 
            v_disp  = V_DISP_4342; 
            v_total = V_TOTAL_4342;            
        end
        16'h7084 : begin
            h_sync  = H_SYNC_7084; 
            h_back  = H_BACK_7084; 
            h_disp  = H_DISP_7084; 
            h_total = H_TOTAL_7084;
            v_sync  = V_SYNC_7084; 
            v_back  = V_BACK_7084; 
            v_disp  = V_DISP_7084; 
            v_total = V_TOTAL_7084;        
        end
        16'h7016 : begin
            h_sync  = H_SYNC_7016; 
            h_back  = H_BACK_7016; 
            h_disp  = H_DISP_7016; 
            h_total = H_TOTAL_7016;
            v_sync  = V_SYNC_7016; 
            v_back  = V_BACK_7016; 
            v_disp  = V_DISP_7016; 
            v_total = V_TOTAL_7016;            
        end
        16'h4384 : begin
            h_sync  = H_SYNC_4384; 
            h_back  = H_BACK_4384; 
            h_disp  = H_DISP_4384; 
            h_total = H_TOTAL_4384;
            v_sync  = V_SYNC_4384; 
            v_back  = V_BACK_4384; 
            v_disp  = V_DISP_4384; 
            v_total = V_TOTAL_4384;             
        end        
        16'h1018 : begin
            h_sync  = H_SYNC_1018; 
            h_back  = H_BACK_1018; 
            h_disp  = H_DISP_1018; 
            h_total = H_TOTAL_1018;
            v_sync  = V_SYNC_1018; 
            v_back  = V_BACK_1018; 
            v_disp  = V_DISP_1018; 
            v_total = V_TOTAL_1018;        
        end
        default : begin
            h_sync  = H_SYNC_4342; 
            h_back  = H_BACK_4342; 
            h_disp  = H_DISP_4342; 
            h_total = H_TOTAL_4342;
            v_sync  = V_SYNC_4342; 
            v_back  = V_BACK_4342; 
            v_disp  = V_DISP_4342; 
            v_total = V_TOTAL_4342;          
        end
    endcase
end
	
//数据使能信号		
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n)	
		lcd_de <= 1'b0;
	else
		lcd_de <= data_req;
end
				  
//请求像素点颜色数据输入  
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n)	
		data_req<=1'b0;
	else if((h_cnt >= h_sync + h_back - 2'd2) && (h_cnt < h_sync + h_back + h_disp - 2'd2)
             && (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp))
		data_req <= 1'b1;
	else
		data_req <= 1'b0;
end
				  
//行计数器对像素时钟计数
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n) 
        h_cnt <= 11'd0;
    else begin
        if(h_cnt == h_total - 1'b1)
            h_cnt <= 11'd0;
        else
            h_cnt <= h_cnt + 1'b1;           
    end
end

//场计数器对行计数
always@ (posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n) 
        v_cnt <= 11'd0;
    else begin
        if(h_cnt == h_total - 1'b1) begin
            if(v_cnt == v_total - 1'b1)
                v_cnt <= 11'd0;
            else
                v_cnt <= v_cnt + 1'b1;    
        end
    end    
end

endmodule

driver_display

用来提供(pixel_xpos,pixel_ypos)处的颜色data

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:www.openedv.com
//淘宝店铺:http://openedv.taobao.com 
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2018-2028
//All rights reserved                               
//----------------------------------------------------------------------------------------
// File name:           lcd_display
// Last modified Date:  2019/8/07 10:41:06
// Last Version:        V1.0
// Descriptions:        LCD显示模块
//----------------------------------------------------------------------------------------
// Created by:          正点原子
// Created date:        2019/8/07 10:41:06
// Version:             V1.0
// Descriptions:        The original version
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//

module lcd_display(
    input                lcd_pclk,    //时钟
    input                rst_n,       //复位,低电平有效
    input        [10:0]  pixel_xpos,  //当前像素点横坐标
    input        [10:0]  pixel_ypos,  //当前像素点纵坐标  
    input        [10:0]  h_disp,      //LCD屏水平分辨率
    input        [10:0]  v_disp,      //LCD屏垂直分辨率       
    output  reg  [23:0]  pixel_data   //像素数据
    );

//parameter define  
parameter WHITE = 24'hFFFFFF;  //白色
parameter BLACK = 24'h000000;  //黑色
parameter RED   = 24'hFF0000;  //红色
parameter GREEN = 24'h00FF00;  //绿色
parameter BLUE  = 24'h0000FF;  //蓝色

//*****************************************************
//**                    main code
//*****************************************************

//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge lcd_pclk or negedge rst_n) begin
    if(!rst_n)
        pixel_data <= BLACK;
    else begin
        if((pixel_xpos >= 11'd0) && (pixel_xpos < h_disp/5*1))
            pixel_data <= WHITE;
        else if((pixel_xpos >= h_disp/5*1) && (pixel_xpos < h_disp/5*2))    
            pixel_data <= BLACK;
        else if((pixel_xpos >= h_disp/5*2) && (pixel_xpos < h_disp/5*3))    
            pixel_data <= RED;   
        else if((pixel_xpos >= h_disp/5*3) && (pixel_xpos < h_disp/5*4))    
            pixel_data <= GREEN;                
        else
            pixel_data <= BLUE; 
    end    
end
  
endmodule

字符实验

相关概念

行场同步模式(HV Mode)

  • LCD的行显示对应时序

HSYNC:行同步信号,当此信号有效的时候就表示开始显示新的一行数据,查阅所使用的 LCD 数据手册可以知道此信号是低电平有效还是高电平有效,在这里是 低电平有效 HSPW:行同步信号宽度,也就是 HSYNC 信号持续时间。HSYNC 信号不是一个脉冲,而是需要持续一段时间才是有效的,单位为 CLK。 HBP:行显示后沿(或后肩),单位是 CLK。 HOZVAL:行有效显示区域,即显示一行数据所需的时间,假如屏幕分辨率为 1024*600,那么HOZVAL 就是 1024,单位为 CLK。 HFP:行显示前沿(或前肩),单位是 CLK。当 HSYNC 信号发出以后,需要等待 HSPW+HBP 个 CLK 时间才会接收到真正有效的像素数据。当显示完一行数据以后需要等待 HFP 个 CLK 时间才能发出下一个 HSYNC 信号,所以显示一行所需要的时间就是:HSPW + HBP + HOZVAL + HFP。

  • RGB LCD的 帧显示时序图

SYNC:帧(场)同步信号,当此信号有效的时候就表示开始显示新的一帧数据,查阅所使用的 LCD 数据手册可以知道此信号是低电平有效还是高电平有效,图 18.1.8 为低电平有效。 VSPW:帧同步信号宽度,也就是 VSYNC 信号持续时间,单位为 1 行的时间。 VBP:帧显示后沿(或后肩),单位为 1 行的时间。 LINE:帧有效显示区域,即显示一帧数据所需的时间,假如屏幕分辨率为 1024*600,那么 LINE 就是 600 行的时间。 VFP:帧显示前沿(或前肩),单位为 1 行的时间。 显示一帧所需要的时间就是:VSPW+VBP+LINE+VFP 个行时间,最终的计算公式: T = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)

// 4.3' 800*480   
parameter  H_SYNC_4384   =  11'd128;    //行同步
parameter  H_BACK_4384   =  11'd88;     //行显示后沿
parameter  H_DISP_4384   =  11'd800;    //行有效数据
parameter  H_FRONT_4384  =  11'd40;     //行显示前沿
parameter  H_TOTAL_4384  =  11'd1056;   //行扫描周期
   
parameter  V_SYNC_4384   =  11'd2;      //场同步
parameter  V_BACK_4384   =  11'd33;     //场显示后沿
parameter  V_DISP_4384   =  11'd480;    //场有效数据
parameter  V_FRONT_4384  =  11'd10;     //场显示前沿
parameter  V_TOTAL_4384  =  11'd525;    //场扫描周期    

https://blog.csdn.net/qlexcel/article/details/86301007?fromshare=blogdetail&sharetype=blogdetail&sharerId=86301007&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

https://blog.csdn.net/weixin_50965981/article/details/134496428?fromshare=blogdetail&sharetype=blogdetail&sharerId=134496428&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

数据使能同步模式(DE Mode)

UART做逻辑分析仪

UART 实现

https://blog.csdn.net/Ryansweet716/article/details/133100965?fromshare=blogdetail&sharetype=blogdetail&sharerId=133100965&sharerefer=PC&sharesource=r1Way&sharefrom=from_link

uart_rx

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/10/25 10:08:43
// Design Name: 
// Module Name: uart_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module uart_rx(
    input               clk         ,  //系统时钟
    input               rst_n       ,  //系统复位,低有效

    input               uart_rxd    ,  //UART接收端口
    output  reg         uart_rx_done=0,  //UART接收完成信号
    output  reg  [7:0]  uart_rx_data=0   //UART接收到的数据
    );

//parameter define
parameter CLK_FREQ = 50000000;               //系统时钟频率
parameter UART_BPS = 115200  ;               //串口波特率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数BPS_CNT次 (传输1bit所需时钟数)

//reg define
reg          uart_rxd_d0=1;
reg          uart_rxd_d1=1;
reg          uart_rxd_d2=1;
reg          rx_flag=0    ;  //接收过程标志信号
reg  [3:0 ]  rx_cnt=0     ;  //记录接收了几位
reg  [15:0]  baud_cnt=0   ;  //波特率计数器
reg  [7:0 ]  rx_data_t=8'b0  ;  //接收数据寄存器

//wire define
wire        start_en;

//*****************************************************
//**                    main code
//*****************************************************
//捕获接收端口下降沿(起始位),得到一个时钟周期的脉冲信号
assign start_en = uart_rxd_d2 & (~uart_rxd_d1) & (~rx_flag);

//针对异步信号的同步处理
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        uart_rxd_d0 <= 1'b0;
        uart_rxd_d1 <= 1'b0;
        uart_rxd_d2 <= 1'b0;
    end
    else begin
        uart_rxd_d0 <= uart_rxd;
        uart_rxd_d1 <= uart_rxd_d0;
        uart_rxd_d2 <= uart_rxd_d1;
    end
end

//给接收标志赋值 单bit接收标志
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        rx_flag <= 1'b0;
    else if(start_en)    //检测到起始位
        rx_flag <= 1'b1; //接收过程中,标志信号rx_flag拉高,拉高后start_en=0
    //在停止位一半的时候,即接收过程结束,标志信号rx_flag拉低
    else if((rx_cnt == 4'd9) && (baud_cnt == BAUD_CNT_MAX/2 - 1'b1))//到最后一位检测时
        rx_flag <= 1'b0;
    else
        rx_flag <= rx_flag;
end        

//波特率的计数器赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        baud_cnt <= 16'd0;
    else if(rx_flag) begin     //处于接收过程时,波特率计数器(baud_cnt)进行循环计数
        if(baud_cnt < BAUD_CNT_MAX - 1'b1)
            baud_cnt <= baud_cnt + 16'b1;
        else 
            baud_cnt <= 16'd0; //计数达到一个波特率周期后清零
    end    
    else
        baud_cnt <= 16'd0;     //接收过程结束时计数器清零
end

//对接收数据计数器(rx_cnt)进行赋值  
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        rx_cnt <= 4'd0;
    else if(rx_flag) begin                  //处于接收过程时rx_cnt才进行计数
        if(baud_cnt == BAUD_CNT_MAX - 1'b1) //当波特率计数器计数到一个波特率周期时
            rx_cnt <= rx_cnt + 1'b1;        //接收数据计数器加1
        else
            rx_cnt <= rx_cnt;
    end
    else
        rx_cnt <= 4'd0;                     //接收过程结束时计数器清零
end        

//根据rx_cnt来寄存rxd端口的数据
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        rx_data_t <= 8'b0;
    else if(rx_flag) begin                           //系统处于接收过程时
        if(baud_cnt == BAUD_CNT_MAX/2 - 1'b1) begin  //判断baud_cnt是否计数到数据位的中间
           case(rx_cnt)
               4'd1 : rx_data_t[0] <= uart_rxd_d2;   //寄存数据的最低位
               4'd2 : rx_data_t[1] <= uart_rxd_d2;
               4'd3 : rx_data_t[2] <= uart_rxd_d2;
               4'd4 : rx_data_t[3] <= uart_rxd_d2;
               4'd5 : rx_data_t[4] <= uart_rxd_d2;
               4'd6 : rx_data_t[5] <= uart_rxd_d2;
               4'd7 : rx_data_t[6] <= uart_rxd_d2;
               4'd8 : rx_data_t[7] <= uart_rxd_d2;   //寄存数据的高低位
               default : ;
            endcase  
        end
        else
            rx_data_t <= rx_data_t;
    end
    else
        rx_data_t <= 8'b0;
end        

//给接收完成信号和接收到的数据赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        uart_rx_done <= 1'b0;
        uart_rx_data <= 8'b0;
    end
    //当接收数据计数器计数到停止位,且baud_cnt计数到停止位的中间时
    else if(rx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX/2 - 1'b1) begin
        uart_rx_done <= 1'b1     ;  //拉高接收完成信号
        uart_rx_data <= rx_data_t;  //并对UART接收到的数据进行赋值
    end    
    else begin
        uart_rx_done <= 1'b0;
        uart_rx_data <= uart_rx_data;
    end
end

endmodule

tb

simulation runtime 需设置为200000ns

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/10/25 10:10:02
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module tb(
    );
    
uart_rx uart_rx0(
    .clk(clk)         ,  //系统时钟
    .rst_n(rst_n)       ,  //系统复位,低有效
    .uart_rxd(uart_rxd)    ,  //UART接收端口
    
    .uart_rx_done(uart_rx_done),  //UART接收完成信号
    .uart_rx_data(uart_rx_data)   //UART接收到的数据
    );
    
reg clk=0;
reg rst_n=1;
reg uart_rxd=1;

wire uart_rx_done;
wire [7:0]uart_rx_data;

parameter CLK_FREQ = 50000000;               //系统时钟频率
parameter UART_BPS = 115200  ;               //串口波特率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数BPS_CNT次 (传输1bit所需时钟数)
parameter delta=1000000000/UART_BPS;
parameter CLK_PERIOD = 20;  // 时钟周期为20ns

always # 10  clk=~clk ;

initial begin
clk=0; 
rst_n=1;
uart_rxd=1;

# delta
uart_rxd<=0;

# delta
uart_rxd<=1;
# delta
uart_rxd<=0;
# delta
uart_rxd<=1;
# delta
uart_rxd<=0;
# delta
uart_rxd<=1;
# delta
uart_rxd<=0;
# delta
uart_rxd<=1;
# delta
uart_rxd<=1;
# delta
uart_rxd<=1;

# (delta/2)
# delta
uart_rxd<=0;
# delta
uart_rxd<=0;
# delta
uart_rxd<=1;
# delta
uart_rxd<=0;
# delta
uart_rxd<=1;
# delta
uart_rxd<=1;
# delta
uart_rxd<=1;
# delta
uart_rxd<=1;
# delta
uart_rxd<=0;

end



endmodule

结果

A9C1232240749328F08434A53A09A71F

uart_tx

module uart_tx(
    input               clk         , //系统时钟
    input               rst_n       , //系统复位,低有效
    input               uart_tx_en  , //UART的发送使能
    input     [7:0]     uart_tx_data, //UART要发送的数据
    output  reg         uart_txd    , //UART发送端口
    output  reg         uart_tx_busy  //发送忙状态信号
    );

//parameter define
parameter CLK_FREQ = 50000000;               //系统时钟频率
parameter UART_BPS = 115200  ;               //串口波特率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数BPS_CNT次

//reg define
reg  [7:0]  tx_data_t;  //发送数据寄存器
reg  [3:0]  tx_cnt   ;  //发送数据计数器
reg  [15:0] baud_cnt ;  //波特率计数器

//*****************************************************
//**                    main code
//*****************************************************

//当uart_tx_en为高时,寄存输入的并行数据,并拉高BUSY信号
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        tx_data_t <= 8'b0;
        uart_tx_busy <= 1'b0;
    end
    //发送使能时,寄存要发送的数据,并拉高BUSY信号
    else if(uart_tx_en) begin
        tx_data_t <= uart_tx_data;
        uart_tx_busy <= 1'b1;
    end
    //当计数到停止位结束时,停止发送过程
    else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - BAUD_CNT_MAX/16) begin
        tx_data_t <= 8'b0;     //清空发送数据寄存器
        uart_tx_busy <= 1'b0;  //并拉低BUSY信号
    end
    else begin
        tx_data_t <= tx_data_t;
        uart_tx_busy <= uart_tx_busy;
    end
end

//波特率的计数器赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        baud_cnt <= 16'd0;
    //当处于发送过程时,波特率计数器(baud_cnt)进行循环计数
    else if(uart_tx_busy) begin
        if(baud_cnt < BAUD_CNT_MAX - 1'b1)
            baud_cnt <= baud_cnt + 16'b1;
        else 
            baud_cnt <= 16'd0; //计数达到一个波特率周期后清零
    end    
    else
        baud_cnt <= 16'd0;     //发送过程结束时计数器清零
end

//tx_cnt进行赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        tx_cnt <= 4'd0;
    else if(uart_tx_busy) begin             //处于发送过程时tx_cnt才进行计数
        if(baud_cnt == BAUD_CNT_MAX - 1'b1) //当波特率计数器计数到一个波特率周期时
            tx_cnt <= tx_cnt + 1'b1;        //发送数据计数器加1
        else
            tx_cnt <= tx_cnt;
    end
    else
        tx_cnt <= 4'd0;                     //发送过程结束时计数器清零
end

//根据tx_cnt来给uart发送端口赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        uart_txd <= 1'b1;//重置时为高电平
    else if(uart_tx_busy) begin
        case(tx_cnt) 
            4'd0 : uart_txd <= 1'b0        ; //起始位
            4'd1 : uart_txd <= tx_data_t[0]; //数据位最低位
            4'd2 : uart_txd <= tx_data_t[1];
            4'd3 : uart_txd <= tx_data_t[2];
            4'd4 : uart_txd <= tx_data_t[3];
            4'd5 : uart_txd <= tx_data_t[4];
            4'd6 : uart_txd <= tx_data_t[5];
            4'd7 : uart_txd <= tx_data_t[6];
            4'd8 : uart_txd <= tx_data_t[7]; //数据位最高位
            4'd9 : uart_txd <= 1'b1        ; //停止位
            default : uart_txd <= 1'b1;
        endcase
    end
    else
        uart_txd <= 1'b1;                    //空闲时发送端口为高电平
end

endmodule

tb

simulation runtime 需设置为200000ns

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/10/25 22:50:18
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module tb(

);

uart_tx uart_tx0(
    .clk(clk)         , //绯荤粺鏃堕挓
    .rst_n(rst_n)       , //绯荤粺澶嶄綅锛屼綆鏈夋晥
    .uart_tx_en(uart_tx_en)  , //UART鐨勫彂閫佷娇鑳�
    .uart_tx_data(uart_tx_data), //UART瑕佸彂閫佺殑鏁版嵁
    .uart_txd(uart_txd)   , //UART鍙戦�佺鍙�
    .uart_tx_busy(uart_tx_busy) //鍙戦�佸繖鐘舵�佷俊鍙�
);

reg clk=0;
reg rst_n=1;
reg uart_tx_en=0;
reg [7:0] uart_tx_data=8'b0;
wire uart_txd;
wire uart_tx_busy;

always #10 clk=~clk; 


initial begin
clk=0;
rst_n=1;
uart_tx_en=0;
uart_tx_data<=8'b01101101;
#20
uart_tx_en=1;
#20
uart_tx_en=0;
end


endmodule

结果

94e77cbc9208c64c793f8973d5be21ba

adadda1c1211917d078eb9e82db878e6

顶层文件

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/10/26 09:27:43
// Design Name: 
// Module Name: uart
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module uart(
input sys_clk,
input sys_rst_n,
input uart_rxd,
output uart_txd
    );
uart_rx_0 my_rx(
  .clk(sys_clk),                    // input wire clk
  .rst_n(sys_rst_n),                // input wire rst_n
  .uart_rxd(uart_rxd),          // input wire uart_rxd
  .uart_rx_done(uart_rx_done),  // output wire uart_rx_done
  .uart_rx_data(uart_rx_data)  // output wire [7 : 0] uart_rx_data
);

wire uart_rx_done;
wire [7:0] uart_rx_data;

uart_tx_0 my_tx(
  .clk(sys_clk),                    // input wire clk
  .rst_n(sys_rst_n),                // input wire rst_n
  .uart_tx_en(uart_rx_done),      // input wire uart_tx_en
  .uart_tx_data(uart_rx_data),  // input wire [7 : 0] uart_tx_data
  .uart_txd(uart_txd)          // output wire uart_txd
);


endmodule

约束文件

基于达芬奇xc7a35tfgg484-2

#时序约束
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]

#IO引脚约束
#------------------------------系统时钟和复位-----------------------------------
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]

#-----------------------------------UART----------------------------------------
set_property -dict {PACKAGE_PIN U5 IOSTANDARD LVCMOS33} [get_ports uart_rxd]
set_property -dict {PACKAGE_PIN T6 IOSTANDARD LVCMOS33} [get_ports uart_txd]

串口调试助手

二选一

d8d8df34e9f1b7308dff8bce493c538a

a70abfe9aa2d2e7d87c91c66fcd61878

智能车小车底座控制

四轮驱动 安装说明书链接:http://pan.baidu.com/s/1eSmCBqq 相关资料链接:http://pan.baidu.com/share/link?shareid=3926830886&uk=2302102993 4WD小车作为模型在科教频道我爱发明栏目做演示 讲解原理请看视频:(请复制到IE观看) http://my.ku6.com/watch?v=VwM9YPcgb4_CI6arP5Wgsw..#share 4WD用Android手机控制演示http://v.youku.com/v_show/id_XNDA3MzUxODg0.html 4WD搭载舵机与超声波避障演示http://v.youku.com/v_show/id_XNDE3ODE4NDE2.html 4WD寻迹演示http://v.youku.com/v_show/id_XMzIxNTYyMzg4.html
4WD弯道寻迹演示http://v.youku.com/v_show/id_XMzIxNTYzMTgw.html 4WD遥控演示http://v.youku.com/v_show/id_XMzY4ODc1Mjc2.html 4WD走迷宫演示http://v.youku.com/v_show/id_XMzY4ODc0NTg4.html\

42步进电机控制

硬件

A4988+扩展板

接口详解

fpga

FPGA产生可调频率占空比的PWM - IntoTheSky - 博客园 (cnblogs.com)

S42H40D20步进电机(额定功率6.12W,额定电流1.7A,电机驱动电压24V)

判断哪两根线是一组

A4988驱动NEMA步进电机(42步进电机) – 太极创客 (taichi-maker.com)

接口

按钮

按下为0

`timescale 1ns / 1ps
module inverse
(
    );

演示

【用 A4988 控制步进电机】https://www.bilibili.com/video/BV1m84y1a79w?vd_source=ec4e4974e1b56ed330afdb6c6ead1501

脉冲波

module pwm_test(
    input wire sys_clk,          // FPGA时钟信号
    input wire btn,          // 按钮输入信号
    output reg pulse_out     // 脉冲输出信号
);

// 定义计数器的位宽,足以计数到1000微秒
// 假设FPGA时钟频率为50MHz,计数器需要计数到50000(1000微秒 * 50MHz)
// 因此,至少需要16位宽(2^16 > 50000)
reg [15:0] counter = 0;

// 检测按钮按下(上升沿)
wire btn_press = btn && !btn_last;
reg btn_last = 0;

always @(posedge sys_clk) begin
    btn_last <= btn;
end

// 生成脉冲
always @(posedge sys_clk) begin
    if (btn_press) begin
        // 按钮按下时,启动计数器
        counter <= 0;
        pulse_out <= 1;
    end else if (pulse_out && counter == 50000) begin
        // 计数器达到1000微秒时,停止计数并结束脉冲
        pulse_out <= 0;
    end else if (pulse_out) begin
        // 计数器进行计数
        counter <= counter + 1;
    end else begin
        
        
        // 按钮未按下且脉冲结束时,计数器清零
        counter <= 0;
    end
end

endmodule

codeql使用

数字识别

  • C++
  • easyx
  • 水笔,周围颜色不一样,停留时间

web前端

参考

什么是 JavaScript? - 学习 Web 开发 | MDN (mozilla.org)

EASYX

  • 封装esayx画图

  • 矩形

  • 圆形

  • 文字

  • 坐标轴

  • 颜色

  • 做一个教程

To Do List

需求

使用描述

1.show

  1. 分成几个板块(当日,近期,长期,紧急)
  2. 展示时间、事件
  3. 颜色 可以加重点

2.选择操作板块

  • 确定你要对哪个板块的代办进行操作

3.对代办进行操作

  1. add
  2. remove
  3. finish
  4. importance

debug体系

  • error类

实现

  1. 语法 information = key + sentence

    • 读入几个句子,砍掉最前面的空格以及最后面的空格

    • 搜索关键字,若合法则继续,不合法,则报错,提示重新输入

    • 若正确,则传入sentence,继续执行

  2. File类

    • 构造函数,板块名字,写入类型
    • write
    • read
    • edit
  3. 文件管理

    • 有三个主文件夹,
      1. 帮助手册
      2. to_do
      • 有 创建日期建在另外一个文件里
      1. finish
      • 年、月、日
      • 每天都有一个txt文件 finish

指令

  • a 增加list a + sentence
  • r 移除list r + number
  • f 完成list f + number
  • h 帮助手册 h
  • n 创建新版块 n
  • s 设置操作对象 s + number
  • q 关闭退出 q
  • t 设置时间 t + number
  • M 回到主界面 M

improvement

  • 可以在遍历时,构建一个函数对象

##旧 1.1展示所有Unit ​ ·从to_do_list.txt中获取sentence ​ ·用timeGet 从 sentence中获取time ​ ·依次输出 序号 time sentence 2.语法 ​ 通过keyGet获取指令 ​ 通过myswitch跳转 ​ 2.1 add+sentence ​ ·将sentence录入to_do_list ​ ·counter++ ​ ·从sentence里get time ​ 2.2remove ​ ·获取n ​ ·n通过字符串 ​ ·从to_do_list读取到temp除了n行 ​ ·再把temp里的东西copy到to_do_list ​ 2.3

bug: 1.bug: r 1会出错 2.获得日期 很困难 数字不仅仅是一个字符

improvement 5.debug当to_do_list与imp的行数不同时,可以进行修改 6.clear清除所有 7.定义一个类,方便打开文件File 有string,fstream,copy,edit且还要包括app或是in的选择 8.每一天都建立一个finish,每一个月为文件夹,在每年的文件夹下面,以方便统计 9.工作区分割,可拖拽。 10.先设置是对哪个文件夹进行操作,再进行子操作 11.支持两套操作方式(命令行/ui) 12.可以固定在桌面上 13.一个目录记录,有多少个种类 14.简化语法,一个句子最多两个部分,前面为关键字,后面为附属,通过关键字确定任务类型, 通过switch(if else)再进行之后执行,之后可以再嵌套myswtich,或者用两层次的switch,这样 可以避免一个switch过于冗长 15.有默认项,每天都保持,但统计完成次数 1.myswitch可以用switch代替,只需要对key[0]的int型进行判断就可以了 2.快捷键展开 3.排名 4.日期提取 timeGet()

5.insert 6.remove 7.分文件编写 8.多文件夹 9.统计完成情况 10.记录常见日期 11.显示今天日期 12.日历 13.help 14.指针动画,两种操作方式

cs1.6 ai图像识别自动瞄准

UI

  • cl_draw_only_deathnotices <0 / 1>

click

  • cl_drawhud <0 / 1>

    关闭所有hud

    completely hide all features of your HUD.1 for on

click

  • cl_drawhud_force_deathnotices <-1 / 0 / 1>

    设置死亡效果

    • 0 - Default, draw deathnotices only when HUD is enabled

    • 1 - display killfeed/deathnotices even when HUD is disabled

    • 1 - never show deathnotices

click

file

[toc]

制作自己的github page

功能开发

中文

中文搜索

mdBook 生成的文档和书记,默认只支持英文搜索,其实我们只需要几个简单的配置,就可以让 mdBook 生成的 HTML 支持中文搜索。

  1. 新建一个和 src 同级的文件夹 assets。
  2. fzf.umd.jselasticlunr.js 文件放到 assets 目录下。
  3. 在 book.toml 的配置中添加配置
[output.html]
additional-js = ["assets/fzf.umd.js", "assets/elasticlunr.js"]

mdbook | 小霖家的混江龙 (lijunlin2022.github.io)

自动生成目录

  • 法一(!!mdbook无法显示)

在markdown文件第一行,输入[toc]并敲击回车

  • 法二

Adding a page table of contents to mdBook | Jorel's Blog

JorelAli/mdBook-pagetoc: A page table of contents for mdBook (github.com)

更换字体

Renderers - mdBook Documentation (rust-lang.github.io)

解决异常 Trouble Shooting

经过测试,该方法在Typora可以进行,但在mdbook中无法生成。

  • 报错
2024-06-17 07:06:54 [WARN] (mdbook::book::summary): Expected a start of a link, actually got Some(Text(Borrowed("常用 always")))
Error: -17 07:06:54 [ERROR] (mdbook::utils): Error: Summary parsing failed for file="/home/runner/work/know/know/src/SUMMARY.md"
Error: -17 07:06:54 [ERROR] (mdbook::utils): Caused By: There was an error parsing the numbered chapters
Error: -17 07:06:54 [ERROR] (mdbook::utils): Caused By: There was an error parsing the numbered chapters
Error: -17 07:06:54 [ERROR] (mdbook::utils): Caused By: failed to parse SUMMARY.md line 3, column 3: The link items for nested chapters must only contain a hyperlink
Error: Process completed with exit code 101
  • 解决

你的 SUMMARY.md 文件中的问题出在 "常用 always" 和 "临时 temp" 这两行。在 mdBook 中,每一行都必须包含一个链接,包括章节的标题。如果一个章节的标题没有对应的链接,你可以创建一个空的 Markdown 文件并链接到那里,或者你可以将标题和其下的第一个子章节合并。

这是一个修改后的 SUMMARY.md 的例子:

# Summary

- [常用 always](./always.md)
  - [Git](always/Git.md)
- [想法 ideas](./ideas.md)
  - [EASYX](ideas/EASYX.md)
  - [To_Do_List](ideas/To_Do_List.md)
  - [cs1.6_ai图像识别自动瞄准](ideas/cs1.6_ai图像识别自动瞄准.md)
- [系统知识 learn](./learn.md)
  - [51单片机学习](learn/51单片机学习.md)
  - [MarkDown教程](learn/MarkDown教程.md)
- [临时 temp](./temp.md)

在这个例子中,我添加了 always.mdideas.mdlearn.mdtemp.md 这四个链接。你需要在相应的位置创建这些文件,或者将链接改为已经存在的文件。

UTF-8

Error: -17 09:53:19 [ERROR] (mdbook::utils): Error: Unable to read "处理文件名" (/home/runner/work/know/know/src/temp/处理文件名/temp.md)
Error: -17 09:53:19 [ERROR] (mdbook::utils): 	Caused By: stream did not contain valid UTF-8
Error: Process completed with exit code 101.
Error: -17 09:58:45 [ERROR] (mdbook::utils): Error: Unable to read "处理文件名" (/home/runner/work/know/know/src/temp/deal-file-name/temp.md)
Error: -17 09:58:45 [ERROR] (mdbook::utils): 	Caused By: stream did not contain valid UTF-8
Error: Process completed with exit code 101.
Run mdbook build
Error: -17 10:03:44 [ERROR] (mdbook::utils): Error: Unable to read "deal filename" (/home/runner/work/know/know/src/temp/deal-file-name/temp.md)
Error: -17 10:03:44 [ERROR] (mdbook::utils): 	Caused By: stream did not contain valid UTF-8
Error: Process completed with exit code 101.
Run mdbook build
Error: -17 10:11:00 [ERROR] (mdbook::utils): Error: Unable to read "deal filename" (/home/runner/work/know/know/src/temp/deal_file_name/temp.md)
Error: -17 10:11:00 [ERROR] (mdbook::utils): 	Caused By: stream did not contain valid UTF-8
Error: Process completed with exit code 101.
  • 解决

似乎是因为之前temp.md是我由temp.txt更改拓展名得到的,因此出现了问题。

Redefinition & Duplicate

Run mdbook build
Error: -19 07:11:54 [ERROR] (mdbook::utils): Error: Invalid configuration file
Error: -19 07:11:54 [ERROR] (mdbook::utils): 	Caused By: redefinition of table `output.html` for key `output.html` at line 9 column 1
Error: Process completed with exit code 101.
Error: -19 07:17:00 [ERROR] (mdbook::utils): Error: Invalid configuration file
Error: -19 07:17:00 [ERROR] (mdbook::utils): 	Caused By: duplicate key: `additional-js` for key `output.html` at line 7 column 1
Error: Process completed with exit code 101.
  • 解决

因为我之前还配置了中文搜索,之后又加上了右边栏目录,所以我的book.toml出现了

[output.html]
additional-js = ["assets/fzf.umd.js", "assets/elasticlunr.js"]
[output.html]
additional-css = ["theme/pagetoc.css"]
additional-js = ["theme/pagetoc.js"]

仅需将上文改为下文即可

additional-js = ["assets/fzf.umd.js", "assets/elasticlunr.js","theme/pagetoc.js"]
additional-css = ["theme/pagetoc.css"]

Adding a page table of contents to mdBook | Jorel's Blog

JorelAli/mdBook-pagetoc: A page table of contents for mdBook (github.com)

本地能打开,网上打不开。

  • 解决

    描述文件路径的时候用/而不是\

参考

multisim教程

  • probe

  • interactive

  • junction

  • 拖动

  • 运行

  • GROUND

  • VCC

  • label隐藏

  • key

python画图讲解

日志

2024

2.17

完成了keyregulate的检查,开始进行mySwitch的构建,正式开始写指令,开始写a的指令,为了确定是对哪个板块的指令,用purpose来确定,并以purpose_1、purpose_2等等命名来建立txt文件储存

每日完成应该单独存在一个文件夹里,以年月日进行划分,

因此第一步是获取电脑时间,以时间为目录以及txt文件的名字

第二部是创建文件夹

vac视频剪辑

框架

  • 第一回合 开转 录制

  • 第二回合 缴枪, usp三爆头,初见端倪

  • 第三、四回合 初识大哥 剪辑多人受害者视角+右上角击杀图标

  • 第五回合 手雷匪家开会 T阵营胜利

  • 第六回合 参数拉大 大哥5杀

  • 第七回合 香蕉道自爆步兵 可惜被制裁了

  • 第九回合 大菠萝武器压制 抓到timing

  • 第十四回合,火烧自己 从天上录制

  • 第十五回合17:03 自爆步兵 从警家到香蕉道的运镜

  • 第十六回合18:36 中路自爆步兵

  • 我们输了,但我们赢了

素材

  • 起初······前30秒

  • forsaken 的twitter

image-20240225183242151

信息统计

输入人名,自动跳转 确定后 输入内容 储存,返回

不同的数据用不同栏进行统计

##自制画图工具

用easyX制作一个像素风画图工具,可以导出jpg文件,以及工程文件

  • 像素风绘画工具可以自己改名称

  • 可以用txt来储存工作文件

  • 可分图层,可拖拽

  • 三列渐变进行调色

  • 一个预示

光纤,解码器和编码器

制作一个vs调试的教程

  • 录制键盘
  • 断点
  • 快捷键
  • 单句 板块
  • 局部变量(及更改)
  • 监视
  • 自动变量
  • 函数堆栈
  • 断点触发条件

医院引导

和猫住 可操控绳索

  • 可操控抓手

多教室打分系统

大帝+图像识别+文字提取

模拟游戏里的键盘操作通常涉及到使用编程语言来发送模拟的键盘事件到操作系统。这可以通过多种方式实现,但具体方法会取决于你使用的编程语言和操作系统。

以下是一个使用Python语言在Windows操作系统上模拟键盘操作的简单示例,使用了pyautogui库:

安装必要的库: 首先,你需要安装pyautogui库。你可以使用pip来安装: bash 复制 pip install pyautogui

编写代码来模拟键盘操作: 下面是一个简单的Python脚本,它模拟按下并释放键盘上的"a"键: python 复制 import pyautogui import time

等待5秒,以便你有时间切换到目标游戏或应用程序

time.sleep(5)

模拟按下并释放'a'键

pyautogui.press('a')

运行脚本: 保存上面的代码到一个.py文件中,然后运行它。你应该会看到脚本模拟按下并释放"a"键。 更复杂的操作: 你还可以模拟更复杂的键盘操作,如组合键、连续的按键等。例如,模拟按下并释放Ctrl+C组合键: python 复制 pyautogui.hotkey('ctrl', 'c')

注意事项: 确保在运行模拟键盘操作的脚本时,目标游戏或应用程序是活动的,并且处于可以接受键盘输入的状态。 某些游戏或应用程序可能有反作弊机制,可能会检测并阻止模拟的键盘操作。在使用这种方法时,请确保你了解并遵守目标游戏或应用程序的使用条款和政策。 模拟键盘操作可能会干扰你的正常工作流程,所以在运行脚本时要小心。 其他库和工具: 除了pyautogui之外,还有其他库和工具可以用来模拟键盘操作,如pynput、keyboard等。你可以根据你的具体需求和偏好选择合适的工具。

实验数据处理

志愿者管理系统

树状结构

手势识别与ppt切换

  • python-pptx

  • 要实现在播放PPT时切换到下一页,可以使用python-pptx模块中的Presentation对象和SlideShowView对象来实现。下面是一个示例代码,演示如何在播放PPT时切换到下一页:

    from pptx import Presentation
    
    # 打开一个PPT文件
    prs = Presentation('example.pptx')
    
    # 创建幻灯片放映视图
    slideshow = prs.slide_show()
    
    # 播放PPT
    for i in range(len(prs.slides)):
        slideshow.next()
    
    # 保存更改
    prs.save('new_presentation.pptx')
    

    在这个示例中,我们打开了一个名为example.pptx的PPT文件,并创建了一个幻灯片放映视图。然后,我们通过循环调用slideshow.next()方法来模拟在播放PPT时切换到下一页的操作。最后,我们将更改保存到了一个名为new_presentation.pptx的新文件中。

    请注意,python-pptx模块并没有直接提供播放PPT的功能,以上代码只是模拟了在播放PPT时切换到下一页的操作。你可以根据自己的需求进一步扩展代码,实现更复杂的PPT操作。希望这可以帮助到你。

技能录像

给自己学会的东西做一个录像,防止遗忘

文档扫描

可将边缘整平

矩形角点检测

  • 通过离散点的曲率找到对应位置

    http://t.csdnimg.cn/7rDsg

  • 二阶导符号不同

  • 离散型函数拐点算法及应用 李涛田晓君

更加方便的查词器

  • 通过快捷键快速选词
  • 与有道词典api进行连接

校园接驳车定位

  • 长期停止关闭渠道

源码 补码生成器

物联网体验组

LED

初始配置

这段代码是用于配置LED驱动器的设置。让我们逐行解释每个部分的作用:

  1. led_rgb_config_t rgb_config = {0}; - 定义了一个名为rgb_config的LED RGB配置结构体,并初始化为零。

  2. rgb_config.red_gpio_num = BOARD_GPIO_LED_R; - 设置红色LED的GPIO引脚号。

  3. rgb_config.green_gpio_num = BOARD_GPIO_LED_G; - 设置绿色LED的GPIO引脚号。

  4. rgb_config.blue_gpio_num = BOARD_GPIO_LED_B; - 设置蓝色LED的GPIO引脚号。

  5. rgb_config.red_ledc_ch = LEDC_CHANNEL_0; - 设置红色LED的LEDC通道号。

  6. rgb_config.green_ledc_ch = LEDC_CHANNEL_1; - 设置绿色LED的LEDC通道号。

  7. rgb_config.blue_ledc_ch = LEDC_CHANNEL_2; - 设置蓝色LED的LEDC通道号。

  8. rgb_config.speed_mode = LEDC_LOW_SPEED_MODE; - 设置LEDC的速度模式为低速模式。

  9. rgb_config.timer_sel = LEDC_TIMER_0; - 设置LEDC的定时器选择为定时器0。

  10. rgb_config.freq = 20000; - 设置LEDC的频率为20,000赫兹。

  11. rgb_config.resolution = LEDC_TIMER_8_BIT; - 设置LEDC

实体按钮

当按钮按下时,button_press_cb函数会被调用。在函数中,它会检查g_led_mode的值,如果为真(即非零),则将其设置为假(0),否则将其设置为真(1)。然后,使用ESP_LOGI函数打印消息,显示当前的灯光模式。

configure_push_button函数用于配置一个按钮的回调函数。它接受两个参数:gpio_num表示按钮连接的GPIO号,btn_cb表示按钮按下时的回调函数。在函数中,它调用iot_button_create函数创建一个按钮句柄,并使用iot_button_set_evt_cb函数将按钮事件回调函数设置为button_press_cb

这段代码的作用是创建一个按钮,并在按钮按下时切换灯光模式,并输出当前的灯光模式。

用遗传算法做一个小东西?

  • 避障

  • 机器人搬运货物

没想到数模就用到了

用链式结构搓一个图

  • 成员变量为指针数组
  • 数据为T,其为模版
  • 可以用BFS与DFS进行遍历,打印
  • 做一个迭代器

盲文打印

备注

  • 侧面有旋钮,调整速度
  • 上下字
  • 机器为一行
  • 步进电机
  • 加法器
  • 直线往复机构
  • 直线往复运动机构
  • 打印机
  • XY滑块模组
  • 电机加同步带
  • 开环控制,闭环控制
  • 编码电机

资料

G:\inspiration\盲文打印机,有图纸

硬件

视频

stm32 开源闭环步进电机控制

(开源)自制基于esp8266网页控制的低成本步进电机滑台

https://www.bilibili.com/video/BV1iP411U7QM/ 小型丝杆滑台 Screw slide table module 来自 HEIECN - MakerWorld

视线跟踪台灯

训练自己文本的GPT

键盘操作与神经网络

  • 通过KLing录制键盘操作,与图像坐标进行训练
  • 通过击杀的时间作为评估函数,进行遗传

AI 绘画 视频

modelscope/DiffSynth-Studio: Enjoy the magic of Diffusion models! (github.com)

markdown 海报

自己写一个串口助手

代码关联助手

需求

写代码时,有时一些属于不同类的函数会有一些关联,这关联不是函数调用,也不是变量传递。例如学生管理系统中,学生Student为一个类,它具有学生信息。如果我需要造一个按钮来添加学生,这个按钮的槽,就会与学生产生关系,但不一定与Student产生关系。为此需要一个知识图谱来帮助我们来修改一些变量。

C++作业管理系统

题目:C++作业管理系统

项目地址

r1Way/work_manage: C++ homework manage system (github.com)

[系统要求]

该系统需创建和管理以下信息:

  1. 作业信息:

- 作业编号、作业标题、作业描述、截止日期、标准答案、分值等。

- 作业提交状态(未提交、已提交、已评分)。

  1. 学生信息:

- 学生姓名、学号、班级、提交的作业文件、提交时间、得分、评语等。

  1. 教师信息:

- 教师姓名、工号、负责的课程和作业、评分信息等。

[系统功能要求]

  1. 创建和管理描述作业信息的对象:

- 教师可以创建、修改和删除作业信息,包括设置作业的截止日期等。

- 教师可以添加详细的作业描述。

  1. 创建和管理描述学生信息的对象:

- 管理学生的基本信息,包括学号、姓名、班级等。

- 系统记录学生每次提交的作业文件、时间、得分等信息。

  1. 作业提交管理:

- 学生可以查看已发布的作业并在线提交作业文件。

- 系统记录提交时间并提供反馈,确保作业在截止日期前提交。

- 支持多次提交作业,教师可以查看所有提交记录。

  1. 评分与反馈:

- 教师可以查看学生提交的作业,手动调整分数并添加评语。

  1. 作业状态管理与变更:

- 支持作业信息的变更,如修改作业描述、调整截止日期等。

- 学生提交作业后,系统自动更新提交状态。

  1. 基本查询功能:

- 查询所有作业及其状态。

- 查询特定作业的学生提交情况、代码运行结果和得分。

- 查询学生个人的作业提交历史和成绩。

  1. 基本信息显示:

- 显示所有已发布的作业及其基本信息。

- 显示特定作业的所有学生提交的作业情况及得分。

[可选功能提升]

  1. 提供在线测试环境,学生可以在正式提交前测试代码,查看其是否通过系统预设的测试用例。

  2. 系统为每个作业提供讨论区,学生和教师可以在此交流作业相关问题。

  3. 根据学生作业成绩,系统自动生成积分与排名。

  4. 系统支持将作业信息、学生提交记录等导出到文件中。

  5. 根据学生提交代码生成对应的文件依赖关系,关系依赖关系图谱。

  6. 提供助教端,可以协助教师批改作业。

Trouble Shooting

记得空格

    QString sql=QString("SELECT homework_class.name,homework_class.description,"
                          "homework_class.d,homework_class.t "
                          "WHERE class_id=%1;").arg(classId);

数据库模版

管理端

密码

pass

身份账号密码
useridpassword

基本信息

student

学号姓名专业
student_idnamemajor

teacher

工号姓名专业
teacher_idnamemajor

class

课程号课程名课程描述
class_idnamedescription

课程管理

class_teacher

班号教师
class_idteacher_id

学生管理

class_student

班号学号
class_idstudent_id

教师端

作业管理

homework_class

班号作业名称作业介绍DATETIME
class_idnamedescriptiondt

学生端

homework_student

学号班级代号作业名称分数DATATIME
student_idclass_idnamescoredt

文件存储

PATH / 班号 / 作业名称 / 学号

路径管理

  • PATH
    • class_id1
      • homework1
        • student_id1
        • student_id2
      • homework2
    • class_id2

想法

  • 用作用域来确定颜色
  • 通过图谱定位代码位置

登录效果

Qt实现登录效果(超详细!超简单!)_qt登录界面输入密码登录-CSDN博客

密码输入框

Qt实现密码输入框-隐藏或显示密码功能_qt密码输入框-CSDN博客

信号与槽

qt中的信号和槽会打断正在执行的函数吗 - 数据处理 - Qt开源社区 - qt qml linux 嵌入式 教程! (qter.org)

搜索

#include <QApplication>
#include <QTableWidget>
#include <QHeaderView>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QWidget>

class StudentWidget : public QWidget {
    Q_OBJECT

public:
    StudentWidget(QWidget *parent = nullptr) : QWidget(parent) {
        // 创建表格控件
        tableWidget = new QTableWidget(this);
        tableWidget->setColumnCount(3);  // 设置列数为3
        tableWidget->setHorizontalHeaderLabels({"姓名", "学号", "专业"});

        // 启用表头的排序功能
        tableWidget->setSortingEnabled(true);

        // 添加一些示例数据
        addStudent("张三", "2021001", "计算机科学");
        addStudent("李四", "2021002", "软件工程");
        addStudent("王五", "2021003", "信息安全");

        // 创建搜索框和按钮
        QLineEdit *searchBox = new QLineEdit(this);
        searchBox->setPlaceholderText("输入姓名、学号或专业进行搜索...");
        QPushButton *searchButton = new QPushButton("搜索", this);

        // 创建布局
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(searchBox);
        layout->addWidget(searchButton);
        layout->addWidget(tableWidget);
        setLayout(layout);

        // 连接搜索按钮点击信号到槽函数
        connect(searchButton, &QPushButton::clicked, [this]() {
            searchStudents(searchBox->text());
        });
    }

private:
    QTableWidget *tableWidget;

    void addStudent(const QString &name, const QString &id, const QString &major) {
        int row = tableWidget->rowCount();
        tableWidget->insertRow(row);
        tableWidget->setItem(row, 0, new QTableWidgetItem(name));
        tableWidget->setItem(row, 1, new QTableWidgetItem(id));
        tableWidget->setItem(row, 2, new QTableWidgetItem(major));
    }

    void searchStudents(const QString &keyword) {
        for (int i = 0; i < tableWidget->rowCount(); ++i) {
            bool match = false;
            for (int j = 0; j < tableWidget->columnCount(); ++j) {
                QTableWidgetItem *item = tableWidget->item(i, j);
                if (item->text().contains(keyword, Qt::CaseInsensitive)) {
                    match = true;
                    break;
                }
            }
            tableWidget->setRowHidden(i, !match);
        }
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    StudentWidget studentWidget;
    studentWidget.setWindowTitle("学生信息管理");
    studentWidget.resize(600, 400);
    studentWidget.show();

    return app.exec();
}

#include "main.moc"

搜索时将对应字体标红

详细

#include <QTableWidget>
#include <QPushButton>
#include <QDialog>
#include <QVBoxLayout>
#include <QLabel>
#include <QMessageBox>

// 初始化表格并添加数据
void setupTableWidget(QTableWidget *tableWidget) {
    tableWidget->setColumnCount(4);  // 比如3列数据列 + 1列按钮列
    tableWidget->setRowCount(10);    // 假设有10个学生

    for (int i = 0; i < tableWidget->rowCount(); ++i) {
        // 添加学生信息到前3列
        tableWidget->setItem(i, 0, new QTableWidgetItem(QString("学生 %1").arg(i + 1)));
        tableWidget->setItem(i, 1, new QTableWidgetItem(QString("学号 %1").arg(1000 + i)));
        tableWidget->setItem(i, 2, new QTableWidgetItem(QString("专业 %1").arg(i + 1)));

        // 在最后一列添加“详细”按钮
        QPushButton *detailsButton = new QPushButton("详细");
        tableWidget->setCellWidget(i, 3, detailsButton);

        // 连接按钮点击事件到槽函数
        QObject::connect(detailsButton, &QPushButton::clicked, [tableWidget, i]() {
            showDetails(tableWidget, i);
        });
    }
}

// 显示学生详细信息的对话框
void showDetails(QTableWidget *tableWidget, int row) {
    // 获取该行的学生信息
    QString name = tableWidget->item(row, 0)->text();
    QString studentID = tableWidget->item(row, 1)->text();
    QString major = tableWidget->item(row, 2)->text();

    // 创建并配置对话框
    QDialog detailsDialog;
    detailsDialog.setWindowTitle("学生详细信息");

    QVBoxLayout *layout = new QVBoxLayout(&detailsDialog);
    layout->addWidget(new QLabel("姓名: " + name));
    layout->addWidget(new QLabel("学号: " + studentID));
    layout->addWidget(new QLabel("专业: " + major));

    // 这里可以添加更多的详细信息,例如联系方式、课程信息等
    layout->addWidget(new QLabel("更多信息..."));

    QPushButton *closeButton = new QPushButton("关闭");
    layout->addWidget(closeButton);

    QObject::connect(closeButton, &QPushButton::clicked, &detailsDialog, &QDialog::accept);

    // 显示对话框
    detailsDialog.exec();
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QTableWidget tableWidget;
    setupTableWidget(&tableWidget);

    tableWidget.show();

    return app.exec();
}

批量删除

#include <QApplication>
#include <QTableWidget>
#include <QPushButton>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QMessageBox>

void setupTableWidget(QTableWidget *tableWidget) {
    tableWidget->setColumnCount(5);  // 4列数据 + 1列复选框
    tableWidget->setRowCount(10);    // 假设有10个学生

    for (int i = 0; i < tableWidget->rowCount(); ++i) {
        // 在第一列添加复选框
        QCheckBox *checkBox = new QCheckBox();
        tableWidget->setCellWidget(i, 0, checkBox);

        // 添加学生信息到后4列
        tableWidget->setItem(i, 1, new QTableWidgetItem(QString("学生 %1").arg(i + 1)));
        tableWidget->setItem(i, 2, new QTableWidgetItem(QString("学号 %1").arg(1000 + i)));
        tableWidget->setItem(i, 3, new QTableWidgetItem(QString("专业 %1").arg(i + 1)));

        // 在最后一列添加“详细”按钮
        QPushButton *detailsButton = new QPushButton("详细");
        tableWidget->setCellWidget(i, 4, detailsButton);

        QObject::connect(detailsButton, &QPushButton::clicked, [tableWidget, i]() {
            showDetails(tableWidget, i);
        });
    }
}

void showDetails(QTableWidget *tableWidget, int row) {
    QString name = tableWidget->item(row, 1)->text();
    QString studentID = tableWidget->item(row, 2)->text();
    QString major = tableWidget->item(row, 3)->text();

    QDialog detailsDialog;
    detailsDialog.setWindowTitle("学生详细信息");

    QVBoxLayout *layout = new QVBoxLayout(&detailsDialog);
    layout->addWidget(new QLabel("姓名: " + name));
    layout->addWidget(new QLabel("学号: " + studentID));
    layout->addWidget(new QLabel("专业: " + major));

    QPushButton *closeButton = new QPushButton("关闭");
    layout->addWidget(closeButton);

    QObject::connect(closeButton, &QPushButton::clicked, &detailsDialog, &QDialog::accept);

    detailsDialog.exec();
}

void deleteSelectedRows(QTableWidget *tableWidget) {
    for (int i = tableWidget->rowCount() - 1; i >= 0; --i) { 
        QCheckBox *checkBox = qobject_cast<QCheckBox*>(tableWidget->cellWidget(i, 0));
        if (checkBox && checkBox->isChecked()) {
            tableWidget->removeRow(i);
        }
    }
}

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget window;
    QVBoxLayout layout(&window);

    QTableWidget tableWidget;
    setupTableWidget(&tableWidget);

    layout.addWidget(&tableWidget);

    // 添加“删除选中”按钮
    QPushButton deleteButton("删除选中");
    layout.addWidget(&deleteButton);

    // 连接“删除选中”按钮到删除槽函数
    QObject::connect(&deleteButton, &QPushButton::clicked, [&tableWidget]() {
        deleteSelectedRows(&tableWidget);
    });

    window.show();

    return app.exec();
}
  • tableWidget->cellWidget(i, 0):获取第 i 行第 0 列(第一列)的单元格中的小部件(一般是 QWidget 类型)。
  • qobject_cast<QCheckBox\*>:将该小部件强制转换为 QCheckBox* 类型。qobject_cast 是一种类型安全的转换方式,用于在运行时进行对象的类型检查。如果转换成功,checkBox 将是指向 QCheckBox 对象的指针;如果失败,则返回 nullptr

滚轮条

#include <QApplication>
#include <QTableWidget>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QWidget>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget window;
    QVBoxLayout layout(&window);

    // 创建 QTableWidget 并设置行列数
    QTableWidget *tableWidget = new QTableWidget(20, 3); // 例如,20行3列

    // 添加一些示例数据
    for (int i = 0; i < 20; ++i) {
        for (int j = 0; j < 3; ++j) {
            tableWidget->setItem(i, j, new QTableWidgetItem(QString("Item %1,%2").arg(i).arg(j)));
        }
    }

    // 创建 QScrollArea 并将 QTableWidget 放入其中
    QScrollArea *scrollArea = new QScrollArea;
    scrollArea->setWidget(tableWidget);
    scrollArea->setWidgetResizable(true); // 让 QTableWidget 随着 QScrollArea 的大小变化

    // 将 QScrollArea 添加到布局中
    layout.addWidget(scrollArea);

    window.show();

    return app.exec();
}

QT的自动滚动区QScrollArea的用法,图文详解-CSDN博客

2.3Qtabwidget和Qlistwidget和Qscrollarea - NoAcalculia - 博客园 (cnblogs.com)

按钮间距

  • 法一
// 设置 rightLayOut 中控件之间的间距为 20 像素
rightLayOut->setSpacing(20);
  • 法二
// 在学生管理和教师管理按钮之间添加 15 像素的间距
leftLayOut->addWidget(studentButton);
leftLayOut->addSpacing(15); // 这里设置间距
leftLayOut->addWidget(teacherButton);
leftLayOut->addSpacing(15); // 这里设置间距
leftLayOut->addWidget(classButton);
  • 法三
// 在 addStudent 和 deleteStudent 按钮之间添加一个弹性空间
searchLayOut->addWidget(addStudent);
searchLayOut->addSpacerItem(new QSpacerItem(20, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
searchLayOut->addWidget(deleteStudent);
  • setSpacing(): 适用于整体设置布局中所有控件之间的间距。
  • addSpacing(): 用于手动控制特定两个控件之间的固定间距。
  • QSpacerItem: 用于添加可伸缩的空间,常用于灵活布局。
  • setContentsMargins(): 用于设置布局的整体边距。

http://t.csdnimg.cn/Lfvpv QSpacerItem用法说明

表 table

#include <QApplication>
#include <QTableWidget>
#include <QHeaderView>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QWidget>

class StudentWidget : public QWidget {
    Q_OBJECT

public:
    StudentWidget(QWidget *parent = nullptr) : QWidget(parent) {
        // 创建表格控件
        tableWidget = new QTableWidget(this);
        tableWidget->setColumnCount(3);  // 设置列数为3
        tableWidget->setHorizontalHeaderLabels({"姓名", "学号", "专业"});

        // 启用表头的排序功能
        tableWidget->setSortingEnabled(true);

        // 添加一些示例数据
        addStudent("张三", "2021001", "计算机科学");
        addStudent("李四", "2021002", "软件工程");
        addStudent("王五", "2021003", "信息安全");

        // 创建搜索框和按钮
        QLineEdit *searchBox = new QLineEdit(this);
        searchBox->setPlaceholderText("输入姓名、学号或专业进行搜索...");
        QPushButton *searchButton = new QPushButton("搜索", this);

        // 创建布局
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(searchBox);
        layout->addWidget(searchButton);
        layout->addWidget(tableWidget);
        setLayout(layout);

        // 连接搜索按钮点击信号到槽函数
        connect(searchButton, &QPushButton::clicked, [this, searchBox]() {
            searchStudents(searchBox->text());
        });
    }

private:
    QTableWidget *tableWidget;

    void addStudent(const QString &name, const QString &id, const QString &major) {
        int row = tableWidget->rowCount();
        tableWidget->insertRow(row);
        tableWidget->setItem(row, 0, new QTableWidgetItem(name));
        tableWidget->setItem(row, 1, new QTableWidgetItem(id));
        tableWidget->setItem(row, 2, new QTableWidgetItem(major));
    }

    void searchStudents(const QString &keyword) {
        for (int i = 0; i < tableWidget->rowCount(); ++i) {
            bool match = false;
            for (int j = 0; j < tableWidget->columnCount(); ++j) {
                QTableWidgetItem *item = tableWidget->item(i, j);
                if (item->text().contains(keyword, Qt::CaseInsensitive)) {
                    match = true;
                    break;
                }
            }
            tableWidget->setRowHidden(i, !match);
        }
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    StudentWidget studentWidget;
    studentWidget.setWindowTitle("学生信息管理");
    studentWidget.resize(600, 400);
    studentWidget.show();

    return app.exec();
}

#include "main.moc"

全屏

AdminMainWindow::AdminMainWindow(QWidget *parent)
    : QMainWindow{parent}
{
    //全屏
    this->showMaximized();
    this->setWindowFlags(Qt::Dialog|Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
	//······
}

http://t.csdnimg.cn/2LYEq

部件替换

http://t.csdnimg.cn/eqBLD

插入按钮

#include <QApplication>
#include <QHBoxLayout>
#include <QPushButton>
#include <QWidget>
#include <QSpacerItem>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget window;
    QHBoxLayout *layout = new QHBoxLayout(&window);

    // 创建三个按钮作为示例
    QPushButton *button1 = new QPushButton("Button 1");
    QPushButton *button2 = new QPushButton("Button 2");
    QPushButton *button3 = new QPushButton("Button 3");

    // 将按钮添加到布局中
    layout->addWidget(button1);
    layout->addWidget(button2);

    // 添加 QSpacerItem 替代 addStretch
    QSpacerItem *spacer = new QSpacerItem(20, 40, QSizePolicy::Expanding, QSizePolicy::Minimum);
    layout->addSpacerItem(spacer);

    layout->addWidget(button3);

    // 在Button2后面插入新按钮
    QPushButton *newButton = new QPushButton("New Button");
    layout->insertWidget(2, newButton);

    // spacer仍然有效,将Button3推到最右边
    window.show();

    return app.exec();
}

删除组件

widget->setParent(nullptr);    //记得移除前将widget的parent置空,不然删不掉
Layout->removeWidget(widget);
delete widget;                //移除并释放

QLayout增加控件、删除控件_layout->removewidget(-CSDN博客

切换界面

#include <QApplication>
#include <QMainWindow>
#include <QStackedWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        QStackedWidget *stackedWidget = new QStackedWidget(this);

        // 创建第一个页面
        QWidget *page1 = new QWidget();
        QVBoxLayout *layout1 = new QVBoxLayout(page1);
        QPushButton *button1 = new QPushButton("Go to Page 2", page1);
        layout1->addWidget(button1);

        // 创建第二个页面
        QWidget *page2 = new QWidget();
        QVBoxLayout *layout2 = new QVBoxLayout(page2);
        QPushButton *button2 = new QPushButton("Go to Page 1", page2);
        layout2->addWidget(button2);

        // 将页面添加到QStackedWidget中
        stackedWidget->addWidget(page1); // index 0
        stackedWidget->addWidget(page2); // index 1

        setCentralWidget(stackedWidget);

        // 连接按钮的点击信号到切换页面的槽
        connect(button1, &QPushButton::clicked, [=]() {
            stackedWidget->setCurrentIndex(1); // 切换到第2页
        });

        connect(button2, &QPushButton::clicked, [=]() {
            stackedWidget->setCurrentIndex(0); // 切换到第1页
        });
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

右键上下文菜单

#include <QApplication>
#include <QTableWidget>
#include <QMenu>
#include <QVBoxLayout>
#include <QMessageBox>

class MainWindow : public QWidget {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);
        tableWidget = new QTableWidget(5, 3, this); // 创建一个5行3列的表格

        // 填充一些示例数据
        for (int row = 0; row < 5; ++row) {
            for (int col = 0; col < 3; ++col) {
                tableWidget->setItem(row, col, new QTableWidgetItem(QString("Item %1").arg(row * 3 + col + 1)));
            }
        }

        tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
        connect(tableWidget, &QTableWidget::customContextMenuRequested, this, &MainWindow::showContextMenu);

        layout->addWidget(tableWidget);
        setLayout(layout);
    }

private slots:
    void showContextMenu(const QPoint &pos) {
        // 获取点击的行
        QModelIndex index = tableWidget->indexAt(pos);
        if (!index.isValid()) {
            return;
        }
        int row = index.row();

        // 创建上下文菜单
        QMenu contextMenu(this);
        QAction *deleteAction = contextMenu.addAction("Delete Row");

        // 显示菜单并捕获用户选择
        QAction *selectedAction = contextMenu.exec(tableWidget->viewport()->mapToGlobal(pos));
        if (selectedAction == deleteAction) {
            tableWidget->removeRow(row);  // 删除第i行
        }
    }

private:
    QTableWidget *tableWidget;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow mainWindow;
    mainWindow.show();

    return app.exec();
}

#include "main.moc"
  1. 设置上下文菜单策略

    tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    

    这一步设置了 QTableWidget 以接受自定义的上下文菜单。

  2. 连接 customContextMenuRequested 信号

    connect(tableWidget, &QTableWidget::customContextMenuRequested, this, &MainWindow::showContextMenu);
    

    customContextMenuRequested 信号连接到槽函数 showContextMenu,在右键点击时触发。

  3. 显示上下文菜单并删除行

    void showContextMenu(const QPoint &pos) {
        QModelIndex index = tableWidget->indexAt(pos);
        if (!index.isValid()) {
            return;
        }
        int row = index.row();
    
        QMenu contextMenu(this);
        QAction *deleteAction = contextMenu.addAction("Delete Row");
    
        QAction *selectedAction = contextMenu.exec(tableWidget->viewport()->mapToGlobal(pos));
        if (selectedAction == deleteAction) {
            tableWidget->removeRow(row);
        }
    }
    
  • indexAt(pos) 获取鼠标点击位置的行号,如果点击的不是有效单元格,函数将返回。
  • 创建上下文菜单并添加“删除行”操作(deleteAction)。
  • 使用 exec() 方法显示菜单,并返回用户选择的操作。
  • 如果选择了“删除行”操作,使用 removeRow(row) 删除点击的行。

数据库->QTableWidget

将数据库表中信息显示在Qtablewidget - CSDN文库

mouseEvent

http://t.csdnimg.cn/8FnGi

View可拖动

    view.setDragMode(QGraphicsView::ScrollHandDrag);

View滚轮放大缩小

class ZoomableGraphicsView : public QGraphicsView
{
public:
    ZoomableGraphicsView(QGraphicsScene* scene) : QGraphicsView(scene) {}

protected:
    void wheelEvent(QWheelEvent* event) override
    {
        // 基于滚轮事件的 delta 值来设置缩放因子
        double scaleFactor = 1.15;
        if(event->angleDelta().y() > 0) {
            // 滚轮向前,放大
            this->scale(scaleFactor, scaleFactor);
        } else {
            // 滚轮向后,缩小
            this->scale(1.0 / scaleFactor, 1.0 / scaleFactor);
        }
    }
};

QGraphicsItem 鼠标点击

#ifndef CLICKABLERECTITEM_H
#define CLICKABLERECTITEM_H
#include<QObject>
#include <QGraphicsRectItem>

class ClickableRectItem : public QObject, public QGraphicsRectItem
{
    Q_OBJECT
public:
    ClickableRectItem(qreal x, qreal y, qreal w, qreal h)
        : QGraphicsRectItem(x, y, w, h) {}

signals:
    void rectClicked();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent* event) override
    {
        emit rectClicked();
        QGraphicsRectItem::mousePressEvent(event);
    }
};


#endif // CLICKABLERECTITEM_H

直线相交

QLineF::BoundedIntersection

布局管理

  • QWidget

    • layout()Returns the layout manager that is installed on this widget, or nullptr if no layout manager is installed.
    • setLayout(QLayout *layout)Sets the layout manager for this widget to layout.
  • QLayout,QHBoxLayout,QVBoxLayout

    • addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment())(该方法继承自父类)
    • addLayout(QLayout *layout, int stretch = 0)(该方法继承自父类)

标签页

#include <QApplication>
#include <QTabWidget>
#include <QTextEdit>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建一个QTabWidget
    QTabWidget *tabWidget = new QTabWidget();

    // 创建一些标签页
    for(int i = 0; i < 3; i++) 
    {
        // 创建一个QTextEdit作为标签页的内容
        QTextEdit *textEdit = new QTextEdit();

        // 将QTextEdit添加到QTabWidget中
        tabWidget->addTab(textEdit, QString("Tab %1").arg(i + 1));
    }

    tabWidget->show();

    return a.exec();
}

获取路径下所有文件名

#include <QDir>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QDir directory("/path/to/your/directory");
    QStringList files = directory.entryList(QDir::Files);

    for(auto fileName : files) {
        qDebug() << fileName;
    }

    return a.exec();
}

文件读写

#include <QApplication>
#include <QTextEdit>
#include <QFile>
#include <QTextStream>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFile file("/path/to/your/file.cpp");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return -1;

    QTextStream in(&file);
    QString content = in.readAll();
    file.close();

    QTextEdit textEdit;
    textEdit.setText(content);
    textEdit.show();

    return a.exec();
}

数据库

QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

http://t.csdnimg.cn/8D7DX

表格宽度

// //调整列宽以适应内容字的宽度
// tableWindow2->tableWidget->resizeColumnsToContents();
//设置列的大小调整模式以填充表格的宽度
tableWindow2->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

获取QTableWIdget中的某一项

item(int row,int col)

itemAt(int ax,int ay)获取像素处

itemAt(QPoint *)获取鼠标处

获取文件路径

QStringList fileNames = QFileDialog::getOpenFileNames(
    this, 
    "Open Files", 
    "/home",
    "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
);

文件复制

QString sourceFileName = "/path/to/source/file";
QString destFileName = "/path/to/destination/file";

if (QFile::exists(destFileName)) {
    // 如果目标文件已经存在,删除它
    QFile::remove(destFileName);
}

QFile::copy(sourceFileName, destFileName);

注意sourceFileName,destFileName都是文件名,不是路径名。

创建文件夹

#include <QDebug>
#include <QString>
#include <QDir>
 
 
QString folder_name("Images");    //要创建的文件夹名称
 
QDir dir(QDir::currentPath());    //初始化dir为当前目录
 
//假设当前目录下有一个test文件夹
 
dir.cd("./test");    //目录切换到test文件夹下
 
if(!dir.exists(folder_name))    //如果Images文件夹不存在
{
    dir.mkdir(folder_name);    //创建文件夹(名为Images)
 
    qDebug()<<QString("文件夹%1创建成功!").arg(folder_name);
}
else
{
    qDebug()<<QString("文件夹%1已存在!").arg(folder_name);
}
 
 
//这样就可以在当前目录下的test文件夹中创建一个Images文件夹

QDate QTime

QDate date = dateEdit->date();
QTime time = timeEdit->time();

QString dateString = date.toString("yyyy-MM-dd");
QString timeString = time.toString("HH:mm:ss");

mysql

INSERT INTO events (event_date, event_time) VALUES ('2024-08-29', '11:03:02');

删除table所有行

// 假设你的 QTableWidget 对象名为 tableWidget
tableWidget->setRowCount(0);

Qprocess 操作文件读写

#include <QCoreApplication>  
#include <QProcess>  
#include <QDebug>  
#include <QTextStream>  

int main(int argc, char *argv[]) {  
    QCoreApplication a(argc, argv);  

    // 创建 QProcess 对象  
    QProcess process;  
    QString program = "path/to/your/my_program.exe"; // 替换为你的可执行文件路径  

    // 启动外部程序  
    process.start(program);  

    // 等待程序启动  
    if (!process.waitForStarted()) {  
        qDebug() << "Failed to start the process:" << process.errorString();  
        return 1;  
    }  

    // 输入参数 n  
    QTextStream in(stdin);  
    int n;  
    qDebug() << "Please enter n:";  
    in >> n; // 从标准输入读取 n  

    // 将 n 发送到外部程序  
    process.write(QString::number(n).toUtf8() + "\n");  
    process.closeWriteChannel(); // 关闭写通道,表示输入结束  

    // 等待程序执行完成  
    if (!process.waitForFinished()) {  
        qDebug() << "Execution failed:" << process.errorString();  
        return 1;  
    }  

    // 读取标准输出和错误输出  
    QByteArray output = process.readAllStandardOutput();  
    QByteArray errorOutput = process.readAllStandardError();  

    // 输出结果  
    qDebug() << "Output:" << output;  
    if (!errorOutput.isEmpty()) {  
        qDebug() << "Error Output:" << errorOutput;  
    }  

    return 0;  
}

允许table排序功能

setSortingEnabled(true);

Table不允许编辑

tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers)

设置QLabel内部内容

searchEdit->setPlaceholderText("输入姓名、学号或专业进行搜索...");

QTextEdit只读

    //只读
    this->setReadOnly(true);

只允许读整型数字

        edit->setValidator(new QIntValidator(edit));

获取当前时间

QDate::currentDate()
QTime::currentTime()

message box

// 创建一个 QMessageBox 对象
QMessageBox messageBox;
// 设置消息框的标题
messageBox.setWindowTitle("输入验证");
// 设置消息框显示的文本
messageBox.setText("输入为空,请重新输入。");
// 设置消息框的图标类型
messageBox.setIcon(QMessageBox::Warning);
// 设置消息框的标准按钮
messageBox.setStandardButtons(QMessageBox::Ok);
// 显示消息框
messageBox.exec();
QMessageBox messageBox;
messageBox.setWindowIcon(QIcon("://img/icopng"));
messageBox.setWindowTitle("输入验证");
messageBox.setText("不存在该教师,删除失败,请重新输入。");
messageBox.setIcon(QMessageBox::Warning);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();

设置图标

->setWindowIcon(QIcon("://img/icopng"));

确认删除

#include <QMessageBox>
#include <QPushButton>

//...

// 创建一个 QMessageBox 对象
QMessageBox msgBox;
msgBox.setWindowTitle("删除确认");
msgBox.setText("你确定要删除这个文件吗?");

// 创建两个 QPushButton 对象,作为自定义的按钮
QPushButton *confirmButton = msgBox.addButton("确认", QMessageBox::YesRole);
QPushButton *cancelButton = msgBox.addButton("取消", QMessageBox::NoRole);

// 显示对话框,并等待用户点击一个按钮
msgBox.exec();

// 判断用户点击了哪个按钮
if (msgBox.clickedButton() == confirmButton) {
    // 用户点击了 "确认" 按钮
    // 在这里执行删除操作
} else if (msgBox.clickedButton() == cancelButton) {
    // 用户点击了 "取消" 按钮
    // 在这里执行取消操作
}

图书检错机器人

需求

  • 近激光笔指出

梅庵云迹

梅庵概述

1

1

1

1

1

师道梅庵

1

1

1

1

1

1

真理耀东南

1

1

1

1

1

1

1

1

会议场景

1

1

1

1

1

1

1

会议记录

1

1

1

1

青年运动

1

1

1

1

1

51单片机学习

MarkDown教程

file

project

vs_studio调试功能

力扣

功能

数据结构

电子学作业

问题

51单片机学习

关键路径

F:\Keil_v5\C51\INC F:\Keil_v5\C51\INC\Atmel

C51数据类型

59261cd986dde0ae01d7f680d971f81a

C51数据运算

b8460e99180552dbad927bb9dad7bec9

创建项目

  • keil->project->new uvision project 记得创建一个新的文件夹

  • 选择atmel->AT89C52

    会问你是否copy 一个东西,是或否都可以点

  • 左侧Protject窗口->target->Source Group1 鼠标右键 Add new item to ··· 选择c,名字取为main

写代码

  • workspace区域 鼠标右键 insert #inlcude<REGX52.H>添加头文件

  • 可通过在#include<REGX52.H>处右键,查看各个接口

    sfr为寄存器

点亮led灯

管脚从A2开发板原理图上找

P2记得大写P

#include <REGX52.H>

void main()
{
	P2=0xFE;//最低位(0xFE的最右边一位)为P2_0,即P0
}
  • 点击左上角build(第二个按钮)

    其左边为translate(编译)

烧录

  • STC-ISP 左上角,单片机型号选择(根据实际情况)atmel->STC89C52RC/LE52RC

  • 串口号选择最长的那个 USB-SERTAL CH340(COM8)

  • 打开程序文件(.hex文件)

    keil编译时默认不生成.hex文件,需在translate、build那一行有一个长得像魔法棒的按钮 options for target->Output->勾选Create HEX File

  • 点击下载/编程

    若右边信息框显示正在搜索单片机,关闭单片机(按一下白色杆状按钮),点击下载/编程,立马打开单片机。

  • 重新打开项目

    Project->Open project-> .uvproj文件

样例

LED闪烁

  • STC-ISP 右上角点击右箭头,软件延时计算器,输入需要的定时长度

    main.c(6): warning C206: '_nop_': missing function-prototype报错

    添加#include <INTRINS.H>

    (#include 与 <INTRINS.H> 间要有个空格)

LED流水灯

  • 通过STC-iSP软件延时计算器(不是定时器计算器),输入需要的定时长度,系统频率选择11.0592(看单片机上的晶振的频率),8051指令集选STC-Y1
#include <REGX52.H>
#include <INTRINS.H>
void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 129;
	k = 119;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
	while(1)
	{
		P2=0xFE;
		Delay500ms();
		P2=0xFD;
		Delay500ms();
		P2=0xFB;
		Delay500ms();
		P2=0xF7;
		Delay500ms();
	}
}

独立按键控制LED灯亮灭

#include <REGX52.H>

void main()
{
    while(1)
    {
        if(P3_1==1)
        {
            P2_0=0;
        }
        else
        {
            P2_0=1;
        }
	}
}
  • P3_1==1代表未按按键,P3_1 ==0代表按键按下(按下,导通,P3_1接GND)

独立按键控制LED灯状态

#include <STC89C5xRC.H>
 
void Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;
	while(xms)
	{
	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
	xms--;
	}
}
 
 
void main()
{
	while(1)
	{
		if(P31==0)
		{
			Delay(20);  // Keys away shaking
			while(P31==0);//未松手
			Delay(20);  // Detection of let go
			P20=~P20;
		}
	}
}

独立按键控制LED显示二进制

#include <REGX52.H>
#include <INTRINS.H>

void Delay20ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 216;
	k = 35;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	while(1)
	{
			if(P3_1==0)
			{
				Delay20ms();
				while(P3_1==0);
				Delay20ms();
				P2=~P2;
				P2++;
				P2=~P2;
			}
			
	}
}

独立按键控制LED移位

按下P31,往左边移一位;按下P30,往右边移一位,以LED灯来展示。

#include <REGX52.H>
#include <INTRINS.H>

void Delay20ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 216;
	k = 35;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main()
{
	int lit=0;
	P2=0x01<<lit;
	while(1)
	{
		if(P3_0==0)//left
		{
			Delay20ms();
			while(P3_0==0);
			Delay20ms();
			if(lit==7)
				lit=0;
			else
				lit++;
		}
		if(P3_1==0)//right
		{
			Delay20ms();
			while(P3_1==0);
			Delay20ms();
			if(lit==0)
				lit=7;
			else
				lit--;
		}
		P2=~(0x01<<lit);
	}
}
  • 0x01<<lit 表示0x01左移lit位

静态数码管显示

#include <REGX52.H>

unsigned char NixieTable[]={//ÄÄЩÊýÂë¹ÜÏÔʾ
 
0x3f,0x06,0x5b,0x4f,
 
0x66,0x6d,0x7d,0x07,
 
0x7f,0x6f,0x77,0x7c,
 
0x39,0x5e,0x79,0x71, 0x00};

void Nixie(unsigned char which,num)
{
	//whichÊÇ´Ó×óÍùÓÒÊýµÚ¼¸¸öµÆ
	switch(which)//choose light
	{
		case 1:P2_4=1,P2_3=1,P2_2=1;	break;//LED8
		case 2:P2_4=1,P2_3=1,P2_2=0;break;
		case 3:P2_4=1,P2_3=0,P2_2=1;break;
		case 4:P2_4=1,P2_3=0,P2_2=0;break;
		case 5:P2_4=0,P2_3=1,P2_2=1;break;
		case 6:P2_4=0,P2_3=1,P2_2=0;break;
		case 7:P2_4=0,P2_3=0,P2_2=1;break;
		case 8:P2_4=0,P2_3=0,P2_2=0;break;
		default:P2_4=0,P2_3=0,P2_2=0;break;
	}
	P0=NixieTable[num];
}	

void main()
{
	while(1)
	{
		Nixie(5,6);
	}
}
  • NixieTable用来记录一位数码管显示某个数字时,具体是那几根数码管亮,对应的引脚是什么。
  • 位选,段选

动态数码管显示

#include <REGX52.H>
#include <INTRINS.H>

void Delay(unsigned char time)		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	_nop_();
	while(time--)
	{
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);
	}
}

unsigned char NixieTable[]={
 
0x3f,0x06,0x5b,0x4f,
 
0x66,0x6d,0x7d,0x07,
 
0x7f,0x6f,0x77,0x7c,
 
0x39,0x5e,0x79,0x71, 0x00};

void Nixie(unsigned char which,num)
{
	switch(which)//choose light
	{
		case 1:P2_4=1,P2_3=1,P2_2=1;	break;//LED8
		case 2:P2_4=1,P2_3=1,P2_2=0;break;
		case 3:P2_4=1,P2_3=0,P2_2=1;break;
		case 4:P2_4=1,P2_3=0,P2_2=0;break;
		case 5:P2_4=0,P2_3=1,P2_2=1;break;
		case 6:P2_4=0,P2_3=1,P2_2=0;break;
		case 7:P2_4=0,P2_3=0,P2_2=1;break;
		case 8:P2_4=0,P2_3=0,P2_2=0;break;
		default:P2_4=0,P2_3=0,P2_2=0;break;
	}
	P0=NixieTable[num];
	Delay(1);
	P0=0x00;
}	

void main()
{
	while(1)
	{
		Nixie(1,1);
		Nixie(2,2);
		Nixie(3,3);
	}
}
  • Delay(1); 是为了保持该数据
  • P0=0x00;是为了置零消除残影

矩阵键盘密码锁

main.c

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "MatrixKey.h"
#include "Nixie.h"
#include "tool.h"

void main()
{
	unsigned char i = 0;

	while (1)
	{
		if (password()==1)
		{

			while (keyNum() != 11)
			{
				for (i = 5; i <= 8; i++)
				{
					Nixie(i, 10);
				}
			}
			break;
		}
		else
		{
			while (keyNum() != 11)
			{
				for (i = 5; i <= 8; i++)
				{
					Nixie(i, 15);
				}
			}
			break;
		}
	}
}

unsigned char password()

#include "tool.h"
unsigned char password()
{

    unsigned char i = 0;
    unsigned char nums = 2, this, passWord = 0, realPassWord = 11;

    for (i = 0; i < nums; i++)
    {
        while ((this = keyNum()) == 0)
        {
            if (i == 0)
                Nixie(1, 14);
            else
                show(passWord);
        }
        passWord = passWord * 10 + this;
    }

    while (keyNum() != 12) // 确认
    {
        show(passWord);
    }

    if (passWord == realPassWord)
    {
        return 1;
    }
    else // wrong password
    {
        return 0;
    }
}
  • 单片机没有标GND的地方,默认接高电平
  • C语言的旧版本中变量声明必须在函数或任何作用域的开头

按键控制流水灯模式

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "MatrixKey.h"
#include "Nixie.h"
#include "tool.h"

unsigned int T0Count = 0;
unsigned char lightMode = 0;

void Timer0_Rountine(void) interrupt 1
{
	T0Count++;
	TL0 = 0x66; // 设置定时初值
	TH0 = 0xFC; // 设置定时初值
	if (T0Count == 1000)
	{
		switch (lightMode)
		{
			case 1:
				P2 = _cror_(P2, 1);
				break;
			case 2:
				P2 = _crol_(P2, 1);
				break;
			default:
				break;
		}
		T0Count = 0;
	}
}


void main()
{
	Timer0Init();
	P2 = 0xFE;
	while (1)
	{
		if (key()==1)
		{
			lightMode++;
			if (lightMode >= 3)
			{
				lightMode = 0;
			}
		}
	}
}

Timer0Init()

void Timer0Init(void) // 1毫秒@11.0592MHz
{
    // AUXR |= 0x80;		//定时器时钟1T模式
    TMOD = 0x01; // 设置定时器模式
	TL0 = 0x66;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
    TF0 = 0;     // 清除TF0标志
    TR0 = 1;     // 定时器0开始计时
    ET0 = 1;
    EA = 1;
    PT0=0;
}

stc-isp 定时器选择 12T,16位。

定时器时钟

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "MatrixKey.h"
#include "Nixie.h"
#include "tool.h"

unsigned int T0Count = 0;
unsigned char lightMode = 0;
unsigned char hour, min=59, sec=45;

void Timer0_Rountine(void) interrupt 1
{
	T0Count++;
	TL0 = 0x66; // 设置定时初值
	TH0 = 0xFC; // 设置定时初值
	if (T0Count == 1000)
	{
		sec++;
		if (sec >= 60)
		{
			sec = 0;
			min++;
		}
		if (min >= 60)
		{
			min = 0;
			hour++;
		}
		if (hour >= 24)
		{
			hour = 0;
		}
		T0Count = 0;
	}
}

void main()
{
	Timer0Init();
	while (1)
	{
		// hour
		if (hour < 10)
		{
			Nixie(1, 0);
			Nixie(2, hour);
			Nixie(2, 17);
		}
		else
		{
			showPos(hour, 1);
			Nixie(4, 17);
		}

		// min
		if (min < 10)
		{
			Nixie(3, 0);
			Nixie(4, min);
			Nixie(4, 17);
		}
		else
		{
			showPos(min, 3);
			Nixie(4, 17);
		}

		// sec
		if (sec < 10)
		{
			Nixie(5, 0);
			Nixie(6, sec);
		}
		else
		{
			showPos(sec, 5);
		}
		
	}
}

  • 记得在main里放Timer0Init();不然定时器会不起作用

警告/报错

  • main.c(6): warning C206: '_nop_': missing function-prototype

    添加#include <INTRINS.H>

  • uncalled segment

    会调用定义过的函数

  • 如果.hex文件更新不了,请检查保存的文件夹是否是你认为的地方(Select Folder for Objects)

  • #include <REGX52.H>下划线标红

    Ctrl+Shift+P 打开命令面板,运行 C/Cpp: Edit configurations,打开UI,添加路径REGX52.h所在路径

    http://t.csdnimg.cn/sn8s1

  • 出现大量undefined identifier

    C语言的旧版本中变量声明必须在函数或任何作用域的开头

keil编译时出现大量莫名其妙的 undefined identifier_keil4 加了头文件 外部声明了 为什么还报错 'sdate': undefined identi-CSDN博客

  • 若vscode检测不到新创建的工程

    应当先用keil5 build,再检查是否生成.hex文件,然后重复打开几次

image-20200210154710148

MarkDown基础

基础篇视频讲解链接 画图篇视频讲解链接

标题

# 标题名字(井号的个数代表标题的级数)

一级标题使用1个#

二级标题使用2个#

三级标题使用3个#

四级标题使4用个#

五级标题使用5个#
六级标题使用6个#

####### 最多支持六级标题#

文字

删除线

这就是 ~~删除线~~ (使用波浪号)

这就是 删除线 (使用波浪号)

斜体

这是用来 *斜体* 的 _文本_

这是用来 斜体文本

加粗

这是用来 **加粗** 的 __文本__

这是用来 加粗文本

斜体+加粗

这是用来 ***斜体+加粗*** 的 ___文本___

这是用来 斜体+加粗文本

下划线

下划线是HTML语法

下划线 下划线(快捷键command+u,视频中所有的快捷键都是针对Mac系统,其他系统可自行查找)

高亮(需勾选扩展语法)

这是用来 ==斜体+加粗== 的文本

这是用来 ==斜体+加粗== 的文本

下标(需勾选扩展语法)

水 H~2~O 
双氧水 H~2~O~2~ 

水 H~2~O

双氧水 H~2~O~2~

上标(需勾选扩展语法)

面积 m^2^ 
体积 m^3^

面积 m^2^ 体积 m^3^

表情符号

Emoji 支持表情符号,你可以用系统默认的 Emoji 符号( Windows 用户不一定支持,自己试下~)。 也可以用图片的表情,输入 : 将会出现智能提示。

一些表情例子

:smile: :laughing: :dizzy_face: :sob: :cold_sweat: :sweat_smile:  :cry: :triumph: :heart_eyes: :relaxed: :sunglasses: :weary:

:+1: :-1: :100: :clap: :bell: :gift: :question: :bomb: :heart: :coffee: :cyclone: :bow: :kiss: :pray: :sweat_drops: :hankey: :exclamation: :anger:

:smile: :laughing: :dizzy_face: :sob: :cold_sweat: :sweat_smile: :cry: :triumph: :heart_eyes: :relaxed: :sunglasses: :weary: :+1: :-1: :100: :clap: :bell: :gift: :question: :bomb: :heart: :coffee: :cyclone: :bow: :kiss: :pray: :sweat_drops: :hankey: :exclamation: :anger:

( Mac: control+command+space点选)

表格

使用 | 来分隔不同的单元格,使用 - 来分隔表头和其他行:

name | price
--- | ---
fried chicken | 19
cola|5

为了使 Markdown 更清晰,|- 两侧需要至少有一个空格(最左侧和最右侧的 | 外就不需要了)。

nameprice
fried chicken19
cola5

为了美观,可以使用空格对齐不同行的单元格,并在左右两侧都使用 | 来标记单元格边界,在表头下方的分隔线标记中加入 :,即可标记下方单元格内容的对齐方式:

|    name       | price |
| :------------ | :---: |
| fried chicken | 19    |
| cola          |  32   |
nameprice
fried chicken19
cola32

使用快捷键command+opt+T更方便(段落→表格→插入表格,即可查看快捷键)

引用

>“后悔创业”

“后悔创业”

>也可以在引用中
>>使用嵌套的引用

也可以在引用中

使用嵌套的引用

列表

无序列表--符号 空格

* 可以使用 `*` 作为标记
+ 也可以使用 `+`
- 或者 `-`
  • 可以使用 * 作为标记
  • 也可以使用 +
  • 或者 -

有序列表--数字 . 空格

1. 有序列表以数字和 `.` 开始;
3. 数字的序列并不会影响生成的列表序列;
4. 但仍然推荐按照自然顺序(1.2.3...)编写。
  1. 有序列表以数字和 . 开始;

  2. 数字的序列并不会影响生成的列表序列;

  3. 但仍然推荐按照自然顺序(1.2.3...)编写。

    可以使用:数字\. 来取消显示为列表(用反斜杠进行转义)
    

代码

代码块

​```语言名称
 public static void main(String[] args) {
    }

行内代码

也可以通过 ``,插入行内代码(` 是 `Tab` 键上边、数字 `1` 键左侧的那个按键):

例如 `Markdown`

Markdown

转换规则

代码块中的文本(包括 Markdown 语法)都会显示为原始内容

分隔线

可以在一行中使用三个或更多的 *-_ 来添加分隔线(``):

***
------
___



跳转

外部跳转--超链接

格式为 [link text](link)

[帮助文档](https://support.typora.io/Links/#faq)

帮助文档

内部跳转--本文件内跳(Typora支持)

格式为 [link text](#要去的目的地--标题)

[我想跳转](#饼图(Pie))

Open Links in Typora

You can use command+click (macOS), or ctrl+click (Linux/Windows) on links in Typora to jump to target headings, or open them in Typora, or open in related apps.

我想跳转

自动链接

使用 <> 包括的 URL 或邮箱地址会被自动转换为超链接:

<https://www.baidu.com>

<123@email.com>

https://www.baidu.com

123@email.com

图片

![自己起的图片名字](图片地址或者图片本地存储的路径)

网上的图片

![friedChicken](https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1580814517&di=2630beac440e5dab0e44c7286a3b2b61&src=http://imgsrc.baidu.com/forum/w=580/sign=12c730c4ff03738dde4a0c2a831ab073/9497794f9258d1091818e6d6d858ccbf6d814d1b.jpg)

炸鸡

本地图片

![friedChicken](friedChicken.jpg)
在同一个文件夹里(用相对路径)
或者直接拷贝

friedChicken

cola

利用Markdown画图(需勾选扩展语法)

image-20200211211500416

markdown画图也是轻量级的,功能并不全。

Mermaid 是一个用于画流程图、状态图、时序图、甘特图的库,使用 JS 进行本地渲染,广泛集成于许多 Markdown 编辑器中。Mermaid 作为一个使用 JS 渲染的库,生成的不是一个“图片”,而是一段 HTML 代码。

(不同的编辑器渲染的可能不一样)

流程图(graph)

概述

graph 方向描述
    图表中的其他语句...

关键字graph表示一个流程图的开始,同时需要指定该图的方向。

其中“方向描述”为:

用词含义
TB从上到下
BT从下到上
RL从右到左
LR从左到右

T = TOP,B = BOTTOM,L = LEFT,R = RIGHT,D = DOWN

最常用的布局方向是TB、LR。

graph TB;
  A-->B
  B-->C
  C-->A
 
graph TB;
  A-->B
  B-->C
  C-->A
graph LR;
  A-->B
  B-->C
  C-->A
graph LR;
  A-->B
  B-->C
  C-->A

流程图常用符号及含义

节点形状
表述说明含义
id[文字]矩形节点表示过程,也就是整个流程中的一个环节
id(文字)圆角矩形节点表示开始和结束
id((文字))圆形节点表示连接。为避免流程过长或有交叉,可将流程切开。成对
id{文字}菱形节点表示判断、决策
id>文字]右向旗帜状节点

单向箭头线段:表示流程进行方向

id即为节点的唯一标识,A~F 是当前节点名字,类似于变量名,画图时便于引用

括号内是节点中要显示的文字,默认节点的名字和显示的文字都为A

graph TB
  A
  B(圆角矩形节点)
  C[矩形节点]
  D((圆形节点))
  E{菱形节点}
  F>右向旗帜状节点] 
graph TB
  A
  B(圆角矩形节点)
  C[矩形节点]
  D((圆形节点))
  E{菱形节点}
  F>右向旗帜状节点]

graph TB
    begin(出门)--> buy[买炸鸡]
    buy --> IsRemaining{"还有没有炸鸡?"}
    IsRemaining -->|有|happy[买完炸鸡开心]--> goBack(回家)
    IsRemaining --没有--> sad["伤心"]--> goBack
    
graph TB
    begin(出门)--> buy[买炸鸡]
    buy --> IsRemaining{"还有没有炸鸡?"}
    IsRemaining -->|有|happy[买完炸鸡开心]--> goBack(回家)
    IsRemaining --没有--> sad["伤心"]--> goBack
    
连线
graph TB
  A1-->B1
  A2---B2
  A3--text---B3
  A4--text-->B4
  A5-.-B5
  A6-.->B6
  A7-.text.-B7
  A8-.text.->B8
  A9===B9
  A10==>B10
  A11==text===B11
  A12==text==>B12
graph TB
  A1-->B1
  A2---B2
  A3--text---B3
  A4--text-->B4
  A5-.-B5
  A6-.->B6
  A7-.text.-B7
  A8-.text.->B8
  A9===B9
  A10==>B10
  A11==text===B11
  A12==text==>B12
graph TB
 A ---B
子图表

使用以下语法添加子图表

subgraph 子图表名称
    子图表中的描述语句...
end
graph TB
	  subgraph 买炸鸡前
   			 begin(出门)--> buy[出门买炸鸡]
    end
    buy --> IsRemaining{"还有没有炸鸡?"}
    IsRemaining --没有--> sad["伤心"]--> goBack(回家)
    IsRemaining -->|有|happy[买完炸鸡开心]--> goBack
graph TB
	  subgraph 买炸鸡前
   			 begin(出门)--> buy[出门买炸鸡]
    end
    buy --> IsRemaining{"还有没有炸鸡?"}
    IsRemaining --没有--> sad["伤心"]--> goBack(回家)
    IsRemaining -->|有|happy[买完炸鸡开心]--> goBack

序列图(sequence diagram)

概述

sequenceDiagram 
	[参与者1][消息线][参与者2]:消息体
    ...

sequenceDiagram 为每幅时序图的固定开头

sequenceDiagram
		Title: 买炸鸡
    救救->>炸鸡店小哥: 还有炸鸡吗?
    炸鸡店小哥-->>救救: 没有,要现炸


sequenceDiagram
		Title: 买炸鸡
    救救->>炸鸡店小哥: 还有炸鸡吗?
    炸鸡店小哥-->>救救: 没有,要现炸

参与者(participant)

传统时序图概念中参与者有角色和类对象之分,但这里我们不做此区分,用参与者表示一切参与交互的事物,可以是人、类对象、系统等形式。中间竖直的线段从上至下表示时间的流逝。

sequenceDiagram
    participant 参与者 1
    participant 参与者 2
    ...
    participant 简称 as 参与者 3 #该语法可以在接下来的描述中使用简称来代替参与者 3

participant <参与者名称> 声明参与者,语句次序即为参与者横向排列次序。

消息线

类型描述
->无箭头的实线
-->无箭头的虚线
->>有箭头的实线(主动发出消息)
–->>有箭头的虚线(响应)
-x末端为叉的实线(表示异步)
--x末端为叉的虚线(表示异步)

处理中-激活框

从消息接收方的时间线上标记一小段时间,表示对消息进行处理的时间间隔。

在消息线末尾增加 + ,则消息接收者进入当前消息的“处理中”状态; 在消息线末尾增加 - ,则消息接收者离开当前消息的“处理中”状态。

sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    99 ->> seller: 还有炸鸡吗?
    seller -->> 99: 没有,要现炸。
    99 -x +seller:给我炸!
    seller -->> -99: 您的炸鸡好了!
sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    99 ->> seller: 还有炸鸡吗?
    seller -->> 99: 没有,要现炸。
    99 -x +seller:给我炸!
    seller -->> -99: 您的炸鸡好了!
    

注解(note)

语法如下

Note 位置表述 参与者: 标注文字

其中位置表述可以为

表述含义
right of右侧
left of左侧
over在当中,可以横跨多个参与者
sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    Note over 99,seller : 热爱炸鸡
    Note left of 99 : 女
    Note right of seller : 男
    99 ->> seller: 还有炸鸡吗?
    seller -->> 99: 没有,要现炸。
    99 -x +seller : 给我炸!
    seller -->> -99: 您的炸鸡好了!


sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    Note over 99,seller : 热爱炸鸡
    Note left of 99 : 女
    Note right of seller : 男
    99 ->> seller: 还有炸鸡吗?
    seller -->> 99: 没有,要现炸。
    99 -x +seller : 给我炸!
    seller -->> -99: 您的炸鸡好了!

循环(loop)

在条件满足时,重复发出消息序列。(相当于编程语言中的 while 语句。)

sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
   
    99 ->> seller: 还有炸鸡吗?
    seller -->> 99: 没有,要现炸。
    99 ->> +seller:给我炸!
    loop 三分钟一次
        99 ->> seller : 我的炸鸡好了吗?
        seller -->> 99 : 正在炸
    end
    seller -->> -99: 您的炸鸡好了!
sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
   
    99 ->> seller: 还有炸鸡吗?
    seller -->> 99: 没有,要现炸。
    99 ->> +seller:给我炸!
    loop 三分钟一次
        99 ->> seller : 我的炸鸡好了吗?
        seller -->> 99 : 正在炸
    end
    seller -->> -99: 您的炸鸡好了!

选择(alt)

在多个条件中作出判断,每个条件将对应不同的消息序列。(相当于 if 及 else if 语句。)

sequenceDiagram    
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    99 ->> seller : 现在就多少只炸好的炸鸡?
    seller -->> 99 : 可卖的炸鸡数
    
    alt 可卖的炸鸡数 > 3
        99 ->> seller : 买三只!
    else 1 < 可卖的炸鸡数 < 3
        99 ->> seller : 有多少买多少
    else 可卖的炸鸡数 < 1
        99 ->> seller : 那我明天再来
    end

    seller -->> 99 : 欢迎下次光临
sequenceDiagram    
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    99 ->> seller : 现在就多少只炸好的炸鸡?
    seller -->> 99 : 可卖的炸鸡数
    
    alt 可卖的炸鸡数 > 3
        99 ->> seller : 买三只!
    else 1 < 可卖的炸鸡数 < 3
        99 ->> seller : 有多少买多少
    else 可卖的炸鸡数 < 1
        99 ->> seller : 那我明天再来
    end

    seller -->> 99 : 欢迎下次光临

可选(opt)

在某条件满足时执行消息序列,否则不执行。相当于单个分支的 if 语句。

sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    99 ->> seller : 买炸鸡
    opt 全都卖完了
        seller -->> 99 : 下次再来
    end
sequenceDiagram
    participant 99 as 救救
    participant seller as 炸鸡店小哥
    99 ->> seller : 买炸鸡
    opt 全都卖完了
        seller -->> 99 : 下次再来
    end

并行(Par)

将消息序列分成多个片段,这些片段并行执行。

sequenceDiagram
   participant 99 as 救救
   participant seller as 炸鸡店小哥
   
    99 ->> seller : 一个炸鸡,一杯可乐!

    par 并行执行
        seller ->> seller : 装可乐
    and
        seller ->> seller : 炸炸鸡
    end

    seller -->> 99 : 您的炸鸡好了!
sequenceDiagram
   participant 99 as 救救
   participant seller as 炸鸡店小哥
   
    99 ->> seller : 一个炸鸡,一杯可乐!

    par 并行执行
        seller ->> seller : 装可乐
    and
        seller ->> seller : 炸炸鸡
    end

    seller -->> 99 : 您的炸鸡好了!

饼图(Pie)

pie
    title Pie Chart
    "Dogs" : 386
    "Cats" : 85
    "Rats" : 150 
pie
    title Pie Chart
    "Dogs" : 386
    "Cats" : 85
    "Rats" : 150 
    "panda" : 200

Typora支持mermaid的官方链接

甘特图(gantt)

  title 标题
	dateFormat 日期格式
	section 部分名
	任务名:参数一, 参数二, 参数三, 参数四,参数五
 
  //参数一:crit(是否重要,红框框) 或者 不填
  //参数二:done(已完成)、active(正在进行) 或者 不填(表示为待完成状态)
  //参数三:取小名 或者 不填
  //参数四:任务开始时间
  //参数五:任务结束时间

官方教程

gantt
       dateFormat  YYYY-MM-DD
       title Adding GANTT diagram functionality to mermaid

       section A section
       Completed task            :done,    des1, 2014-01-06,2014-01-08
       Active task               :active,  des2, 2014-01-09, 3d
       Future task               :         des3, after des2, 5d
       Future task2              :         des4, after des3, 5d

       section Critical tasks
       Completed task in the critical line :crit, done, 2014-01-06,24h
       Implement parser and jison          :crit, done, after des1, 2d
       Create tests for parser             :crit, active, 3d
       Future task in critical line        :crit, 5d
       Create tests for renderer           :2d
       Add to mermaid                      :1d

       section Documentation
       Describe gantt syntax               :active, a1, after des1, 3d
       Add gantt diagram to demo page      :after a1  , 20h
       Add another diagram to demo page    :doc1, after a1  , 48h

       section Last section
       Describe gantt syntax               :after doc1, 3d
       Add gantt diagram to demo page      :20h
       Add another diagram to demo page    :48h
gantt
       dateFormat  YYYY-MM-DD
       title Adding GANTT diagram functionality to mermaid

       section A section
       Completed task            :done,    des1, 2014-01-06,2014-01-08
       Active task               :active,  des2, 2014-01-09, 3d
       Future task               :         des3, after des2, 5d
       Future task2              :         des4, after des3, 5d

       section Critical tasks
       Completed task in the critical line :crit, done, 2014-01-06,24h
       Implement parser and jison          :crit, done, after des1, 2d
       Create tests for parser             :crit, active, 3d
       Future task in critical line        :crit, 5d
       Create tests for renderer           :2d
       Add to mermaid                      :1d

       section Documentation
       Describe gantt syntax               :active, a1, after des1, 3d
       Add gantt diagram to demo page      :after a1  , 20h
       Add another diagram to demo page    :doc1, after a1  , 48h

       section Last section
       Describe gantt syntax               :after doc1, 3d
       Add gantt diagram to demo page      :20h
       Add another diagram to demo page    :48h

[TOC]

数学建模

待学习

  • 三维作图
  • 文件读写

一、线性回归:用于预测一个连续的输出变量。

import numpy as np
from sklearn.linear_model import LinearRegression
 
# 创建一个随机数据集
np.random.seed(0)
X = np.random.rand(100, 1)# 生成一个形状为(100, 1)的随机数组,表示特征X。#表示一个二维数组,其中有100行和1列#随机数是在0到1之间均匀分布的。
y = 2 + 3 * X + np.random.rand(100, 1)# 生成目标变量y,其中包含噪声项。
 
# 创建线性回归模型并拟合数据
model = LinearRegression()
model.fit(X, y)
 
# 打印模型的系数和截距项
print('Coefficients:', model.coef_)#斜率
print('Intercept:', model.intercept_)#截距
 
# 预测新数据
X_new = np.array([[0.5], [1.0]])
y_new = model.predict(X_new)
 
# 打印预测结果
print('Predictions:', y_new)

这段代码是一个简单的线性回归示例,用于拟合一个随机生成的数据集并进行预测。我会逐行解释代码的功能:

  1. import numpy as np: 导入NumPy库,并将其命名为np,用于处理数组和矩阵等数值运算。

  2. from sklearn.linear_model import LinearRegression: 从scikit-learn库中导入线性回归模型。

  3. np.random.seed(0): 设置随机种子为0,以确保每次运行代码时生成的随机数相同。

  4. X = np.random.rand(100, 1): 生成一个形状为(100, 1)的随机数组,表示特征X。

  5. y = 2 + 3 * X + np.random.rand(100, 1): 生成目标变量y,其中包含噪声项。

  6. model = LinearRegression(): 创建一个线性回归模型的实例。

  7. model.fit(X, y): 使用X和y拟合线性回归模型。

  8. print('Coefficients:', model.coef_): 输出模型的系数,即斜率。

  9. print('Intercept:', model.intercept_): 输出模型的截距项。

  10. X_new = np.array([[0.5], [1.0]]): 创建新的特征数据用于预测。

  11. y_new = model.predict(X_new): 使用训练好的模型对新数据进行预测。

  12. print('Predictions:', y_new): 输出预测结果。

这段代码的主要目的是演示如何使用线性回归模型拟合数据并进行预测。

资料

数学建模老哥

A003史上最全Matlab资料大合集网盘链接

链接:https://pan.baidu.com/s/1NBqiSIKkIJoS32MQhR82IA?pwd=1111

提取码:1111

数据 P64

国家统计局 (stats.gov.cn)

中国 - 中国统计信息网 (tjcn.org)

Statista - The Statistics Portal for Market Data, Market Research and Market Studies 贵 淘宝

World Bank Open Data | Data

镝数聚网站-权威数据 海量聚合 (dydata.io)月卡

和鲸社区 - Heywhale.com免费

matlab基础

快捷键

  • 切换文本与代码 ctrl+e
  • 分节 ctrl+alt+enter
  • 切换不同的节 ctrl + 上/下
  • 运行节 ctrl+enter
  • 帮助 help
  • 为添加和取消注释ctrl + r/t (%)
  • 多行注释
  • 打印disp("hello world")
%{
	hello world
%}
  • 显示高精度format long g
  • 清空命令行clc
  • 清空工作区clear

格式

  • format
  • 精度
    • Digits()
    • vpa()

矩阵

  • 生成向量(左闭右闭)

    x=0:2:6
    # 0 2 4 6
    x=linspace(first,last,numbers)
    
  • 特殊矩阵

    • eye 单位矩阵
    • ones 全为1
    • zeros 全为0
    • rand (0,1)随机
  • 取数

x=[1,2,3]
x(2)%第二个
x([1,3])%第1,3个
x(1:2,m)=[]%删除
  • 变维

    reshape()

  • 变向

    Rot()

    Fliup() 上下翻转

  • 向量

    %点乘
    dot(a,b)
    %叉乘
    cross(a,b)
    
  • 广播机制

    % 创建一个矩阵
    A = [1, 2, 3; 4, 5, 6; 7, 8, 9];
    
    % 创建一个向量
    B = [2, 3, 4];
    
    % 使用广播机制实现矩阵每一行中的每一个元素除以向量中对应位置的元素
    result = A ./ B;
    result =A.* B;%对应元素相乘
    
    disp(result);
    
  • 矩阵的抽取

  • 运算

    .*

    inv(X) 逆

    det(X) 行列式

    .‘ 或 transpose() 转置

    e=eig(A) 特征值

多项式

  • 表示

    p=[1,2,3]
    poly2sym(p)
    1*x^2+2*x^1+3
    
  • 乘法、除法

    x=[1,2]
    y=[2,34,4]
    z=conv(x,y)%本质是卷积
    [x,r]=dconv(z,x)%商和余数
    
  • 求导

    p=[123,31,321]
    x=polyder(p)
    

cell元胞数组

  • 创建

    cell(4)% 44
    cell(2,3)% 2x3
    cell(size(A))%与A相同大小
    c1={1:3,"af"}%花括号
    
  • 引用

    • 小括号,引用的是元胞,
    data=c1(row,col)%class(data)=cell  data={[1,2,3]}
    
    • 大括号,引用的是数据
    data=c1{1,1};% data=1:3  1 2 3 
    [x,y]=c1{1,:};%x=1,y=2 x,y是线性索引顺序
    
  • 类型转换

    • num2cell 数组转化为元胞数组,
    • mat2cell
    • cell2num

struct/字典

s=struct('field1',{},'field2',{})
s=struct('field1',value1,'field2',value2)
s(1)%各field的第一个
s(2).field1%取field的第二个
  • 创建方法

分类数组

  • 创建
c={'女','男','男'}
c1=categorical(c)
%c1= 女 男 男
  • 显示种类
categories(c1)%按照unicode进行编码
  • 排序
  • sort
sort(c1)%默认将c1按照unicode进行升序排序
  • reorderccats
cc={'low','low','middle','high','middle','low'}
neworder={'low','middle','high'};
cc=reordercats(c,neworder)%要有左值进行接收

可用categories(cc)查看是否生效。

注意:

1.改的是类别的顺序,不是元素的顺序

2.建议对元胞数组

  • 实战
%cc为分类数组
cc=reordercats(cc,{'low','middle','high'});
[~,ind]=sort(cc,'descend');
ss=s(ind,:)

符号运算

  • 创建

    syms x y
    z=[x+y;x-y]
    
  • subs(z,x,1) 部分代入

  • eval()

  • sym

  • expand(cos(x+y)) 多项式展开

  • simple 符号简化

  • [n,m]=numden(A) 通分

  • 运算

syms x y
f1=x+y;
f2=x-y;
f11=matlabFunction(f1);%转化为能进行数值运算的函数
f11(1,2);% 3
  • fsolve 函数句柄
% deal.m
function f=deal(x)
    f(1)=x(1)+x(2)+1;
    f(2)=x(1)-x(2);
end
% test.mlx
clc
clear
fun=@deal;
x0=[0,0];
x=fsolve(fun,x0);

含参的 fsolve(@f,x,c)

# deal2.m
function f=deal2(x,c)
    f(1)=x(1)+x(2)+c;
    f(2)=x(1)-x(2);
end
% test.mlx
clc
clear
fun=@(x)deal2(x,10);%重点是这一行
x0=[0,0];
x=fsolve(fun,x0);

文件读写

  • readtable()
  • ismissing()函数返回缺失值位置

数学工具

求和

p=[1,2,3,4;4,3,5,2]
sum(p)%对每列求和,返回行向量

阶乘

  • factorial

极限与导数

%极限
syms x h
f=sin(x)/x
limit(f,x,0)

%导数
f=(sin(x+h)-sin(X))/h%同理可计算偏导

拆分

diff()

级数求和

F=symsum(f,k,start,final)% 可求不定项

积分

int(f,x,start,final)
  • 二重积分

    integral2()
    
  • 三重积分

    integral3()
    

傅里叶变换

fourier

泰勒展开

  • taylor

常微分方程

解析解法

dsolve()

e.g.1

syms y(t) a
eqn = diff(y,t) == a*y;
S = dsolve(eqn)

e.g.2

syms y(x)
eqn = (x^2-1)^2*diff(y,2) + (x+1)*diff(y) - y == 0;
S = dsolve(eqn)

e.g.3

syms y(t) a b
eqn = diff(y,t,2) == a^2*y;
Dy = diff(y,t);
cond = [y(0)==b, Dy(0)==1];
ySol(t) = dsolve(eqn,cond)
数值求解
欧拉法
yp=yn+h*f(xn,yn)
yc=yn+h*f(xn+1,yp)
yn+1=1/2*(yp+yc)
龙格库塔法 ode P81

求解一阶微分方程

偏微分方程 PDE P82

椭圆型,抛物型,双曲型二阶非齐次偏微分方程

  • 椭圆型二阶非齐次偏微分方程

    对空间求二阶偏导数

  • 抛物型,双曲型二阶非齐次偏微分方程

    多了对t的偏导

  • 散度内含有函数

  • 偏微分方程组

  • 步骤

构造标准方程

确定边界pdegeom

求解

==pdeTool==

有限元法

作图工具

通用部分

清空及创造数据

clear;clc;close all
x=linspace(1,200,100);%1~200,100个点
y1=log(x)+1;
y2=log(x)+2;
figure;%生成图形窗口

二维曲线

clear;clc;close all

x=linspace(1,200,100);%1~200,100个点
y1=log(x)+1;
y2=log(x)+2;
figure;%生成图形窗口

plot(x,y1);
hold on%多图共存在一个窗口上

plot(x,y2,'color',r,'LineWidth',2)%指定线的宽度
hold off%关闭多图共存
legend('y1','y2');%生成图例

45a3502497a6deae0fa34319c2a9d67e

散点图

clear;clc;close all
x=linspace(1,200,100);%1~200,100个点
y1=log(x)+1;
y2=log(x)+2;
figure;
y3=y1+rand(1,100)-0.5
plot(x,y1,'LineWidth',2,'Color',[0.21,0.21,0.67]);%rgb颜色
hold on
plot(x,y3,"o",'LineWidth',0.2,'Color',[0.46,0.63,0.90],'MarkerFaceColor',[0.35,0.90,0.89],'MarkerEdgeColor',[0.18,0.62,0.17]) %MarkerFaceColor->内部填充%MarkerEdgeColor->边框

31509edeb9126000d110551651f3e3ba

二维渐变图

clear;clc;close all
x=linspace(0,3*pi,200);
y=cos(x)+rand(1,200);%随机1行200列,0~1
sz=25;%圈尺寸为200
c=linspace(1,10,length(x));%代表100中颜色
scatter(x,y,sz,c,'filled')%filled for 填充

60e1928ccaa9ae23a8c8e4933191c184

条形图

A=[60.6679;87.412;143.2;267.93];
C=[127.5;160;231;400]
B=C-A;
D=[A,B,C];
bar1=bar([2:5:17],A,'BarWidth',0.2,'FaceColor','k')
bar2=bar([3:5:18],B,'BarWidth',0.2,'FaceColor',[0.5,0.5,0.5]);
bar3=bar([4:5:19],C,'BarWidth',0.2,'FaceColor','w');
hold on;
ylabel('耗时/s')
xlabel('GMM阶数')
legend('训练耗时','测试耗时','总耗时');
labelID={'8阶','16阶','32阶','64阶'};
set(gca,'XTick',3:5:20);
set(gca,'XTickLabel',labelID)

8a8ecd48a956a6a87fb2fc429b698843

填充图

x=0.4:0.1:2*pi;
y1=sin(2*x);
y2=sin(x);
%确定y1,y2上下界
maxY=max([y1;y2]);
minY=min([y1:y2]);
%确定填充多边形,按照顺时针方向来确定点
%fliplr实现左右翻转,从 
xFill=[x,flipr(x)];
yFill=[maxY,fliplr(minY)];
figure
fill(xFill,yFill,[0.21,0.21,0.67]);
hold on
plot(x,y1,'k','LineWidth',2)
plot(x,y2,'k','LineWidth',w)
hold off

多y轴

分组直方图

scatterhistogram()

load patients
Smoker = categorical(Smoker);
s = scatterhistogram(Age,Smoker);
xlabel('Age')
ylabel('Smoker')

上色

xvalues = [7 6 5 6.5 9 7.5 8.5 7.5 10 8];
yvalues = categorical({'onsale','regular','onsale','onsale', ...
    'regular','regular','onsale','onsale','regular','regular'});
grpvalues = {'Red','Black','Blue','Red','Black','Blue','Red', ...
    'Red','Blue','Black'};
s = scatterhistogram(xvalues,yvalues,'GroupData',grpvalues);

s.Title = 'Shoe Sales';
s.XLabel = 'Shoe Size';
s.YLabel = 'Price';
s.LegendTitle = 'Shoe Color';

分组散点图

gscatter()

算法

层次分析法

  • 筛选
  • 评价

主观性强,不适合作为主要算法

论文

https://kns.cnki.net/kcms/detail/detail.aspx?filename=CN113869568A&dbname=SCPDTEMP

算法

剩余矩形匹配算法

功能

依照某一列进行排序

  • 基于sort
[~,ind]=sort(p,'descend')%降序排列
ss=s(ind,:)

learn

project

##cs2贴纸 设计

  • 输入steam id
  • 自动生成

实现

  1. 用py爬下所有选手签名

vs调试功能

  • F5运行、shift+ F5停止调试
  • F9设置、取消断点
  • F10逐过程执行
  • F11逐语句执行(可进入函数内部)
  • 局部变量窗口显示局部变量的值,可以被更改
  • 用鼠标拖拽箭头,可以跳过一些语句

##力扣

###P3无重复字符的最长子串

P3无重复字符的最长子串

思路一

不完全正确

int max(int a,int b)
{
    if(a>b)
    {
        return a;
    }
    else
    {
        return b;
    }
}
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        string sub;
        char c;
        int counter=0;
        for(int j=0;j<s.length();j++)
        {
            int place=sub.find(s[j]);
            if(place==string::npos)//没有找到
            {
                sub+=s[j];
            }
            else
            {

                sub=sub.substr(place+1);
            }
            counter=max(counter,sub.length());
        }
        return counter;
    }
};
  • string中有查找函数find(),会返回字符找到的下标,若没有找到,会返回string::npos(一个很大的常数),可以用这个来判断是否存在字符

  • substr(pos,len)pos为第一个字符的下标,len为子字符串的长度。

    这两个参数都有默认参数,pos为0,lenstring::npos。若pos超过string,则抛出异常,若pos+len超过string,则会只拷贝到string的末尾。

####思路二

  • 用哈希表,因为只用增删找查。
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(int(s.length())==1)
        {
            return 1;
        }
        else if(s.length()==0)
        {
            return 0;
        }
        else
        {
            unordered_set<char> sub;
            int ans=1;
            char *begin=&s[0];
            char *end=begin;
            sub.insert(*begin);//插入第一个字符
            while(*(end+1)!='\0')
            {
                if(sub.find(*(end+1))==sub.end())//如果下一个字符没有重复
                {
                    ++end;
                    sub.insert(*(end));//插入新字符
                    ans=max(ans,int(end-begin+1));
                }
                else//如果有重复
                {
                    if(begin==end)//只有一个字符
                    {
                        ++end;
                        ++begin;
                    }
                    else//多个字符
                    {
                        sub.erase(*begin);
                        ++begin;
                    }
                }
            }
            return ans;
        }

       
    }
};
  • 小心特殊元素,0,1 字符串为空。

  • 可以用sub.count(key)来判断元素存不存在

  • rk=-1开始,然后用rk+1的值进行判断,可以避免头部的一些问题。

###P5最长回文子串

最长回文子串

  • pair<int,int>可以用来接受两个函数返回值
#include<utility>
using namespace std;
pair<int,int> person()
{
	return {1,1};
}

##错题本 ###样例

  • 小心特殊元素,0,1 字符串为空。
  • 完全相同

###代码细节

  • string::length()string::size()的数据类型是unsigned int无符号整型,所以与负数比较时会出问题。可以使用int强转来解决。

功能

上色

#include<windows.h>
void color(int ForgC, int BackC) //0~15 
{
	/*
	0=黑色,1=蓝色,2=绿色,3=湖蓝色,4=红色,5=紫色;
	6=黄色,7=白色,8=灰色,9=淡蓝色,10=淡绿色,11=浅绿色;
	12=淡红色,13=淡紫色,14=淡黄色,15=亮白色。
	*/
	WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}

//eg:
int main()
{
    color(14,0);
    cout<<"hello"<<endl;
	return 0;
}

获取文件目录

#include  <direct.h>  
#include  <stdio.h> 
 
char   buffer[MAX_PATH];   
getcwd(buffer, MAX_PATH); 

文件夹

创建

#include <Windows.h>   //头文件  
#include<iostream>  
using namespace std;
 
int main()
{
	string path = "E:\\1";
	bool flag = CreateDirectory(path.c_str(), NULL);
	return 0;
}

删除

#include <iostream>  
#include <Windows.h>   //头文件  
using namespace std;
 
int main()
{
	string path = "E:\\1";
	bool flag = RemoveDirectory(path.c_str());
	return 0;
}

检查是否存在

#include<direct.h>    
#include<io.h>  
#include<iostream>  
 
using namespace std;
int main()
{
	string path = "D:\\test1";
	if (access(path.c_str(), 0) == -1)//返回值为-1,表示不存在
	{
		printf("不存在,创建一个\n");
		int i = mkdir(path.c_str());
	}
	return 0;
}
/*
amode参数为0时表示检查文件的存在性,如果文件存在,返回0,不存在,返回-1。
这个函数还可以检查其它文件属性:
06 检查读写权限
04 检查读权限
02 检查写权限
01 检查执行权限
00 检查文件的存在性
而这个就算这个文件没有读权限,也可以判断这个文件存在于否
存在返回0,不存在返回-1
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/cao_jie_xin/article/details/114302984
*/

easyX

initgraph(ROW*SPACE,COL*SPACE);
	RECT r;
	r.left = r.top = 0;
	r.right = r.bottom = SPACE;
	settextstyle(20, 0, _T("宋体")); // 设置文本的字体大小为20,字体为宋体
	while (1)
	{
	drawtext(LPCTSTR("hello"),&r, DT_CENTER);
	}

int double 格式化转为字符串

  • 代码
#include <iostream>
#include <sstream>

int main() {
    int num = 42;
    float f = 3.14;

    std::stringstream ss;
    ss << "The number is " << num << " and the float is " << std::fixed << std::setprecision(2) << f;

    std::string formattedString = ss.str();
    std::cout << "Formatted string: " << formattedString << std::endl;

    return 0;
}
  • 结果: Formatted string: The number is 42 and the float is 3.14

Lingo

unordered_map

    unordered_map<int,string> m;
    m.insert({1,"s"});//插入
    m.size();//元素个数
	m.find(key);//返回迭代器
    m.count(key);//检测一个值存不存在
    m.erase(key);//释放
    m[key];//value

例子:

#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
	unordered_map<char,int> m;
    m['a']=9;
    m[' ']=5;
    m['c']=99;
    cout<<m.size()<<endl;
    for(auto it=m.begin();it!=m.end();i++)
    {
		cout<<it->first<<endl;//key
        cout<<it->second<<endl;//value
    }
	return 0;
}

map

  • 函数同uordered_map

  • 头文件: #include<map>

###异同

  • map是基于红黑树,unordered_map是基于哈希表
mapunordered_mapAVL
红黑树哈希表平衡二叉树
适用于频繁增删查找不一定稳定调整复杂
有序无序

set

  • 语法同unordered_map

  • 去重、排序

unordered_set

第八周

    • 高放式
  • 超外插

  • 发电机🏌跟电动机🛀🏻的最大差别🧚‍♀️就是🖖没有丝毫🐲必要使用⛵️电刷,直接🚁让永磁体💎旋转获得💍交流电,需要直流电🏇只需要加上🕹整流桥🐌

问题

函数压栈以及调用的细节过程

c++ 导出 位图bmp

迪克斯特拉算法

kmp算法

next chat

图片灰度实现 RGB学习

静态函数能传this指针吗

vs c++编译流程

逛图书馆 找建模的书

实时翻译工具

Real-time-translation-typing:实时打字翻译工具! 该项目是一个实时打字翻译软件,提供语音实时打字、语音实时翻译功能,尤其适用于游戏(如LOL)的语音打字输入。 其主要功能包括: - 实时打字翻译:支持中英文等多种语言的实时翻译。 - 实时语音转文字并翻译:能够将语音实时转换为文字并进行翻译。 - 游戏语音转文字输入:专为游戏玩家设计,特别是LOL玩家,通过语音输入实现快速打字。 目前支持搜狗、百度、有道等翻译API,通过配置文件可选择和切换主翻译API。 GitHub:https://github.com/sxzxs/Real-time-translation-typing

某行是否包括

import pandas as pd
import os

# 假设BASE_DIR是您存放Excel文件的目录
BASE_DIR = 'F:\\1school\\校团委文案编辑\\2024.11.19网络安全文化节'  # 请确保这里的路径是正确的

# 读取整个Excel文件
excel_file = '2024网络安全文化节评分计算.xlsx'  # Excel文件名
xls = pd.ExcelFile(os.path.join(BASE_DIR, excel_file))

# 要搜索的字符串
search_string = '法学院'  # 替换为您想要搜索的字符串

# 初始化奖项统计字典
awards_count = {'一等奖': 0, '二等奖': 0, '三等奖': 0, 'NaN': 0}

# 遍历每个sheet并进行处理
for sheet_name in xls.sheet_names:
    df = pd.read_excel(xls, sheet_name=sheet_name)
    print(f"Data from sheet '{sheet_name}' containing '{search_string}' and non-NaN in column 8:")
    # 使用df.apply函数检查每一行,如果包含搜索字符串,并且第八列不是NaN,则返回该行
    filtered_rows = df.apply(lambda row: (row.astype(str).str.contains(search_string, na=False).any() and
                                          pd.notna(row.iloc[7])), axis=1)
    # 输出包含搜索字符串的行,不打印表头和索引
    if not df[filtered_rows].empty:
        print(df[filtered_rows].to_string(index=False, header=False))

    # 统计奖项
    for index, row in df[filtered_rows].iterrows():
        if pd.notna(row.iloc[7]):
            award = row.iloc[7]
            if award in awards_count:
                awards_count[award] += 1
            else:
                awards_count['其他'] += 1  # 如果有不属于前三者的奖项,计入其他

# 打印统计结果
print("Awards count:")
for award, count in awards_count.items():
    print(f"{award}: {count}")

每行的某一格是否包括

import pandas as pd
import os

# 假设BASE_DIR是您存放Excel文件的目录
BASE_DIR = 'F:\\1school\\校团委文案编辑\\2024.11.19网络安全文化节'  # 请确保这里的路径是正确的

# 读取整个Excel文件
excel_file = '2024网络安全文化节评分计算.xlsx'  # Excel文件名
xls = pd.ExcelFile(os.path.join(BASE_DIR, excel_file))

# 要搜索的字符串
strings=['建筑','机械','能源','信息','土木','电子','数学','自动化','计软智','物理']
search_string = '建筑'  # 替换为您想要搜索的字符串

# 初始化奖项统计字典
awards_count = {'一等奖': 0, '二等奖': 0, '三等奖': 0, 'NaN': 0}
for search_string in strings:
    print('--------------------------\n',search_string)
    awards_count['一等奖']=0
    awards_count['二等奖']=0
    awards_count['三等奖']=0
    # 遍历每个sheet并进行处理
    for sheet_name in xls.sheet_names:
        df = pd.read_excel(xls, sheet_name=sheet_name)
        #print(f"Data from sheet '{sheet_name}' containing '{search_string}' and non-NaN in column 8:")
        # 使用df.apply函数检查每一行,如果包含搜索字符串,并且第八列不是NaN,则返回该行

        filtered_rows = df.apply(lambda row: ((search_string in row.iloc[2]) and
                                              pd.notna(row.iloc[7])), axis=1)
        # 输出包含搜索字符串的行,不打印表头和索引
        #if not df[filtered_rows].empty:
            #   print(df[filtered_rows].to_string(index=False, header=False))

        # 统计奖项
        for index, row in df[filtered_rows].iterrows():
            if pd.notna(row.iloc[7]):
                award = row.iloc[7]
                if award in awards_count:
                    awards_count[award] += 1
                else:
                    awards_count['其他'] += 1  # 如果有不属于前三者的奖项,计入其他

    # 打印统计结果
    print("Awards count:")
    for award, count in awards_count.items():
        print(f"{award}: {count}")

放大 ctrl+Numpad+

缩小 ctrl+Numpad-

抓手 H

旋转视角工具 R

画笔 B

橡皮 E

取色 I

移动工具 V

画笔缩小 [

画笔放大 ]

撤回 ctrl+z

重写 ctrl+shift+z

222

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
string deal(string str)
{
	int len=str.length();
	int pos=0;
	for(int i=0;i<len;i++)
	{
		if(str[i]=='.')
		{
			pos=i;
		}
	}
	return str.substr(0,pos);
}

int main()
{
	string txtName; 
	cout<<"输入txt名字如file.txt :";
	cin>>txtName; 
	fstream fcin(txtName.c_str(),ios::in);
	string str;
	string category;
	fstream fcout("fileout.txt",ios::app);
	cout<<"输入文件夹名:";
	cin>>category; 
	while(getline(fcin,str))
	{
		fcout<<"    - ["<<deal(str)<<"]("<<category<<"/"<<str<<")"<<"\n";
	}
	return 0;
} 

未用初始化列表时是否会构造成员对象

  • 代码
#include <iostream>
using namespace std;
class Member
{
public:
    Member()
    {
        age=0;
        cout << "construction Memer()\n";
    }
    Member(int age)
    {
        this->age=age;
        cout << "construction Member(int age)\n";
    }
    ~Member()
    {
        cout<<age<<"  destruct\n";
    }
    int age;
};
class Team
{
public:
    Team()
    {
        m = Member(120);
        cout << "construct Team\n";
    }
    Member m;
};
int main()
{
    Team t;
    return 0;
}
  • 输出结果
construction Memer()
construction Member(int age)
120  destruct
construct Team
120  destruct
  • 结论

可以看出初始化列表未赋值时,成员变量会调用默认构造函数。

三层继承成员变量生成顺序

class A{
public:
	A(int a){ cout << "A ctor!" << endl; }
	A(){ cout << "A default ctor!"<< endl; }
	~ A() { cout << "A dtor!" << endl; }
};
class B{
public:
	B(int a, int b){ cout<<"B ctor!"<<endl; }
	B(): m(0) { cout<<"B default ctor!"<<endl;}
	~B(){ cout<<"B dtor!"<<endl;}
private:
	A m;
};
class C: public B{
public:
	C(int a, int b) { cout<<"C ctor!"<<endl; }
	~C(){ cout<<"C dtor!"<<endl;}
private:
	A m;
};
int main()
{
	C obj(0, 0);     
	return 0;
}

副屏一线通出问题

1.电脑静电

已解决: 战66关于typec无法使用问题询问 - 惠普支持社区 - 1252209