Markdown简单语法

1.综述

Markdown 的语法全由一些符号所组成,这些符号经过精挑细选,其作用一目了然。比如:在文字两旁加上星号,看起来就像强调。Markdown 的列表看起来,嗯,就是列表。Markdown 的区块引用看起来就真的像是引用一段文字,就像你曾在电子邮件中见过的那样。

2.兼容html

markdown的语法目标是成为一种网络的书写语言。
markdown语法种类很少,只对应HTML语言的一小部分,不在markdown覆盖范围内的标签都可以直接在文档里面用HTML书写。不需要额外标准这是HTML还是Markdown。
需要注意的是HTML标签间的Markdown语法是不会被处理的。但是在Markdown语法之间的HTML语法是会被处理的。
###2.1特殊字符自动转化
在html中有两个需要特殊注意的字符<和&,如果要原样输出需要&lt;&amp;。但是在Markdown中直接原样输出即可。写成&lt;或者&amp;会和HTML中的一样效果。

3.区块元素

3.1标题

markdown支持两种形式的标题。
一种是利用=(第一阶标题)和-(第二阶标题),例如

这是第一阶标题
======
这是第二阶标题
------

任何数量的=-效果都一样,但是写=-所在行不能出现别的符号和文字

另外一种是在行收插入1到6个#,对应标题1到6阶,例如:

#这是一级标题
##这是二级标题
###这是三级标题

3.2区块标记

Markdown标记区块是使用>的方式,在每行的最前面加上>(最好动手试一下看结果)。
Markdown也允许你偷懒在每一个段落的第一行最前面加上>,允许换行,只要中间不插入空行,就算是一个区块的内容:

>我是一块内容我是一块内容我是一块内容我,是一块内容我是一块内容我是一块内容我是
一块内容我是一块内容

区块还可以嵌套,只要根据层次加上不同数量的>

>我能够嵌套我能够嵌套我能够嵌套我能够嵌套我能够嵌套我能够嵌套我能够嵌套
>我能够嵌套我能够嵌套我能够嵌套我能够嵌套我能够嵌套
>>我能够嵌套我能够嵌套我能够嵌套我能够嵌套
>我能够嵌套我能够嵌套我能够嵌套
>我能够嵌套我能够嵌套我能够嵌套

引用的区块内还可以使用其他的Markdown语法,包括标题、列表、代码块等:

> ## 这是一个标题。
>
> 1.   这是第一行列表项。
> 2.   这是第二行列表项。
>
> 给出一些例子代码:
>
>     return shell_exec("echo $input | $markdown_script");

3.3列表

Markdown 支持有序列表和无序列表。

无序列表使用星号、加号或是减号作为列表标记:

* aaa
* bbb
* ccc

等同于:

+ aaa
+ bbb
+ ccc

也等同于:

- aaa
- bbb
- ccc

有序列表则使用数字连着一个内容数字和内容之间要有空格隔开:

1. first
2. scond
3. third

重要的一点是你在有序列表里面改变行首的数字(不是第一行),不会影响输出结果。上面那个列表和下面这个列表等同:

1. first
3. second
9. third

所以在写有序列表的时候你只需要标记一下第一行的数字就行,后面的数字完全不用在意。
如果要在列表里面引用区块,为了美观最好缩进两个空格。

1. aaa
2. bbb
2. sdad
   > dasdasd

列表内容还能嵌入代码块,不过嵌入代码块要有一个空行,然后在首行缩进八个空格或者两个制表符(这得看你的编辑器设置的一个制表符等于几个空格)

1. 代码示例:

        return a+b

当然有时候写文档还会遇见这种写法:

1937. 中日战争爆发。

Markdown也会默认把它当成列表。换句话说只要行首出现数字+句点+空白,都会被Markdown识别为列表,为了避免这种情况,你可以在句点前面加上反斜杠:

1937\. 中日战争爆发

###3.4代码区块
写文档的时候有时候会有已经排班好的代码区块,通常我们不希望它以段落的形式去排版,而是显示原来的样子。
第一种方法是只要简单地缩进 4 个空格或是 1 个制表符就可以,代码快前面要有一个空行。一个代码区块会一直持续到没有缩进的那一行(或是文件结尾)。

这是一个普通段落:

    这是一个代码区块。

第二张方法就是成对出现'''(这个是数字1前面那个符号不是单引号):

'''
这是一个代码区块
'''

3.5分割线

你可以在一行中用三个以上的星号、减号、底线来建立一个分隔线,行内不能有其他东西。你也可以在星号或是减号中间插入空格。下面每种写法都可以建立分隔线:

* * *

***

*****

- - -
_ _ _
------------------------------------

3.6链接

Markdown 支持两种形式的链接语法: 行内式和参考式两种形式。

不管是哪一种,链接文字都是用 [方括号] 来标记。

要建立一个行内式的链接,只要在方块括号后面紧接着圆括号并插入网址链接即可,如果你还想要加上链接的 title 文字(鼠标浮动到链接上显示的文字),只要在网址后面,用双引号把 title 文字包起来即可,例如:

这是[百度](http://www.baidu.com "百度")的链接

如果你是要链接到同样主机的资源,你可以使用相对路径:

See my [About](/about/) page for details.

参考式的链接是在链接文字的括号后面再接上另一个方括号,而在第二个方括号里面要填入用以辨识链接的标记:

这是[百度][百度]的链接

接着,在文件的任意处,你可以把这个标记的链接内容定义出来:

[百度]:http://www.baidu.com

链接内容定义的形式为:

  • 方括号(前面可以选择性地加上至多三个空格来缩进),里面输入链接文字
  • 接着一个冒号
  • 接着链接的网址
  • 选择性地接着 title 内容,可以用单引号、双引号或是括弧包着
  • 前面必须要有一个空行

网址定义只有在产生链接的时候用到,并不会直接出现在文件之中。

链接辨别标签可以有字母、数字、空白和标点符号,但是并不区分大小写,因此下面两个链接是一样的:

[百度][a]
[百度][A]

隐式链接标记功能让你可以省略指定链接标记,这种情形下,链接标记会视为等同于链接文字,要用隐式链接标记只要在链接文字后面加上一个空的方括号,如果你要让 "Google" 链接到 google.com,你可以简化成:

[google][]

然后定义链接内容:

[google]:http://google.com

3.7强调

Markdown使用*_作为标记强调字词的符号,被一个*或者_包围的字体会变成斜体,用两个包起来会变成加粗。用三个会变成加粗的斜体。再多就会原样输出。例如:

*a*
**a**
***a***
____a____

会变成
a
a
a
a
你可以随便用你喜欢的样式,唯一的限制是,你用什么符号开启标签,就要用什么符号结束。
你还可以在文字中间加强调:

我是一个粉刷匠,粉刷**能力强**

如果要在文字前后直接插入普通的星号或底线,你可以用反斜线:

\*我是一个粉刷匠,粉刷能力强\*

3.8图片

图片使用atom的Markdown-img-paste插件既可以截图粘贴插入了,Mac下面的粘贴是Ctrl+v,Windows下的粘贴图片是Ctrl+Shift+v.

C++中的文件读写操作

#include<iostream>
#include <fstream> //头文件引用
using namespace std;

//输出到缓冲区(写文件)
void test01()
{
    //流对象 参数 1 文件路径 2 打开方式
    //ofstream ofs("./test.txt", ios::out | ios::trunc);
    ofstream ofs;
    ofs.open("./test.txt", ios::out | ios::trunc); //指定打开方式

    //判断是否打开成功
    if ( ! ofs.is_open() )
    {
        cout << "文件打开失败" << endl;
    }

    ofs << "姓名:德玛" << endl;
    ofs << "年龄:18" << endl;
    ofs << "身高:165cm" << endl;

    ofs.close(); //关闭流对象,更新缓冲区
}

//输入到缓冲区(读文件)
void test02()
{
    ifstream ifs;
    ifs.open("./test.txt",ios::in); //读文件

    if (ifs.is_open() == false)//可以这样写if(!ifs)
    {
        cout << "文件打开失败" << endl;
    }
    //第一种方式读文件
    //char buf[1024] = {0};
    ////每次都读1行数据,并且放到buf中
    //while (ifs >> buf)//肯定重载了>>运算符
    //{
    //  cout << buf << endl;
    //}


    //第二种方式
    //char buf[1024] = { 0 };
    //while (!ifs.eof()) //判断是否读到文件的尾部
    //{
    //  ifs.getline(buf, sizeof(buf));
    //  cout << buf << endl;
    //}


    //第三种方式 单个字符读取
    // ifs.get() 以单个字符读取文件
    char c;
    while ((c = ifs.get()) != EOF)
    {
        cout << c;
    }

    //关闭文件对象
    ifs.close();




}

int main(){

    test01();//运行test01后在相应的目录中能找到test.txt文件

    test02();//要保证相应的目录中有test.txt文件

    system("pause");
    return EXIT_SUCCESS;
}

函数模板具体化

我们知道函数模板是把数据类型参数化了,一个函数模板可以传入不同的数据类型,都可以使用这个函数功能,但这里的数据类型只是基础数据类型,我们自己定义的数据类型就不可以,因为c++的编译者们并不知道用户定义的是什么样的数据类型,这个时候我们就要把函数模板具体化,其实就是告诉编译器我们自己定义的数据类型该怎么样使用:
class Maker{
public:
    Maker(string name, int age)
    {
        this->name = name;
        this->age = age;
    }
public:
    string name;
    int age;
};
template<class T>
void mySwap(T &a, T &b)//要有这个函数模版,下面的具体化函数模版才不会报错
{
    if (a > b)
    {
        cout << "a>b" << endl;
    }
    else{
        cout << "a<=b" << endl;
    }   
}
//具体化函数模版,具体化函数模版优先于常规函数模版
template<> void mySwap<Maker>(Maker &p1, Maker &p2)
{
    cout << "具体化" << endl;
    if (p1.age > p2.age)
    {
        cout << "p1>p2" << endl;
    }
    else
    {
        cout << "p1<=p2" << endl;
    }
}
int main()
{
        int a = 10;
    int b = 20;
    mySwap(a, b);
    
    Maker p1("悟空", 20);
    Maker p2("布尔玛", 24);

    mySwap(p1, p2);
        return 0;
}

CMake从入门到精通

0. 了解

cmake是cross platform make的缩写,用于跨平台的工程构建和编译。它在make基础上,使用比make更加简单的语法来构建软件工程。cmake能感知系统和平台,生成不同的工程文件,比如unix的Makefile,Windows的sln或者苹果系统的XCode工程。

在Linux系统,比起手写Makefile来,cmake也是简单一些,目前很多开源软件都提供了cmake脚本来构建项目。在Linux下,cmake的功能是根据脚本,生成Makefile文件,用于构建。

1. 熟悉

1.1 环境搭建

Ubuntu系统,通过以下命令安装cmake

sudo apt-get install cmake

1.2 HelloWorld

先来一个最简单的例子,打开终端,输入以下命令:

mkdir HelloWorld
cd HelloWorld
touch CMakeLists.txt
touch main.c

编辑main.c和CMakeLists.txt

main.c内容如下:

#include <stdio.h>
int main()
{
    printf("hello world\n");
    return 0;
}

CMakeLists.txt内容如下

project(HelloWorld)
add_executable(HelloWorld.bin main.c)

在HelloWorld目录下,执行以下命令:

mkdir build
cd build
cmake ..
make

编译后会产生一个HelloWorld.bin,执行它会输出HelloWorld

1.3 HelloWorld的解释

HelloWorld工程的CMakeLists.txt非常简单,简要介绍以下

# 指定工程名称为HelloWorld
project(HelloWorld)
# 用main.c编译HelloWorld.bin
add_executable(HelloWorld.bin main.c)

命令的解释:

mkdir build

由于cmake在编译时产生很多中间文件,为了隔离中间文件和源代码,一般会创建一个目录来存放中间文件,一般目录名字为build,这个是可选的,但是大家都这么做。

cd build
cmake ..

进入到中间目录,执行cmake命令,cmake命令的参数..表示CMakeLists.txt在上层目录,cmake命令会生成Makefile,同时做一些必要的环境检查。

make

编译

2 掌握

恭喜你,到这里时,你已经学会如何使用cmake来构建应用程序了。但是还不够的是,还是有许多的问题没有解决。

2.1 使用变量

使用变量能够使代码变得有可读性和可维护性,通过set指令,来定义变量,通过${}来引用变量。以上的CMakeLists.txt,也可以改成这样子:

project(HelloWorld)
set(src main.c)
add_executable(HelloWorld.bin ${src})

set(src main.c)表示定义一个变量src,让它等于main.c。如果一个工程有多个文件,那么可以写成这样子:

project(HelloWorld)
set(src main.c func.c foo.c)
add_executable(HelloWorld.bin ${src})

2.2 搜索目录

如果目录下有100个文件,10000个文件,这么写超级累,还是用大招吧。aux_source_directory可以将目录中的所有源码,加入到工程。

cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
# set(src main.c foo.c func.c)
aux_source_directory(. src)
add_executable(HelloWorld.bin ${src})

注意上面的代码,set指令已经被注释了,取而代之的是aux_source_directory指令。

要注意的是,aux_source_directory这个指令,不会递归的搜索子目录,如果有子目录的代码也要加入,比如该目录下有一个sub目录,那么应该这样写:

cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
# set(src main.c foo.c func.c)
aux_source_directory(. src)
aux_source_directory(./sub src)
add_executable(HelloWorld.bin ${src})

注意,从这里开始多了一行cmake_minimum_required(VERSION 3.7),这个表示要求用户的cmake版本是3.7以上

以后把代码写到一个目录,然后xxx就完事儿了,貌似是比make方便一些。

2.3 链接动态库

如果代码用了pthread_create,要链接一个动态库怎么办?不用着急,对cmake来说,是小意思。使用target_link_libraries,让最终目标链上动态库即可。不过要注意的是,target_link_libraries指令要放在add_executable指令之后。例子如下:

cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
#set(src main.c foo.c func.c)
aux_source_directory(. src)
aux_source_directory(./sub src)
add_executable(HelloWorld.bin ${src})
target_link_libraries(HelloWorld.bin pthread)

上面的例子,HelloWorld.bin用了两次,这意味着将来如果要修改,那么可能会修改多次,可以使用变量优化一下。

cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
set(target HelloWorld.bin)
aux_source_directory(. src)
aux_source_directory(./sub src)
add_executable(${target} ${src})
target_link_libraries(${target} pthread)

2.4 设置头文件目录和库目录

2.4.1 设置头文件目录

有时候需要链接第三方库,以及要包含第三方的头文件,cmake那么强大,这个自然也是小意思的,用include_directories就可以了,它可以同时指定多个目录。下面的代码没测试过,我就那么一写,读者可以去测试一下效果。

cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
set(target HelloWorld.bin)
set(opencv_include /home/xueguoliang/opencv/include)
set(libevent_include /home/xueguoliang/libevent/include)
include_directories(${opencv_include} ${libevent_include})
aux_source_directory(. src)
aux_source_directory(./sub src)
add_executable(${target} ${src})
target_link_libraries(${target} pthread)

2.4.2 设置库目录

使用link_directories来设置库目录。比如

link_directories(/home/xueguoliang/opencv/lib /home/xueguoliang/libevent/lib)

2.5 编译目标是一个动态库或者静态库

add_library
set_target_properties

2.6 定义宏

可以通过指令add_definitions(-DFOO -DBAR ...),也可以在命令时通过cmake -DFOO来增加,也可以让cmake内置变量,是什么来着,忘记了,以上两种也够用了啊。

所有内置变量:https://cmake.org/cmake/help/v3.0/manual/cmake-variables.7.html

2.7 设置编译选项

使用add_compile_options(-std=c++11)来添加-std=c++11选项,其他选项也类似。

python操作数据库(三)数据库操作类的封装

观察前面的操作可以发现,python操作数据库除了sql语句及参数不同,其它语句都是一样的,为了避免重复造轮子,我们可以封装一个数据库操作类来简化我们的数据库操作。具体步骤如下
创建MysqlHelper.py文件,定义类
import pymysql
import pymysql.cursors

class MysqlHelper():
def init(self,host,db,user,passwd):
self.host=host
self.db=db
self.user=user
self.passwd=passwd

def connect(self):
    self.conn=pymysql.connect(host=self.host,db=self.db,user=self.user,passwd=self.passwd)
    self.cursor=self.conn.cursors()

def close(self):
    self.cursor.close()
    self.conn.close()

def get_one(self,sql,params=()):
    result=None
    try:
        self.connect()
        self.cursor.execute(sql, params)
        result = self.cursor.fetchone()
        self.close()
    except Exception as e:
        print(e.message)
    return result

def get_all(self,sql,params=()):
    list=()
    try:
        self.connect()
        self.cursor.execute(sql,params)
        list=self.cursor.fetchall()
        self.close()
    except Exception as e:
        print(e.message)
    return list

def insert(self,sql,params=()):
    return self.__edit(sql,params)

def update(self, sql, params=()):
    return self.__edit(sql, params)

def delete(self, sql, params=()):
    return self.__edit(sql, params)

def __edit(self,sql,params):
    count=0
    try:
        self.connect()
        count=self.cursor.execute(sql,params)
        self.conn.commit()
        self.close()
    except Exception as e:
        print(e.message)
    return count

添加

创建testInsertWrap.py文件,使用封装好的帮助类完成插入操作
#encoding=utf8
from MysqlHelper import *

sql='insert into students(sname,gender) values(%s,%s)'
sname=input("请输入用户名:")
gender=input("请输入性别,1为男,0为女")
params=[sname,bool(gender)]

mysqlHelper=MysqlHelper('localhost','test1','root','mysql')
count=mysqlHelper.insert(sql,params)
if count==1:
print('ok')
else:
print('error')
查询一个

创建testGetOneWrap.py文件,使用封装好的帮助类完成查询最新一行数据操作
#encoding=utf8
from MysqlHelper import *

sql='select sname,gender from students order by id desc'

helper=MysqlHelper('localhost','test1','root','mysql')
one=helper.get_one(sql)
print(one)