25 / 08 / 2014 buling

      之前做了一个单机游戏,由于记录的游戏大小是下载器的大小,现在想还原为安装包大小,被迫从excel中解析大小出来,刚开始使用 xlrd模块,在解析某些excel文件时出现:xlrd.compdoc.CompDocError: Workbook corruption: seen[2] == 4错误信息,被迫改为别的方案,当然,最好的方法使用win32com包调用excel提供的开放接口,刚开始还是报错,错误原因没有记录下来,后来搜索得知是安装的office软件有问题,之前安装的是wps,卸载后安装了微软office2010,测试正常,下面对两个模块读取excel的方法做记录

ipmort xlrd
def test_xlrd():
    xfile = 'xxx/1399864038_0.xls'
    xls = xlrd.open_workbook(xfile)
    table = xls.sheets()[0]
    nrow = table.nrows
    for i in range(nrow):
        row = table.row_values(i)
        #print cell 5 value
        print row[5]

如果上面的方法会出错,请选择win32com模块的方法,如下

def test_win32com():
    xfile = 'F:/wamp/www/softadmin/pcmgr_app/python/bin/xxx/1399864038_0.xls'
    xlApp = win32com.client.Dispatch('Excel.Application')
    xlApp.Visible = False
    xls = xlApp.Workbooks.Open(xfile)
    #index from 1
    table = xls.Worksheets(1)
    #get used info
    info = table.UsedRange
    nrows = info.Rows.Count
    for i in range(nrow):
        cell = table.Rows[i].Cells
        #print cell 5 value
        print cell[5].Value
    #close without save
    xls.Close(SaveChanges=0)

o…

无标签信息 0 条

      额,连续第三天中午写blog了,中午大家休息,抽空来更新一下,最近这几天自己学习了很多。一直以来很想学习游戏中地图的加载,物体碰撞的检测等等。前晚睡觉前看了一下园子,有人发了一篇重力小球的文章,就顺便研究了一下,原文地址:HTML5重力感应小球冲撞动画实现教程,当然我接下来要说的这个和原文的不是一个东东,是小球的碰撞检测。
      相对于很多不规则图形来讲,小球的碰撞检测要相对简单很多,稍微学过物理数学就很容易做速度分解,我参考了这篇文章: 碰撞检测算法优化 ,主要是说一下其中的几个点吧
      1、优化算法。文章说的格子优化算法,把屏幕中的小球分为大小相同的N个格子,碰撞检测只检测,每个格子中的小球是否碰撞,和相邻格子是否有碰撞过程,在检测过程中,应该计算:(i,j),(i-1,j-1),(i,j-1),(i-1,j),(i-1,j+1)这四个,而非对应(i,j)的上下左右四个格子,仔细想想就明白了

      2、动画帧使用requestAnimationFrame,如果没有使用settimeout 1000/60,60是指刷新频率,也可以参考:Javascript高性能动画与页面渲染
      3、在写Too类时,当把类的prototype用{}覆盖后,需要设置 Too.prototype.constructor = Too; 其实理论上不设置也不会有任何问题,也不会影响new时候的构造函数,参考文章: Javascript面向对象编程 以及文章 Why is it necessary to set the prototype constructor?
      废话少说,效果图来,测试地址:http://www.mjix.com/code/canvas-ball.html

无标签信息 0 条
21 / 08 / 2014 buling

      以前吧,一直用python来干这种事情,每次为了能加快速度,写一堆线程代码来做并行。这次用nodejs来实现,怕请求过猛,用了一大堆callback来保证同步,唉,差别啊,爬取是异步,入库还是异步,唉,神伤。结果写完了,测试6个页面并行,一会就悲剧了,对方封了我IP,我那个去,好吧,就不纠结了,代码奉上,看着难受就忍一忍,我也没有使用when或者jquery.deferred啥的,两个表我就不贴了
      话说nodejs确实不错,全异步的感觉,和erlang写个循环需要用递归一样的酷。我觉的最好的地方莫过去,当你处理玩业务需要返回,但还有些事情可以在你返回后完成的,譬如,以前入库完成后,需要发个广播消息,如果是PHP,返回前需要先发送广播需要才能结束,但nodejs就不用,示例代码

app.get('/hello/:query', function(req, res){
  console.log(req.params.query);
  res.send('Hello World');
  //页面返回后需要异步处理别的事件
  setTimeout(function(){
    console.log('do some event');
  }, 1000);
});

是不是…,好,下面是爬去代码

var request    = require('request');
var mysql      = require('mysql');
var crypto     = require('crypto');
var __TIMEOUT__ = 10000;
var URL_CONFIG = [
    ['1', 'http://www.juzimi.com/books?page='],
    ['2', 'http://www.juzimi.com/allarticle/%E7%94%B5%E5%BD%B1?page='],
    ['3', 'http://www.juzimi.com/allarticle/%E5%B0%8F%E8%AF%B4?page='],
    ['4', 'http://www.juzimi.com/allarticle/%E6%95%A3%E6%96%87%E9%9A%8F%E7%AC%94?page='],
    ['5', 'http://www.juzimi.com/allarticle/%E5%8A%A8%E6%BC%AB?page='],
    ['6', 'http://www.juzimi.com/lianxujutaici?page='],
    ['7', 'http://www.juzimi.com/allarticle/%E5%8F%A4%E6%96%87?page=']
];
var URL_HOST = 'http://www.juzimi.com';
var Mysql = {
    config : {
        host     : '127.0.0.1',
        user     : 'root',
        password : '123456',
        database : 'nice_quote',
        charset  : 'utf8'
    },
    connect : function(callback){
        var ins = this.getInstance();
        ins.connect(function(err) {
            if(err) {
                return console.error('error connecting: ' + err.stack);
            }
            console.log('connected as id ' + ins.threadId);
            callback();
        });
    },
    getInstance : function(){
        if(!this._ins){
            this._ins = mysql.createConnection(this.config);
        }
        return this._ins;
    }
};
var getCurrentPage = function(body){
    var page = 0;
    body.replace(/
  • (.*?)<\/li>/ig, function(match, cpage){ page = cpage-1; }); return page; }; var saveDirectory = function(type, info, callback){ var db = Mysql.getInstance(), insertId = 0; var post = { type : type, title : info[1], author : info[2], href : info[0] }; db.query('INSERT IGNORE INTO directory SET ?', post, function(err, result) { if(err){ console.error('error connecting: ' + err.stack); } if(result.insertId===0){ //uniq db.query('SELECT * FROM directory WHERE href=?', [post.href], function(err, result) { if(result){ callback(result[0].id); }else{ callback(0); } }); return ; } callback(result.insertId); }); }; var saveWords = function(did, contents, callback){ var db = Mysql.getInstance(), insertId = 0, md5 = '', post = []; contents.forEach(function(info, index){ md5 = crypto.createHash('md5').update(info).digest('hex'); post.push([did, md5, info]); }); var query = db.query('INSERT INTO info (did, md5, content) VALUES ?', [post], function(err, result) { if(err){ console.error('error connecting: ' + err.stack); } callback(result); }); console.log(query.sql); }; var getInfo = function(url, page, callback){ url += page; console.log(url); request.get({ url : url, timeout : __TIMEOUT__ }, function(error, response, body){ if(!response || !response.statusCode){ callback(-1); return console.log('error:'+error.stack); } if(response.statusCode != 200){ callback(-2); return console.log(response.statusCode); } var cpage = getCurrentPage(body), flag = cpage==page; if(!flag){ //不对的页面 return callback(false); } var rets = []; body.replace(/class=\"xlistju\">([.\s\S]*?)<\/a>/ig, function(match, content){ rets.push(content); }); callback(rets); }); }; /** * //for test * var url = 'http://www.juzimi.com/article/54933?page='; * allInfo(url, 0, function(){ * console.log(url+'-----over!'); * }); */ var allInfo = function(id, url, page, callback){ getInfo(url, page, function(content){ if(content){ if(content==-1){ return allInfo(id, url, page, callback); }else if(content==-2){ callback(); return console.log('error:-1'); } console.log(content); saveWords(id, content, function(){ allInfo(id, url, ++page, callback); }); }else{ //完成 callback(); } }); }; var getList = function(url, page, callback){ //<<<<<<<<<<<<<<<<<<<<<<<<< //if(page>0) return callback(false); url = url + page; request.get({ url : url, timeout : __TIMEOUT__ }, function(error, response, body){ if(!response || !response.statusCode){ callback(-1); return console.log('error:'+error.stack); } if(response.statusCode != 200){ callback(-2); return console.log(response.statusCode); } var cpage = getCurrentPage(body), flag = cpage==page; //console.log(page+'__'+cpage+'__'+flag); if(!flag){ //不对的页面 return callback(false); } var rets = []; body.replace(/\"views-field-tid\">[\s\S]*?(.*?)<\/a>.*?(.*?)<\/a>/ig, function(match, href, bookname, author){ if(author == '喜欢'){ author = ''; } rets.push([href, bookname, author]); }); callback(rets); }); }; var allPages = function(type, list, index, callback){ if(index>=list.length){ return callback(); } var info = list[index]; console.log(type+'__'+info[0] + '__'+info[1]+'__'+info[2]); saveDirectory(type, info, function(id){ allInfo(id, URL_HOST+info[0]+'?page=', 0, function(){ allPages(type, list, ++index, callback); }); }); }; var allList = function(type, url, page, callback){ console.log('curl:['+type+']'+url+page); getList(url, page, function(list){ if(!list){//over return callback(); } if(list==-1){ return allList(type, url, page, callback); }else if(list==-2){ //404 callback(); return console.log('error:-1'); } allPages(type, list, 0, function(){ allList(type, url, ++page, callback); }); }); }; var allSite = function(index){ if(index>=URL_CONFIG.length){ return ; } var info = URL_CONFIG[index]; allList(info[0], info[1], 0, function(){ allSite(++index); }); }; //allSite(0); Mysql.connect(function(){ URL_CONFIG.forEach(function(info, index){ allSite(index); }); // Mysql.getInstance().end(function(err) { // console.log('end mysql!'); // }); });
  •       一看上一篇文章的时间,唉,这就是tx的工作节奏,过去1年基本没有太多需要记录的东西,做了很多运营后台的事情,以及在软件管理V3页面上的优化工作。最近事情稍少一些,闲来学习一下。想想从毕业到现在,刚开始PHP,然后觉得后端很神奇,果断进入后端学习,python做server开发,后来进tx,以前端开发进入,刚开始想在cgi和后端c++上有所成,后觉升级很重要,走专业方向,死攻前端。今年开始尝试了很多前端解决方案,grunt, backbone, seajs, requirejs, nodejs, express等等,这方面还是steve(小碗)牛,也学到了不少。
          由于之前这个岗位在开发中除了使用了extjs,其它方面没有什么特别的积累,所以基本全靠自己摸索学习,从软件管理V3上线,到现在的软件管理,总共修改了很多次,css sprite, grunt, uglify, jshint, cssmin, concat, seajs; js代码基本模块化为多个;由于CSS代码的加载会影响页面呈现,公司的CDN有些问题,所以直接生成在页面中,js的加载也会影响用户的操作,后来真想去jquery,时间问题,最后还是放弃了,现在最新版本,js和首页直接存客户端本地,这样客户端首页就能即刻呈现。
          前不久做了一个微信页面的动画,当时时间很紧急,由于设计给的页面大小不一致没有办法做翻页效果,随意最后的动画也不是很明显,使用了animate.css动画框架,有兴趣自行google或axx;效果地址:http://www.mjix.com/wp-code/wechat/ 相比而言,iphone效果/体验优于android很多。
          最近也在常识sass,编写css代码确实有很多好处,和less、stylus相比,我还是倾向于sass,虽然stylus也是一个不错的选择。sass使用$命名变量,对于phper/jqueryer来说自然比较习惯,再加之混入使用 @mixin声明更明了,在css嵌套中,sass的做法币less好,具体可以查看这篇文章 http://www.oschina.net/question/12_44255
    给一段示例代码

    $dred : darken(#f00, 10%);
    $green : #ff0;
    @mixin test($border:2px){
        border : $border $dred solid;
    }
    .base{position: absolute; top:0; left:0;}
    .test{
        @extend .base;
        @include test(1px);
        background:#ccc;
        .hi{
            color : $green
        }
        $:hover{
            font-weight: bold;
        }
    }
    

    安装一个sass的grunt模块

    grunt.loadNpmTasks('grunt-contrib-sass');
    //建一个sass任务
    sass : {
        dist : {
            options : {
                style : 'expanded'
            },
            files : {
                'sass/test.css' : 'sass/test.scss'
            }
        }
    },
    //建一个watch任务
    watch: {
        files: ['sass/*.scss'],
        tasks: ['sass'],
        options: {
            debounceDelay: 500
        }
    }
    

          其实以前我比较讨厌各种自定义语言,主要是增加学习成本,又不能提升自身对native的学习,当在对这些语言css/js/html等了解的比较熟练的情况下,使用这样的自定义语言可以提高效率,减小维护成本,比如最近看express的jade,这货像python一样的写html。
          之前为了js代码模块化,使用seajs来做开发,其实早在500的时候做配置中心就使用了seajs,但从来没有了解过为何seajs就造出来了还这么流行,最近在infoq上看到一篇文章,里面阐述了seajs和requirejs的区别,文章中引用这里的讨论 http://www.douban.com/note/283566440/ 后来我又看了一个类requirejs的源码,忘了名字了,其实也不复杂。
          backbone,默认需要underscore依赖,那还得去了解一下underscore吧,underscore提供了大量的常用方法,但在一个项目中也不会使用太多,具体可以查询官网API,源码也值得阅读。backbone很适合做单页面的js框架,以前在500的配置中心也是使用了单页面形式,那个时候还没有时间学习backbone,使用hashchange加seajs实现。学习backbone,这确实是一篇不错的教程 https://github.com/the5fire/backbonejs-learning-note
          打开淘宝首页,按F12,查看console栏,它告诉你了一个前端应该了解的大部分技能,如果还有没听过的,那就赶紧。

    无标签信息 0 条