月度存档: 四月 2011

面试感想(一)

不错不错,今天面完回想一下还是有很多可以改进的地方的。主要是两点:
1. 针对简历巩固知识。
比如今天被问到lucene的搜索过程,居然在merge那一块说不上来了,囧,当时可是看了很久的。
2. 话题要往长处引啊,并备好些说辞,今天是total 失败。不过裸面嘛,自我原谅了!

去除冗余css

话说前端果然是不行啊。。总是被要求抄某个网站的样式什么的,于是总会发现css多了好多,一条条的去除又太麻烦了。于是昨天抽空写了个脚本来处理,现在还很简陋,输入一个html,一个css文件,把css中有用的标出来写入另一个文件。本来还想再处理一下代码,不过要出去玩了,就先丢上来吧。大致的思路是分别解析css文件和html文件,再遍历html节点,和css规则相匹配。

#!/usr/bin/python
#encoding:utf8

import re
import copy
import BeautifulSoup as bs

html_file_name = 'result.html'
css_file_name = 'mobile.css'
class css_rule:

    selecters = []
    raw = ''
    style = ''

    def __init__(self, selecters, raw, style):
        self.selecters = selecters
        self.raw = raw
        self.style = style

def print_css(css_rule):
    if css_rule['used'] > 0:
        for attr in ['selecters', 'raw', 'style']:
            print "%s : %s \n" % (attr, getattr(css_rule['rule'], attr))
        print "used : %d" % css_rule['used']

class html_tag:

    myclass = ''
    name = ''
    myid = ''

    def __init__(self, myclass, name, myid):
        self.myclass = myclass
        self.name = name
        self.myid = myid

def walk_html(tag):
    if not isinstance(tag, bs.NavigableString):
        yield tag
        for i in tag.contents:
            for tmp in walk_html(i):
                yield tmp

def get_format_node(tag):
    return html_tag(tag.get('class', ''), tag.name, tag.get('id', ''))

def rule_match(format_nodes, selecters):
    if not selecters:
        return True
    if not format_nodes:
        return False
    n = format_nodes.pop(0)
    s = selecters.pop(-1)

    if node_match_selecter(n, s):
        return rule_match(format_nodes, selecters)
    else:
        selecters.append(s)
        return rule_match(format_nodes, selecters)

def node_match_selecter(node, selecter):
    name = re.findall('^(\w*)', selecter)
    if name:name = name[0]
    if name and name != node.name:
        return False

    class_name = re.findall('\.([\w]+)', selecter)
    if class_name: class_name = class_name[0]
    if class_name and class_name not in node.myclass.split(' '):
            return False

    id_name = re.findall('#([\w]+)', selecter)
    if id_name: id_name = id_name[0]
    if id_name and id_name != node.myid:
            return False

    return True

def print_node(node):
    for attr in ['myclass', 'myid', 'name']:
        print "%s : %s \n" % (attr, getattr(node, attr))

css_list = []
with open(css_file_name) as css_file:
    css_content = re.sub('/\*[\d\D]+?\*\/', '', css_file.read().lower())
    css_re = re.compile('([\d\D]+?)\{([\d\D]+?)\}')
    for (selecter, style) in css_re.findall(css_content):
        selecter = re.sub('[\n\t]', '', selecter)
        style = re.sub('[\n\t]', '', style)

        selecter = re.sub('\s*,\s*', ',', selecter)
        parent_list = selecter.split(' ')
        #print parent_list
        last = parent_list.pop(-1)
        #print last
        selecter_list = last.split(',')
        #print selecter_list
        map(lambda x:re.sub('[\n\t ]', '', x), selecter_list)

        for a_selecter in selecter_list:
            #if ':' in a_selecter:
            #    (se, st) = a_selecter.split(':')
            #else:
            #    se = a_selecter
            #    st = ''
            nodes = copy.copy(parent_list)
            nodes.append(a_selecter)
            c = css_rule(nodes, "%s{%s}" % (selecter, style), style)
            css_list.append({'rule' : c, 'used' : 0})

with open(html_file_name) as html_file:
    soup = bs.BeautifulSoup(html_file.read().replace('\n', '').lower())
    body = soup.body

    for i in walk_html(body):
        #print i.name, "finished! \n"
        format_nodes = [get_format_node(k) for k in i.findParents() if k.name not in ['html', '[document]']]
        format_nodes.insert(0, get_format_node(i))

        for rule in css_list:
            tmp_rule = copy.deepcopy(rule['rule'].selecters)
            tmp_nodes = copy.deepcopy(format_nodes)
            if rule_match(tmp_nodes, tmp_rule):
                rule['used'] += 1

#map(print_css, css_list)
aaa = open('processed.css', 'w')
for rule in css_list:
    if rule['used'] > 0 :
        aaa.write(rule['rule'].raw + '\n')

aaa.close()

在遍历html树时用了yield,注意下递归时yield的用法,http://www.iteye.com/topic/338111。代码就是随手写写,有些命名规则什么的实在是很囧,要是以后想做成一个成熟的项目的话还得再完善下。

有一个bug:css规则我不是很熟,只考虑了如selecter1 selecter2,selecter3这种用法,试了下后发现样式漏掉了一点,检查后原来css可以这么写selecter1 selecter2,selecter3 selecter4,fix起来也简单,逻辑没有问题就好说了。还有点小问题,比如现在只能匹配一个html文件(这改起来很方便),写入css文件后会有冗余(每行一个规则,再去除一下即可)。

然后用不会用gdb,pdb真是坑爹啊,还是得学,为了debug下专门开eclipse,好麻烦,然后写代码还坑爹,编辑效率太低了。

tmux配置

最近实在是受不了曹楼的网络了,远程到服务器上开服务总是因为网络断开,不过上次用screen又实在觉得不好用,这次试试tmux,发现还不错,发个配置文件,不知道的看 这里。参考了这里,再结合自己的习惯修改了下。


set-option -g prefix C-a
unbind-key C-b
bind-key C-a send-prefix
setw -g mode-keys vi
setw -g xterm-keys on
unbind %
bind | split-window -h
bind h split-window -h
unbind '"'
bind - split-window -v
bind v split-window -v
set-option -g visual-activity on
setw -g monitor-activity on
setw -g automatic-rename off
setw -g utf8 on
set -g base-index 1
set -g terminal-overrides "*88col*:colors=88,*256col*:colors=256,xterm*:colors=256"
set -g default-terminal "screen-256color"
set -g status-utf8 on
set -g status-justify centre
set -g status-bg default
set -g status-left "#[fg=cyan]:#[fg=blue]: #[fg=red][ #[fg=green]#S@#H #[fg=red]]#[default]"
set -g status-left-length 20
set -g mouse-select-pane on
set -g status-right-length 25
set -g status-right "#[fg=red][ #[fg=green]%H:%M #[fg=magenta]%a %m-%d #[fg=red]] #[fg=blue]:#[fg=cyan]:#[default]"
#setw -g window-status-format '#[fg=blue,bold]#I #T#[default] '
#setw -g window-status-current-format '#[fg=blue,bold,reverse]#I #T#[default] '
#setw -g window-status-alert-fg red

bind -n M-c new-window
bind -n M-p previous-window
bind -n M-n next-window
bind -n M-o down-pane
bind -n M-\; command-prompt
bind -n M-d detach-client

我vim里使用了很多F11这样的map,所以切换窗口就不能用了,本身是bind M-Left之类的键的,但发现它本身有修改大小的作用,于是取了个折衷,用M-n/p这样,M-o是在各个pane中切换。M-;是显示命令行提示符,话说在出现提示符后按ESC居然不能取消。再研究研究。M-d是detach。感觉tmux还是很好用的恩。

顺便总是没找到好和terminal啊,上次试用的urxvt,怎么折腾也不能输入中文,网上翻了个遍,shlug,hzlug也问了都没答案。只能先继续 gnome-terminal凑和着用了。。

update: 和vim有冲突啊。。在insert模式下面按ESC,再很快地输入:w,这时候出来的是tmux的command-prompt,有点坑爹。。明明没有prefix发送过去。为啥就被认为是操作tmux呢。。并且我的vim亮黄变屎黄了。。算了,还是单独给vim开个terminal吧,纠结来纠结去快捷键也因为不能冲突而弄的很麻烦。一点都不快捷了。。