Thursday, May 31, 2007

Q1: multiplying rabbits

Question: A newly born rabbit is capable of reproducing at one month old (when it matures). Suppose the rabbit never dies, and it continues reproducing one new rabbit every month. So, when the rabbit is born, it has one member in its own family. After a month, it matures, and by the second month it adds a new born member to its family. In the third month, the rabbit produces another offspring; its first child also matures and will be ready to have an offspring in the next month. How many pairs of rabbits can be produced in a year from a single pair?

Answer: Let us write down the sequence of the rabbit number: 1, 1, 2, 3, 5, 8, 13 ... . It is a Fibonacci numbers.

The following code is the implementation in Java.

public class Fibonacci {
public static int getFibonacci(int n){
if(n < 0) return 0;
if((n == 0) || (n == 1)) return 1;
return getFibonacci(n-1) + getFibonacci(n-2);
}

public static void main(String[] args) {
for(int n=-1; n < 13; n++)
System.out.println(n + ": \t" + Fibonacci.getFibonacci(n));
}
}
}

The result:
-1: 0
0: 1
1: 1
2: 2
3: 3
4: 5
5: 8
6: 13
7: 21
8: 34
9: 55
10: 89
11: 144
12: 233

Monday, May 28, 2007

RoR: lighttpd proxy setting

For accessing other servers' resources transparently, setting up the web server to support reverse proxy.

In lighttpd, the steps:
1. add 'mod_proxy' in server module group;
2. set up the server as:
=================================================
$HTTP["host"] == "rails.qiang.com" {
server.document-root = "/rails/sample/public"
url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
server.error-handler-404 = "/dispatch.fcgi"
server.errorlog = "/rails/sample/lighttpd.log"
fastcgi.server = ( ".fcgi" =>
( "localhost" =>
(
"min-procs" => 2,
"max-procs" => 4,
"socket" => "/tmp/stage-fcgi.socket",
"bin-path" => "/rails/sample/public/dispatch.fcgi",
"bin-environment" => ("RAILS_ENV" => "rail")
)
))

proxy.server = ( "/other" => ( "other" => ("host" => "1.1.1.1/other", "port" => 80)))
}
=================================================

For apache, please read the followed link: http://www.apachetutor.org/admin/reverseproxies.

Friday, May 18, 2007

RoR: unexpected nil when trying to parse a query string

While sending a HTTP post message that contains a substring '&&' in the body to a ruby on rails application, there is a error reported:

==================================================
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?
/public/../config/../vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb:49:in `parse_request_parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb:47:in `parse_request_parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/cgi_process.rb:71:in `request_parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/request.rb:13:in `parameters'
/public/../config/../vendor/rails/actionpack/lib/action_controller/session_management.rb:122:in `set_session_options_without_components'
/public/../config/../vendor/rails/actionpack/lib/action_controller/components.rb:178:in `set_session_options'
/public/../config/../vendor/rails/actionpack/lib/action_controller/session_management.rb:116:in `process'
/public/../config/../vendor/rails/railties/lib/dispatcher.rb:38:in `dispatch'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:150:in `process_request'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:54:in `process!'
/usr/lib/ruby/site_ruby/1.8/fcgi.rb:612:in `each_cgi'
/usr/lib/ruby/site_ruby/1.8/fcgi.rb:609:in `each_cgi'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:53:in `process!'
/public/../config/../vendor/rails/railties/lib/fcgi_handler.rb:23:in `process!'
/public/dispatch.fcgi:24
==================================================

The error occurred because '&' is the separator of different name/value pair in a message body, such as "name1=value1&name2=value2", and rails framework doesn't handle the string "&&" properly. According to a bug report and its patch in rubyonrails.org (http://dev.rubyonrails.org/ticket/5714), we need to change "/vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb" line 47 from

==================================================
for key, value in params
value = [value] if key =~ /.*\[\]$/
unless key.include?('[')
# much faster to test for the most common case first (GET)
# and avoid the call to build_deep_hash
parsed_params[key] = get_typed_value(value[0])
else
build_deep_hash(get_typed_value(value[0]), parsed_params, get_levels(key))
end
end
==================================================

to

==================================================
for key, value in params
if (not key.nil?)
value = [value] if key =~ /.*\[\]$/
unless key.include?('[')
# much faster to test for the most common case first (GET)
# and avoid the call to build_deep_hash
parsed_params[key] = get_typed_value(value[0])
else
build_deep_hash(get_typed_value(value[0]), parsed_params, get_levels(key))
end
end
end
==================================================