Python PIL 生成带阴影的缩略图

iimport sys
from PIL import Image, ImageFilter
 
def dropShadow( image, offset=(5,5), background=0xffffff,
        shadow=0x444444, border=8, iterations=3):
    """
    把图像放在一个作了高斯模糊的背景上
 
    image       - 要放在背景上的原始图像
    offset      - 阴影相对图像的偏移,用(x,y)表示,可以为正数或者负数
    background - 背景色
    shadow      - 阴影色
    border      - 图像边框,必须足够用来制作阴影模糊
    iterations - 过滤器处理次数,次数越多越模糊,当然处理过程也越慢
    """
 
    # 创建背景块
    totalWidth = image.size[0] + abs(offset[0]) + 2*border
    totalHeight = image.size[1] + abs(offset[1]) + 2*border
    back = Image.new(image.mode, (totalWidth, totalHeight), background)
 
    # 放置阴影块,考虑图像偏移
    shadowLeft = border + max(offset[0], 0)
    shadowTop = border + max(offset[1], 0)
    back.paste(shadow, [shadowLeft, shadowTop, shadowLeft + image.size[0],
        shadowTop + image.size[1]] )
 
    # 处理阴影的边缘模糊
    n = 0
    while n < iterations:
        back = back.filter(ImageFilter.BLUR)
        n += 1
 
    # 把图像粘贴到背景上
    imageLeft = border - min(offset[0], 0)
    imageTop = border - min(offset[1], 0)
    back.paste(image, (imageLeft, imageTop))
 
    return back
 
if __name__ == "__main__":
    pic="BCEB4D33FC86DC647461670FFC23D260.jpg"
    image = Image.open(pic)
    image.thumbnail( (300,300), Image.ANTIALIAS)
 
    dropShadow(image).show()
    dropShadow(image, background=0xeeeeee,
                  shadow=0x444444, offset=(0,5)).show()

生成前的原图:
生成前的原图
生成后的带阴影图:
生成后带阴影图

发表在 Programming | 标签为 | 2 条评论

Python 批量生成缩略图

首先上代码

# coding=utf-8
 
import os
import Image
 
# 字义缩放百分比
rate = 40
 
# 缩略图命名,在后面加上
resizedAddone = '_resized'
 
# 支持格式
suportFormat = ['bmp', 'gif', 'jpg', 'png']
 
def process(arg, dirs, files):
    for file in files:
        fileExt = os.path.splitext(file)[1].lower()[1:]
        if fileExt in suportFormat:
            img = Image.open(file)
            img.thumbnail((img.size[0] * rate / 100,
                                img.size[1] * rate / 100))
            img.save(os.path.basename(file)  \
                               + resizedAddone    \
                               + str(rate) + '.' + fileExt)
 
if __name__ == '__main__':
    os.path.walk('.', process, '123')

要运行此段代码需要安装PIL库,这是一个比较优秀的Python 图像处理库,使用的普及率类似PHP中的GD库,比较成熟和稳定,如果你需要更高的性能,image magick 是个相当不错的选择,image magick 的PHP扩展仍然有相当多的Bug,一般应用应该问题不大,至少在我的项目中应用还没出现过问题,我只是简单的应用到了缩略图的功能,仍然建议以命令行的形式调用,python 版本的还没试用过,从各方的使用反馈来看,似乎比PHP版本的口碑更好。

上面的代码是按照比例做缩略图,只需把源码放到你的图片目录下,然后运行就能批量生成缩略图了,如果你是需要固定尺寸的缩略图,只是需要 img.thumbnail()传递一个固定尺寸的tuple就好了,类似这样:img.thumbnail((120,100)),更多详细请查看PIL文档,不过这个文档相当的长,PDF版本有77页,非常的详细,当然也是因为PIL功能相当的完备和强大

发表在 Programming | 标签为 | 留下评论

Linode VPS 主机评分

配置是最低入门的512plan

4 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables 12912633.7 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2151.7 MWIPS (10.0 s, 7 samples)
Execl Throughput 892.6 lps (29.9 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 174974.5 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 46414.1 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 521010.8 KBps (30.0 s, 2 samples)
Pipe Throughput 249578.0 lps (10.0 s, 7 samples)
Pipe-based Context Switching 44742.9 lps (10.0 s, 7 samples)
Process Creation 1479.8 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 2334.2 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 673.1 lpm (60.1 s, 2 samples)
System Call Overhead 248224.2 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 12912633.7 1106.5
Double-Precision Whetstone 55.0 2151.7 391.2
Execl Throughput 43.0 892.6 207.6
File Copy 1024 bufsize 2000 maxblocks 3960.0 174974.5 441.9
File Copy 256 bufsize 500 maxblocks 1655.0 46414.1 280.4
File Copy 4096 bufsize 8000 maxblocks 5800.0 521010.8 898.3
Pipe Throughput 12440.0 249578.0 200.6
Pipe-based Context Switching 4000.0 44742.9 111.9
Process Creation 126.0 1479.8 117.4
Shell Scripts (1 concurrent) 42.4 2334.2 550.5
Shell Scripts (8 concurrent) 6.0 673.1 1121.8
System Call Overhead 15000.0 248224.2 165.5
========
System Benchmarks Index Score 343.5

————————————————————————
4 CPUs in system; running 4 parallel copies of tests

Dhrystone 2 using register variables 47311139.0 lps (10.0 s, 7 samples)
Double-Precision Whetstone 8496.2 MWIPS (9.8 s, 7 samples)
Execl Throughput 2652.3 lps (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 224996.5 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 60198.2 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 747652.1 KBps (30.0 s, 2 samples)
Pipe Throughput 948490.2 lps (10.0 s, 7 samples)
Pipe-based Context Switching 170475.4 lps (10.0 s, 7 samples)
Process Creation 4747.2 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 5697.3 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 746.2 lpm (60.1 s, 2 samples)
System Call Overhead 873882.0 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 47311139.0 4054.1
Double-Precision Whetstone 55.0 8496.2 1544.8
Execl Throughput 43.0 2652.3 616.8
File Copy 1024 bufsize 2000 maxblocks 3960.0 224996.5 568.2
File Copy 256 bufsize 500 maxblocks 1655.0 60198.2 363.7
File Copy 4096 bufsize 8000 maxblocks 5800.0 747652.1 1289.1
Pipe Throughput 12440.0 948490.2 762.5
Pipe-based Context Switching 4000.0 170475.4 426.2
Process Creation 126.0 4747.2 376.8
Shell Scripts (1 concurrent) 42.4 5697.3 1343.7
Shell Scripts (8 concurrent) 6.0 746.2 1243.6
System Call Overhead 15000.0 873882.0 582.6
========
System Benchmarks Index Score 839.6

单核测试性能也有300多分,这个表现相当出色,四核的测试能够超过839分也出乎意料,由于linode的高可用性和对亚洲的访问速度非常的快,虽然最低也要19美元,也算是物有所值

附上测试脚本:Unix bench

发表在 Operating System | 标签为 | 2 条评论

Burstnet VPS 主机评分

前些日子搞特惠,买了一个最低配置的,512M内存

VPS PACKAGE #1
VPS Software: vePortal™ / OpenVZ™
CPU: 1000MHZ GUARANTEED
Memory: 512MB GUARANTEED
Disk Space: 20GB (RAID BASED CONFIG)
Bandwidth: 1000GB/MONTH
IP Addresses: 2 (IPv4) + IPv6
Management: BASIC MANAGED
DDOS Protection: CISCO™ GUARD
FREE SETUP $5.95/MONTH

================================================================
BYTE UNIX Benchmarks (Version 5.1.3)

System: 200689.www.foxapp.com: GNU/Linux
OS: GNU/Linux — 2.6.18-194.26.1.el5.028stab070.14 — #1 SMP Thu Nov 18 16:34 :01 MSK 2010
Machine: x86_64 (x86_64)
Language: en_US.utf8 (charmap=”UTF-8″, collate=”UTF-8″)
CPU 0: Intel(R) Xeon(R) CPU E5620 @ 2.40GHz (4788.1 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization
05:07:23 up 6 min, 1 user, load average: 0.08, 0.02, 0.01; runlevel 3

————————————————————————
Benchmark Run: Fri Jan 28 2011 05:07:23 – 05:37:17
1 CPU in system; running 1 parallel copy of tests

Dhrystone 2 using register variables 12759700.9 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2797.2 MWIPS (10.0 s, 7 samples)
Execl Throughput 3383.2 lps (29.6 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 506737.3 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 142917.2 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 1087584.1 KBps (30.0 s, 2 samples)
Pipe Throughput 948149.4 lps (10.0 s, 7 samples)
Pipe-based Context Switching 277958.2 lps (10.0 s, 7 samples)
Process Creation 10813.4 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 4151.6 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 583.2 lpm (60.1 s, 2 samples)
System Call Overhead 862516.8 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 12759700.9 1093.4
Double-Precision Whetstone 55.0 2797.2 508.6
Execl Throughput 43.0 3383.2 786.8
File Copy 1024 bufsize 2000 maxblocks 3960.0 506737.3 1279.6
File Copy 256 bufsize 500 maxblocks 1655.0 142917.2 863.5
File Copy 4096 bufsize 8000 maxblocks 5800.0 1087584.1 1875.1
Pipe Throughput 12440.0 948149.4 762.2
Pipe-based Context Switching 4000.0 277958.2 694.9
Process Creation 126.0 10813.4 858.2
Shell Scripts (1 concurrent) 42.4 4151.6 979.2
Shell Scripts (8 concurrent) 6.0 583.2 972.0
System Call Overhead 15000.0 862516.8 575.0
========
System Benchmarks Index Score 883.3

883.3的评分相当彪悍,相对于其价格来说,相当不错了,Burst有个很大的Bug是他的统计流量的系统,那玩意一点也不靠谱,我发过ticket给他们,回复说是已知的Bug,目前不限制流量,也就是显示多少无所谓了。

发表在 Operating System | 标签为 , | 一条评论

Httpsqs Python Client

Httpsqs 是张宴基于Tokyo Cabinet做的一个队列服务
前些日子项目中需要一个队列服务,因为配合Gearman做分发服务,因为之前的一些经历和教训,没有采用PHP作为脚本语言,当然并不是说PHP不行,只是懒得去折腾一些莫名其妙的问题,转而采用在更稳定更省心的Python做开发,之前其他的项目组中有使用Httpsqs的经历,我的leader强烈建议我使用这个,其实我更倾向memcacheQ 或者redis,Httpsqs没有Python版本的client,顺手写了一个,地址如下:
http://code.google.com/p/httpsqs/source/browse/#svn%2Ftrunk%2Fclient%2Fpython

这个玩意是能正常的跑在我的项目中,不能保证能完全满足你的需求,如果你有任何建议或者意见,也欢迎联系我,特别附加一句:本人对此代码所带来的一切悲剧或者喜剧不承担任何责任,请慎重使用!

贴一段关于httpsqs的介绍,怕有些人不知道,知道的请忽略。

TTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。

  项目网址:http://code.google.com/p/httpsqs/
  使用文档:http://blog.s135.com/httpsqs/
  使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
  软件作者:张宴

  队列(Queue)又称先进先出表(First In First Out),即先进入队列的元素,先从队列中取出。加入元素的一头叫“队头”,取出元素的一头叫“队尾”。利用消息队列可以很好地异步处理数据传送和存储,当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据,就可采取消息队列来异步插入。另外,还可以将较慢的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台处理,例如FLV视频转换、发送手机短信、发送电子邮件等。

  HTTPSQS 具有以下特征:

  ● 非常简单,基于 HTTP GET/POST 协议。PHP、Java、Perl、Shell、Python、Ruby等支持HTTP协议的编程语言均可调用。
  ● 非常快速,入队列、出队列速度超过10000次/秒。
  ● 高并发,支持上万的并发连接,C10K不成问题。
  ● 支持多队列。
  ● 单个队列支持的最大队列数量高达10亿条。
  ● 低内存消耗,海量数据存储,存储几十GB的数据只需不到100MB的物理内存缓冲区。
  ● 可以在不停止服务的情况下便捷地修改单个队列的最大队列数量。
  ● 可以实时查看队列状态(入队列位置、出队列位置、未读队列数量、最大队列数量)。
  ● 可以查看指定队列ID(队列点)的内容,包括未出、已出的队列内容。
  ● 查看队列内容时,支持多字符集编码。
  ● 源代码不超过800行,适合二次开发。

发表在 Programming | 标签为 | 留下评论

Python Queue 的多线程(multi thread)死锁问题

废话不多说,先上代码:

#encoding=utf-8
import threading
import random
import time
from Queue import Queue
import mutex
 
class Producer(threading.Thread):
 
    def __init__(self, threadname, queue, lock):
        threading.Thread.__init__(self, name = threadname)
        self.sharedata = queue
        self.lock = lock
 
    def run(self):
        for i in range(20):
            #----------------
            self.lock.acquire()
            print self.getName(),'<< ',i
            self.lock.release()
            #----------------
            self.sharedata.put(i)
            time.sleep(random.randrange(10)/50.0)
            #time.sleep(1)
        print self.getName(),'Finished'
 
 
# Consumer thread
 
class Consumer(threading.Thread):
 
 
    global lock
    def __init__(self, threadname, queue, lock):
        threading.Thread.__init__(self, name = threadname)
        self.sharedata = queue
        self.lock = lock
 
 
    def run(self):
        for i in range(20):
            #----------------
            self.lock.acquire()
            print self.getName(),'        >> ',self.sharedata.get()
            self.lock.release()
            #----------------
            time.sleep(random.randrange(10)/50.0)
            #time.sleep(1)
        print self.getName(),'Finished'
 
 
# Main thread
 
def main():
 
    lock = threading.RLock()
    queue = Queue()
    producer = Producer('Producer', queue, lock)
    consumer = Consumer('Consumer', queue, lock)
    print 'Starting threads ...'
    producer.start()
    consumer.start()
    producer.join()
    consumer.join()
    print 'All threads have terminated.'
 
if __name__ == '__main__':
    main()

这个是在学习多线程的时候入门经典实例之一,这里只是加了个同步锁(RLock)
多次执行这个脚本会发现,大部分时候这个脚本会发生死锁的现象,偶尔却能正确的执行完

这个问题并不是锁本身的问题,是程序的逻辑问题

producer和 consumer 都sleep 如下时间

time.sleep(random.randrange(10)/50.0)

当consumer sleep时间小于producer 的时候而队列为空的时候就会发生貌似死锁的现象

之所以说是貌似,是因为这个并不是死锁引起的问题,而是queue 的get方法,这个方法有个timeout的可选参数,如果没有这个参数,那么get会一直等待队列中添加新的元素进来才会返回,所以后面的consumer 的 release并没有执行导致队列一直锁在那里,producer也没法写入,

关于queue get方法的更详细用法请参阅python手册Queue章节

Python 的 queue 实现就是线程安全的,没有必要上锁,这里就是因为 queue 内部的锁机制同你的锁冲突了,如果要是想自己控制的话,那么 queue 的 put 和 get 都得用 nowait 的方法

发表在 Programming | 标签为 | 留下评论

又过去了一年

感觉2009年总结才刚刚写,怎么又写2010年总结了呢,如果不是在Google Reader中看到那么多牛人都发布了自己的总结,差点忘记了已经又过了一年。
回首过去的一年,对于国家只有一个字:“涨”,房价涨,菜价涨,食用油涨价,电费涨价,连厕纸都涨了20%以上,楼下的包子以前一块钱两个小的,现在一块钱只能买一个喽,公司食堂最贵的菜从8块跳到了10块,还好,工资没涨!
对于自己,也只能用一个字形容:“忙”,非常忙,特别忙,忙得昏天暗地,不停的加班、加班、加班、加班……去年元旦前后进入状态后,一直就是不停的做着各种各样项目。
关于生活
过去的一年不欢不喜,老人说这就是生活,我租了一套在资产泡沫的朦胧的光辉下价值两百万人民币的公寓。在杭州这样的高空置率的城市里,最大的好处就是房租相对还算可以接受,虽然房价虚高。给房子里填齐了各种各样的锅碗瓢盆,明年老娘来的时候就不用被说空着那么大的厨房,没地方做饭了,想想日子倒是也过得衣食无忧,连感冒都没有过,不过没存下来什么钱。又长一岁,开始更关注,房子、车子、票子、妻子、老子……
关于工作:
前面说过这一年主旋律是就一个“忙”字,不过也算是看了不少的书,甚至不少好书,也实践了不少想法,甚至又重新尝试搞起了垃圾站,实践证明现在的搜索引擎已经不是四年前的搜索引擎,实在没那么好欺骗,自然我的小九九就落空了。在我的2009年总结中,我提到2010年要好好学习两门语言,一个英语一个 Python,英语没怎么学,除了多认识了几个单词之外,无所长进,Python倒是学习并应用了一段时间,写了一个google app engine 应用,写了一个简单的CMS系统,写一个爬虫,写了个静态文件的压缩与简单分词,爬虫每天可以抓取和处理四千万左右个页面,压缩与去重处理大概能处理几十G数据,看了好些关于这方面的论文,也算是一种收获吧,虽然都是实践性项目。关于我所每天从事的工作,一个考虑公司可能不让说,另外一个考虑也没啥好说的,社区电子商务这个模式跟我曾经对某位在搞互联网电视的朋友说的一样:没人踏足的领域不一定就是块风水宝地,做成功了,我们就是英雄,做不成功就是英烈,当然成为英烈的可能性更大一些。年末进入的移动互联网倒是有奔头,但目前这个领域也仅仅是看好,并没有成熟的用户群,一群公司蜂拥而上就跟当年美国和苏联抢着登月球一样。我咋这么悲观呢……
关于机遇:
2010年是中国经济全面从复苏走向泡沫的一年,各种资本变着法进入各种领域深藏起来,从年初的民工荒,到后来的技术荒,团购网站铺天盖地,优酷、当当等乘着机会到海外圈钱,创业版的开市又为中国无辜的P民提供了一个合法的赌场,过去一年中国股市新发股票价值超过万亿,而市值却没有任何提升,蒸发了万亿。好友离开公司去了北京,本也想换个环境,最后为了几斗米而折腰,人家说会有期权和股权,我觉得那些都是骗人的,结果就在这个月(2011年1月)这丫居然真的在纳斯达克上市了,悲哉!2010年过得是这辈子到目前为止最忙的一年,也是最有想法的一年,或许慢慢的进入了这个圈子,或者是迫于压力,总是试着去做一些尝试,虽无所收获,也算是一种锻炼和对自己的历练。
关于2011年:
不管明年是不是2012,努力还是要努力的。去年没有完成的今年肯定要完成,比如英语,阅读已经不是什么问题,问题出在口语上,实在不行,出点血吧,去新东方搞一下,这玩意没环境确实不好学。Python暂时搁置一下,准备搞一下C和搜索算法这一块的东西,或许能为移动终端贡献一点东西

发表在 Life Diary | 标签为 , , | 留下评论

python满足你需要的50个模块

Python具有强大的扩展能力,网上有人列出了50个很棒的Python模块,包含几乎所有的需要:比如Databases,GUIs,Images, Sound, OS interaction, Web,以及其他。推荐收藏。

Graphical interface wxPython http://wxpython.org
Graphical interface pyGtk http://www.pygtk.org
Graphical interface pyQT http://www.riverbankcomputing.co.uk/pyqt/
Graphical interface Pmw http://pmw.sourceforge.net/
Graphical interface Tkinter 3000 http://effbot.org/zone/wck.htm
Graphical interface Tix http://tix.sourceforge.net/

Database MySQLdb http://sourceforge.net/projects/mysql-python
Database PyGreSQL http://www.pygresql.org/
Database Gadfly http://gadfly.sourceforge.net/
Database SQLAlchemy http://www.sqlalchemy.org/
Database psycopg http://www.initd.org/pub/software/psycopg/
Database kinterbasdb http://kinterbasdb.sourceforge.net/
Database cx_Oracle http://www.cxtools.net/default.aspx?nav=downloads
Database pySQLite http://initd.org/tracker/pysqlite

MSN Messenger msnlib http://auriga.wearlab.de/~alb/msnlib/
MSN Messenger pymsn http://telepathy.freedesktop.org/wiki/Pymsn
MSN Messenger msnp http://msnp.sourceforge.net/
Network Twisted http://twistedmatrix.com/
Images PIL http://www.pythonware.com/products/pil/
Images gdmodule http://newcenturycomputers.net/projects/gdmodule.html
Images VideoCapture http://videocapture.sourceforge.net/

Sciences and Maths scipy http://www.scipy.org/
Sciences and Maths NumPy http://numpy.scipy.org//
Sciences and Maths numarray http://www.stsci.edu/resources/software_hardware/numarray
Sciences and Maths matplotlib http://matplotlib.sourceforge.net/

Games Pygame http://www.pygame.org/news.html
Games Pyglet http://www.pyglet.org/
Games PySoy http://www.pysoy.org/
Games pyOpenGL http://pyopengl.sourceforge.net/
Jabber jabberpy http://jabberpy.sourceforge.net/
Web scrape http://zesty.ca/python/scrape.html
Web Beautiful Soup http://crummy.com/software/BeautifulSoup
Web pythonweb http://www.pythonweb.org/
Web mechanize http://wwwsearch.sourceforge.net/mechanize/

Localisation geoname.py http://www.zindep.com/blog-zindep/Geoname-python/

Serial port pySerial http://pyserial.sourceforge.net/
Serial port USPP http://ibarona.googlepages.com/uspp

Parallel Port pyParallel http://pyserial.sourceforge.net/pyparallel.html

USB Port pyUSB http://bleyer.org/pyusb/

Windows ctypes http://starship.python.net/crew/theller/ctypes/
Windows pywin32 http://sourceforge.net/projects/pywin32/
Windows pywinauto http://www.openqa.org/pywinauto/
Windows pyrtf http://pyrtf.sourceforge.net/
Windows wmi http://timgolden.me.uk/python/wmi.html

PDA/GSM/Mobiles pymo http://www.awaretek.com/pymo.html
PDA/GSM/Mobiles pyS60 http://sourceforge.net/projects/pys60

Sound pySoundic http://pysonic.sourceforge.net/
Sound pyMedia http://pymedia.org/
Sound FMOD http://www.fmod.org/
Sound pyMIDI http://www.cs.unc.edu/Research/assist/developer.shtml

GMail libgmail http://libgmail.sourceforge.net/
Google pyGoogle http://pygoogle.sourceforge.net/
Expect pyExpect http://pexpect.sourceforge.net/
WordNet pyWordNet http://osteele.com/projects/pywordnet/
Command line cmd http://blog.doughellmann.com/2008/05/pymotw-cmd.html
Compiler backend llvm-py http://mdevan.nfshost.com/llvm-py/
3D VPython http://vpython.org

发表在 Excellence Article, Programming | 标签为 | 留下评论

软件开发中的几个经典问答

  1. Q:如何保证产品可用性?
    A:先做出来吧,能用就行,不能用再改嘛,不行就加机器
  2. Q:如何保证产品的性能?
    A:狗屁性能,现在人都没有还要啥性能,先照简单的做,把功能实现了先,以后的事情以后再说
  3. Q:如何保证产品的可维护性?
    A:维护啥啊,还有一堆功能要实现呢!刚开完会,前面做的那些东西又要整,再说这个项目已经做成这样了,现在没时间回头整理东西,需求要得急啊,这个东西应该一开始就做啊,现在代价太大了,下个项目再说吧
  4. Q:如何进行产品测试?
    A:这个真没想过,让测试去做计划吧,尽量做好自测吧,用户急着要这个功能,先赶工吧

以上是我经常听到的回答,至于对与错,屁股决定脑袋

发表在 Life Diary | 标签为 , | 留下评论

vim xxx编辑完了后发现没有写权限

很多时候我们在vim一个文件然后保存的时候却发现没有写权限,这个很纠结,尤其是在编辑了一个文件的好几处,而且不在一屏的时候,其实有个变通的方法,原理稍后介绍,现在你可以在保存的时候使用下面的命令:

:w !sudo tee %

原理是w ! 可以把当前尚未保存的内容输出到标准输入中,然后用tee 把标准输入的东西写入到%文件中。 而在vim中,%代表当前正在编辑的文件。

发表在 Operating System | 标签为 | 留下评论