mysql,Linux,HighPerformance,ruby on Rails

2010年2月27日星期六

小写金额转换为大写金额(Ruby实现)

这个题目已经被无数人写过,网上有Ruby版,有Javascript版,有Python版,有JAVA版。但我看到的即没有测试也没有图例,能看的清晰的不多。
这不,我也凑凑热闹,写一版,方便大家对比指正。

我从网上整理的条件:
一、中文大写金额数字应用正楷或行书填写,如壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样。
二、 中文大写金额数字到"元"为止的,在"元"之后,应写"整"字,在"角"之后可以不写"整"字。数字有"分"的,"分"后面不写"整"字。
三、阿拉伯小写金额数字中有"0"时,中文大写应按照汉语语言规律、金额数字构成和防止涂改的要求进行书写。举例如下:
    (一)阿拉伯数字中间有"0"时,中文大写金额要写"零"字。如¥1,409.50,应写成人民币壹仟肆佰零玖元伍角。
    (二)阿拉伯数字中间连续有几个"0"时,中文大写金额中间可以只写一个"零"字。如¥6,007.14,应写成人民币陆仟零柒元壹角肆分。
    (三)阿拉伯金额数字万位或元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写金额中可以只写一个零字,也可以不写"零"字。如¥1,680.32,应写成人民币壹仟陆佰捌拾元零叁角贰分,或者写成人民币壹仟陆佰捌拾元叁角贰分;又如¥107,000.53,应写成人民币壹拾万柒仟元零伍角叁分,或者写成人民币壹拾万零柒仟元伍角叁分。
    (四)阿拉伯金额数字角位是"0",而分位不是"0"时,中文大写金额"元"后面应写"零"字。如¥16,409.02,应写成人民币壹万陆仟肆佰零玖元零贰分;又如¥325.04,应写成人民币叁佰贰拾伍元零肆分。

 写的图例在上面,你可以看。

代码在这里:两个文件:
chinesedecimal.rb
http://gist.github.com/316775

testhelpers.rb
http://gist.github.com/316780

你只要把上面两个文件贴到你的记事件成为对应的文件名,在命令行下键入ruby chinesedecimal.rb即可跑出结果。
因为有测试,所以我很放心这样的结果。即使有错误,我也可以通过测试样例去解决。这就是最简单的unit test过程了。

__DONE__

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月25日星期四

使用rvm体验rails3-pre版

作为rails爱好者,现在rails3呼之欲出。但总归没有出来。想玩一玩,怎么搞呢。看下面:

1. Install Ruby Version Manager
 $ sudo gem install rvm $ rvm-install
2. Install Ruby 1.9.2 HEAD
 $ rvm install 1.9.2-head -C --enable-shared,--with-readline-dir=/opt/local
注意:readline目录你需要自己指定

$ rvm list rubies (执行此命令知道有哪些可以跑。)
 
rvm Rubies

=> ruby-1.9.2-head [ i386 ]

System Ruby

   system [ i386 ]

这行就是指定确认ruby runtime
$ rvm  ruby-1.9.2-head --default
最后验证一下:
 $ ruby -v ruby 1.9.2dev (2010-02-25 trunk 26759) [x86_64-darwin10.2.0]
3. 给gem当然创建一个集合,把这个beta版的所有依赖gem安装在这里,不合其它ruby runtime混在一起:
 $ rvm gems create rails3beta $ rvm 1.9.2-head%rails3beta
 $ gem install sqlite3-ruby
$ gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
$ gem install --no-rdoc --no-ri tzinfo builder memcache-client rack rack-test rack-mount erubis mail text-format thor bundler i18n
$ gem install --no-rdoc --no-ri rails --pre
注意mysql_config的路径要配置成自己的。
最后成果如下:
 $ ruby -v   ruby 1.9.2dev (2010-02-25 trunk 26759) [x86_64-darwin10.2.0] $ rails --version   Rails 3.0.0.beta $ gem list   *** LOCAL GEMS ***  	abstract (1.0.0) 	actionmailer (3.0.0.beta) 	actionpack (3.0.0.beta) 	activemodel (3.0.0.beta) 	activerecord (3.0.0.beta) 	activeresource (3.0.0.beta) 	activesupport (3.0.0.beta, 2.3.5) 	arel (0.2.1) 	builder (2.1.2) 	bundler (0.9.7) 	erubis (2.6.5) 	i18n (0.3.3) 	mail (2.1.3) 	memcache-client (1.7.8) 	mime-types (1.16) 	mysql (2.8.1) 	rack (1.1.0) 	rack-mount (0.6.0, 0.4.7) 	rack-test (0.5.3) 	rails (3.0.0.beta) 	railties (3.0.0.beta) 	rake (0.8.7) 	sqlite3-ruby (1.2.5) 	text-format (1.0.0) 	text-hyphen (1.0.0) 	thor (0.13.3) 	tzinfo (0.3.16)
最后注意:
之后想使用这个rails3+1.9.2dev的完整环境,应该使用这个命令:
rvm 1.9.2-head%rails3beta
如果想返回系统本身的ruby
rvm system

这些都在rvm的手册有详细说明,不过想掌握,还是需要花时间看一会的。记住上面两条就已经可以应付90%情况。

最后你就可以创建一个rails3-pre
$ rails blog; cd blog
$ rails server

会出错:
 
Your bundle is complete!
run rails generate rspec:install from "."
/usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:20:in `alias_method': undefined method `dependencies' for class `Gem::Specification' (NameError)
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:20:in `<class:Specification>'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:9:in `<module:Gem>'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler/rubygems_ext.rb:6:in `<top (required)>'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler.rb:4:in `require'
from /usr/lib/ruby19/gems/1.9.1/gems/bundler-0.9.8/lib/bundler.rb:4:in `<top (required)>'
from /home/hal/dm_rails3_app/config/boot.rb:6:in `require'
from /home/hal/dm_rails3_app/config/boot.rb:6:in `rescue in <top (required)>'
from /home/hal/dm_rails3_app/config/boot.rb:2:in `<top (required)>'
from /home/hal/dm_rails3_app/script/rails:9:in `require'
from /home/hal/dm_rails3_app/script/rails:9:in `<main>'

 郁闷吧。搞到这时就郁闷了.没关系,只要注释这行代码:
 
/rubygems_ext.rb:20
运行一切OK。

__DONE__

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月23日星期二

我对AppEngine的理解及JrubyOnAppEngine入门最精简版

用Ruby一年了,让自己感触深处的是自己的成长。所以私底下里暗想,多去理解一门语言对于开发者还是有必要的。在ChinaonRails社区我正好发起一次线上Ruby聚会讨论Jruby on GAE,使用Google Wave来缩短Ruby爱好者的距离和时空。有不少朋友在Wave上Ping我,参加我发起的聚会,因为之前我们并不认识,也不了解对方,但我们就是通过Ruby话题能产生线上聚会的能力。用Google Wave来解决实用操作问题,这也是我突发奇想,因为我之前一直找不准用Wave能干嘛。所以试试吧。

言归正传,Google AppEngine对于开发者来说,它的价值在哪里。实际上我在按它的教程中一步走下来后,我认为那就是简化了开发流程,让开发者只要有网络,就可以发布自已的应用(有限制,但可以付费解决。实际情况是作中小行应用产生的流量还不是很差,对我们来说起步是没有问题的)。它可以存储数据,可以处理图片,邮件,还能Cron。在这样一个有限的空间里,目前我看到已经有的应用有Blog,Email及image Services.如果你是SOA的架构,你完全可以使用它来处理一个小功能模块。

上手时我使用了Python,可以说我对Python的学习就是1天的时间,我并没有想掌握这门语言,我就是去在线教程看了一下安装,helloword就可以了。你这时就可以去看Google Appengine的手册了,按着它的要求一步一步走下去作一遍。具体在哪里呢,这里的《使用入门》有Python,Java两块,全中文,只要是中国人就能去写。我当然直接Python直接去跑了一遍。理解到了WSGI和Ruby对应的就是Rack,对于什么是Rack可看这里,在Python中使用GAE的入门文档,不会有任何未之错误,一路走下来很快就能掌握。

当然为了明天(2-24星期三下午1点到2点)的聚会当主持,不至于什么都不清楚,我特意去找了JRuby的资料,很显然这块并不是很热,所以大部分单独使用Jruby结合GAE for JAVA SDK的文章,只会增加难度,让我也是很受伤。不过最后还是发现了金子:appengine-jruby,跟进了一下文档,实作了一把。明白它这个项目就是我们需要的,完全是一路顺风就能用上ruby On Engine。意义在于你会Ruby,那么你就可以直接无痛的实作在GAE上。
如果我理解没有错误的话,对于GData层,它使用DataMapper解决,Sinatra对应Google的webapps框架,这很重要,template也被HAML替换。也就是说你编码使用的是纯ruby。所以你完全透明使用它,不必考虑它的兼容性语法问题。Awesome!

那么如果你也想使用上JRuby On GAE的话,怎么整呢,入门手册你看多了也不会消化,我给你最直接的方式:
第一步:安装JAVA,5,6都可以,6当然好,性能取胜。
第二步:安装appengine-jruby gem,
 $ sudo gem install google-appengine
可能会出现问题,不要急,很有可能是gem兼容性问题,不用急着翻阅资料,看看错误性能再找找。为什么我这里强调就是因为我出现问题就去找了好大一会,其实是多虑了。
第三步:先跑hello应用:这里:

$ mkdir hello
$ cd hello
新建config.ru放在hello下,输入如下代码

run lambda { |env| Rack::Response.new('Hello World!').finish }

然后跑吧
hello $ dev_appserver.rb .
浏览验证它:
http://localhost:8080/

第四步:来个真实的sinatra版的helloWorld。 按这里走

以上就是全部,更多看这里

其实看多了也没有意义,就是Request,Respone这个模式。

总结下来,我们掌握了Jruby就可以作与twitter,Google..Service交互的web应用。
如果你想不出来,可以去github下去看看代码去部署一个Blog

参考:
appengine-jruby代码库:
http://code.google.com/p/appengine-jruby/

Yoko Harada
http://yokolet.blogspot.com/

Rake for jruby
http://github.com/nicksieger/jruby-rack

sinatra framework
http://www.nicecabbage.com/tag/sinatra/


__END__

2010年2月21日星期日

看Facebook是如何作网站优化的,即推荐OReilly的《Even Faster Websites》

update: 加一个Facebook的华人工程师作报告用的Slide

首先,鉴于Facebook需要翻墙才能浏览,上面的好友一只手就能数清楚,所以再次上去浏览新版的界面,并没有感觉有快的意思。但前几天,看到@Fenng推的链接,才点了链接看了Facebook的engineer's Notes的精彩技术分享:
Making Facebook 2x Faster 写的技术上的内容真是可以成为极致优化的精典案例了。用2009年差不多半年的时间就让浏览速度翻番,绝对的工程性创举,并且对我们来说,参考价值或者说可参考的点非常多。从思路到实作我感觉比它发布的PHP-Hithop更具实用价值。如果你的互联网工程师,绝对可以一读,长长见识遇到哪位大虾再乱喷也能作个心理有数。

第二,我要推荐的Facebook华人工程师作的报告,内容更是具体。小视频托管在youtube上,品质保证,地址是http://www.youtube.com/watch?v=51JGykHrwZA。当然要想从这个视频里获得点,我估计你需要能完全听懂英文。
都是中国人发音,你考虑下。:-),这里我说一下听到的心得,
1、我们做任何优化时都需要有参考数据,也就是Metrics。想起以前领导要求我作这样的分析,我能想到的就是去别的网站看看,再找一些历史数据分析分析。说白了我根本就没有数据可参考。杯具啊,硬着头皮去写一些优化性能报告。在看完Facebook的之后,我那思路其实就是扯淡,一点工程师的风格都没有。还好,现在听完之后起码不会乱搞。
2、Facebook的这次优化是极致优化,所以并不是国内工程师在搭建新系统的时候才想到的优化,所以这对性能及实施都是极度的挑战。所以他们想到了针对海量的Static Resource作管理,从技术上讲,这个技术根本就不是技术,但我斗胆相信国内根本就不会这种管理策略。懂的就想想别人的思路,不明白的您请绕道看下一段。
3、Quickling,Ajaxify的框架,细节不会透露,但真是汗颜的地方是他们对技术的娴熟程度给我一个新的启示,那就是要对技术的本质掌握。作互联网的工程师,你不对本质的东西来来回回的在心里面揣摩,肯定成不了专家。警示自己别去看什么JQuery的手册,看源代码。从本质入手。总想着作专职的"Javascript"专家。记住,专家的称号是别人给你的,如果没有本质的掌握,别人随时可能再给你拿走这个专家头衔。看好了,这后半句才是精华。

上面就是我这一天来的感受,当然言词中对Facebook技术的兴奋或更可说成是一种崇拜。但细想下来,人不可能一日成精,如果能赶上它们的步伐呢。是的,我找到一本书,其实也很知名,什么心得啊体会啊根本就不用写,你只需要知道两点,OReilly出版,书名《Even Faster Websites》.再送一句话,国内买不到,国内要刷Visa卡。当然喽,对于资本主义的糟糠,我们还是可以从垃圾桶里捡到.

http://i192.photobucket.com/albums/z18/virtualzin/eB/Eveastebsites.jpg


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月19日星期五

第一章体会,About Driving Code Through Tests

http://covers.oreilly.com/images/9780596523015/cat.gif
《Ruby Best Practices》是一本很棒的Ruby技术提升书籍。有了它,成为Ruby"大牛"只日可待啊。呵呵。
首先第一章(Driving Code Through Tests)就从测试开始,足以显示测试技巧的重要性。那个咱们扪心自问,你在写最近的代码中是否有使用过Test?你有哪些不爽的地方想解决?不管怎么说,我是带着这些问题去看的这章。

第一步,Designing for Testability,书中讲的就是如何测试,是不是遵循"Red, Green, Refactor",按此法来跑测试会有什么误解,书中有一个论断:how much work needs to be done between each phase of this cycle.实际上这是在遵循TDD开发过程中遇到的比较实际的,并且是程序员需要面对的问题。所以这才是最重要的,这是一本写给Coder的书,它不是"教条课本",对咱们大白话来说,实用主义,拿来用先看看吧。因为书中代码使用的是Ruby Core Library,Test::Unit,所以有通用性,大家直接可以上手。事实上,在新手阶段,使用好Unit已经是很好的开始,而使用RSpec这种更为人性化的"复杂"的多的Test FrameWork来说,你应该在Testing学习中使用UnitTest.

第二步,Testing Fundamentals,测试基础,没有人天生就会写测试代码。别看那些牛人发布在github上的代码,上来就有test代码(当然也有垃圾代码,小心),让我等除了膜拜之外,无从下手。那么TDD中测试的关系点在哪几点呢,书中给了详细解释。

第三步,Testing Exceptions,测试异常,这是我之前没有注意到的,就是一个知识点,就是要会使用assert_raises,assert_nothing_raised,个中体会这是行为测试里面的东西吧,细节啊,要注意。

第四步,Run the Whole Suite at Once,把多个Test打包,怎么实现的。这里有技巧。

第五步,高级测试技术,Using Mocks and Stubs,(题外话:这个术语翻译起来我感觉特别绕口,还不好理解。因为从原理上来说,这英文术语和它本来的原意是有一个联系的,不然人家用它干什么。但如果翻译成中文,那就煞笔了,从此诀别原来的本意了。建议还是背英文单词都比翻译从中文强。说白了,有些技术,你就看这关键的词,把自己的心得记下来,慢慢体会这也是一种积累。)那么什么是Mocks,Stubs?实话实说,我说不清楚,但Martin大叔有论断:Mocks Aren't Stubs,一大陀英文看着说来挺费事,更推荐台湾友人的中文心得Slide。反正说来说去,有一点我是明白的,Mocks多用,Stubs是老Test风格,仅此而以。但限于开源软件的多样性,不管别人的代码是使用什么风格,我认为只要管用就可以,因为有test,总是能读懂的,你说是吧。这种提到的问题是测试的可用性及覆盖率的问题,是属于高阶测试技术,一定要注意。详细的可看书中的观点。

第六点,高级测试技术,Testing Complex Output,我不认为这有多高阶,不过在开发OpenTaobao的Client代码时,确实遇到这个问题,并且我不知所措,最后情急之下,直接跑代码用肉眼来分析返回值,有点傻。:-(,看完这段内容后我终于知道问题出在哪里,以后我知道怎么作了。
在Testing Complex Output结尾的段落里有一小段高级测试技术的总结,都是精华。一定要关注。

第七点,Keeping Things Organized,管理测试代码,经验之谈,很好很实用。

That's All.

参考:
1. http://oreilly.com/catalog/9780596523015
2. http://blog.rubybestpractices.com/posts/gregory/015-rbp-ch1.html
3. http://www.martinfowler.com/articles/mocksArentStubs.html
4. http://www.slideshare.net/weijenlu/mock-arent-stub


--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月17日星期三

使用Python和AppEngine制作发送中文邮件DEMO应用

在twitter上看过livid年前就说过2010年Google AppEngine是一个方向。我开始没有什么感觉。不过今天的投入开发让我多少有些信心,最起码对于初创的应用来说,AppEgnine是一个合适的平台。所以我想到使用mail api接口来试一下。最后在http://mail4china1.appspot.com/上架起了AppMail的应用。支持中文。
附件是python代码,client端使用php+PHPUnit可以快速测试。



python tools :
1. appcfg.py
2. dev_appserver.py

1. helloworld练习,
包括: 工程目录名,同名py, app.ymal

*其中ymal格式参考:http://code.google.com/intl/en/appengine/docs/python/config/appconfig.html

2.App Engine的自有webapp框架
参考: http://code.google.com/intl/zh-CN/appengine/docs/python/tools/webapp/

3.app engine处理中文通用解法

4.Google App engine Slides , http://www.slideboom.com/people/cyrilwang



参考:
Install Python PIL module in Mac OS X
http://blog.bracewell.org/2009/08/11/install-python-pil-module-in-mac-os-x/

--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月15日星期一

免费的远程图片处理服务,仅使用Heroku和Imagery

先看例子:
http://lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app.png
可以远程转换:
http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app_medium.png

实现方法:
这里fork一份代码,注意这是一份Rack版本的应用。(什么是rack?
使用heroku直接创建一个目录,上传此代码就马上可以运行。

想在你的应用中使用这个缩略图处理服务需要一个小技巧:
你需要使用一个子域名绑定到heroku。免费,但需要你输入一次信用卡帐号信息。

为什么呢?因为核心代码是这个处理的:

run Imagery::Server.new

-------------挖掘深层代码分割线-----------------
[SvgGenerator, ImageVariantGenerator].each do |generator|
if image = generator.from_url(env['SERVER_NAME'].split('.')[1..-1].join('.'), env['PATH_INFO'] + (env['QUERY_STRING'].empty? ? '' : "?#{env['QUERY_STRING']}"))
return send_file(image)
end
end
标红的代码的作用就是把
'images.lucidcode.co.nz'换成'lucidcode.co.nz'
-------------挖掘深层代码分割线-----------------
def self.variant_parser
@variant_parser ||= /(.*)\_(#{Transformations.list.join('|')})(#{SupportedImageTypes.join('|')})/i
end

def self.from_url(server, path)
return nil unless path =~ variant_parser

remote_path = "#{$1}#{$3}"

file = Image.new(server, remote_path)
if file.found?
transform_content(file, $2)
file
else
nil
end
end
标红的代码就是拿到regex中的第一处匹配和第三处匹配。再看例子你就能明白:
irb(main):020:0* path = 'http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app_medium.png'
=> "http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app_medium.png"
irb(main):022:0* path =~ /(.*)_(medium|large|)(.png|.gif)/
=> 0
irb(main):023:0> $1
=> "http://images.lucidcode.co.nz/assets/4b70dca0dabe9d5d3700003e/harmony-app"
irb(main):024:0> $2
=> "medium"
irb(main):025:0> $3
=> ".png"
标红的地方就是精华,实际上就是拼字符串。把中间的_medium这个变量给去掉。得到实际的图片地址。

这个好东西有什么用处呢?
有,可以帮你节约一些图片存储空间。heroku一个应用可以有20M的免费空间。对于小图片来说,就能存储不少了。
好好利用,给你的免费用户使用这样的空间,应该可以帮你节约流量。

所有技术全部归于老外,我就是转转。

参考:
http://lucidcode.co.nz/blog/archives/2010/02/09/remote-thumbnails-with-heroku-and-imagery/
--
tommy xiao
E-mail: xiaods(AT)gmail.com

2010年2月5日星期五

LinkedLn的新贡献->LinkedIn Search: A Look Beneath the Hood

今天有幸看了LinkedIn Search: A Look Beneath the Hood中的ppt,LinkedLn的工程师又给我们带来的完全
开源的搜索框架解决方案,基于Aapche Lucene的Zoie搜索框架。

这是这项搜索技术的领域:
Faceted search
, also called faceted navigation or faceted browsing, is a technique for accessing a collection of information represented using a faceted classification, allowing users to explore by filtering available information. A faceted classification system allows the assignment of multiple classifications to an object, enabling the classifications to be ordered in multiple ways, rather than in a single, pre-determined, taxonomic order. Each facet typically corresponds to the possible values of a property common to a set of digital objects.

另,Rails 3 Beta已经出来,相信今年早些时间,我们就可以用上新的Rails3。期待。


--
tommy xiao
E-mail: xiaods(AT)gmail.com