分类: '编程相关' 的归档
谷歌音乐下载器
之前有很多下载baidu mp3的程序,有bash的,java的,python的,其中也包括我这个.
但是baidu的歌曲都是用程序收集自网络的,所以排行榜的歌曲质量就没有保障了,下载下来的歌曲ID3信息可谓一塌糊涂,而且还可能下载到网友自己翻唱的歌或者其他杂七杂八的东西,严重影响我们的听觉神经.
而谷歌(不是google)最近推出了谷歌音乐搜索,联合top100,也推出了类似百度榜单的音乐排行榜.但不同于百度的是,谷歌里的歌曲都是收集整理过的,不会有死链,质量也很不错,而且,对于最终非商业用途的个人用户而言,是不存在版权问题的(但我不确定批量下载下来的有没有版权问题.请用户自行考虑.).
所以我顺势就推出了这个谷歌音乐下载器 .
目前程序还很简陋,没有图形界面,也没有很多可以设置的地方.运行程序只会把”华语新歌”这个榜单的100首歌下载到本地当前目录.所以仅供有兴趣尝鲜的同学测试使用.但是以后,我打算把这个程序做成有图形界面的,可以试听/下载/播放的一个整合工具,哈哈.请大家多多关注吧.
PS:有人说这类工具还是不要发布出来,小范围流传下比较好,因为发布出来以后,很可能遭到google的封杀.这说法其实也有些道理,但是我想想,如果谷歌真的因为这个来封杀我,我也够有面子的,嘿嘿.所以我还是按照Google的Project hosting页面所说的做了: Release early, release often
SQLite简介
SQLite大致就是”SQL lite”,也就是一个微型的SQL解释器.它的赞助商和使用者包括mozilla,adobe,symbian等软件巨头,也算是来头不小了.
说它微型,那么它到底有多微型呢?我们可以看看它的可执行文件的大小,linux版本的打包文件是203.93 KiB,解压以后是350.88 KiB,是不是很微型呢?
除了微型之外,SQLite主要还要以下特点:
- 无须配置: SQLite不需要安装,直接解压可执行文件即可运行.
- 没有服务进程: SQLite无须通过TCP/IP等通信协议提交SQL到服务端,处理后再返回结果.
- 单个数据文件: SQLite将用户数据存于单个普通文件里面.也就是说用户只要有数据文件的读权限,就可以读取所有数据;有写权限也能改变数据.
- 数据文件可跨平台迁移: SQLite本身是跨平台的,它的数据文件同样也是跨平台的.数据文件和平台的字节序无关,也和CPU的位数无关.直接复制数据文件就可以实现数据迁移.
- 紧凑: 如上所述,SQLite的运行环境非常小,如果在编译的时候去掉不需要的功能,可以减小至170KiB,用于嵌入式环境也是没问题的.
- 松散数据类型: 不同于其他数据库的严格的数据类型检查,SQLite在尝试类型转换失败以后,允许在任何表的任何列里面插入任何类型的数据(一个例外是:整型的主键列里面只能存整型数据)
- 变长的数据记录: 任何文本都是VARCHAR
- 可读性很高的源码: 普通的程序员都能读懂,关键的变量和函数都有详细的注释.
- SQL语句编译成虚拟机器语言: SQLite把SQL语句预编译成一种类似机器预言的代码,程序员可以方便得打印出代码及代码的执行结果,这样对debug很有好处.
- 完全的公开: SQLite的源码可以任意下载使用,没有任何约束和版权(一些文档和测试代码是受开源license保护的).
- SQL语言扩展: SQLite可以模块化地添加扩展,以增强其功能
说了这么多特点,那么,SQLite究竟怎么使用呢?
在一般的linux发行版下,安装 sqlite 这个包以后,就可以使用 sqlite3 这个命令来创建和处理数据库文件了.windows/DOS则下载这个文件解压到系统目录,mac则是下载这个文件.
安装完毕以后,就可以用
sqlite3 test.db
这个命令来创建一个空的数据库文件了.
然后,你可以用以下命令来建立一个含有两个列的表:
sqlite3 test.db "create table memos(text, priority INTEGER);"sqlite3 test.db "insert into memos values('deliver project description', 10);" sqlite3 test.db "insert into memos values('lunch with Christine', 100);"
然后可以这样查询出需要的数据:
sqlite3 test.db "select * from memos where priority>20;" lunch with Christine|100
很简单吧~
下面展示一下,SQLite在C语言下的用法,同样用的是上面那个test.db,我们建立一个test.c,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <stdio.h> #include <sqlite3.h> static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } int main(int argc, char **argv){ sqlite3 *db; char *zErrMsg = 0; char SQLbuffer[1024]; int rc; if( argc!=2 ){ fprintf(stderr, "Usage: %s num\n", argv[0]); return 1; } rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return 1; } sprintf(SQLbuffer, "select * from memos where priority > %s;", argv[1]); rc = sqlite3_exec(db, SQLbuffer, callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } sqlite3_close(db); return 0; } |
用
gcc -lsqlite3 test.c
进行编译,完成之后,执行
./a.out 30 text = lunch with Christine priority = 100
怎么样,相当简单吧~
注: 文中部分内容翻译和参考自官方文档和man页.
调srt字幕时间的小脚本
首先,我知道mplayer和很多其他播放都有个类似 -subdelay的开关,可以实现字幕和电影的时间调整。
此脚本和subdelay又部分功能交叉,但是某些特殊的时候,还是用个这个脚本方便。
我当时的是电影一个avi文件,但srt字幕却只找到分CD1和CD2的那种,前半段电影的时间和CD1对上了,但是后半段就没字幕了。
为了解决这个文件,就写了这个脚本,名为 adjsrt.sh
我当时执行了 ./adjsrt.sh 3061 cd2.srt >> cd1.srt 就把第二个字幕的时间整体加上3061秒,然后加在了第一个字幕的后面了,哈哈。
脚本如下:
#!/bin/sh offset=$1 shift awk -v offset=$offset ' BEGIN{ FS="[ :,]+" } /^[0-9][0-9]:[0-9]*/ { ST=toT($1,$2,$3)+offset; ST1=int(ST/3600); ST2=int((ST-ST1*3600)/60); ST3=ST%60; ET=toT($6,$7,$8)+offset; ET1=int(ET/3600); ET2=int((ET-ET1*3600)/60); ET3=ET%60; printf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n", ST1,ST2,ST3,$4,ET1,ET2,ET3,$9); } $0 !~ /^[0-9][0-9]:[0-9]*/ { print $0 } function toT( hour, min , sec ){ return hour*3600 + min*60 + sec } ' $*
python多处理器编程
由于上次做的那个一维随机游走程序,虽然简单,但是大数据的时候很费CPU,而且我注意到我的双核处理器始终只有一核是处于满负荷工作,另一个核的性能没有得到发挥.而且我也试过把同样的程序放到一个8核的服务器上运行,结果解题的速度也只是比我本本快那么一点点,估计也只是那服务器的CPU主频(2GHz)比我的1.86GHz略高而已,完全没有发挥出他8核的优势.
所以马上想到了python有没有多处理机的机制,上网google一下,发现由于python是解释型的语言,而Python解释器使用GIL(全局解释器锁)来在内部禁止并行执行,正是这个GIL限制你在多核处理器上同一时间也只能执行一条字节码指令.猜想这个GIL也是当初为了设计解释器方便而搞的吧.而且据说python 3.0 里面已经改进了,默认有了多处理器编程的库了.但是毕竟现在python3.0还没有流行起来,那么现在有没有变通的方法呢?
当然有~不然我就不会写这文章了嘛~
Parallel Python 这个库,正是为了解决我们的问题而设计的,而且它不仅可以多核处理器协同工作,还可以通过网络集群运行呢,嘿嘿.
下面的中文介绍来自这里:
1 简介
PP 是一个Python模块,提供了在SMP(多CPU或多核)和集群(通过网络连接的多台计算机)上并行执行Python代码的机制。轻量级,易于安装,并集成了其他软件。PP也是一个用纯Python代码实现的跨平台,开放源码模块。
2 功能
* 在SMP和集群上并行执行Python代码
* 易于理解和实现的基于工作的并行机制,便于把穿行应用转换成并行的
* 自动构造最佳配置(默认时工作进程数量等同于系统处理器数量)
* 动态处理器分配(允许运行时改变工作处理器数量)
* 函数的工作缓存(透明的缓存机制确保后续调用降低负载)
* 动态负载均衡(任务被动态的分配到各个处理器上)
* 基于SHA的连接加密认证
* 跨平台移植(Windows/Linux/Unix)
* 开放源代码3 开发动机
现代Python程序已经广泛的应用在商业逻辑,数据分析和科学计算等方面。其中广泛应用着SMP(多处理器或多核)和集群(通过网络连接的多台计算机),市场需要并行的执行的Python代码。
在SMP计算机上编写并行程序最简单的方法是使用多线程。尽管如此,使用 ‘thread’ 和 ‘threading’ 模块仍然无法在字节码一级实现并行。因为Python解释器使用GIL(全局解释器锁)来在内部禁止并行执行。这个GIL限制你在SMP机器上同一时间也只能执行一条字节码指令。
PP 模块正是为了解决这个问题而来,提供简单的方式实现并行Python应用。 ppsmp 在内部使用 进程 和 IPC (进程间通信)来组织并行计算。并处理了所有内部的细节和复杂性,你的应用程序只需要提交工作任务并取回结果就可以了。这也是编写并行程序的最简单的方法。
为了更好的实现,所有使用 PP 的软件通过网络来连接和协作。跨平台和动态负载均衡使得 PP 可以轻松组织多平台、异构的集群计算环境。4 安装
任何平台:下载模块压缩包,解压,运行setup脚本:
python setup.py install
Windows:下载和执行安装包。
另外,debian和ubuntu用户,也可以通过apt直接下载安装,包名是 python-pp ,但是由于版本比较老,是 1.5.4 版本的,而最新的是 1.5.6 ,所以官方页面上的示例代码可能运行不了,会出现以下错误提示:
Traceback (most recent call last):
File “testpp.py”, line 46, in
job_server = pp.Server(ppservers=ppservers)
File “/var/lib/python-support/python2.5/pp.py”, line 312, in __init__
raise ValueError(“secret must be set using command-line option or configuration file”)
ValueError: secret must be set using command-line option or configuration file
原因是代码的不兼容性,解决办法就是找到 pp.Server 那行,多加一个参数,如下:
job_server = pp.Server(ppservers=ppservers,secret="")
由于这个库,包装得不错,所以用起来也比较简单,基本上看了示例代码,就会了,使用方面也就不多介绍了,如果有可能的话,我倒是想写个gentoo的ebuild文件,嘿嘿.
给 iPod 转视频的脚本
由于新买了个 iPod touch,这几天认真钻研了下它的视频格式,搞了个nautilus脚本,使用mencoder做后端.
以后想把某个视频文件转成iPod的格式的话,直接在 nautilus 里面右键点文件-脚本-toIpod 就可以搞定了.
脚本的特点:
* 借助mplayer的强大,支持N多的源格式(已测试: avi rmvb mov flv).
* 支持srt/ass格式的外挂字幕.
* 自动缩放画面比例到适合ipod touch的480*320,如果是 ipod shuffle 之类的话,可以自己修改下脚本.
* 可视化的进度提示
* 转换速度较快
* 默认保存到当前目录,可修改脚本,输出到统一目录,方便管理.会自动加上 _ipod.mp4 的后缀名.
使用方法,保存以下脚本到 ~/.gnome2/nautilus-scripts/toIpod ,并加可执行权限…或者这里下载
PS: 如果压缩出来的字幕有乱码,请参照我以前的文章,建个 ~/.mplayer/mencoder.conf 文件,写上一行 subcp=cp936 就好了.
#!/bin/bash #filename: ~/.gnome2/nautilus-scripts/toIpod #Copyright (c) 2008 bones7456 (bones7456<A>gmail<D>com) #License: GPL #version 20081101 #用于将视频转成 ipod touch / iphone 格式.右击文件使用 SAVEDIR=`pwd` #SAVEDIR="/data/movie" INFILE="$1" PWD=`pwd` CMD="mencoder -of lavf -lavfopts format=mp4 -oac lavc -ovc lavc " CMD+="-lavcopts aglobal=1:vglobal=1:vcodec=mpeg4:vbitrate=600:acodec=libfaac:abitrate=128 " CMD+="-af lavcresample=22050 -vf dsize=480:320:0,scale=0:0,expand=480:320,harddup -ofps 25 -srate 22050 " P="没有找到对应的字幕." if [[ -f "${INFILE%.*}.srt" ]];then CMD+=" -sub ""\"$PWD/${INFILE%.*}.srt\"" P="找到字幕文件: ""${INFILE%.*}.srt" elif [[ -f "${INFILE%.*}.ssa" ]];then CMD+=" -sub ""\"$PWD/${INFILE%.*}.ssa\"" P="找到字幕文件: ""${INFILE%.*}.ssa" elif [[ -f "${INFILE%.*}.aas" ]];then CMD+=" -sub ""\"$PWD/${INFILE%.*}.aas\"" P="找到字幕文件: ""${INFILE%.*}.aas" fi CMD+=" -o ""\"$SAVEDIR/${INFILE%.*}_ipod.mp4\""" ""\"$PWD/$INFILE\"" P+="\n\n保存目录: $SAVEDIR" P+="\n\n是否继续?" #echo "$CMD" >> ~/toIpod.log if ! zenity --question --text "$P" ; then exit 0; fi eval "$CMD 2>&1" |\ while read line; do echo $line |\ awk -F '[ :\(\)%]+' '/^Pos/{print "# 速度:",$5,"(点\"取消\"转入后台运行.)";print $4}' ; done |\ zenity --progress --title "正在转换..." --percentage=0 --auto-close --width=500
截图:

google code jam
玩了下google编程大赛,我那轮3道题目,题目球猫帖这里了,其中的第3,超烦,算什么打苍蝇的概率,算的累死了,为了不让自己的程序白写,贴在这里晒晒,嘿嘿.
PS: 初学python,发现真好用…
- #!/usr/bin/env python
- # -*- encoding: utf-8 -*-
- import math
- def sg(x,R):
- '''求弓形面积'''
- return math.acos(x/R)*(R**2)-x*math.sqrt(R**2-x**2)
- inf=file('C-large.in','r')
- outf=file('C-large.out','w')
- casenum=int(inf.readline())
- for c in range(0,casenum):
- tmp=inf.readline()
- f=float(tmp.split(' ')[0])
- R=float(tmp.split(' ')[1])
- t=float(tmp.split(' ')[2])
- r=float(tmp.split(' ')[3])
- g=float(tmp.split(' ')[4])
- TotalArea=math.pi*R**2/4.0
- A=0
- fn=0
- r=r+f
- t=t+f
- g=g-2*f
- if g > 0:
- i=0
- while i*(g+r*2.0)+r < (R-t):
- x=i*(g+r*2.0)+r
- xp=x+g
- j=0
- Yi=math.sqrt((R-t)**2-x**2)
- try:
- Yip=math.sqrt((R-t)**2-xp**2)
- except:
- Yip=0
- while j*(g+r*2.0)+r 0:
- fn+=nfn
- j+=nfn
- #print "c=",c,"i=",i,"j=",j,nfn
- continue
- if xp < R-t:
- if yp Yip and yp <= Yi:
- if y Yi
- if y < Yip:
- A+=(sg(x,R-t)-sg(xp,R-t))/2.0-g*y
- #w="3a.不规则"
- elif y < Yi:
- A+=(sg(y,R-t)-sg(Yi,R-t))/2.0-(Yi-y)*x
- #w="3b.不规则"
- else: #这个是不可能的
- print "c=",c,"i=",i,"j=",j,"y=",y,"yp=",yp,"Yi=",Yi,"Yip=",Yip,"x=",x,"xp=",xp,"R-t=",R-t #,w
- else:
- if yp <= Yi:
- A+=(sg(y,R-t)-sg(yp,R-t))/2.0-g*x
- #w="4.下不规则"
- else:
- A+=(sg(y,R-t)-sg(Yi,R-t))/2.0-(Yi-y)*x
- #w="5.三角不规则"
- j+=1
- i+=1
- A+=fn*g*g
- #print TotalArea,A
- outf.write('Case #%d: %0.6f\n'%(c+1,(1-A/TotalArea)))
- inf.close()
- outf.close()
C 语言 IQ 题..
http://linuxfire.com.cn/~alecs/fun/xiaoming.txt
小明初学 C 语言,写了个程序,想打印 99 个 ‘#’. 程序如下:
int i, n=99; main() { for(i=0; i<n ; i--) { printf("#"); } }但是这个程序是错的.
Question 1: 请大家帮他改正, 但只允许 1) 删除一个字符 or 2) 增加一个字符 or 3) 改变一个字符
Question 2: 同样的限制条件, 使得只打印一个 ‘#’
Qeustion 3: 同样的限制条件, 打印 100 个 ‘#’
这个题目,粗看无聊,仔细想想还挺有意思的,我归纳了下,有这些答案. 点击查看全文 »
下面要帖答案了,要自己思考下的先别往下看了.
跟我一起写 Makefile (PDF)
以前有人在论坛里发过: http://forum.ubuntu.org.cn/viewtopic.php?t=61841
原文在这里: http://blog.csdn.net/haoel/archive/2004/02/24/2886.aspx
作者: 陈皓
我整理成了PDF,并修改少量错字.
给有需要的人,估计受众不会很大,嘿嘿.
链接期的”undefined reference to”问题又一解
今天拿到公司的一个程序,在本机(ubuntu8.04)编译了一下,编译起见是一堆的警告:” 警告: 不建议使用从字符串常量到‘char*’的转换”,可以跳过去,但是到了链接期间,就又是可恶的 “undefined reference to”问题了,网上查了一些资料说是因为找不到 *.a/*.o 之类的库文件,或者是库文件里面没有相关的符号导致,但是我这程序原样复制到服务器里面,借给是可以编译的,而且提示错误的那个 .a 文件也是从服务器复制的,可以保证是一模一样的,但为什么本机编译就是不行呢?后来想到服务器是RHEL4,
gcc –version 的输出是: gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-8)
g++ –version 的输出是: g++ (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-47.3)
而我本机的 gcc和g++确都是 4.2.3 的新版本,会不会是编译器的版本不兼容呢?看makefile里面用的是 g++ ,所以我先安装了 g++-3.4 ,然后把makefile里面的 PUBCC = g++ 改为 PUBCC = g++-3.4 ,再编译的时候发现编译期间的警告没了,但是链接还是照样报错;于是又卸载了 g++-3.4,换成了 g++-3.3,再编译的时候,居然是一切正常,和服务器上的表现一样了….
最后: 虽然是找到了 链接期的”undefined reference to”问题 的又一个答案,但个人对编译器的不兼容问题表示忧虑.
修改了下lunar-applet的源代码
lunar-applet是一个可以显示农历的软件,我一直是用这个代替原来的时钟的。最近把panel改成透明的了,而且壁纸的颜色比较深,这样一来,黑色的时钟文字在深色背景下看起来就有点累了.刚好,TX兄发现了修改applet时钟颜色的方法,可以自己写HTML定义颜色等.但是那个是针对原版的applet的,在lunar-applet上实验了下,居然无效,有点郁闷了.
好在linux下,一切都是自由的,居然原来无效,那就自己加上这功能吧,于是找来源码,自己修改了一些,嘿嘿,实现了想要的功能:
gconftool-2 --set --type string /apps/panel/applets/applet_2/prefs/format "custom" gconftool-2 --set --type string /apps/panel/applets/applet_2/prefs/custom_format '<span color="#ee1111">%Y-%m-%d %A <b>%H:%M:%S</b></span>'
效果:

如果有需要,可以放出修改后的源码或者deb包. (其实是因为本人至今都不知道怎么用patch和打deb包…)