Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

python3与python2的区别与兼容

发表于 2018-05-26 | 更新于 2018-10-09

Python是一种广泛使用的高级编程语言,属于通用型编程语言,由吉多·范罗苏姆创造,第一版发布于1991年。可以视之为一种改良(加入一些其他编程语言的优点,如面向对象)的LISP。作为一种解释型语言,Python的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进划分代码块,而非使用大括号或者关键词)。相比于C++或Java,Python让开发者能够用更少的代码表达想法。不管是小型还是大型程序,该语言都试图让程序的结构清晰明了。

与Scheme、Ruby、Perl、Tcl等动态类型编程语言一样,Python拥有动态类型系统和垃圾回收功能,能够自动管理内存使用,并且支持多种编程范式,包括面向对象、命令式、函数式和过程式编程。其本身拥有一个巨大而广泛的标准库。

Python 解释器本身几乎可以在所有的操作系统中运行。Python的正式解释器CPython是用C语言编写的、是一个由社区驱动的自由软件,目前由Python软件基金会管理。

python3与python2区别

print函数

Python 2 的 print 声明在Python 3中已经被 print() 函数取代

1
2
3
4
5
#!/usr/bin/python2
print 'Hello, World!'

#!/usr/bin/python3
print('Hello, World!')

整除

/是精确除法,//是向下取整除法,%是求模。

//和%运算符在2和3版本中一样,但是运算符/不一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python2
>>> 3 / 2
1
>>> 3 // 2
1
>>> 3 / 2.0
1.5
>>> 3 // 2.0
1.0

#!/usr/bin/python3
>>> 3 / 2
1.5
>>> 3 // 2
1
>>> 3 / 2.0
1.5
>>> 3 // 2.0
1.0

Unicode

由于历史遗留问题,Python 2.x版本虽然支持Unicode,但在语法上需要’xxx’和u’xxx’两种字符串表示方式。

在Python 3.x版本中,把’xxx’和u’xxx’统一成Unicode编码,即写不写前缀u都是一样的,而以字节形式表示的字符串则必须加上b前缀:b’xxx’。

1
2
3
4
5
6
#!/usr/bin/python2

#!/usr/bin/python3
>>> 中国 = 'china'
>>> print(中国)
china

xrange模块

在 Python 2 中 xrange() 创建迭代对象的用法是非常流行的。比如: for 循环或者是列表/集合/字典推导式。

在 Python 3 中,range() 是像 xrange() 那样实现以至于一个专门的 xrange() 函数都不再存在(在 Python 3 中 xrange() 会抛出命名异常)。

不等运算符

Python 2.x中不等于有两种写法 != 和 <>

Python 3.x中去掉了<>, 只有!=一种写法

数据类型

  • Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
  • 新增了bytes类型,对应于2.X版本的八位串
  • dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),用 in替代它吧 。

异常

  • 在 Python 3 中处理异常也轻微的改变了,在 Python 3 中我们现在使用 as 作为关键词。
  • 捕获异常的语法由 except exc, var 改为 except exc as var。
    使用语法except (exc1, exc2) as var可以同时捕获多种类别的异常。 Python 2.6已经支持这两种语法。

解析用户的输入

  • 在python2.x中raw_input()和input(),两个函数都存在,其中区别为

    raw_input()—将所有输入作为字符串看待,返回字符串类型

    input()—–只能接收“数字”的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float)

  • 在python3.x中raw_input()和input()进行了整合,去除了raw_input(),仅保留了input()函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。

返回可迭代对象,而不是列表

如果在 xrange 章节看到的,现在在 Python 3 中一些方法和函数返回迭代对象 — 代替 Python 2 中的列表。

因为我们通常那些遍历只有一次,我认为这个改变对节约内存很有意义。尽管如此,它也是可能的,相对于生成器 —- 如需要遍历多次。它是不那么高效的。

而对于那些情况下,我们真正需要的是列表对象,我们可以通过 list() 函数简单的把迭代对象转换成一个列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/python2
>>> print range(3)
[0, 1, 2]
>>> print type(range(3))
<type 'list'>

#!/usr/bin/python3
>>> print(range(3))
range(0, 3)
>>> print(type(range(3)))
<class 'range'>
>>> print(list(range(3)))
[0, 1, 2]

For循环变量和全局命名空间泄漏

在 Python 3.x 中 for 循环变量不会再导致命名空间泄漏。

在 Python 3.x 中做了一个改变,在 What’s New In Python 3.0 中有如下描述:
“列表推导不再支持 [… for var in item1, item2, …] 这样的语法。使用 [… for var in (item1, item2, …)] 代替。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python2
>>> i = 1
>>> print 'before: i =', i
before: i = 1
>>> print 'comprehension: ', [i for i in range(5)]
comprehension: [0, 1, 2, 3, 4]
>>> print 'after: i =', i
after: i = 4

#!/usr/bin/python3
>>> i = 1
>>> print('before: i =', i)
before: i = 1
>>> print('comprehension:', [i for i in range(5)])
comprehension: [0, 1, 2, 3, 4]
>>> print('after: i =', i)
after: i = 1

兼容python3与python2

当前python3的普及还不尽人意,因此编写的python程序能同时兼容python2与python3是十分必要的。下面介绍同时支持python2与python3的方法。

  • 放弃python 2.6之前的python版本
  • 使用 2to3 工具对代码检查
  • 使用python -3执行python程序
  • from future import
    “from future import”后即可使使用python的未来特性了。python的完整future特性可见 future 。python3中所有字符都变成了unicode。在python2中unicode字符在定义时需要在字符前面加 u,但在3中则不需要家u,而且在加u后程序会无法编译通过。为了解决该问题可以 “from future import unicode_literals” ,这样python2中字符的行为将和python3中保持一致,python2中定义普通字符将自动识别为unicode。
  • import问题
    python3中“少”了很多python2的包,在大多情况下这些包之是改了个名字而已。我们可以在import的时候对这些问题进行处理。
    1
    2
    3
    4
    5
    6
    7
    try:#python2
    from UserDict import UserDict
    #建议按照python3的名字进行import
    from UserDict import DictMixin as MutableMapping
    except ImportError:#python3
    from collections import UserDict
    from collections import MutableMapping
  • 使用python3的方式写程序
  • 检查当前运行的python版本
    1
    2
    3
    4
    5
    import sys
    if sys.version > '3':
    PY3 = True
    else:
    PY3 = False
  • six
    不推荐使用six。

参考链接

  1. https://zh.wikipedia.org/wiki/Python, by wikipedia
  2. https://www.jianshu.com/p/85583e032eb8, by EarthChen
  3. http://python.jobbole.com/83987/, by 天地一沙鸥

Git用法总结

发表于 2018-05-24 | 更新于 2025-02-27

git是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计[1]。

git结构

新建代码库

1
2
3
4
5
6
7
8
# 在当前目录新建一个Git代码库
$ git init

# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]

# 下载一个项目和它的整个代码历史
$ git clone [url]

配置

Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

1
2
3
4
5
6
7
8
9
# 显示当前的Git配置
$ git config --list

# 编辑Git配置文件
$ git config -e [--global]

# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"

代码提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 提交暂存区到仓库区
$ git commit -m [message]

# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]

# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a

# 提交时显示所有diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]

# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...

查看信息

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
# 显示有变更的文件
$ git status

# 显示当前分支的版本历史
$ git log

# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat

# 搜索提交历史,根据关键词
$ git log -S [keyword]

# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s

# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature

# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]

# 显示指定文件相关的每一次diff
$ git log -p [file]

# 显示过去5次提交
$ git log -5 --pretty --oneline

# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn

# 显示指定文件是什么人在什么时间修改过
$ git blame [file]

# 显示暂存区和工作区的差异
$ git diff

# 显示暂存区和上一个commit的差异
$ git diff --cached [file]

# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD

# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]

# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"

# 显示某次提交的元数据和内容变化
$ git show [commit]

# 显示某次提交发生变化的文件
$ git show --name-only [commit]

# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]

# 显示当前分支的最近几次提交
$ git reflog

Git 工具 - 子模块

有种情况我们经常会遇到:某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。 现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。

Git 通过子模块来解决这个问题。 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。

1
2
3
4
5
6
7
$ git submodule add https://github.com/chaconinc/DbConnector
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.

默认情况下,子模块会将子项目放到一个与仓库同名的目录中,本例中是 “DbConnector”。 如果你想要放到其他地方,那么可以在命令结尾添加一个不同的路径。

Git代理设置

1
2
3
4
5
6
7
8
9
10
git config --global https.proxy http://127.0.0.1:1080

git config --global https.proxy https://127.0.0.1:1080

git config --global --unset http.proxy

git config --global --unset https.proxy


npm config delete proxy

不常用操作

  • 查看代码仓库中标签

    1
    git tag
  • 检出指定标签代码

    1
    git checkout tag_name
  • 丢弃本地修改

    1
    git checkout .
  • 打包导出仓库代码

    1
    git archive --format zip --output ..\emsdk\zips\1.38.8.zip HEAD

参考链接

  1. Git, by wikipedia
  2. git 如何获取指定 tag 代码, by 一介布衣
  3. 常用 Git 命令清单,by 阮一峰.
  4. 7.11 Git 工具 - 子模块,by git.
  5. Git submodule用法,by jinlei_123.

Vue.js集成three.js

发表于 2018-05-13 | 更新于 2023-03-23

Three.js是一个跨浏览器的脚本,使用JavaScript函数库或API来在网页浏览器中创建和展示动画的三维计算机图形。Three.js使用WebGL。源代码托管在GitHub。

下面介绍在Vue.js中集成three.js的步骤。

  1. 安装vue-cli脚手架
  2. 安装three.js
    1
    npm install --save three
  3. 编写使用three.js创建3D场景的Vuejs组件
    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
    <template>
    <div id="container"></div>
    </template>
    <script>
    import * as Three from 'three'

    export default {
    name: 'Home',
    data () {
    return {
    camera: null,
    scene: null,
    renderer: null,
    mesh: null
    }
    },
    methods: {
    init: function () {
    var container = document.getElementById('container')

    this.camera = new Three.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 10)
    this.camera.position.z = 1

    this.scene = new Three.Scene()

    var geometry = new Three.BoxGeometry(0.2, 0.2, 0.2)
    var material = new Three.MeshNormalMaterial()

    this.mesh = new Three.Mesh(geometry, material)
    this.scene.add(this.mesh)

    this.renderer = new Three.WebGLRenderer({ antialias: true })
    this.renderer.setSize(container.clientWidth, container.clientHeight)
    container.appendChild(this.renderer.domElement)
    },
    animate: function () {
    requestAnimationFrame(this.animate)
    this.mesh.rotation.x += 0.01
    this.mesh.rotation.y += 0.02
    this.renderer.render(this.scene, this.camera)
    }
    },
    mounted () {
    this.init()
    this.animate()
    }
    }

    </script>
    <style rel="stylesheet/scss" lang="scss" scoped>
    #container {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    }

    </style>

参考链接

  1. Three.js, by Wikipedia
  2. Import and use three.js library in vue component, by Stackoverlflow

Windows批处理编程语法解析

发表于 2018-05-13 | 更新于 2024-03-04

批处理文件(BAT文件)是DOS,OS/2和Microsoft Windows中的一种脚本文件[1]。 它由命令行解释器执行的一系列命令组成,存储在纯文本文件中,通常以BAT为扩展名。批处理文件可以包含解释器交互接受的任何命令,并使用在批处理文件中启用条件分支和循环的构造,如IF,FOR和GOTO标签。在Windows平台自动化部署或处理日常重复性工作时,常使用Windows批处理文件。

批处理命令简介

下面简单介绍Windows BAT文件的语法。

变量操作

  • 设置变量

格式:set 变量名=变量值
详细:被设定的变量以%变量名%引用

  • 取消变量
    格式:set 变量名=
    详细:取消后的变量若被引用%变量名%将为空

  • 展示变量
    格式:set 变量名
    详细:展示以变量名开头的所有变量的值

  • 列出所有可用的变量
    格式:set

常用命令

  • @

让执行窗口中不显示它后面这一行的命令本身。

1
2
// 使用@将不显示后面的echo off命令
@ echo off
  • echo

echo即回显或反馈的意思。它由两种状态:打开和关闭。

1
2
3
4
// 将不显示后续的命令
@ echo off
// 将显示后续的命令
@ echo on
  • ::

注释命令。在批处理文件中与rem命令等效

  • call

call命令用来从一个批处理文件调用另一个批处理文件。只有当被调用的批处理文件执行完成时,才返回。

1
call pm2-startup install
  • start

启动单独的“命令提示符”窗口来运行指定程序或命令。如果在没有参数的情况下使用,start 将打开第二个命令提示符窗口。

  • pause

暂停命令。方便用户查看信息,查看完毕后可继续执行。

  • explorer

在 cmd 下输入explorer可打开文件夹图形界面,例如:

1
2
// 在图形界面中打开当前文件夹
explorer .
  • %i

for循环在cmd命令行中的固定用法for %i in (set) do (…),循环变量格式为%i

1
for %i in (1,2,3,5,8) do echo %i
  • %%i

for循环在bat处理程序中的固定用法for %%i in (set) do (…),循环变量格式为%%i

  • &

顺序执行多条命令,而不管命令是否执行成功

  • &&

顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令

  • ||

顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令(即:只有前面命令执行错误时才执行后面命令)

  • |

管道命令 前一个命令的执行结果输出到后一个命令 如:help|more

清除文件中原有的内容后再写入

追加内容到文件末尾,而不会清除原有的内容主要将本来显示在屏幕上的内容输出到指定文件中指定文件如果不存在,则自动生成该文件。

1
certutil -hashfile user-history.db md5 >> hash.txt
  • cd /d %~dp0
1
2
3
4
5
6
/d 表示直接切换到对应分区
%0代表批处理本身 d:\qq\a.bat
~dp是变量扩充
d既是扩充到分区号 d:
p就是扩充到路径 \qq
dp就是扩充到分区号路径 d:\qq

批处理脚本示例

示例1:

1
2
3
4
5
6
7
8
9
10
11
12
@echo off
set PATH=E:\Simulation\x64\Release\;%PATH%;
E:
cd E:\Simulation\x64\Release\
cd BlueSimu
start FlightSimServer.exe
cd ../RedSimu
start FlightSimServer.exe
cd ..
start Simulation.exe
start Simulation.exe
pause

示例2:

1
2
3
4
5
6
7
8
9
10
11
12
13
:: 定义变量
set dataset=j:\tensorflow\dataset\LSOTB-TIR\Training Dataset
set imagedir=%dataset%\LSOTB-TIR_TrainingData\TrainingData\TIR_training_004\bird_001
set xmldir=%dataset%\LSOTB-TIR_TrainingData\Annotations\TIR_training_004\bird_001
set labelpath=j:\tensorflow\workspace\training_demo\annotations\label_map.pbtxt
set outputdir=j:\tensorflow\workspace\training_demo\annotations\infrared_train_bird_004_001
set process_script=j:\tensorflow\scripts\preprocessing\generate_pascal_tfrecord.py

:: 调用tfrecord脚本程序, for循环,字符串截取,字符串拼接,路径空格处理
for /L %%i in (1,1,7) do python %process_script% -i "%imagedir:~0,-1%%%i" -x "%xmldir:~0,-1%%%i" -l %labelpath% -o %outputdir:~0,-1%%%i.record
:: for /L %%i in (10,1,16) do python %process_script% -i "%imagedir:~0,-2%%%i" -x "%xmldir:~0,-2%%%i" -l %labelpath% -o %outputdir:~0,-2%%%i.record

pause

参考链接

  1. Batch file,by Wikipedia.
  2. 批处理最完整人性化教程(.bat文件语法), by s1ihome.
  3. 批处理命令之Start的详细用法,by QiaoZhi.
  4. windows批处理set命令,by 鹤唳九天.
  5. windows批处理——变量,命令换行,by undefined.
  6. Batch批处理字符串操作、for循环学习记录,by blingbling_110.
  7. .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别,by AlbertS.
  8. Bat命令学习-批处理中的&、&&、|、||、>、>>符号,by iloli.
  9. Windows certutil.exe 命令 简单举例 计算MD5与SHA1/256,by ldq_sd.
  10. cmd: cd /D %~dp0 的含义,by Nemo_XP.
  11. CMD获取当前目录的绝对路径 (当前盘符和路径:%~dp0),by 亟待!.

Vue.js集成Cesium

发表于 2018-05-11 | 更新于 2019-07-18

近期在研究集成封装Cesium为Vue.js组件,记录一下过程,防止忘了。

安装环境

  • node.js: v8.9.4
  • npm: 5.6.0
  • vue: 2.5.2
  • cesium: 1.45.0
  • vue-cli: 2.9.3
  • webpack: 3.6.0

注意此处vue-cli版本是2,因此该教程不适用vue-cli 3。如需在Vue-cli 3中构建Cesium,请参考Vue-cli 3.0 + cesium 构建.

安装配置

  1. 安装nodejs
  2. 安装vue-cli脚手架
    1
    2
    3
    4
    5
    npm install -g vue-cli
    vue init webpack my-project
    cd my-project
    npm install
    npm run dev
  3. 安装cesium
    1
    npm install --save cesium
  4. webpack配置
  • 在build/webpack.base.conf.js文件中做如下修改

    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
    //定义cesium源代码位置
    const cesiumSource = '../node_modules/cesium/Source'
    ...
    module.exports = {
    ...
    output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
    ? config.build.assetsPublicPath
    : config.dev.assetsPublicPath,
    // Needed to compile multiline strings in Cesium
    sourcePrefix: ''
    },
    amd:{
    // Enable webpack-friendly use of require in Cesium
    toUrlUndefined: true
    },
    resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
    'vue$': 'vue/dist/vue.esm.js',
    '@': resolve('src'),
    //设置cesium的别名
    'cesium': path.resolve(__dirname, cesiumSource)
    }
    },
    module: {
    rules: [
    ...
    ],
    //不让Webpack打印载入特定库时候的警告
    unknownContextCritical: false
    },
    ...
    }
  • 在build/webpack.dev.conf.js文件中做如下修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //定义 Cesium 源代码路径,前面没有../
    const cesiumSource = 'node_modules/cesium/Source'
    //定义 Cesium Workers 路径
    const cesiumWorkers = '../Build/Cesium/Workers'
    ...
    plugins: [
    ...
    new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' } ]),
    new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets' } ]),
    new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' } ]),
    new webpack.DefinePlugin({
    // Define relative base path in cesium for loading assets
    CESIUM_BASE_URL: JSON.stringify('')
    })
    ...
    ]
  • 在build/webpack.prod.conf.js文件中做如下修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //定义 Cesium 源代码路径,前面没有../
    const cesiumSource = 'node_modules/cesium/Source'
    //定义 Cesium Workers 路径
    const cesiumWorkers = '../Build/Cesium/Workers'
    ...
    plugins: [
    ...
    new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' } ]),
    new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets' } ]),
    new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' } ]),
    new webpack.DefinePlugin({
    //定义 Cesium 从哪里加载资源,如果使用默认的'',却变成了绝对路径了,所以这里使用'./',使用相对路径
    CESIUM_BASE_URL: JSON.stringify('./')
    })
    ...
    ]

Vue.js组件编写

  • 在src/components下新建 CesiumViewer.vue vue组件
    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
    <template>
    <div id="cesiumContainer">
    </div>
    </template>
    <script type="text/javascript">
    import Cesium from 'cesium/Cesium'
    import widgets from 'cesium/Widgets/widgets.css'

    export default {
    name: 'CesiumViewer',
    mounted () {
    var viewer = new Cesium.Viewer('cesiumContainer')
    }
    }

    </script>
    <style rel="stylesheet/scss" lang="scss" scoped>
    #cesiumContainer {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    }
    </style>
  • 创建全局样式文件src/styles/index.scss,做如下修改
    1
    2
    3
    4
    5
    6
    7
    8
    html,
    body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    }
  • 在src/main.js中做如下修改
    1
    import '@/styles/index.scss' // global css

参考链接

  1. 基于webpack 构建Cesium + Vue 的应用, by QingMings
  2. Vue-cli 3.0 + cesium 构建,by QingMings.
  3. cesium-and-webpack, by cesiumjs.org
  4. vue-cli生成的项目,main.js引入scss时报错,by segmentfault.

离线环境下Node.js应用部署方法

发表于 2018-05-10 | 更新于 2019-12-17

离线环境下Node.js应用部署时需要解决以下三个基本问题:

  1. Node.js应用的进程管理,如性能监控、自动重启、负载均衡等
  2. Node.js应用开机如何自启动
  3. 离线环境下如何部署Node.js应用

下面以在Windows Server 2012上离线部署Node.js应用为例,记录上述问题的解决方案:

Node.js应用的进程管理

在生产环境中运行 Express 应用程序时,使用进程管理器对于完成以下任务很有帮助[1]:

  • 在应用程序崩溃后将其重新启动。
  • 获得对运行时性能和资源消耗的洞察。
  • 动态修改设置以改善性能。
  • 控制集群。

进程管理器有点类似于应用程序服务器:它是应用程序的“容器”,可促进部署,提供高可用性并使您可以在运行时管理应用程序。

用于 Express 和其他 Node.js 应用程序的最流行的进程管理器包括:

  • StrongLoop Process Manager
  • PM2
  • Forever

上述三种工具的比较请参阅http://strong-pm.io/compare/。其中,StrongLoop Process Manager无法在Windows平台工作,再综合比较PM2和Forever,由于Forever没有操作系统自启动的脚本,故选择PM2作为Windows平台Node.js应用的进程管理器。

Node.js应用开机如何自启动

选择PM2作为Node.js应用的进程管理器后,Node.js应用开机自启动的问题就变为如何开机自启动PM2。Windows平台存在两个自启动PM2的脚本:

  • pm2-windows-service
  • pm2-windows-startup

pm2-windows-service基于 node-windows将PM2注册为Windows服务,从而实现自启动。pm2-windows-startup则基于start-on-windows-boot在注册表中将PM2设为自启动程序,从而实现自启动。两种方案经测试,只有pm2-windows-startup在Windows Server 2012上可行,故选择pm2-windows-startup作为解决Node.js应用开机自启动的方案。

离线环境下如何部署Node.js应用

PM2和pm2-windows-startup必须全局安装,如何简单方便地在离线环境下全局安装这两个模块是一个问题。网上搜到的方法有:

  • npm link
  • npm-bundle

npm link[2]是npm的一个命令,可将本地包链接成全局包,但实际测试过程中,无法解决PM2包的依赖问题,故放弃。而npm-bundle[3]则能很好的解决PM2的依赖问题。具体过程为:

1
2
3
4
5
6
\\在线环境下全局安装
npm install -g pm2
npm install -g pm2-windows-startup
npm install -g npm-bundle
npm-bundle pm2
npm-bundle pm2-windows-startup

离线部署Nodejs Express应用

1
2
3
4
5
6
7
@echo off
SET NODE_ENV=production
call npm install .\pm2-2.10.3.tgz -g
call npm install .\pm2-windows-startup-1.0.3.tgz -g
call pm2-startup install
call pm2 start ./bin/www -i 0
call pm2 save

离线卸载Nodejs Express应用

1
2
3
4
5
@echo off
call pm2 stop all
call pm2-startup uninstall
call npm uninstall pm2 -g
call npm uninstall pm2-windows-startup -g

参考链接

  1. Express 应用程序的进程管理器, by Express
  2. npm离线安装全局包,内网安装npm中的包, by 爱死费崇政
  3. What exact command is to install pm2 on offline RHEL, by stackoverflow.
  4. NodeJS: PM2 Startup on Windows,by Walter Accantelli.
  5. bat脚本%cd%和%~dp0获取当前目录区别,by dmfrm

Vue.js集成Highcharts

发表于 2018-05-10 | 更新于 2019-09-03

Vue.js集成Highcharts方法

  1. 安装highcharts
    1
    npm install --save highcharts
  2. 封装hightcharts成Vue.js组件
    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
    <template>
    <div class="highcharts-container">
    </div>
    </template>
    <script>
    import Highcharts from 'highcharts/highstock'
    import HighchartsMore from 'highcharts/highcharts-more'
    import HighchartsDrilldown from 'highcharts/modules/drilldown'
    import Highcharts3D from 'highcharts/highcharts-3d'
    HighchartsMore(Highcharts)
    HighchartsDrilldown(Highcharts)
    Highcharts3D(Highcharts)

    export default {
    props: ['options'],
    name: 'HighCharts',
    data () {
    return {
    chart: null
    }
    },
    watch: {
    options: function (newVal, oldVal) { // watch it
    this.chart.update(newVal, true)
    }
    },
    mounted () {
    this.initChart()
    },
    methods: {
    initChart () {
    this.chart = new Highcharts.Chart(this.$el, this.options)
    }
    }
    }

    </script>
  3. 在src/main.js引入组件
    1
    2
    import HighCharts from './components/HighCharts.vue'
    Vue.component('HighCharts', HighCharts)
  4. 使用组件
    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    <template>
    <div class="radarGraph">
    <HighCharts :options="options" class="radar" ></HighCharts>
    </div>
    </template>
    <script>

    export default {
    name: 'RadarGraph',
    computed: {
    gameInfo () {
    return this.$store.state.gameInfo
    },
    options () {
    return {

    chart: {
    polar: true,
    type: 'line',
    marginTop: 0,
    marginBottom: 0,
    marginLeft: 0,
    marginRight: 0
    },

    credits: {
    enabled: false
    },

    pane: {
    size: '75%'
    },

    title: null,

    legend: {
    enabled: false
    },

    xAxis: {
    categories: ['分类1', '分类2', '分类3', '分类4',
    '分类5', '分类6'
    ],
    labels: {
    style: {
    fontSize: '14px'
    }
    },
    tickmarkPlacement: 'on',
    lineWidth: 0
    },

    yAxis: {
    gridLineInterpolation: 'polygon',
    lineWidth: 0,
    min: 0
    },

    series: [{
    type: 'area',
    name: '得分',
    data: [this.gameInfo.radar1, this.gameInfo.radar2, this.gameInfo.radar3, this.gameInfo.radar4, this.gameInfo.radar5, this.gameInfo.radar6],
    pointPlacement: 'on'
    }]
    }
    },
    ...mapGetters([
    'userId'
    ])
    },
    created () {
    this.fetchData()
    },
    methods: {
    fetchData () {
    this.$store.dispatch('GetGameInfo', this.userId)
    }
    }
    }

    </script>
    参考链接

  1. 在 Vue 中使用 Highcharts,by 简数科技.

Vue.js集成Socket.io

发表于 2018-05-09 | 更新于 2018-06-03

Socket.IO简介

Socket.IO 是一个面向实时 web 应用的 JavaScript 库。它使得服务器和客户端之间实时双向的通信成为可能。他有两个部分:在浏览器中运行的客户端库,和一个面向Node.js的服务端库。两者有着几乎一样的API。像Node.js一样,它也是事件驱动的.

Socket.IO 主要使用WebSocket协议。但是如果需要的话,Socket.io可以回退到几种其它方法,例如Adobe Flash Sockets,JSONP拉取,或是传统的AJAX拉取,[2]并且在同时提供完全相同的接口。尽管它可以被用作WebSocket的包装库,它还是提供了许多其它功能,比如广播至多个套接字,存储与不同客户有关的数据,和异步IO操作。

Vue.js集成Socket.IO

  1. 安装socket.io-client
    1
    npm install --save socket.io-client
  2. 在src/main.js中载入socket.io-client
    1
    2
    3
    import io from 'socket.io-client'
    const socket = io(process.env.BASE_API)
    Object.defineProperty(Vue.prototype, '$socket', { value: socket })
  3. 在Vuejs组件中使用socket.io-client
    1
    this.$socket.on('event',function(e){})
    参考链接

  1. https://zh.wikipedia.org/wiki/Socket.IO, by Wikipedia
  2. https://socket.io/get-started/chat/, by socket.io

PowerDesigner使用经验总结

发表于 2018-05-09 | 更新于 2023-02-10

需求分析

在系统工程及软件工程中,需求分析指的是在创建一个新的或改变一个现存的系统或产品时,确定新系统的目的、范围、定义和功能时所要做的所有工作。需求分析是软件工程中的一个关键过程。在这个过程中,系统分析员和软件工程师确定顾客的需要。只有在确定了这些需要后他们才能够分析和寻求新系统的解决方法。

在软件工程的历史中,很长时间里人们一直认为需求分析是整个软件工程中最简单的一个步骤,但在过去十年中越来越多的人认识到它是整个过程中最关键的一个过程。假如在需求分析时,分析者们未能正确地认识到顾客的需要的话,那么最后的软件实际上不可能达到顾客的需要,或者软体无法在规定的时间里完工。

软件设计

软件设计是从软件需求规格说明书出发,根据需求分析阶段确定的功能设计软件系统的整体结构、划分功能模块、确定每个模块的实现算法以及编写具体的代码,形成软件的具体设计方案。

软件设计是把许多事物和问题抽象起来,并且抽象它们不同的层次和角度。将问题或事物分解并模块化使得解决问题变得容易,分解的越细模块数量也就越多,它的副作用就是使得设计者考虑更多的模块之间耦合度的情况。

UML

统一建模语言(英语:Unified Modeling Language,缩写UML)是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。

这个语言由葛来迪·布区,伊瓦尔·雅各布森与詹姆士·兰宝于1994年至1995年间,在Rational Software公司中开发,于1996年,又进一步发展。UML集成了Booch,OMT和面向对象软件工程的概念,将这些方法融合为单一的,通用的,并且可以广泛使用的建模语言。UML打算成为可以对并发和分布式系统的标准建模语言。

在UML系统开发中有三个主要的模型:

  • 功能模型:从用户的角度展示系统的功能,包括用例图。
  • 静态模型:采用对象,属性,操作,关联等概念展示系统的结构和基础,包括类别图、对象图。
  • 动态模型:展现系统的内部行为。包括序列图,活动图,状态图。)

PowerDesigner工具

PowerDesigner是Sybase的企业建模和设计解决方案,采用模型驱动方法,将业务与IT结合起来,可帮助部署有效的企业体系架构,并为研发生命周期管理提供强大的分析与设计技术。

PowerDesigner独具匠心地将多种标准数据建模技术(UML、业务流程建模以及市场领先的数据建模)集成一体,并与 .NET、WorkSpace、PowerBuilder、Java™、Eclipse 等主流开发平台集成起来,从而为传统的软件开发周期管理提供业务分析和规范的数据库设计解决方案。此外,它支持60多种关系数据库管理系统(RDBMS)/版本[来源请求]。PowerDesigner运行在Microsoft Windows平台上,并提供了Eclipse插件。

PowerDesigner使用经验

遵循UML方法,使用PowerDesigner对系统进行建模。

在需求分析阶段,通常使用用例图、序列图(序列图中主要描述用户与系统之间交互关系)、组合结构图、类图(用于描述组件或类的接口及其调用关系)等UML图描述。

在设计阶段,从架构设计、概要设计到详细设计,粒度由粗到细。

通常架构设计是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。
架构设计通常使用组织结构图、对象图、活动图、状态图等UML图描述。

概要设计就是设计软件的结构,包括组成模块,模块的层次结构,模块的调用关系,每个模块的功能等等。同时,还要设计该项目的应用系统的总体数据结构和数据库结构,即应用系统要存储什么数据,这些数据是什么样的结构,它们之间有什么关系。概要设计从模块角度描述系统,通常使用组合结构图进行描述。

详细设计就是为每个模块完成的功能进行具体的描述,要把功能描述转变为精确的、结构化的过程描述。如采用面向对象的开发方法,详细设计通常使用UML类图描述。

状态图绘制

请参考PowerDesigner16 状态图。

参考链接

  1. 统一建模语言,by wikipedia.
  2. Power Designer 概念数据模型导出 逻辑数据模型和物理数据模型 生成数据库脚本,by 子澈课堂.
  3. PowerDesigner使用教程,by 芝麻软件.
  4. PowerDesigner使用教程-使用PowerDesigner创建应用架构图的,by 常山造纸农.
  5. PowerDesigner使用,by 写程序的小王叔叔.
  6. PowerDesigner16 状态图,by 猪脚踏浪.

Vue.js集成Bootstrap4

发表于 2018-05-09 | 更新于 2019-08-22

记录在Vue.js中集成Bootstrap4的方法,防止忘了!

环境配置

  • vue-cli: 2.x

集成过程

  1. 创建Vue.js工程
    1
    2
    npm install -g vue-cli
    vue init webpack project_name
  2. 安裝 Sass-loader / node-sass
    1
    npm install sass-loader node-sass --save-save
  3. 安裝BootStrap / jQuery / Popper
    1
    npm install bootstrap jquery popper.js --save
  4. 配置build/webpack.base.conf.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    module.exports = {
    ...
    // 新增plugins
    plugins: [
    new webpack.ProvidePlugin({
    '$': "jquery",
    'jQuery': "jquery",
    'Popper': 'popper.js'
    })
    ],
    ...
    }
  5. 在src/main.js中载入Bootstrap
    1
    2
    import 'bootstrap'
    import 'bootstrap/dist/css/bootstrap.css'
  6. 使用Bootstrap和sass编写Vue.js组件

参考链接

  1. Bootstrap Webpack,by bootstrap homepage.
  2. Setup Bootstrap 4 With Vue Cli 3 Webpack,by lua software code.
  3. Adding Bootstrap to a Vue CLI Project,by Travis Horn.
上一页1…515253下一页

Jack Huang

523 日志
67 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse