毕设中学习Python的一些笔记

控制台输出中文

文件首设置了#coding: utf-8后,输出字符串能够正常地显示中文了,但是直接print一个list或则 dict的时候,出现中文的地方都会变成u'\u81ea\u52a8'之类的编码文字,因为打印的是一个对象, 实质上相当于print repr(dict.items()),使用json.dumps(dict, encoding="utf-8", ensure_ascii=False) 就好了

UDP和TCP

原理 Py实例

struct 二进制处理相关

有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用 python的struct模块来完成.可以用 struct来处理c语言中的结构体.

pack(fmt, v1, v2 ... )

按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)

unpack(fmt, string)

按照给定的格式(fmt),返回解析出来的tuple

calcsize(fmt)

计算给定的格式(fmt)占用多少字节的内存

fmt的格式说明

点击查看

以二进制的方式读取文件

#coding: UTF-8
fileData = open('./sample.dat', 'rb')

读取文件的前4个字节,将读取的4个字节转换为long

data_id = struct.unpack("l", fileData.read(4))
print data_id

二进制文件的输出

在shell中,直接print二进制文件的string格式会导致乱码,先转换成hex的形式再输出就 好了。print data.encode('hex_codec')print repr(data)则会输出原始字符串。它的 输出相当于VIM里面:%!xxd之后,中间列的hex值加上右边列的文字值,即有的时候会出现 x0fB@这样的值
注:socket.recvfrom(1024)会返回(data,ip)格式的Tuple,其中data是字符串格式的,这 就是我二进制文件的string格式的由来

ord 和 chr 和 repr

Python提供了ord{转换成ASCII}和chr{转换成字符串}两个内置的函数,用于字符与ASCII码 之间的转换。
str()一般是将数值转成字符串,所以直接输出二进制的字符串表示是乱码
repr()是将一个对象转成字符串显示,注意只是显示用,有些对象转成字符串没有直接的意 思。如list,dict使用str()是无效的,但使用repr可以,这是为了看它们都有哪些值,为了 显示之用。

int转换为整数

int(12.0) //12int('12',16)//按16进制数转换成十进制数

python多线程编程

使用thread模块

thread.start_new(fn, (arg1,) [,kwargs=None])需要注意的是(data,)是显示申明元组 类型,其第一个变量是data,与表达式()区分开来,否则Python无法知道是不是变量data 的值。
线程的结束可以等待其自然结束,也可以调用thread.exit()/thread.exit_thread()来结束 也可以通过实现threading.Thread的子类来实现一个线程对象,详见

使用xml.etree.ElementTree读写xml

查找节点

Element.getiteratorElement.getchildrenElement.findElement.findall

python连接MySQL

使用MySQLdb来与数据库进行通信APIMySQL建表操作API数据类型

用到的awk指令 awk -F '\t' '$3!="" {print FNR,$3,$4}' ato_f.lst > awk.lst 用到的自动添加分类序号的方法:

#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
    current = "g"
}
#运行中
{
    if( $1 == current ){
        math++
    }else{
        current = $1
        math = 0
    }
    printf "%s%d %s %s\n", $1,math, $2, $3
}
#运行后
END {
}

含有自增字段插入时注意问题

SQL语句的写法应该把除了自增列外的其他对应数据列罗列出来,如下面的形式: INSERT INTO 表名(列名1,列名2,列名3......) VALUES(值1,值2,值3........) 或者 INSERT INTO 表名(列名1,列名2,列名3......) SELECT 值1,值2,值3........ FROM 表名 如果用下面的形式(不带除了字增列外的其他对应数据列)进行插入: INSERT INTO 表名 VALUES(值1,值2,值3........) 或者INSERT INTO 表名 SELECT 值1,值2,值3........ FROM 表名 ,就会出现提示的错误:Column count doesn't match value count at row 1

MySQL设置utf8编码

创建数据库UTF8: CREATE DATABASEtest2DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
创建数据表CREATE TABLE test( ... )ENGINE=MyISAM DEFAULT CHARSET=utf8;

python MySQL存放中文字段

使用"','".join(LIST)来封装成字符串的形式,而不是repr或者str之后的结果,因为那 些方法输出的都是已经转码之后的中文,即本来输出的车头主系变成了u'\u8f66\u5934\u4e3b\u7cfb' 相当于insert into test values(..., u'\u8f66\u5934\u4e3b\u7cfb',...),想要通过这个 语句插入中文显然是错误的,应该是insert into test values(...,'车头主系',...) 总结:传入给cursor.execute()的应该是原始字符串,而不是python表示的字符串

sys模块的setdefaultencoding方法

这个方法可以设定python的默认编码是ascii还是utf-8,直接import sys过来居然找不到 这个方法,但是reload(sys)之后就有了

Python切片

切片指的是抽取序列的一部分,其形式为:list[start:end:step]。默认值为start0,end元素个数 (即为最后一个元素n-1后的序号n:包括最后一个元素),step为1,实例说话:

[1, 2, 3, 4, 5][::2]  # [1, 3, 5]
[1, 2, 3, 4, 5][:-1:2]  # [1, 3]
[2013-03-25]

SSH的一些配置

参考配置

建立Alias

例如想要通过ssh vps来实际执行ssh wy@hellofe.com,则在~/.ssh/config文件中,加入以下配置

Host vps
    HostName hellofe.com
    User wy
    Port 1014

注意:需要chmod ~/.ssh/*将所有文件都变成600的模式才能正常执行

避免每次都输入密码

1 用ssh-keygen命令生成private/public密钥对,提示问题都用默认回答即可。(.ssh/idrsa为私有 密钥,.ssh/idrsa.pub为公有密钥,这在github上也用到过) 2 用ssh-copy-id命令把公钥复制到远程主机上ssh-cody-id -i /root/.ssh/id_rsa.pub user@remotehost 这样下次再ssh到该主机上时,就不用输入密码了。(这里居然直接将idrsa私钥上传也可以实现无密码登录..) (**需要chmod600 authorizedkeys**才能生效)

[2013-03-23]

修改Gnome窗口标题高度 + fedora18更新后要点

按住alt+F2输入r就可以完成Gnome界面重启

本来是想用yum安装node的,结果发现fedora18发布了,而且从17更新过去非常便捷,只需要 sudo fedup --network 18就可以了,用上了fedora18之后,发现原来设置的窗口最大化时自动隐藏 标题栏的功能没有了,google了一下找到解决方法:

修改对应的主题文件

默认的是:/usr/share/themes/Adwaita/metacity-1/metacity-theme-3.xml

将标题栏填充高度设置为0

找到所有的title_vertical_pad value="0~9"改成value="0"这样标题栏看上去就没那么高了

设置最大化时隐藏标题栏

找到

<frame_geometry name=”max” title_scale=”medium” parent=”normal” 
rounded_top_left=”false” rounded_top_right=”false”>

改成

<frame_geometry name=”max” title_scale=”medium” parent=”normal” 
rounded_top_left=”false” rounded_top_right=”false” has_title=”false”>

并且在下面几行中找到<distance name=”title_vertical_pad” value=”9″/>,将value改成0即可

最终设置

仅仅隐藏标题栏会导致残留,索性把填充高度也去掉了,这样窗口标题栏看起来要窄一些,但效果还不错

参考

Fedora 16的Gnome3个人配置笔记[3月7日更新]

fedora18更新后注意事项

防火墙不再是iptables

因此我的主机的web服务就无法被访问了,删除掉防火墙就好了sudo yum remove firewalld

[2013-03-19]

Node Web开发

前言

图书馆里来了两本关于Node.js的新书,于是果断借过来看了一下,《Node.js开发指南》是国人编著的, 因此和《Node Web开发》有很多类似的内容,索性将两者的读书笔记写在一起好了

Node的优势

Node应用高性能的关键是要快速返回事件循环,确保服务器的利用率
Node不适合计算密集型的程序,单用户多任务型应用,逻辑十分复杂的事务,Unicode和国际化

Node服务器一直运行的原理

http.createServer().listen()创建了一个实现HTTP协议的事件监听器,会使当前脚本一直处于执行 状态,所以node进程不会退出

Node模块

模块名就是一个没有文件后缀.js的路径名,Node也支持.node后缀的二进制原生语言库

Node模块的加载

Node.js的模块可以分为两大类,一类是核心模块,一类是文件模块。

核心模块

是Node.js标准API中提供的模块,如fshttpnet等,这些都已经编译成两二进制代码,拥有 最高的加载优先级

文件模块

存储为单独的文件(文件夹),Node.js会分别试图加上.js,.json,.node扩展名

加载顺序

  1. 如果是核心模块,直接加载
  2. 如果是以/ ./ ../等开头的,按路径加载查找相应的模块
  3. 查找当前目录和父级目录的node_modules文件夹下相应的模块,直至找到为止

也就是说我有一个hello的包,可以将其放在node_modules/文件夹下,通过require('hello') 来加载,也可以直接放在当前目录下,通过require('./hello')来加载,效果是一样的

Node.js包

Node.js包是一个目录,包含一个JSON格式的包说明文件package.json,具有以下特性

  • ./package.json [必须的,其余都是推荐的]
  • ./bin/下面存放二进制文件
  • ./lib/下面存放js文件
  • ./doc/下面存放文档
  • ./test/下面存放单元测试

实例:创建hello目录,并且在hello/lib/interface.js中写入

module.exports = function(){ 
  console.log("hello world!") 
}

然后,在hello/package.json中写入

{
  "main": "./lib/interface.js"
}

这样,就可以在与hello同级的目录中,调用require('./hello')来加载hello/lib/interface.js 这个模块了,注意,这里./hello中的./必须要加,否则应该将hello模块放到node_modules文件夹下

npm包管理器

获取npm的帮助

npm help <cmd>

查看包信息

一个npm包是包含了package.json(描述这个文件夹的结构)的文件夹,npm view <pkg> 可以查看该模块的package.json信息,可以通过npm help json来查看帮助文档。
[tips:今天发现直接npm view package无效,会报错,后来发现sudo下是可以的,但是请求了不同的 ip,于是想到是不是曾经配置过npm的repo,果然在.npmrc下面,registy='xxxx'设置过了,果断改之]

安装包

npm install会将模块安装在.node_module/路径下,npm install -g会统一安装在核node的 安装位置相关的位置

列出已安装的包

npm list查看当前目录和父级目录中安装的module,--global列出-g方式安装的module, --long显示扩展信息,--parseable显示可解析的完整路径而不是树状图

查看修改包内容

npm explore package会创建一个shell,并进入package对应的目录,可以对其进行修改,然后 npm rebuild package来使更改生效

更新包内容

npm outdated [-g]会列出可以更新的包,再调用npm update <pkg>就可以了

卸载

npm uninstall [-g]

开发npm包

npm init初始化

npm link设置一个链接到源文件目录的符号链接,可以自由编辑源文件而不需要npm rebuild <pkg>

才生效,其使用分两个步骤

  1. 将开发项目链接到node安装程序上,在项目根目录执行npm link
  2. 将开发项目链接到应用中 npm link <mod>

npm publish就发布到npmjs.org上去了

npm的配置

  1. 通过npm confignpm set/get在命令行中设定
  2. NPM_CONFIG_开头的环境变量来设定
  3. 配置文件:~/.npmrc或者<NODE_INSTALL_DIR>/etc/npmrc来设定
[2013-03-19]

学习SeaJS的一些笔记

实用资源

实例解析SeaJS内部执行过程

SeaJS是什么?模块的加载启动

SeaJS 是一个模块加载器,模块加载器需要实现两个基本功能:

  1. 实现模块定义规范,这是模块系统的基础。
  2. 模块系统的启动与运行。

1. 模块定义规范的实现

这就是 definerequireexportsmodule 的实现。具体实现细节,有兴趣的可以看 SeaJS 的源码:seajs/src。可以按照 build.xml 中声明的合并顺序阅读,核心是 module.js 文件。

2. 模块系统的启动 / 使用

//id = "seajsnode" 有助于sea.js直接确定自身路径,提升效率
<script src="path/to/sea.js" id="seajsnode"></script>
<script>
  //类似于node main.js, 执行main.js中的全部代码
  seajs.use('./main');
  //加载完后执行回调函数
  seajs.use('./main', function(main){
    //@param {Object} main - main.js中exports出来的对象,
  })
  /**
   *@param {Array} [] -- jquery是在config.js中定义的alias,指定了jQuery的位置
   *@desc:回调函数会在所有加载的文件都执行完毕之后再执行
   */
  seajs.use(['jquery', './main'], function($, main) {
    $(function() {
      main.init();
    });
  });
</script>

简便的调用方式

当seajs.use只加载一个模块,且没有回调函数的时候,可以通过在引入sea.js文件的同时,通过对应的 attribute来引入,data-config相当于加载其配置文件,配置文件中用seajs.config()来金喜配置 data-main加载模块文件,如下所示:

<script src="static/seajs/sea.js?t=20130306"
        data-config="test/config.js?20130306"
        data-main="test/main.js?20130306"></script>

通过引入sea.js文件,同时提供sea.js的配置文件和使用文件(在该文件内使用seajs加载模块)即可。 其路径为:sea.js文件的父目录——seajs目录的位置,也就是说,seajs/sea.js与test是同级别的。

SeaJS API

配置:seajs.config()

  //基本的alise,用于加载符合cmd规范的模块
  alias: {
    'es5-safe': 'gallery/es5-safe/0.9.3/es5-safe',
    'json': 'gallery/json/1.0.2/json',
    'jquery': 'lib/jquery-1.9.1.min.js'
  },
  plugin: ['shim'],
  //使用shim插件来将现成代码转换成CMD规范
  alias: {
    /*将jquery对应到相应的文件路径,使seajs.use('jquery') == seajs.use('lib/jquery-1.9.1.min.js')*/
    'jquery': 
     {/*shim object, src {String}源文件路径, deps {Array}指定模块依赖, 
     exports {String|Function}表示require时该返回哪个全局变量或者函数:jQuery.noConflict()*/
      src: 'lib/jquery-1.9.1.min.js',
      /*指定导出该脚本中的变量jQuery,作为参数传入到seajs.use的callback中去,
        相当于手动将脚本封装在define()中,并且module.exports=jQuery的写法*/
      exports: 'jQuery'
    }
  }

注意:seajs.config()不能和define写在一起:

  • 配置文件应该独立出来
  • seajs.config()貌似是一个同步函数,也就是说只有当前脚本执行完毕之后才会正式的执行
  • 它的原理更接近于setTimeout(function(){},0),所以任何在同一个文件之后,直接require()通 过seajs.config()设定的alias都是无效的。

加载(通过define()定义的)模块:seajs.use()

seajs.use 理论上只用于加载启动不应该出现在 define 中的模块代码里。在模块代 码里需要异步加载其他模块时,可以使用 require.async 方法。

定义模块:define()

/**
 *@desc -- define()会自动传入三个变量
 *@param {Function} require -- 通过这个函数获取指定模块的接口
 *@param {Object} exports -- 通过这个对象来对外提供接口
 *@param {Object} module -- 通过module.exports对象来提供对外接口
 *                      .
 */
define(function(require, exports, module) {
  // 模块代码
  var a = require('./a'); 
  //exports是module.exports的一个引用,只能通过赋值来添加
  exports.foo = 'bar';
  //module.exports支持覆盖赋值
  module.exports = {
    foo: 'bar';
  }
});

获取指定模块的接口:require()

define(function(require) {

  // 获取模块 a 的接口,在文件a.js里面exports出来的所有方法被赋值作为一个对象返回
  var a = require('./a'); 

  // 调用模块 a 的方法
  a.doSomething();
});

它和seajs.use()的不同主要在于后者用于加载启动,它用与在define()中加载文件

在模块内部对外提供接口:exports() / modlue.exports() 区别 / CMD规范

define(function(require, exports, module){

  // 对外提供 foo 属性
  exports.foo = 'bar';

  // 对外提供 doSomething 方法
  exports.doSomething = function() {};
})

require()的路径

不加任何前缀,表示的是在baseurl的基础之上查找,baseurl为seajs/目录所处的pathname, 比如blog.hellofe.com/asset/,加上"./",表示的是当前代码文件所处的目录,与seajs无关。 与默认的无任何前缀表示当前目录不同

[2013-03-15]

SVG和CANVAS的一些比较

昨天去群核公司面试,做的是一个SVG技术相关的插件raphaeljs的应用

全文参考

SVG是什么?

SVG 是一种使用 XML 描述 2D 图形的语言。
SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。 在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。

CANVAS是什么?

Canvas 通过 JavaScript 来绘制 2D 图形。
Canvas 是逐像素进行渲染的。在 canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。 如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

两者的比较

SVG特点

  • 不依赖分辨率
  • 支持事件处理器
  • 最适合带有大型渲染区域的应用程序(比如谷歌地图)
  • 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
  • 不适合游戏应用

SVG应用场景

Canvas特点

  • 依赖分辨率
  • 不支持事件处理器
  • 弱的文本渲染能力
  • 能够以 .png 或 .jpg 格式保存结果图像
  • 最适合图像密集型的游戏,其中的许多对象会被频繁重绘

Canvas应用场景

  • 一些demo
  • 高效能(滤镜,光源追踪程序)
  • 非交互即时资料输出
  • 复杂场景,即时运算动画
  • 视讯剪辑
[2013-03-11]

CSS3中word-wrap, word-break和white-space设定对排版的影响

word-wrap

  • normal -- 超长的英文长度大于box的宽度时会撑破box伸展到box外
  • break-word -- 超长英文大于box的宽度时,其碰到box边缘会自动折行显示 [截断英文单词需要下面的word-break属性]

word-break

  • normal -- word-break取值为normal时,和word-wrap值为normal一样的效果,超长英文文本宽度大于box的宽度时会撑破box伸展出去
  • break-all -- 可以强行截断英文单词,达到词内换行效果
  • keep-all -- 不允许字断开

实际应用中

最好是行内换行而不应该是词内换行, //对单词换行 word-wrap:break-word; overflow:hidden;

white-space

  • normal -- 默认:空白处会被浏览器忽略
  • pre -- 空白处会被浏览器保留,类似于<pre>,不会进行自然换行
  • nowrap -- 不换行,除非碰到<br/>
  • pre-line -- 合并空白符序列,但保留换行符<cr>,相当于在pre的基础上合并空格
  • pre-wrap -- 相当于pre,但是会进行自然换行
  • inherit
[2013-03-07]

配置Intellij中碰到的一些问题

IDEA自动去掉行尾的空格

这个功能本来挺好的,但是在写Markdown的时候,行尾的空格是有作用的,Strip trailing spaces关键字打进去都找不到相关的配置项,最后是通过save 找到的,Editor里面的other里面Strip trailing spaces on Save:[None/ALL/Modefied lines]

IDEA设置自动编译less文件

参考
安装LESS CSS Complier插件,并且在设置选项中的LESS Profiles一项设置好要编译的目录和 编译好之后的目标文件夹(可以选择是否压缩),这样下次在自动保存相应目录下面的.less文件的时候,就 会自动编译到对应的目录中去,非常方便。在底部左侧可以看到LESS CSS Complier的输出信息。

[2013-03-07]

深入浅出CoffeeScript

深入浅出CoffeeScript是一本相当全面的书

里面不但对CoffeeScript的介绍非常详细,而且对JS的介绍也很深入透彻

[2013-03-07]

响应式Web设计

重置样式,rest.css

针对html4:Eric MeyerReset.cssv2.0
针对html5:normallize.css
目前使用的:Twitter的reset.less

媒体查询

按条件加载

<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width: 800px), projection" href="800wide-portrate-screen.css" />

可供媒体查询检测的特性:width/height/device-width/device-height/orientation/aspect-ratio/device-aspect-ratio/color/resolution/ 上述特性都可以加min/max进行修饰

在css文件中判断

@media screen and (max-width: 500px){}

写在其内的css仅当满足条件的时候才会生效

用em替换px

默认文字大小1em=16px;

实现无障碍站点:添加role属性

-application 定义网页应用 -banner 定义一个站点级别的区域,如头部和logo -complementary 对页面主要区域进行补充说明的区域 -contentinfo 定义页面主要内容相关的信息区域,如页脚的网站版权信息区域 -form -main 定义页面的主体内容 -navigation 定义导航链接 -search 定义一个用于搜索的区域

快速而有效的CSS技巧

多栏布局-webkit-column-width: xxem; //指定每一栏的宽度,内容会分栏显示 -webkit-column-gap: xxem; //分栏间隙 -webkit-column-rule: //分栏样式 详细的配置还有很多很多

CSS3中新增加的选择器

/*属性选择器*/
img[alt^='value'] //具有alt属性,且以value开头
img[alt*='value'] //具有alt属性,且包含value
img[alt$='value'] //具有alt属性,且以value结尾
/*伪类选择器(自身),和js中的firstChild不同(孩子节点)*/
li:first-child    //第一个li元素 
li:last-child     //最后一个li元素
li:nth-child(*)   //*:even/odd/X/Xn+x/【从1开始计数】
li.test:nth-of-type(*) //选择符合条件的类名为test的列表项
li:not(.test)     //选择不是test类名的li
/* 伪元素 使用::来和伪类区分 */
li::first-line
li::first-letter

RGBA和HSLA来设定颜色

  • 使用RGBA可以#不改变子元素的opacity#,而直接设置opacity的话,会使其子元素也透明
  • HSL(360色环中的一个分布,饱和度,亮度)
[2013-03-07]

开发本博客中碰到的一些问题

若干个a标签直接连在一起并且设置了float之后会导致全部选中问题

link 文字内部加上空格,就可以解决

开发过程中发现对nav元素(header的第一个子元素)设置的margin-top会撑开header的margin-top

一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠。

而我的header也正是没有设置padding-top和border-top,原来如此,怪不得在nav之前加个其他元素再设置margin-top就不会这样了
参看这篇博文不要告诉我你懂margin

代码的高亮功能

  • 采用了google-code-pretty这一js脚本,调用prettyPrint()来实现
  • 原理:<pre/code class="prettyprint linenums">或者<?prettify?>加在MarkDown的代码之前, 生成一个<!--?prettify?-->的注释。遗憾的是在我这里不行,为啥?因为我的markdown解析引擎自动 的在代码块外生成了<div class="highlight"><pre><code></code></pre></div>这个hightlight 的wrap块,导致在md文件中写<??>的方式不行而且现在的md parse engine连<??>都无法解析为注释
  • 最终解决方案:通过js,找出具有pre\>code结构的code,加上'prettyprint linenums'的className
  • linenums默认为5行显示一次,那是因为pretty.css里面将每四个的list-style都设置为了none,改成decimal就好了

代码缩进的问题(3.15)

自从加上两google-code-pretty之后,就对网站的代码高亮寄予了很大的期望,坑爹的是,今天发现写 的code居然无法缩进?一开始还以为是我的markdown parse engine又出了问题,然后转到天外 天blog看了下,发现它没啥问题啊,晕倒。最后才想到,会不会是引用了别的网站的code的样式表的缘故, 果然,white-space: pre-line;自动去掉了空格,改成white-space: pre;就OK了

本地无page.path变量的解决(6.24)

考虑到开发一个博客到github编辑页面的插件,了解每篇文章的文件路径是很重要的,查阅了jekyll帮助文档发现可以从_posts/Tips/2013-3-3-develop-this-blog.md中获得某文件的路径信息,但是在本地的测试环境中,并没有该变量。stack overflow上提到的写一个jekyll扩展来实现,于是在_plugins/path.rb文件中加入了相应的代码,测了一下,本地果然可以了。但是github pages是不支持plugin的,经过测试,page.path变量在部署到github上的文件中是可以访问的!

总结:github pages上的jekyll环境并不是原生的jekyll程序环境,前者不支持插件扩展,但是默认提供了一些额外的功能,比如获取文件路径的变量page.path

[2013-03-03]