分类:'编程随笔' 的所有文章

tagwin - windows命令行利器 - 利用标签在文件夹中快速跳转

Update @ Tuesday, March 1, 2011, 18:26:54: Fix 一些小问题,最新版是1.1

前两天看到了Dreamers’s blog:Bash 小技巧:给目录加上书签,快速切换目录(bashmarks),感觉用批处理脚本实现应该不难

套用Dreamer的一段话(略改):

当我们在命令行下面做开发的时候,很大一部分时间都浪费在了目录切换上面,相信不少人每天敲 “cd” 都敲得想吐。如果目录层次多一点,Tab 键也会饱受摧残。虽然Windows命令行有内置的 “cd -”, “pushd” 和 “popd” 命令,但用起来都不是很顺手。

如果能用几行简单的 Batch 脚本巧妙地给目录加上了书签,这样你就可以给最常用的那几个工作目录加上书签,不需要每次都敲 cd 了。还可以在各个常用的文件夹之间来回快速切换。

当天晚上回来就实现了第一版,感觉很是不错,由于一直没有时间写博,留到今天才拿出来跟大家分享

使用方法

1. 点击此处下载: http://www.2maomao.com/blog/wp-content/uploads/tagwin-dglt-11.zip
 (或者尝试 这个链接

2. 解压所有文件到系统PATH包含的任意目录下

3. 打开命令行,进入要加标签的目录
  t abc —> 给当前目录加标签为abc
  g abc —> 切换到标签为abc的目录
  d abc —> 删除标签abc
  l ———–> 列出所有标签

在你解压缩的那个目录找到dglt.list文件,里面是所有的标签,也可以通过编辑这个文件来管理

另外在Google Code建了一个项目用来保存最新的代码,有兴趣的可以去看看代码:
http://code.google.com/p/tagwin-dglt/

使用演示:

D:\projects>t proj

 proj   D:\projects

D:\projects>cd py\django\fayaa

D:\projects\py\django\fayaa>t fayaa

 fayaa  D:\projects\py\django\fayaa

D:\projects\py\django\fayaa>pushd g:\relax\movie

G:\relax\movie>t movie

 movie  G:\relax\movie

G:\relax\movie>g proj

D:\projects>g fayaa

D:\projects\py\django\fayaa>g movie

G:\relax\movie>l

Tagged Folders
--------------
proj    D:\projects
fayaa   D:\projects\py\django\fayaa
movie   G:\relax\movie
  • Share/Bookmark

把Picasa加星标的图片一次性导出

年前买了个千万级的照相机,再加上不加节制的使用,200G的硬盘开始不够用了,为了节省空间,决定把多数照片放在一个不是很常用的地方+刻盘,只把选择出来的照片留下

为了达到这个目标,现在安装的Faststone Image Viewer就不是很好用,安装的光影看看更是管理图片的废材。最后Google了一下,发现最好用的还是Picasa

下载了最新版,又花了过年的三四天的精选了照片,最后想把照片导出的时候遇到问题了,一共四五十个文件夹,Picasa并没有提供一次性导出的功能,只能一个文件夹一个文件夹的导出。最后还是决定写个脚本来搞定,研究了一下,发现每个目录下都有个.picasa.ini文件,格式十分简单,比如这个:

[IMG_0152.JPG]
faces=rect64(78f63255a1427ae3),155499df12e3d390
backuphash=4191
star=yes

其中的star=yes代表该照片已加星标。这就简单了,半小时写,十分钟导出,搞定!

脚本如下,注意脚本运行完以后生成了一个叫做copystar_go.bat的批处理文件,执行它才是真正的导出,这本来是调试用的,后来发现可以手工控制删掉一些不需要的导出操作(用Vim很快的),就没改回来,不多说,上代码:

Python语言: Export all stared photos in Picasa once
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
#Purpose: export all picasa stared photos under a folder and it's subfolders
#         because Picasa doesn't support - it only can export one folder once
#
#  Reach me via: realfun AT gmail DOT com
#
#  http://2maomao.com/blog/py-script-export-all-stared-photos-in-picasa/
#  http://www.google.com/profiles/realfun
#  2011-02-22, 22:26:28

from os import walk
from os.path import join

#damn python encoding hack
import sys
reload(sys)
sys.setdefaultencoding("gb2312")

PICASA = '.picasa.ini'
PICASA_OLD = 'Picasa.ini'
TARGET = 'G:\\ipad\\sync\\temp\\'

def get_stars(dir, picasa):
    stars = []
    last = None
    for line in open(join(dir, picasa)).readlines():
        line = line.rstrip("\n")
        if line.startswith("[") and line.endswith("]"):
            last = line[1:-1].decode("utf-8")
        elif line.startswith("star=yes"):
            stars.append(last)
    return stars

out = open("copystar_go.bat", "wb")
for root, dirs, files in walk("."):
    picasa = None
    if PICASA in files:
        picasa = PICASA
    elif PICASA_OLD in files:
        picasa = PICASA_OLD
    if picasa:
        stars = get_stars(root, picasa)
        for star in stars:
            line = 'robocopy "%s" "%s" "%s"\r' % (root, join(TARGET, root), star)
            print >>out, line

  • Share/Bookmark

SRT subtitle splitter,字幕分割程序,in Python

Verycd终于顶不住了

这周末整理了一下从Verycd上面拖下来的一百多G电影,发现教父1/2/3依然没有看过,想要看看才发现没字幕,射手影音也没下载到,只好到射手网上面去找,找到了几个都是一个字幕到底的;于是Google字母分割工具,一边找一边感叹下载站的没落,连国外的下载站也开始搞中国这一套欺骗点击的骗术。

找了半天,没找到一个可用的,有那么几个软件,用起来完全达不到自己的要求;
研究了一下srt的格式,自己写了段python脚本,居然花了一个小时,不过总算搞定了,代码如下:

Python语言: SRT subtitle splitter,字幕分割程序
#! /usr/bin/env python
# -*- coding: utf-8 -*-

#Author: 半瓶墨水 # 2011-02-20, 13:59:14
#Email : realfun AT gmail DOT com
#Usage : split srt files
#Examples:
#   将"教父.srt"分两段,起始时间向前错位29秒
#    第一段长1小时45分48秒,依次为第二段第三段,剩下的为第四段
#      srt.py 教父.srt offset=00:00:29 00:42:55 00:46:24 00:42:39
# *NOTICE* Serial number is not handled
#
#写这段代码主要是因为,从Verycd上面下的教父没找到对应的字幕;Verycd is Gone :(

import sys, os

def srttime2int(st):
  ""”
  >>> srttime2int("-00:01:19")
  -79000
  >>> srttime2int("00:01:19")
  79000
  >>> srttime2int("10:21:29")
  37289000
  >>> srttime2int("00:01:19,601")
  79601
  >>> srttime2int("10:21:29,601")
  37289601
  ""”
  flag = False
  if st[0] == '-':
    flag = True
    st = st[1:]
  value = ((int(st[0:2])*60+int(st[3:5]))*60+(int(st[6:8])))*1000+int(st[9:12] or 0)
  return flag and -value or value

def int2srttime(i):
  ""”
  >>> int2srttime(-79601)
  '-00:01:19,601'
  >>> int2srttime(79601)
  '00:01:19,601'
  >>> int2srttime(37289601)
  '10:21:29,601'
  ""”
  flag = False
  if i<0:
    i = -i
    flag = True
  srttime = "%02d:%02d:%02d,%03d" % (i/3600000, i%3600000/60000, i%60000/1000, i%1000)
  return flag and '-' + srttime or srttime

def srt_split():
  if len(sys.argv) < 3:
    print "\n\n\tplease read source code for usage\n\n"
    sys.exit(0)

  filename = sys.argv[1]
  splits = sys.argv[2:]
  offset = 0
  if splits[0].startswith("offset="):
    offset = srttime2int(splits[0][len("offset="):])
    splits = splits[1:]
  splits.append("24:00:00") #assume no more than 24 hours :)
  splits = [srttime2int(s) for s in splits]

  lines = open(filename, "rb").read().splitlines()
  f = open("001.srt", "wb")
  newlines = []
  count = 0
  limit = splits[0] + offset
  for line in lines:
    #00:01:16,564 –> 00:01:18,532
    if len(line)>=29 and line[13:16] == "–>":
      start = srttime2int(line[:12])
      end = srttime2int(line[17:])
      if start > limit:
        f.writelines(newlines)
        f.close()
        newlines = []
        offset += splits[count]
        count += 1
        limit += splits[count]
        f = open("%03d.srt" % (count+1), "wb")
      line = int2srttime(start - offset) + " –> " + int2srttime(end - offset)
    newlines.append(line + "\r\n")
  f.writelines(newlines)
  f.close()

if __name__ == "__main__":
    import doctest
    doctest.testmod()
    srt_split()

  • Share/Bookmark

关于Singleton (单件),线程安全

很就没写技术相关的blog了,Twitter和Buzz都很少用了,甚至很少有时间静下来思考、敲打键盘

今天面试问到static关键字的时候,有个应试者提到了Singleton的实现,就顺便多问了一点儿,回来自己又查了查

Singleton,单件,四人帮(GoF)写design pattern那本书的时候提出来的,一个进程内有且只有一个实例

说起这些Design Pattern,当时一看,我操,酷毙了,你不知道都不好意思跟别人说你是搞编程的

后来,渐渐的发现,没有银弹,只是有些Design Pattern或许有些淫荡,比如这个Singleton

一个最初的C++标准实现是这样的(S-V1):

//——————Implementation #1 ———————-
//s.h
class Singleton {
  private:
    Singleton();
    static Singleton* instance_;
  public:
    static Singleton* getInstance() {
        if (!instance_)
            instance_ = new Singleton();
        return instance_; } };

//s.cpp
Singleton* Singleton::pInstance_ = 0;

注意其中构造函数是私有的,所有只能通过getInstance构造,构造前又会先检查,所以只有一个

后来有人说,这样不是线程安全的,哦,那就简单点儿,这样吧(S-V2):

//——————Implementation #2 ———————-
//s.h
class Singleton {
  private:
    Singleton();
  public:
    static Singleton* getInstance() {
        static Singleton* instance_ = new Singleton();
        return instance_; } };

结果有人说,这个是依赖于编译器的,GCC能保证static的初始化不会出问题,但是VC就难说了。
于是,有人觉得既然第一个实现稍微改改就行了,只要加一个淫荡的锁(S-V1.1):

//——————Implementation #1.1 ———————-
//s.h
class Singleton {
  private:
    Singleton();
    static Singleton* instance_;
  public:
    static Singleton* getInstance() {
        lock_mutex();
        if (!instance_)
            instance_ = new Singleton();
        unlock_mutex();
        return instance_; } };

//s.cpp
Singleton* Singleton::pInstance_ = 0;

再后来,有人说这样也不行啊,每次get都加锁,效率太低了吧,那就更加淫荡一点,加锁之前我先check,加锁以后,我再check(S-V1.2):

//——————Implementation #1.2 ———————-
//s.h
class Singleton {
  private:
    Singleton();
    static Singleton* instance_;
  public:
    static Singleton* getInstance() {
        if (!instance_) {
          lock_mutex();
          if (!instance_)
              instance_ = new Singleton();
          unlock_mutex();}
        return instance_; } };

//s.cpp
Singleton* Singleton::pInstance_ = 0;

到这里,在搜索网络以前,我曾经认为已经OK了,但是多CPU多线程的复杂超乎想象,有人说,后一个实现不是线程安全的,因为对于instance的读和写并不是原子操作会发生写一半读一半的情况!
好吧,对效率没啥要求每个singleton就只会用个几次的用S-V1.1,没有多线程的用S-V2


========== 以下我也不是很懂的分割线 ==========

难道真的没办法优化S-V1.1了吗?

有办法,那个instance读一半写一半的情况对于int这个类型是不会发生的,那么,就多来一步,check一个int类型的标识吧:

//——————Implementation #1.3 ———————-
//s.h
class Singleton {
  private:
    Singleton();
    static Singleton* instance_;
    static int flag_;
  public:
    static Singleton* getInstance() {
        if (!flag_) {
          lock_mutex();
          if (!instance_)
              instance_ = new Singleton();
          unlock_mutex();}
          flag_ = 1;
        return instance_; } };

嘿嘿,这下你该满足了吧,NO!,还是有问题的,具体啥问题,参见这里那里,代码已经贴太多了。


进行到这里,你应该已经体会到,Singleton是很变态的,Design Pattern是很淫荡的。。。

Singleton最淫荡的地方在于:真正需要它的机会太少太少了,更多讨论参见:
[1] Singleton,你坏。。。在哪里?
[2] Singleton,银弹还是狗屎
[3] Singleton,何日才能用到你


路人甲:OMG,这是什么代码格式啊!
好吧,肯定有人不喜欢这个缩进,但是我敢肯定,肯定有人知道我喜欢Python了 :D

  • Share/Bookmark

最近写的几个Python脚本

最近太忙,忙的过程中写了七八个小脚本,其中一些比较通用的,贴在了代码发芽网上:

模拟《骇客帝国》中的滚屏效果,只需要几行简单的Python语句哦,以下是效果图:

matrix

Python语言: 简单的几句Python语句,模拟《骇客帝国》中的滚屏
#coding:utf-8

#
#简单的几句Python语句,模拟滚动的Matrix屏保
#
# 1. 打开Windows命令行(运行-》输入“cmd”然后回车)
# 2. 打开命令行属性设置,设置背景为黑色,前景为绿色
# 3. 执行这个脚本,就可以看到类似电影《骇客帝国》中的经典滚屏了 - 不过是反着的。。。
#
#呵呵,无聊之作。。。Alt+Enter全屏观看效果更好

import random, string
a = " " * 100 + string.printable
while True:
    print a[random.randint(0,len(a)-1)],


Python语言: 命令行小工具:输出系统Path中的符合条件的文件全路径,Python脚本
#What  : a small tool to locate files in system "PATH" variable

import sys

if len(sys.argv) < 2:
   print "  Usage:"
   print "    where.py test     #  normal  search"
   print "    where.py te*      #  blurred search"
   print "    where.py -x te*.cmd   #  regular expression search"
   sys.exit()
elif len(sys.argv) == 2:
   pattern = sys.argv[1].replace(".", "\\.").replace("*", "\\*").replace("?", ".?").lower()
else:
   pattern = sys.argv[2]#tricky, no "-x" checking here

import os
paths = [p for p in os.getenv('PATH').split(";") if p]
exts = [ext.lower() for ext in os.getenv('PATHEXT').split(";") if ext]
paths.append(".\\")
import re
for p in paths:
  if not os.path.isdir(p):
    continue
  for f in os.listdir(p):
    if re.search(pattern, f.lower()):
      is_exe = False
      for ext in exts:
        if f.endswith(ext):
          is_exe = True
          break
      if is_exe:
        print os.path.join(p,f)


Python语言: Python脚本获取Windows窗口标题,输出到命令行
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from win32gui import *
titles = set()
def foo(hwnd,nouse):
  #去掉下面这句就所有都输出了,但是我不需要那么多
  if IsWindow(hwnd) and IsWindowEnabled(hwnd) and IsWindowVisible(hwnd):
    titles.add(GetWindowText(hwnd))

EnumWindows(foo, 0)
lt = [t for t in titles if t]
lt.sort()
for t in lt:
  print t

  • Share/Bookmark

« 上一页下一页 »