重绘Panel边框线

最近有一个需求,是重绘panel边框的颜色成指定的颜色,参考了网上的一些示例代码和结合实际情况,形成了自己的解决方案,以下是实现过程。

示例代码

边框绘制类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/// <summary>
/// panel边框绘制类
/// </summary>
public static class PanelBorderPainter
{
private static Color _colorPanelBorder = Color.FromArgb(215, 215, 215); //d7d7d7
private static int BorderSize = 1;

/// <summary>
/// 重绘panel的边框颜色
/// <para>Padding 需要设置为1,例如:panel.Padding = new System.Windows.Forms.Padding(1);</para>
/// <para>默认颜色值是d7d7d7</para>
/// <para>可以通过panel.Tag=Color.FromArgb(255, 0, 0)设置颜色为红色</para>
///<para>注意:该Paint事件应置于InitializeComponent()之后实现,重新生成Designer.cs会导致代码丢失。</para>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public static void Paint(object sender, PaintEventArgs e)
{
if (sender is Control control)
{
#region panel颜色信息通过Tag传递

if (control.Tag != null)
{
if (control.Tag is Color color)
{
_colorPanelBorder = color;
}
}

#endregion


ButtonBorderStyle style = ButtonBorderStyle.Solid;
ControlPaint.DrawBorder(e.Graphics, control.ClientRectangle,
_colorPanelBorder, BorderSize, style,
_colorPanelBorder, BorderSize, style,
_colorPanelBorder, BorderSize, style,
_colorPanelBorder, BorderSize, style);
}
}
}

声明两个Panel

容器panelOuter包含panelInner

1
2
private System.Windows.Forms.Panel panelOuter;
private System.Windows.Forms.Panel panelInner;

关键代码

panelOuter

1
2
3
4
5
this.panelOuter.Padding = new System.Windows.Forms.Padding(1); //Padding属性设置为1。
this.panelOuter.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panelOuter.Controls.Add(panelInner); //必须

panelInner

1
this.panelInner.Dock = System.Windows.Forms.DockStyle.Fill;

Form1构造函数

1
2
3
4
5
6
public Form1()
{
InitializeComponent();
this.panelOuter.Paint += new PaintEventHandler(PanelBorderPainter.Paint);
}

答疑

为什么需要两个Panel?
答:因为如果注释掉以下代码,水平拖拽时会出现如下的界面效果。

1
this.panelOuter.Controls.Add(panelInner);

错误重绘示例
取消该行代码注释则页面拖拽效果正常。

是否必须需要两个Panel?
答:不是,内部是DataGridView等控件,其Dock=DockStyle.Fill,可以起到同样的效果。

参考资料

SqlServer 迁移到mysql

最近有开展Sqlserver 迁移到mysql的工作,以下经验基本上是别的博客没有提到过的,故行此文以作补充。

版本差异

时间精度

Mysql 5.5版本不支持毫秒,Mysql 5.6以上才支持。
时间格式为DateTime(3),当前时间为**Now(3)**。在5.5版本上,这两种写法为提示错误。

row_number函数

mysql 8.0才支持row_number函数,低版本都不支持该函数。
低版本实现方式: 游标查询,或者少量数据的情况下,创建带有自增主键的临时表。

mysql.proc表

该表在mysql 8.0版本中已经不存在了,所以 **select * from mysql.proc;**在mysql 8.0版本中会报错;
需要转换成 **show procedure status where db=’sys’;**这种写法来获取存储过程的相关信息。

with cte

mysql 8.0以上才支持cte,不过Mysql递归cte的写法与sql server存在差异,需要添加关键字recursive,否则会提示cte不存在错误。

如下

1
2
3
4
5
6
7
8
9
with recursive cte as
(
select Id,Pid,DeptName,0 as lvl from Department
where Id = 2
union all
select d.Id,d.Pid,d.DeptName,lvl+1 from cte c inner join Department d
on c.Id = d.Pid
)
select * from cte

.net framework框架

5.6 及以上的的版本使用mysql.data.dll时需要 .net framework 4.5.2以上。

Mysql不具备的SQL Server语法

uniqueidentifier

SqlServer 通过WorkBench 迁移到Mysql时,该字段会自动变成varchar(36)类型。Mysql对应的生成Guid的语法是**uuid()**。
因object不支持强制转换成Guid,所以应将接口代码中的 (Guid)cmd.ExecuteScalar()替换成new Guid(cmd.ExecuteScalar())

deleted,Inserted

SqlServer在执行 insert into table_a select top 10 columnname from table_b时可以通过inserted获取到新插入的十条记录的自增主键,而Mysql不可以。
实现方式 表新增Guid辅助字段,并将Guid放在临时表,通过多表链接查询获取数据。

select top … percent

SqlServer在执行 select top 10 percent columnname from table_a,如果table_a中有200条记录,则会返回前20条记录。
实现方式 Mysql 需要通过获取总记录条数,然后获取总条数*百分比来获取数据。

临时表编码

CREATE TEMPORARY TABLE
temptable1(groupname VARCHAR(50))
DEFAULT CHARSET=utf8;
这样可以解决临时表不能插入中文的问题。

配置文件

默认位置

各版本的配置文件的位置如下:
5.5: C:\Program Files\MySQL\MySQL Server 5.5\my.ini
5.6: C:\ProgramData\MySQL\MySQL Server 5.6\my.ini
5.7: C:\ProgramData\MySQL\MySQL Server 5.7\my.ini
8.0: C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
配置文件修改以后重启mysqlserver才会生效。

longtext存储

max_allowed_packet 的默认值是4M。
设置max_allowed_packet=100M可以解决longtext数据的存储长度的问题。

数据库名大小写

lower_case_table_names
设置lower_case_table_names=1,表名称都设置为统一小写。

id自增不连续

innodb_autoinc_lock_mode=0 解决id自增不连续的问题;

语法差异

不等于

SqlServer的不等于符号 **!=**中间可以存在空格,而Mysql的不可以。
Sql Server: select * from a where a.column ! = 0 不报错
Mysql: select * from a where a.column ! = 0 报错
Mysql: select * from a where a.column != 0 不报错

逻辑取反

SqlServer : update table_a set isOk=~isOk;
Mysql : update table_a set isOk=!isOk;

总结

以上就是本人在做SqlServer 迁移到Mysql的过程中遇到的问题以及相应的解决方案。
如果其中有不正确的地方,强烈欢迎指正,避免误导他人。
希望该文能为你的迁移大业贡献一份力量。

python画爱心

该文算是python版的”Hello world”初探,故作相关的记录。
环境准备:Visual Studio 2017,python

正文

爱心一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

x_coords = np.linspace(- 100, 100, 500)
y_coords = np.linspace(- 100, 100, 500)
points = []

for y in y_coords:
for x in x_coords:
if((x* 0.03)** 2+(y* 0.03)** 2- 1)** 3-(x* 0.03)** 2*(y* 0.03)** 3<= 0:
points.append({ "x": x, "y": y})

heart_x = list(map( lambda point: point[ "x"], points))
heart_y = list(map( lambda point: point[ "y"], points))

plt.scatter(heart_x, heart_y, s= 10, alpha= 0.5)
plt.show()

效果如图
爱心1

爱心二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import turtle
import time

# 画心形圆弧
def hart_arc():
for i in range(200):
turtle.right(1)
turtle.forward(2)

def move_pen_position(x, y):
turtle.hideturtle() # 隐藏画笔(先)
turtle.up() # 提笔
turtle.goto(x, y) # 移动画笔到指定起始坐标(窗口中心为0,0)
turtle.down() # 下笔
turtle.showturtle() # 显示画笔


#love = input("请输入表白话语,默认为‘I Love You’:")
#signature = input("请签署你的大名,不填写默认不显示:")

signature= ''
love = 'I Love You'

if love == '':
love = 'I Love You'

# 初始化
turtle.setup(width=800, height=500) # 窗口(画布)大小
turtle.color('red', 'pink') # 画笔颜色
turtle.pensize(3) # 画笔粗细
turtle.speed(1) # 描绘速度
# 初始化画笔起始坐标
move_pen_position(x=0,y=-180) # 移动画笔位置
turtle.left(140) # 向左旋转140度

turtle.begin_fill() # 标记背景填充位置

# 画心形直线( 左下方 )
turtle.forward(224) # 向前移动画笔,长度为224
# 画爱心圆弧
hart_arc() # 左侧圆弧
turtle.left(120) # 调整画笔角度
hart_arc() # 右侧圆弧
# 画心形直线( 右下方 )
turtle.forward(224)

turtle.end_fill() # 标记背景填充结束位置

# 在心形中写上表白话语
move_pen_position(0,0) # 表白语位置
turtle.hideturtle() # 隐藏画笔
turtle.color('#CD5C5C', 'pink') # 字体颜色
# font:设定字体、尺寸(电脑下存在的字体都可设置) align:中心对齐
turtle.write(love, font=('Arial', 30, 'bold'), align="center")

# 签写署名
if signature != '':
turtle.color('red', 'pink')
time.sleep(2)
move_pen_position(180, -180)
turtle.hideturtle() # 隐藏画笔
turtle.write(signature, font=('Arial', 20), align="center")

# 点击窗口关闭程序
window = turtle.Screen()
window.exitonclick()

效果如下图
爱心2

爱心三

1
2
3
4
5
6
7
8
9
10
11
12
13
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import numpy as np

x=np.linspace(-2,2,200)
y1 =np.sqrt(1-np.square(np.fabs(x)-1))
y2 =np.arccos(1-np.fabs(x))-np.pi

plt.plot(x,y1,'r',x,y2,'r')
plt.axis([-2.5,2.5,-3.5,1.5])

plt.title('hello world of python,copy from @andrew',fontsize=16)
plt.show()

效果如下图
爱心3

遇到问题

在visual studio 2017中命令行执行 pip install numpy 无效
在nuget程序包管理器控制台执行即可
pip install pyinstaller之后生成的exe无法执行
在我电脑上的路径是C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\Scripts,
把run.py拷贝到该目录,执行pyinstaller -F -W p . run.py解决问题

总结

暴击


参考资料

第一个AI应用

我的第一个AI应用是参考实战:从0搭建完整 AI 开发环境写出第一个 AI 应用AI应用开发实战 - 从零开始配置环境两篇文章进行的实施,故以该文做出相应的补充。

遇到的问题

‘python’ 不是内部或外部变量

命令行执行python –version提示’python’ 不是内部或外部变量,在命令行中输入

1
set PATH="C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64";%PATH%

之后,再输入

1
python --version

输出版本为3.6.5
但是关闭命令行之后,再输入python –version时,依旧提示 ‘python’ 不是内部或外部变量
故在计算机→属性右键→高级系统设置→环境变量→选择PATH→点击新建→将C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64添加→确定,之后再运行python –version,显示正常。

saved_model.pb路径不对

单独参考第一篇文章进行配置时,发现没有samples-for-ai\export\saved_model.pb这个路径。
原因是没有启动examples\tensorflow\TensorflowExamples.sln这个解决方案,将MNIST项目设置为启动项目并运行,则会有samples-for-ai\export\saved_model.pb这个文件了。

命令行无响应

安装scipy-1.1.0mxnet_cu90-1.2.0时,命令行一直无响应,解决方案是到scipy-1.1.0mxnet-cu90 1.2.0下载指定的文件,然后通过pip3命令来执行安装,其余问题也可以通过类似命令来解决。

1
2
pip3 install D:\scipy-1.1.0-cp36-none-win_amd64.whl
pip3 install D:\mxnet_cu90-1.2.0-py2.py3-none-win_amd64.whl

通过下载的文件可以得知,文件较大,命令行无法及时完成下载,所以需要有一定的耐心等待

注意需要将C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\Scripts添加到PATH变量中。

cudnn版本不对

现在官网https://developer.nvidia.com/cudnn提供的cudnn版本是7.4.1,而微软示例代码中的cudnn版本是7.0.3,高版本的cudnn也会导致编译失败,需要找低版本的7.0.的cudnn替换到*C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\bin\cudnn64_7.dll

运行结果

解决了这部分问题之后,能正常展示winform界面,运行结果如下:
正确识别
错误识别
该部分涉及到训练模型是否足够多的问题,该文不做深入的研究。

总结

参考资料中提及的两篇文章都已经是做手写识别非常好的入门资料,该文仅仅是对这两篇文章做一个相应的补充,以作备忘。
另外我希望早日掌握以下技能

识别开心消消乐的游戏界面,然后通过能够确定执行的最佳下一步,达到这个目的,我觉得我对人工智能的了解和我的AI编程就进入了新的层次了。

#参考资料

怎么学习C++

该文章转自网上,个人感觉适用于多种编程语言,未知原作者是谁。未经允许转载,向原作者表示抱歉。

正文

1.把C++当成一门新的语言学习(和C没啥关系!真的。);

2.看《Thinking In C++》,不要看《C++变成死相》;

3.看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看;

4.不要被VC、BCB、BC、MC、TC等词汇所迷惑——他们都是集成开发环境,而我们要学的是一门语言;

5.不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可以引伸出很多知识点;

6.会用Visual C++,并不说明你会C++;

7.学class并不难,template、STL、generic programming也不过如此——难的是长期坚持实践和不遗余力的博览群书;

8.如果不是天才的话,想学编程就不要想玩游戏——你以为你做到了,其实你的C++水平并没有和你通关的能力一起变高——其实可以时刻记住:学C++是为了编游戏的;

9.看Visual C++的书,是学不了C++语言的;

10.浮躁的人容易说:XX语言不行了,应该学YY;——是你自己不行了吧!?

11.浮躁的人容易问:我到底该学什么;——别问,学就对了;

12.浮躁的人容易问:XX有钱途吗;——建议你去抢银行;

13.浮躁的人容易说:我要中文版!我英文不行!——不行?学呀!

14.浮躁的人容易问:XX和YY哪个好;——告诉你吧,都好——只要你学就行;

15.浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人;

16.把时髦的技术挂在嘴边,还不如把过时的技术记在心里;

17.C++不仅仅是支持面向对象的程序设计语言;

18.学习编程最好的方法之一就是阅读源代码;

19.在任何时刻都不要认为自己手中的书已经足够了;

20.请阅读《The Standard C++ Bible》(中文版:标准C++宝典),掌握C++标准;

21.看得懂的书,请仔细看;看不懂的书,请硬着头皮看;

22.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;

23.请看《Effective C++》和《More Effective C++》以及《Exceptional C++》;

24.不要停留在集成开发环境的摇篮上,要学会控制集成开发环境,还要学会用命令行方式处理程序;

25.和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好;

26.请看《程序设计实践》,并严格的按照其要求去做;

27.不要因为C和C++中有一些语法和关键字看上去相同,就认为它们的意义和作用完全一样;

28.C++绝不是所谓的C的“扩充”——如果C++一开始就起名叫Z语言,你一定不会把C和Z语言联系得那么紧密;

29.请不要认为学过XX语言再改学C++会有什么问题——你只不过又在学一门全新的语言而已;

30.读完了《Inside The C++ Object Model》以后再来认定自己是不是已经学会了C++;

31.学习编程的秘诀是:编程,编程,再编程;

32.请留意下列书籍:《C++面向对象高效编程(C++ Effective Object-Oriented Software Construction)》《面向对象软件构造(Object-Oriented Software Construction)》《设计模式(Design Patterns)》《The Art of Computer Programming》;

33.记住:面向对象技术不只是C++专有的;

34.请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码;

35.把在书中看到的有意义的例子扩充;

36.请重视C++中的异常处理技术,并将其切实的运用到自己的程序中;

37.经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去;

38.不要漏掉书中任何一个练习题——请全部做完并记录下解题思路;

39.C++语言和C++的集成开发环境要同时学习和掌握;

40.既然决定了学C++,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设计技术,而程序设计技术是跨语言的;

41.就让C++语言的各种平台和开发环境去激烈的竞争吧,我们要以学习C++语言本身为主;

42.当你写C++程序写到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设计和编写(参见43);

43.别心急,设计C++的class确实不容易;自己程序中的class和自己的class设计水平是在不断的编程实践中完善和发展的;

44.决不要因为程序“很小”就不遵循某些你不熟练的规则——好习惯是培养出来的,而不是一次记住的;

45.每学到一个C++难点的时候,尝试着对别人讲解这个知识点并让他理解——你能讲清楚才说明你真的理解了;

46.记录下在和别人交流时发现的自己忽视或不理解的知识点;

47.请不断地对自己写的程序提出更高的要求,哪怕你的程序版本号会变成Version 100.XX;

48.保存好你写过的所有的程序——那是你最好的积累之一;

49.请不要做浮躁的人;

50.请热爱C++!

补充:

对c++学习的一点感想,希望对初学者能有些帮助

1.如果你以前从来没有接触过c++,那么选择的第一本c++教程就显得尤为重要,我认为你可以参照以下的标准进行选择:

a.对标准c++进行讲解,毕竟c++比从前发生了很大的变化。

b.要求全面,但不要很深,这要有助于你对于c++有一个全面的认识,打好基础,并且易懂的教材还能加快学习的进度,让自己保持一种成就感。

c.要有完整的范例来讲解每一个知识点如何运用,请注意这里所说的完整,并不是一个个代码片断。因为由于你以前从未接触过用c++进行编程,完整的代码可以使你有一个整体的概念,并且能够很快去进行大量的实践,因为变编程是从模仿开始,完整的代码恰恰告诉你了一个完整的步骤。不必自己去揣测。

d.推荐:《c++ primer plus》

2.当你有了一定的基础以后,就要选择一些书来迅速提高自己。这类书的特点是不仅仅教你如何去运用,而且要叫你如何去思考,并且你读起来也不是那么轻松。它意味深远,并不是你读一遍就能掌握的。

推荐:《thinking in c++》《effective c++》《more effective c++》《c++ programming language》…《c++ 沉思录》

3.接下来就是对第二步所介绍的书籍进行反复的阅读,并且进行实践。由于这些书一位深远,每个人基于自己的基础都会有不同的收获,例如如果你的基础还没有达到某一高度,那么你就对一些精深的技术视而不见,不信?你可以试试,看看当自己有了一定提高之后再来读从前的一本书,你会发现许多新的东西。

总结

除去部分推荐的书籍,其中很多部分思想都适用于其余编程语言或技能的学习。