Showing posts with label Articles. Show all posts
Showing posts with label Articles. Show all posts

Saturday, May 28, 2011

Calculating Cubic Bezier Function

If you ever played with the CSS3 native css-transitions, you know that they use cubic-bezier notation to define the transition formula. Cubic Bezier is a parametric function that allows you to define all sorts of smooth curvatures that looks kinda like that



The reason why it's used instead of sinuses and exponents, is that it allows you to define all sorts of shapes with just a few more or less intuitively understandable parameters. Plus, unlike other mathematical functions it can be computed very fast, because it's a simple parametric function, no sequences no nothing.

In RightJS we support native css3 transitions, but it also has a pure JavaScript fx-engine to handle old browsers. And the thing is that native CSS3 transitions use the cubic-bezier functions, while the pure JavaScript engine uses a bit of mumbo-jumbo with Math.sin() and Math.log(), and what I wanted is to allow the developers to use cubic-bezier notation with the old engine.

The problem is that it's not that simple. The cubic-bezier function itself is pretty much straightforward and you can calculate a set of X and Y coordinates in no time, but it won't make you any good because both x-s and y-s will be related to the third t parameter and therefore unevenly distributed agains the t parameter. What you really need is a straight Y = B(x) function.

And here it gets tricky. That much tricky. But, luckily for us, there is always a better way to do it. All you need is to recall a bit of kindergarden math.

Originally, the cubic bezier function is used in a parametric form, but it also can be converted into a polynomial form, in which case it will look like that (you can google it and find say this document)

a = 3 P0
b = 3 P1
c = 3 P2
c0 = P0
c1 = b - a
c2 = a - 2b + c
c3 = P3 - P0 + b - c

B(t) = c0 + t(c1 + t(c2 + tc3))

In case of CSS3 cubic-bezier definitions, P0 is always 0 and P3 is always 1, in which case the formula gets even simpler

c3 = 3 * P1
c2 = 3 * (P2 - P1) - c3
c1 = 1 - c3 - c2

B(t) = t * (c1 + t * (c2 + t * c3))

Which, in case of of CSS3 x1,y1,x2,y2 parameters, can be written in javascript with two functions, for example this way

var Cx = 3 * x1;
var Bx = 3 * (x2 - x1) - Cx;
var Ax = 1 - Cx - Bx;

var Cy = 3 * y1;
var By = 3 * (y2 - y1) - Cy;
var Ay = 1 - Cy - By;

function bezier_x(t) {
return t * (Cx + t * (Bx + t * Ax));
}

function bezier_y(t) {
return t * (Cy + t * (By + t * Ay));
}

There are two reasons why we use the polynomial form of the equation. Firstly, it has less operations and therefore will work faster. Secondly, we are going to use Newton's method to approximate the values and will need a first derivative of one of the functions, which in case of polynomial functions is pretty simple.

Now, to the fun part. We converted the function from one form to another, but the question remains the same, how are we going to get the y = B(x) from x = B(t) and y = B(t)? Quite simple my friends, we will use the kindergarden math, or more exactly the Newton's method to approximate a parametric x value for every t value so that we could get an evenly distributed set of x values and then get a set of y for them using the same bezier_y(t) function.

Newton's method might look a bit scary for those who are not familiar with it, but it is actually very simple. Check this video the guy explains it nicely.

All you need to make it work is to have a derivative to your function, which in our case will look like that

function bezier_x_der(x) {
return Cx + t * (2*Bx + t * 3*Ax);
}

And after that, we just define a little function that will make several iterations trying to find an x value which came from the current t value. We don't have to be very precise in our case, we just make 5 iterations tops and limit the precision by the 3 digits after the pointer.

function find_x_for(t) {
var x = t, i = 0, z;

while (i < 5) {
z = bezier_x(x) - t;
if (Math.abs(z) < 1e-3) break;

x = x - z / bezier_x_der(x);
i++;
}

return x;
}

Now you can create a loop and calculate a set of evenly distributed values, just like that:

var result = [];
for (var i=0; i < 1.001; i+=0.1) {
result.push(bezier_y(find_x_for(i)));
}
console.log(result);



That's basically all of it. You can find the full version of this script in this gist.

Enjoy!

Sunday, May 8, 2011

How To Read User Input With NodeJS

I think it's time for me to join the NodeJS hysteria. So, I'd like to share a bit of things I was tackling today because there is not really much of docs on that matter right now.

Short things short. If you're writing a little console script in NodeJS that supposed to ask the user this and that, here's how you can get it done.

Node's global object process has two properties called .stdin and .stdout, which are essentially streams. You can write things into the stdout and listen to the 'data' event in the stdin stream. A simple example from the api-docs looks like that

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function (chunk) {
process.stdout.write('data: ' + chunk);
});

You need to call that .resume() method first, it initializes the STDIN reading process.

It is pretty straightforward, but it's almost useless when you need to ask the user several questions, more of that validate the input data and re-ask questions when something was entered wrong.

The basic trouble here is that .on('data' handler that will fire every time the user hits the Enter, so you'll have to figure out which question is currently asked an where to put the data. Given the fact that everything is happening asynchronously, it pretty quickly gets really messy.

Fortunately for us, there is another events handler in NodeJS called .once(.. it's basically same as .on( but it detaches the listener after the first event received. Knowing that, we can write a little helper function like that

function ask(question, format, callback) {
var stdin = process.stdin, stdout = process.stdout;

stdin.resume();
stdout.write(question + ": ");

stdin.once('data', function(data) {
data = data.toString().trim();

if (format.test(data)) {
callback(data);
} else {
stdout.write("It should match: "+ format +"\n");
ask(question, format, callback);
}
});
}

There are two important moments. First of all, don't use console.log to ask the user the question, otherwise it will print a new line at the end, which is kinda sucks. Secondly note that you should call .toString() and .trim() on your data, the first one to convert the data from a stream into an actual string, the second one is needed because the string will have a trailing new line symbol at the end after the user hits the Enter key.

After that, you can ask the user all sorts of questions. For example like that

ask("Name", /.+/, function(name) {
ask("Email", /^.+@.+$/, function(email) {
console.log("Your name is: ", name);
console.log("Your email is:", email);

process.exit();
});
});

And don't forget to call the process.exit() when you done, otherwise the script will just hung in there.

That's basically all of it. Enjoy!

Thursday, April 28, 2011

Why Make A Run For It

It has been almost two years since I decided to go public with RightJS and on this occasion I'd like to post some reflections on it.

Those days, thanks to github, it's pretty simple to start an open-source project. You just make a repo, write some awesome stuff and push it under the "I don't owe you shit" license. And I like it, in most cases that's all you really need. But, as fun as it is, there is actually another level to open-source projects. The level, where you decide to get serious about it and go public with your project. With promotions, users, official site, docs, tutorials and so on.

It is not completely necessary to make your project kinda "officially public", in many cases it might be even a bad idea, because that will distract you from the actual programming, but there are several important things in this process, which can be pretty valuable as well. And that's what I'd like to write about today.



It Will Make You A Better Programmer

The trouble with programmers is that we work in this area where most people don't really understand anything. And because of that, at some level, programmers tend to start thinking that they are pretty darn smart and kick ass.

A healthy portion of self-esteem is not a bad thing, it might help you to overcome some small obstacles on your way, but for a programmer as a knowledge worker it is crucial to stay hungry for new information.

And running your project for real, will give you exactly that. If you do something interesting enough, people will respond, they will throw all sorts of ideas at you, they will criticize and they will like (hopefully :)) some parts of your work, which will give you all sorts of new information.

With new information you'll face new problems and discover new ways to solve them, and that will make you better at what you do.



It Will Make You More Organized

It is not a secret that many developers don't like TDD and Tickets. Even the ones that do, often cheat and don't cover everything, don't document bugs and so on.

But, when you start an open project for real, you will have to deal with those things. You will have to handle tickets, document bugs and cover everything you can with tests so that folks who use your code had a hight quality experience.

More of that, most open-source projects, especially individual ones, are just about "scratching your own itch". It is highly doubtful that you will make any real money directly from your project, and as much as you might enjoy the creative process of writing code, at some point, you will have to get pragmatic about what you do.

You will need to start thinking strategically, where is it worth to invest your time and where it's not. And that is a highly valuable skill, not just for developing a software project, but genuinely in life.



It Will Make You Better With People

Well, you know what they say "all programmers are bad with people" :). The thing is, that people are irrational, even the smart ones. And there is only one way to learn how to deal with irrational - by accumulating experience.

One of the hazards of the trade is that programmers spend most of their time with computers, and that's certainly not a good thing for your social skills.

When you run an open-source project you will have to handle contributors and do that nicely. Because contributors are privilege. But as all people have different coding styles, different ways to approach issues and just different personalities, you will learn how to find common grounds with different folks, how to work together and how to coordinate the changes.



Conclusion

I don't want to sound like an open-source project is the most awesome thing that might happen to you. By the end of the day, if you're vicious bastard then all that will help you is an old-fashioned kick in the ass.

But, if you're interested in software-development, if you want to learn why and how the things done, running your own project for real might be very insightful and teach you quite a few things.

Monday, April 4, 2011

Making Tags With Rails And RightJS

As the tags widget appeared recently on the RightJS UI list, I'd like to write a simple how-to about tags in case of using RubyOnRails.

You can see the tags widget in action on this demo page, and over here you can find a demo rails application that has the tags feature implemented, along with some other right-rails features.

Let's start

The Initial Model

When you need to add a tags feature in a ruby-on-rails project, a standard model would look kinda like that

class Article < ActiveRecord::Base
has_and_belongs_to_many :tags, :uniq => true
end

class Tag < ActiveRecord::Base
has_and_belongs_to_many :articles, :uniq => true

validates_presence_of :name
validates_uniqueness_of :name
end

As you can see, it's a pretty much straightforward m2m association, articles have many tags and tags have many articles.


Tags To Strings Conversion

The next standard step is usually to add a couple of methods to convert the list of tags into a coma separated string back and forth. The basic reason is that tags are data-base records and it's not much of user-friendly to use integer ids

class Article < ActiveRecord::Base
has_and_belong_to_many :tags, :uniq => true

def tags_string
tags.map(&:name).join(', ')
end

def tags_string=(string)
self.tags = string.split(',').map do |tag|
unless tag.blank?
Tag.find_or_create_by_name(tag.strip)
end
end.compact
end
end

After that you can use this proxy property in forms directly, like that

<%= form_for @article do |f| %>
<p>
<%= f.label :tags_string %>
<%= f.text_field :tags_string %>
</p>
<% end %>

This way the user will always manipulate the tags list as a simple string and your app will automatically create the tag records and associations on fly


Hooking Up RightJS

At this point your rails app will present a kind of a standard and simple case of tags handling. Time to make it look nice and friendly with a bit of javascript.

To hook up RightJS into your Rails application all you need is just add the right-rails gem into your Gemfile

gem 'right-rails'

And run the following code generator

rails g right_rails

Don't worry when you see a tall list of scripts it copies into your public/javascripts directory, right-rails handles most of them automatically, so you won't really need to look inside of those.


Adding The Tags Widget

Ironically, the actual RightJS part of this enterprise is the shortest one. Once you added right-rails into your application, all you need to do is replace 'f.text_field' with 'f.tags_field' in your form

<%= form_for @article do |f| %>
<p>
<%= f.label :tags_string %>
<%= f.tags_field :tags_string %>
</p>
<% end %>

RightRails handles everything else automatically, it generates all necessary html, includes javascript/css modules, it even switches between minified and source builds of javascript libraries depending on the working environment.

More of that, it can automatically use the google hosted rightjs cdn-server for a superfast, shared scripts delivery.


Adding Autocompletion

By default the f.tags_field will make you a pretty looking tags-field, if you want to add the tags autocompletion feature to it, all you need is to specify a list of known tags in it

....
<%= f.tags_field :tags_string, :tags => Tag.all.map(&:name) %>
....


There is also a few additional options you can use with tags widgets, you can find them at the rightjs.org documentation


Conclusion

This is a good example to show how RightJS is build with server-side developers in mind. As you have noticed we didn't write a single line of javascript in our little exercise, not like we couldn't, just we don't have to bother with those routine things every time we need a simple form with a bunch of standard widgets.

More of that, if you take a look into your HTML code, you'll see that RightRails didn't write a single line of script either, all it did is added the data-tags attribute to your input field.

<input data-tags="{tags: ['one','two','three'}" value="one, two"
id="article_tags_string" name="article[tags_string]" />

This way, even if something will go wrong, the user will still see the standard input field with coma separated tags. All your styles and content will remain were it was.


--
Well, this is pretty much the whole story. If you're interested, go check the RightJS UI collection, it has many more useful widgets that you can use in your applications.

Thursday, March 24, 2011

Why ==null, Not ===null

Sometimes in RightJS source code you might see a thing like this

if (value == null) {
// ...
}

And as every JavaScript optimization tutorial tells you to use '===null' instead of '==null' and JSLint yells at you when do otherwise, people immediately try to change it to the "right" way.

Meanwhile there is a pretty good case when it is much better to use '==null' than '===null'.

The thing is, that in JavaScript we have this ugly thing called 'undefined', which is quite clunky and often weird in use. Like say you might have a piece of code like that

var hash = {a: undefined};
console.log(hash.a); // -> undefined
console.log(hash.b); // -> undefined

console.log('a' in hash); // -> true
console.log('b' in hash); // -> false

Which is a bit strange. So, it is quite often, people use 'null' to predefine keys in hashes and then need to check whether a certain value is not 'null' or 'undefined', kinda like this

if (value !== null && value !== undefined) {
// ...
}

Another case is that the 'null' thing is an object in JavaScript and sometimes you might need to check if a variable is a plain type value, you go with things like that

if (
typeof(value) !== 'object' &&
value !== null && value !== undefined
) {
// ..
}

There are lots of cases where you need this double check. You also should keep in mind the fact that 'undefined' is a variable in JavaScript and someone actually can define a variable named 'undefined', and in general case you'll need to handle that too. Well, you get the ugly picture.


So, what about that '==null' business anyways?

The trick is that '==null', unlike other boolean comparisons (for example '==true'), returns 'true' only for 'null' and 'undefined' values.

null == null;      // -> true
null == undefined; // -> true

null == false; // -> false
null == ''; // -> false
null == 0; // -> false

Which basically means that you can use value == null instead of

value === null || value === unefined

More of that, except being more compact, 'value == null' also will be protected from 'undefined' replacements, and the browser also won't perform a variable name lookup, because null is a keyword and there is nothing besides it. Which will make the things faster.

How much faster? Let's see. I cranked this little script and run it in FF4

function test1() {
var i=0, t = new Date(), v1 = null, v2 = undefined, r;
for (; i < 100000; i++) {
r = v1 === null && v1 === undefined;
r = v2 === null && v2 === undefined;
}
console.log(new Date() - t);
}

function test2() {
var i=0, t = new Date(), v1 = null, v2 = undefined, r;
for (; i < 100000; i++) {
r = v1 == null;
r = v2 == null;
}
console.log(new Date() - t);
}

console.log('--');
10..times(test1);
console.log('--');
10..times(test2);

And here is the result

--
22
24
23
23
23
23
23
23
24
23
--
2
1
1
1
1
1
1
1
1
1


Well, that's the whole story. Think you can put it in a good use :)

Friday, February 18, 2011

If I Would Design A Simple Format

There is an idea I wanted to spit out for quite a while now. It is about simple formats and to keep the short story short, here is a simple spec I cooked up.

Basically it is a mix of RDoc, Markdown and Maruku, plus some stuff I miss in all of them. The main goal in this one is readability mixed with abilities to handle everyday things, like images, tables, API references and stuff. HTML might be allowed as a fallback.

That's all, let me know what you think about it.


= Head 1
== Head 2
=== Head 3
==== Head 4

# Head 1
## Head 2
### Head 3
#### Head 4

= Head 1 #anchor1
## Head 2 #anchor2


*bold*
~italic~
_underline_
-strike through-
`type text`


http://some.url
</some.url>
<http://some.url>
<Some text:/some.url>

some@email.com
<some@email.com>
<Some email:some@email.com>


API Links

{ClassName#instanceMethod}
{ClassName.classMethod}

Defining a default scope
{-ClassName} after that
{#instanceMethod}
{.classMethod}


<img:/some.url>
<swf:/some.url>

<img:123x234:/some.url>
<swf:123x234:/some.url>

<img:Some title text:/some.url>
<swf:Some title text:/some.url>

<img:Some title text:123x234:/some.url>
<swf:Some title text:123x234:/some.url>


Code formatting


Just a genuine piece of code
That is pre formatted


Ruby piece of code

:ruby
this.is_a?(Ruby)
code.which_we do
paint in some do
nice(colors)
end
end

Javascript code

:javascript
this.isA(JavaScript).code();
that.we(Paint).accordingly();


> This is a quote text
> It will be converted to a block-quote
> > This is and internal quote
> > it will be nested into the original one


* List item 1
* List item 2

- List item 1
- List item 2


1. Num list item 1
2. Num list item 2


a. Letter list item 1
b. Letter list item 2


I. Roman number list item 1
II. Roman number list item 2
III. Roman number list item 3


* Mixed list 1
* Mixed list 2

- Mixed List 3
- Mixed List 4

1. Mixed List 5
2. Mixed List 6

a. Mixed List 7
b. Mixed List 8

I. Mixed List 9
II. Mixed List 10


Head | Head | Head
-----|------|-------------------
Cell | Cell | Cell
Cell | Cell | Cell
-----|------|-------------------
Foot | Foot | Foot


Head | Head | Head
| Head | Head |
-----|------|------|------------
Cell | Cell | Cell | Cell
Cell | Cell | Cell
Cell | Cell | Cell | Cell
| Cell | Cell |
-----|-------------|------------
Foot | Foot | Foot


Right | Left | Center |
----->|<-----------|------x------|
1 | 1 | 1 |
11 | 11 | 111 |
111 | 111 | 11111 |
1111 | 1111 | 1111111 |

Saturday, October 2, 2010

Making Pretty CLI Applications In Ruby

Sometimes we need to process large amount of data in Ruby, convert things from one format to another, process a large database, etc. And when you start implementing those things as rake tasks or something like that you need some feedback, say to see the progress and so one. Normally people would use puts

index = 0
count = things.size
things.each do |thing|
do_something_about thing

puts "#{index +=1} of #{count}"
end

But when you have several thousands or millions things to process this approach doesn't work, because it will just blow into the console, which is ugly and well... there are ways to do it much better, prettier and more professionally looking.

There are gems and libs that will help you to do it properly, but in this article I'd like to show how it actually works internally.


Strings Rewriting

One of the first things you might want to learn in order to make seriously looking CLI app is how to rewrite strings all over. It is a bit tricky in Ruby so here how it looks like. First of all you need to learn the "\r" symbol, which is called "caret return" and well it returns the caret. A simple example will demonstrate. Say you have a line of code like that

puts "one\ranother"

when you run it, you will see in the console a string like "another" and what's happening is that ruby will print "one" then return the caret and print "another" over it, so that you see the last one only. But the trouble is that if you'll write something like that

puts "one"
puts "\ranother"

It won't work and you'll see two strings in the console "one" and "another", and because of that if you'll put into your loop something like that

puts "\r#{index += 1} of #{count}"

it won't work either and you will see the same ugly roll of strings. To make it working you have to use the a combination of the print and STDOUT.flush calls, kida like that

8.times do |i|
print "\r#{i}"
STDOUT.flush
sleep 0.1
end

In this case it will print a string and stay on it. STDOUT.flush dumps the current stdout into the console, and on the next iteration, it will normally go to the beginning of the string and write it over as you needed.

But it is still not everything. If you run a piece of code like this one

%w{looooong short}.each do |str|
print "\r#{str}"
STDOUT.flush
sleep 0.5
end

You will see that on the second iteration, the previous line won't be entirely overwritten and instead of "short" you will see "shortong", to make it work properly you need to write a long enough string that contains spaces at the end, for example

%w{looooong short}.each do |str|
print "\r#{str.ljust(80)}"
STDOUT.flush
sleep 0.5
end

String#ljust makes a string of the given length by filling the remaining places with spaces. This way you will always overwrite 80 symbols of the line in the console.

To wrap it up nicely you might create a simple function and your loop will look like that

def print_r(text, size=80)
print "\r#{text.ljust(size)}"
STDOUT.flush
end

index = 0
count = things.size
things.each do |thing|
do_something_about thing

print_r "#{index +=1} of #{count}"
end
puts "\n" # <- a final new line



Displaying the progress

With the trick above you will be able to show a constantly updating status line, but there are still some meat on this bone. Showing the user things like "345 of 87654" is not particularly user friendly, because it might be a bit annoying to calculate the actual progress in your head all the time. Would be nice to show the progress in percents as well. Happily it is very simple to do using placeholders

print_r(
"%d of %d (%d%%)" %
[index+=1, count, (index.to_f/count * 100)]
)

The other usual problem with status reports is that you might have particularly large set of things, say several millions of them and your script might process several thousands of them per second. In this case hitting your console several thousands times per second will seriously slow the process down, so you might need a way to skip some steps and print reports in some periods of time. You can do that the following way

index = 0
count = things.size
step = count / 1000 # 1/10th of a percent

things.each do |thing|
if (index += 1) % step == 0
print_r "....."
end
end

As you can see we defined the step variable and then skip all the non-round iterations. In this particular case it will make the script to update the report every 1/10th of a percent of the job done. Which is in most cases is not a big drawback and still provides the user with progress updates.

You also might think of ETA calculations, but you probably can figure it out on your own now, it's very simple.


Add Some Colors

And the last thing I'd like to show is how to make colors in the console, which might make your application look even cooler. Some developers already know how to do that, but some don't. So here it is.

Basically it is very simple and in some ways similar to HTML tags. You use things called escape sequences which are just some markers like tags, you have an opening one, and you have a closing one, like that

puts "\e[32mGREEN TEXT\e[0m"
puts "\e[31mRED TEXT\e[0m"
puts "\e[36mBLUE TEXT\e[0m"

As you can see, the closing sequence is always the same and the opening one differs only by a number, and this number is basically describes the properties of the following text. It might be a color, or a blinking effect, you can nest them just like normal HTML tags and so one. You can find full list of options on wikipedia

The only trouble with those things is that the format of escape sequences differs from a platform to platform. The example above is for OSX terminal. How to make those things working in DOS and Linux you can find that on the same wikipedia page.


This is about it. Now go and make the world prettier!

Friday, May 21, 2010

Making a Colorpicker

The other day I've been implementing this colorpicker widget for RightJS and now I'd like to share some mathematics and mechanics behind the widget.

I won't bore you to death describing the actual layout, just some necessary theory and math. And I also will use RightJS semantics. Well, just because I love it.

The Color Theory

Lets start with a bit of a theory. Every giggling school girl those days knows that any color can be created by a proper mix of three basic colors, red, green and blue. That's a brilliant idea, but the problem is that not many people actually can use it. Personally me, I don't know anyone who can instantly say how much of every color you need to take to create say a color of coffee and milk.

And because of this problem the humanity created another, more natural way of color picking which is based on another three dimensions: tone, saturation and brightness. And the main idea of the colorpicker widget is to convert one system into another.

The Tone Parameter

The tone picker usually looks like a vertical bar and represents the following system of colors.



The principle is that with this tone scale you can have any tints available with full saturation and brightness. Note also that in every point of the scale, one of the colors is always has a zero value, and at least one of them has the full value.

Keep also in mind that this scale is some sort of closed circle, the end on the right is actually joined with the beginning on the left.

The Saturation And Brightness

The saturation and brightness field usually looks like that.



The saturation parameter is zero at the left side and have the full value on the right. The brightness is full at the top and zero at the bottom. This way, you will always have the white color at the top left corner, your current tint color at the top-right corner and a black line at the bottom side.

With those three handlers you also can chose any visible color but in more natural way.

Converting TSB into RGB

The first task of the colorpicker is to convert the tint, saturation and brightness parameters which the user picks into the actual RGB value.

It was proven that the best way of keeping your values in this case is if you keep your TSB parameters in float values of range 0..1 and RGB values in integers of range 0..255. This way you won't have systematic round up errors and it will be working faster.

So your TSB -> RGB script will look like that
var tint = [1, 0.5, 0];
var saturation = 0.6;
var brightness = 0.4;

var color = [0, 0, 0];

for (var i=0; i < 3; i++) {
color[i] = 1 + saturation * (tint[i] - 1);
color[i] = (color[i] * brightness * 255).round();
}
The principle is simple, first we combine the tint and saturation which will give as a raw color in range 0..1, then we apply the brightness parameter and convert the float value into a 0..255 integer.

Converting RGB into STB

The backward conversion is a bit trickier. I've drown a simple picture to help you understand the principle



Say you have some RGB color with values in range of 0..255. Remember our tint picture, where one value is always 1 and another is always 0. So this smaller area between the green and red values is the same thing, if you take it and normalize to the 0..1 range you'll have your clear tint values. The brightness parameter will be the proportion between the brightest color and the 255 value, and your saturation is relation between the minimal color to the maximum.

The script looks like that
// the initial RGB value
var color = [200, 100, 50];

// finding the minimal and maximal values
var color_sorted = color.clone().sort(function(a,b) { return a-b; });
var max = color_sorted[2];
var min = color_sorted[0];

// calculating the brightness and saturation
var brightness = max / 255;
var saturation = 1 - min / (max || 1);

// calculating the tint
var tint = [0, 0, 0];
for (var i=0; i < 3; i++) {
tint[i] = ((!min && !max) || min == max) ? i == 0 ? 1 : 0 :
(color[i] - min) / (max - min);
}
It is pretty much straight forward, but we also have some failsafe conditions like (max || 1) and (!min && !max) in case if all the RGB values are zeros.


HEX to RGB Conversions

And couple more things which you also will need. Converting your 0..255 colors array into HEX and RGB formatted strings back and forth.

Converting an array to a HEX value is simple
'#'+ color.map(function(c) {
return (c < 16 ? '0' : '') + c.toString(16);
}).join('');

Converting RGB string into an array of values looks like that
if (match = /rgb\((\d+),(\d+),(\d+)\)/.exec(value)) {
return [match[1], match[2], match[3]].map('toInt');
}

And converting any HEX color into an array can be done like that
// converting the shortified hex in to the full-length version
if (match = /^#([\da-f])([\da-f])([\da-f])$/.exec(value))
value = '#'+match[1]+match[1]+match[2]+match[2]+match[3]+match[3];

if (match = /#([\da-f]{2})([\da-f]{2})([\da-f]{2})/.exec(value)) {
return [match[1], match[2], match[3]].map('toInt', 16);
}

Well, that all you need to know to make one cool colorpicker of yours.
Enjoy!

Tuesday, March 2, 2010

My Top 5 on that RightJS vs. jQuery Question

During the last several months of RightJS promotion, the absolute hit among the questions of 'what?' and 'why?' was understandable the question of what is the difference between RightJS and jQuery.

There were lots of talks about RightJS speed and then more about speed, and then we had some abstract talks about its philosophy and its way among the others and we also have that simple comparison page.

And what I find important in a brainwashing process is systematicness and methodicalness. We did some talks on an abstract matter, we did some talks on the opposite side of scale with performance tests, now lets touch something real. Something in the middle. And probably summarize some previous talks.

So here it is, your next session; my top 5 as I see it at this morning.


1. Syntax

When I'm saying "jQuery is like PHP", first of all I mean the nature of its syntax. When you boil it down to the essence, both of them are just collections of helper functions. And as PHP defines a new kinda language upon C, almost the same way jQuery defines a new language upon JavaScript.

RightJS on the other hand is built right into JavaScript itself. In 90% it is the good old JavaScript, where we bring features from later JavaScript specifications and spice it with some standard features from more serious dynamic languages like Ruby and Python.

As the result, when you learn jQuery, you mostly learn jQuery, I've seen many nice fellas around, who know jQuery quite well, but stuck when they needed to do simplest things in pure JavaScript.

When you learn RightJS, you learn the actual JavaScript, yes we have some funny shortcuts and features that make mature web-developers happily giggling like school girls, but all of them are built upon JavaScript standards.

RightJS makes you do the things in JavaScript and do them right. And because of that, whatever the future brings, your knowledge and skills will remain with you.


2. The Actual STL

When I read someone saying "jQuery is the JavaScript STL", it usually makes me laughing so much, that my neighbors probably think that I've finally went nuts and going to blow off the Kremlin.

Now, don't get me wrong, I have no problems with jQuery's popularity and I respect that. Well, at least, as long as it keeps me away from people who doesn't know the difference between popularity and standards.

jQuery is a DOM DSL at best. First of all it doesn't have anything to do with JavaScript itself, because it's a DOM wrapper, secondly there is nothing standard about jQuery in terms of JavaScript. Take for example a look at the .each() function where the arguments are in just the opposite order than they are in the JavaScript own Array#forEach method.

If you need something that actually follows the standards, you should take a look at RightJS. It brings many standard features from later JavaScript specifications, plus many other none the less standard features from server-side programming languages, for example methods like String#startsWith or Array#random.

The DOM interfaces are just one part of RightJS and it has much more. We even have a build of RightJS without DOM features which you can use on the server-side with Node.js or say writing scripts in Qt.


3. Multiple Paradigms

As jQuery is simply a wrapper over DOM interface, it doesn't give you any alternatives but use its own way of dealing with the things. Yes, you might imagine that you're practicing Lisp in JavaScript, but the reality is that 99% of jQuery code (including jQuery itself) is just a spaghettish pieces of crap.

RightJS on the other hand is not just a DOM wrapper, it is a multi-paradigm framework. We have an advanced OOP stack that allows you to write clean and properly designed applications that are easy to support and refactor. We also have most of the standard FP features, like binding, curring, chains and stuff. We also have some standard native units extensions that are most helpful in procedural programming.

RightJS gives you options and flexibility, so that you could deal with your work in the most effective way.


4. Open Sandbox

Maybe jQuery forces you to write a spaghetti code, but there is a bigger problem. Most of jQuery and its plugins code are closed behind anonymous scopes that makes it impossible to change them part by part.

You know, people are actually already invented OOP, inheritance, functionality injection and other fancy stuff to deal with those sort of things. And that's why in RightJS we have radically opposite architecture.

RightJS is built using proper OOP structures and modules and it represents an open sandbox where virtually everything is accessible and customizable. You can easily bend and tune RightJS for your needs, changing and replacing its parts, adding your own features, methods and so one.

And because of that it is super easy to write any sort of plugins and extensions for RightJS. Take for example a look at the right-rails plugin; couple of dozens of lines of code and RightJS API was completely transformed to have the naming system of Ruby, with underscored syntax and other features.

RightJS gives you the same flexibility and hacker's joy as Ruby or Python.


5. Official Plugins

I'm sure you know what they say "jQuery has a gazillion of plugins that will do everything for you". It kinda reminds me other folks who was saying "Everything in Java has already been done".

Normal people usually add on that "badly".

That gazillion of plugins has actually a pretty nasty back side. The problem is in the closed architecture and inflexibility. For every case there are usually half a dozen of implementations, and quite often the choice is like "bad, bad or bad?". At the end you might spend more time looking for a proper plugin than you could spend writing it yourself, and at the finish your app will look like a Frankenstein, all stitched of different parts.

Yes I know, I know, Frankenstein is a romantic figure in gothic culture, but there is so few romantic in supporting such an app.

With RightJS we don't have the luxury of too many plugins, but we have several good points on that matter too. First of all, many common and frequently used features that you have as plugins for jQuery, are already baked into the RightJS core, like for example, additional form features, Ajax via iframes functionality, cookies and stuff.

Then we have all the standard plugins, like D'n'D, JSON, Behaviors, plus most of the standard UI elements like Calendar, Autocompleter, Tabs, Lightbox, etc. already implemented and served in the official plugins repository.

And what's different about RightJS plugins is that all of them are implemented in the same way, using the same set of rules. All events handling, options, usage principles all are the same. So that if you had experience with one plugin, you will be familiar with the rest of them too.

Then all the plugins follow the open-sandbox principles of the RightJS Core. All of them are implemented using proper OOP approach and can be easily extended using inheritance, functionality injection or even monkey patching if you will.

This way you don't need a dozen of variations of the same plugin, you can easily tweak any standard one to do exactly what you need.

Saturday, February 20, 2010

Slowing Things Down Under OS X

You know what they say "you need to slow down to see some certain things". In case of web-development, sometimes you need to emulate a realistically slow internet connection to see some problems with your project. See how quickly it loads up, how it receives the images, especially it useful to test file-uploads and ajax operations. So here is a little tip how can slow down requests to your local server to test the things properly.

Under OS X you have access to the FreeBSD traffic shaping util ipfw. First of all you need to define some rule which will work on local interactions.
sudo ipfw add 1 pipe 1 src-ip 127.0.0.1
sudo ipfw add 1 pipe 2 dst-ip 127.0.0.1

After that we can set up the connection speed, and also I like to add some delay to emulate a request to a remote server
sudo ipfw pipe 1 config bw 40Byte/s delay 100ms

After that all your local requests will slow down to 40Byte/s speed with a realistic 100ms response delay.

When you have done with your tests, you can remove the rule with the following command.
sudo ipfw delete 1

Now it is all interesting but lets wrap it up in a simple shell script so we didn't need to memorize all the fancy calls.
sudo touch /usr/bin/slowdown
sudo chmod +x /usr/bin/slowdown

After that open the file with your favorite editor and write the following little script

#!/bin/bash

if [ $1 = "clear" ] ; then

ipfw delete 1

else

ipfw add 1 pipe 1 src-ip 127.0.0.1
ipfw add 1 pipe 2 dst-ip 127.0.0.1
ipfw pipe 1 config bw $1KByte/s delay 100ms

fi

Now you can create and remove pipes just like that
sudo slowdown 40

And to remove the rule call it like that
sudo slowdown clear

That's all about it. Happy testing!

Friday, July 17, 2009

Customizing The Rails Forms Builder

The word "customer", usually means someone who come and say "I wanna custom stuff". And because it is their nature they do it all the time. Sometimes several times a day.

I'm skipping here the obvious question "why would I need to customize a forms builder?" and get straight to the point.

So you need to customize your forms. Big time. And if the first what comes on your mind are helper methods and partial templates, this article is for you.

And please don't think about monkey patching rails form-builder. Don't behave like a php developer thinking he can use rails. Lord save their poor souls.

There are better way of doing that.

First of all you should realize that in 99.99% of cases you should not change the default rails templates. Meaningly that

<% form_for(@model) do |f| -%>
<%= f.error_messages %>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<% end -%>

Despite that it is a simple structure, with a little bit of imagination and css magic you can make it look like anything you need.

Secondly you really should pay a dollar of penalty every time you think about monkey patching. Ruby is not just a monkey patching language it is object oriented too, and rails form builder is a quite well organized structure.

Instead of patching, we will create our own form-builder using advantages of the inheritance and then swap the default builder from the built-in to our own one. This way we can change the logic of the forms building transparently for the templates, you even can have several form-builders which behave differently and swap them depend on the context.

The basic example would look like this. You create another helper module called FormsHelper and save it along with the other helpers in your application

module FormsHelper
def self.included(base)
ActionView::Base.default_form_builder = CustomFormBuilder
end

class CustomFormBuilder < ActionView::Helpers::FormBuilder
# your custom methods go here
end
end

Inside the class you will have access to the form builder context with all its built in methods and variables. For the beginning you should know about the following ones

  • @template - the template context, you call this variable if you need to call the basic helpers

  • @object - the current model of the form

  • @object_name - the string name under which the form knows the model


Okay now lets play with the thing a little. Say the customer says "don't like the <h2> header on the error reports, the one with the number of errors on the form". No problem, we just override the built in method

def error_messages(options={})
super options.reverse_merge(:header_message => nil)
end

Then say you as many other developers usually put your forms in a partial and then depends on the model state change the submit button caption. something like this

form_for(@model) do |f|
f.submit @model.new_record? ? "Create" : "Save"

This is a little bit annoying. Say I'd like just call it <:%= f.submit %> and want the form automatically set the caption. Here is the code

def submit(caption=nil, options={})
super(caption || @object.new_record? ? "Create" : "Save"), options
end

Then I got completely lazy and started to want my form builder to build a block of label + text-field in a single call, like this

form_for(@model) do |f|
f.labeled_text_field :name

# this should build the thing like that
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>

# you could do it like this
def labeled_text_field(name, options={})
@template.content_tag(:p, label(name) + text_field(name, options))
end

Then, all the sudden, your customer comes back and says a scary thing "I like this, but I want for this particular controller, there actually was the h2 header saying 'Oh noooo!'. Yes, just for this special case".

No, my friend we are not going to the monkey patchers hell! We just define another form-builder over our own builder, and automatically swap it in the particular controller

class SpecialFormBuilder < CustomFormBuilder
def error_messages(options={})
super options.reverse_merge(:header_message => "Oh noooo!")
end
end

class ParticularController < ApplicationController
before_filter :swap_form_builder

def swap_form_builder
ActionView::Base.default_form_builder = SpecialFormBuilder
end
end

Think you understand the idea. If you do the things in a serious way, lord will love you and grand you a big deal of flexibility and rapidness.

This is pretty much it. Have a good one!

Tuesday, July 7, 2009

Psychic Abilities Test

I've created another toy, Psych Test.

The thing is fairly simple, you've seen it lots of times in movies. You have a standard 36 playing cards deck, and one by one you are trying to guess the next card suit color. Red or black.

Well... I'm not a psychic but I know what are you thinking.

"...50%...", right?

I bet, if you ask any of your friends or colleagues who is occupied in CS, mathematics or physics you'll have the same exact answer. But the thing is not actually that simple, and here is where the fun begins.

If you open up the link above and will click on the same exact prediction button during the whole test, the result will be exactly those 50%, well +/- 1% in some unlucky situations. You might repeat the test several times, it's pretty consistent almost without any deviations.

But if you will have the same test, but will actually try to guess the next card's color, you'll have a different result, usually in range between 40 and 60%. And you almost never will have 50% again.

You should try it to believe, you can check the source code too, there is no back door. Everything is fair.

So what do you think, how is that possible? Do you think it is you actual ability to predict the future affects the result?

I could tell a spooky story about underground CIA laboratories where they study those things since 60s, and that there is a standard measurement for such tests and an exact percentage which defines you as a proven psychic.

Or, if you prefer, we could think about the problem rationally. There are just four practically independent cases and two of them correct, so the result should be close to 50% every time, no matter which button you choose. But yet it's ain't like that.

As you understand this is not the test for a psychic abilities, this is a test for rational thinking.

Okay, I'm not going to marinade you any further, as you come here and read this far I owe you an answer.

The thing is simple but not that obvious. There's no mathematical or logical problem, every time you click any of those buttons, you've got an exact 50% probability to score. But in case when you click the same button all the time, you put your guess against an almost ideal random sequence generated by the computer. And that's why you have this pretty close 50% result every time.

But when you do the "guessing", your brain follows some patterns and tries to predict the next card. Yes, generally that's a random process and every guess as good as any other, but the distribution of those guesses in time is not such good as a random distribution generated by the computer. There are fluctuations and attempts to guess, which affect the quite short 36 cards selection and gives you the non 50% result.

The first time you test the computer's random numbers generator, the second time you test your own.

Wednesday, July 1, 2009

Sudoku Puzzle Generating, Pragmatic Way

Couple of days ago I described how you could generate a good random sudoku field, today I'm going to advocate for just opposite thing. There's no controversy in really, just there are different cases, when you should and when you should not do that.

You should or could write your own sudoku puzzles generator if you are particularly interested in the field and ready to spend lots and lots of time, getting deep in all the various rules which actually make a good sudoku. Well at least it will keep your self-esteem up.

But if you are just writing some implementation of the sudoku game, you actually better not to do that. And here is why.

  • Sudoku generating is a random process with generally unpredictable duration. There is a good chance that your generator will get unlucky and stuck. And a hanging over application is the last thing you want your user to see.
  • The process of generating of a really good, hard sudoku usually takes time, sometimes a few seconds
  • There are lots of rules you need to get into, implement test over, and then if you are not an expert in sudoku you wont be able to check it out if you have done everything properly
  • You will probably forget and never use again all the knowledge you gain during the implementation. I don't want to call it a waste of time, but I'm pretty sure there are better ways to actually waste your time.
  • A good sudoku generator might be quite big and complicated piece of software, which will be hard to test and support.

Luckily there are better ways to do that. Use other people's work to be precise. There are lots and lots of online sudoku generators, or you could use any desktop applications, most of them cache boards in files. I used the gnome-sudoku application, it lets you generate any number of sudoku and saves them in the files in the gnome configuration directory, or you can grab my archive right here puzzles.zip

What about the number of puzzles ask you? You need some storage to keep them and have big enough collection to keep the user happy.

Actually not, and here is the trick of the article. You actually can keep just a few puzzles for each level and then generate new puzzles out of the originals. You can safely do the following things with your puzzles

  • Rotate them
  • Flip in any way
  • Randomly shuffle rows and columns inside the 3x3 boxes
  • Shuffle rows and columns of the 3x3 boxes

As the result, if you say have initially a collection out of 16 puzzles, then you can rotate and flip it in 5 ways, then you can shuffle rows and columns in 9 ways in each of the nine 3x3 boxes, and eventually you can have 9 combinations of the 3x3 blocks.

16 * 5 * 9 * 9 * 9 = 58320

That's more than enough for your user never see the same puzzle twice in a row. More of that, all of those puzzles will be really consistent by the difficulty level because initially it is just the same puzzle.

And for the end you can see a possible JavaScript implementation right here boards.js

This is pretty much it. Have a good one!

Monday, June 29, 2009

Sudoku Random Field Generator

The task is simple, to fill up a 9x9 field by the sudoku game rules.

Generally it's not a rocket science and there are lots of simple solutions. For example filling up the field with shifted sequences. Say you have a sequence of numbers from 1 to 9, then you might generate a valid field like that.

1 2 3 4 5 6 7 8 9
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6

2 3 4 5 6 7 8 9 1
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7

3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8

As you see, the principle is simple, you start with your basic sequence, and then shift it by 3 positions inside 3x3 box, and by one position between the levels. The principle will still work if you start with any randomly sorted sequence of unique numbers.

3 5 6 2 7 4 1 9 8
2 7 4 1 9 8 3 5 6
1 9 8 3 5 6 2 7 4

5 6 2 7 4 1 9 8 3
7 4 1 9 8 3 5 6 2
9 8 3 5 6 2 7 4 1

6 2 7 4 1 9 8 3 5
4 1 9 8 3 5 6 2 7
8 3 5 6 2 7 4 1 9

After that you might shuffle columns and rows in scope of boxes to make the field more random, you even might shuffle the 3x3 rows and columns as well to have even better results.

But this thing is not really serious and kinda boring. The problem is that all your numbers are grouped by three numbers and those groups in different orders will appear all over the field. And this might be used for cheating. Say you open one of the sequences 4 1 9 and then wherever you open any of those three numbers you immediately know the numbers next to it.

Well for smarty pants like you and me, we need something different, something bigger, better and more bad ass.

After several coups of coffee I've come to the following algorithm.

1. We generate our field row by row
2. For each cell in a row, depends on the other existing numbers in the 3x3 box or the column, we generate a list of options
3. Out of the list of options for each cell we randomly select a value
3.1 When we convert a list of the options into a row we watch for intersections with other options and choose the most optimal collection

For example we have the following thing

1 5 6 9 8 7 4 3 2
9 2 3 4 6 5 8 7 1
8 7 4 3 1 2 6 9 5

4 9 7 6 3 1 5 2 8
5 3 2 7 4 8 1 6 9
? ? ? ? ? ? ? ? ?
----------------------
The options will be following

6 1 1 2 2 9 3 4 3
6 8 5 5 7 4
8 9 7

----------------------
Out of the options we might create sequences

6 1 8 2 5 9 7 4 3
6 8 1 5 2 9 4 7 3
......

This way we will have no patterns and truly random valid sudoku field.

The only problem is that it is not exactly working.

As it's a random process, for each valid field there will be about 5-10 cases when there will be no ability to create a correct sequence. But despite the "not exactly" prefix, the algorithm is actually working and creates beautiful truly random fields.

And then you have a choice. Think about the algorithm by yourself and try to make it work every time, or you can make your computer think through the algorithm several times until a fully covered field will pop up.

Yes, I know, for a piece of software it sounds cheesy, but in reality there are not much calculations in the algorithm and make it running 5-10 times is not a big deal, it takes just a few milliseconds in javascript. Besides, if you need a speed, you can always cache the fields and shuffle them later as you shuffle the fields generated by patterns.

And for the grand finale here is a possible solution in JavaScript + RightJS

....
// generates randomly distributed field
generateGrid: function() {
var numbers = '123456789'.split('').map('toInt');
var matrix = numbers.map(function() { return []; });

for (var x=0; x < 9; x++) {
var options = [];

for (var y=0; y < 9; y++) {
var col_numbers = numbers.map(function(i) { return matrix[i-1][y]; });
var box_numbers = numbers.map(function(i) {
var box_x = (x/3).floor() * 3 + ((i-1) % 3);
var box_y = (y/3).floor() * 3 + ((i-1)/3).floor();

return matrix[box_x][box_y];
});

options.push(numbers.without.apply(numbers, col_numbers.concat(box_numbers)));
}

matrix[x] = this.sequenceFromOptions(options);

// drop and start over if there sequence was damaged
if (matrix[x].compact().length < 9)
return this.generateGrid();
}

return matrix;
},

sequenceFromOptions: function(options) {
for (var i=0; i < 9; i++) {
this.cleanOptions(options);

options[i] = [options[i].random()];
for (var j=i+1; j < 9; j++) {
options[j] = options[j].without(options[i][0]);
}
}

return options.map('first');
},

cleanOptions: function(options) {
for (var i=0; i < 9; i++) {
if (options[i].length == 1) {
for (var j=0; j < 9; j++) {
options[j] = options[j].length == 1 ? options[j] : options[j].without(options[i][0]);
}
}
}
}
....

Thursday, May 14, 2009

Being Pragmatic about Agility

There is a book appeared recently called "Pragmatic Career" and there was a sentence in its annotation saying "when I started to look at my life throw the glasses of agility I started to see agile patterns just everywhere". Ok, that probably not the exact quote but the point is that some people getting the agility too far. They start to worship it almost as a religion and sure see its deeds just everywhere.

Don't get me wrong I'm not against agility and this is not another crapy article a la "agility sucks, I hate it". Nope, agile approach is a wonderful tool and I use it every day and pretty much happy with that. My point is that the agile approach is just a tool, you should use it wisely and be critical about it.

Agile approach works pretty well if you are an experienced developer, a ninja who knows how to give a good punch from almost any position. You don't plan too much, be flexible and if the things go a wrong way, you just adjust. It reduces the entry level, gives you ability to try this and that and see how is it going, etc., etc. You take all the advantages of the technique.

But when you are young, have a lack of experience and good habits, it might lead you to a wrong path. Because of it nature, people quite often start practicing the "shoot first think later" approach. They write crap and hope they will fix it later, don't write tests and documentation. They think that they are agile because they produce a lot of code and kinda buggy features which they gonna make better later. But in reality they go in circles over and over, and eventually spent an ugly amount of time.

Agile approach is not about creating crap now and make it better later, it's not about skip all the things you are too lazy to do or just don't know how to do. As the matter of fact, the original "Pragmatic Programmers" book in one of its tenants says directly opposite "Don't live with broken windows". More of that, any normal professional in any area will tell you the main rule of being effective "Do the things once and only once". If you need to get back and fix your solutions, you are just killing time.

Agility is all about flexibility and rapidness. It is a contradiction to the old fashioned heavy planning approach, a tool which lets avoid painful situations when you at the finish line and realize that you have not what you needed. With agile approach you do small steps, but it doesn't cancel the idea that you should do your steps right. You do small steps but each step should be done in a good way. If you rush to the end target, skipping steps and taking all the possible shortcuts, move by an unpredictable trajectory, at the end you will have something as much painful as if you was sticking to some wrong plan.

And the problem actually, the problem is in ourselves, it is in our brains, in the way it works. The mother nature designs the things the way they were working in the most effective way, consuming as less energy as possible, that's the matter of surviving, and our brains are not an exception. Instead of careful thinking, we tend to jump to conclusions based on our experience, on the things we believe. That's kind of solutions caching mechanism. And the agile approach fits it like a glove, you just make rapid decisions based on current situation and your guts and move forward.

The problem is that if you have right solutions in your cache/experience, you are good, but if you don't you'll go through all the problems and become one big pain in the butt, for yourself, for your colleagues and eventually for your customer.

And here we come to the sake of "evil" old planning.

Planning is getting evil almost the same way as anything else getting evil, including agile approach. When you overuse it. The sake of planning is that it lets you make the reality check, think critically, review your experience cache. You write some simple roadmap and ask yourself a question "How do I know what I know?". It lets you filter out problematic cases, make you aware about problems before you meet them. That's the way to make your brain actually work, not just return some first thing out of the cache.

The bottom line.

I think you've got the idea. Sometimes you should ask yourself what are you actually practicing when you are practicing an agile development? Don't you feel like going circles, getting back and fix the things all the time? How do you know about the decisions you made? Don't you call something useless just because you too lazy or just don't really know how to use it? If you have any hesitations, it's okay to stop, sit down and think about the things for 20 minutes, do some reality check, maybe even take a good old pencil and piece of paper and write down some short plan.

This will make you actually think about the things, which will make you better, and better you will produce a better work.

Monday, April 27, 2009

One Image Round Corners

I'd like to share with you some fancy idea how you make easily maintainable css-based round corners on your pages. It's quite a common feature those days and if you don't know how to do that it might be quite a headache.

The Idea

The idea is pretty simple. You create an image which contains all four of your box corners. Usually it's just a small circle or a ring. Something like that.



Then you create an html-tags structure, like this.

<div class="box">
<div class="corners top"><div class="left"></div><div class="right"></div></div>

<div class="data">
Your text goes here
</div>

<div class="corners bottom"><div class="left"></div><div class="right"></div></div>
</div>

It is not necessary to have the middle div.data, but it will provide you move flexibility for css-alterations in future, so you'd better have it in there.

And eventually you write some piece of css-code.

div.box {
padding: 8px;
}
div.box div.corners div {
height: 8px;
width: 8px;
position: relative;
float: left;
margin-top: -8px;
margin-left: -8px;
margin-right: -8px;
background: url('corners_image.gif') no-repeat 0 0;
}
div.box div.bottom div { margin-top: 0; }
div.box div.corners div.right {
float: right;
background-position: 100% 100%;
}
div.box div.top div.right { background-position: 100% 0; }
div.box div.bottom div.left { background-position: 0 100%; }

The stylesheet uses the images shading technique and displays a quoter of the image for each corner, so the pixel sizes in style definition should be equal to a quoter of your corners image. And the box by itself has some nice padding of the same size, so the box was looking visually correct and fit the corners.

This is pretty much it.

Why Do It Like That?

Well. There are several reasons.

a) It gets down the number of server requests to the server. For such tiny images, the actual loading time is the time of request and response to the server. So making it one image instead of four you make your page loading faster and don't bother your server.

b) When you have one image, you don't need to deal with each corner separately, you can unify and compact the styles, and then if you need, you can replace all the corners really easy but replacing just one image. It provides you really good flexibility in terms of css-based design. Take a look in here One Image Corners Example, I've created some demo for you. See how it's easy alterable for various cases. You just change the background color and image url and have another box ready to go.

c) With such approach in most cases your boxes will be still looking consistent if there is some problem with the image loading. User doesn't see unprofessionally looking cases when you have four separated images and one of them was lost or just when they are getting loading one by one. With one image the user will have all the corners at once, and if the image was lost, he will still see appropriate looking box on the page.


PS: If you need transparent backgrounds at the outer angles of the corners, you can have them on the same exact tags structure, but you will need some additional mambo jumbo in your stylesheet, which I didn't intend to cover in the article. But in 99.9% of good modern designs you won't need that anyway.

PPS: This certain css example does not work correctly on IE6, although it is entirely possible to make it working there, just I don't want to spend my free time on that zombie. If you need to support it you just put some additional adjustments into you css file with IE patches.

Sunday, July 20, 2008

Rails + Gettext Crash Course, Part 2

This is the second part of the first rails+gettext article. In this part we will take a look at some advanced points of using gettext and its bind to ruby/rails. Generally there is nothing "advanced", just say we move a little bit beyond elementary _('some text') calls.

Interface

Except the _(String) method, there are several more standard methods to define messages for gettext. Generally there are two parts of them, for singular and plural forms. The first ones take as the main argument your usual message string, the second ones two more arguments, singular form of the message, plural form of the message and an optional number which helps to determinate when it is a singular form and when it is a plural form.

Singular methods
  • String _(String) - the standard method as we now it. The method takes a string and returns its translated version.

  • String s_(String message[, String div="|"]) - this one for the cases when you need to define a scope for the message, say you have just the same message in two different context which might have different translation. So you write a string like s_('context|phrase'), your message will be splat by the divider ('|' by default) and if there is no translation the last part of it will be returned. Simple example s_('gender|sex') and s_('activity|sex'), by default both of them will return 'sex', but you may have two different translations of the word in different languages depend on the context.

  • String N_(String) - this one might look a little bit strange. It tells gettext to define in its base the given string as a message, but does not translate anything and returns the given string as is. Generally it does just nothing, it is a dummy method and just a marker for the gettext parser. You will be given some examples of its usage below.

Plural methods
  • n_(String msg, String msg_plural, Integer number) - this one is same as _(String) but for the plural cases. The first argument is a singular version of the message the second is the plural version of the message. And the last argument the current lets call it plurality marker by which gettext will define which message use. NOTE: despite that you pass here only two messages, when you translate your .po files you may define several (more than two) translations of the messages which will depend on the plurality marker.

  • ns_(String msg, String msg_plural, Integer number[, String div='|']) - same as s_(String[, div]) but for plural forms

  • Nn_(String msg, String msg_plural) - same as the N_(String) method but for plural forms

That's all about the message definition methods.

Models Internationalization

GetText by default has all the standard error messages translations for most of the languages inside the package. And the parser will automatically define translations for your model fields which are in the database (meant field-names translation). So you don't need to worry about that.

But sure you have got your special cases and you can follow the next instructions. Say the usual case, a user model where you have got some virtual fields

class User < ActiveRecord::Base
has_one :profile
has_many :comments

attr_accessor :password, :password_confirmation

# we can define the virtual fields translation like that
N_("User|Profile")
N_("User|Comments")
N_("User|Password")
N_("User|Password confirmation")

# we can create custom error-messages in this way
validates_uniqueness_of :login, :message => N_('The login-name is already taken')

def validate
errors.add("password", _("%{fn} is wrong!")) unless password == password_confirmation
end
end

As you see we have used the method N_(String) for class initialisation calls and the method _(String) inside the custom validation method. The point is simple, in the first case you don't really need the translation result, you just need to define some messages and the second case works in runtime so you need an already translated version of the message.

And another moment, we have used the 'User|' prefix in the field name definitions, this is to determinate in the translation which model the field name belongs, so you could have different translations of the field names for different models. By default it will be splat by '|' and the last token will be taken.

If you don't want to translate some particular field names, you may define to skip them by calling the untranslate(*names) method like that

class User < ActiveRecord::Base
untranslate :login, :email
# or
untranslate_all
end


Templates Internationalization

In most cases of templates internationalization you just use the standard gettext methods, like <%= _('Some label text') %>, but there is another way.

Sometime templates contain lots of text with big descriptions, so it is more comfortable to have another template file special for a particular language rather than put big pieces of text in the _(String) function. It is simple, just create another file next to existing one but with a name which have a suffix named after the locale you want. For example

app/views/pages/
about.html.erb
about_de_DE.html.erb
about_ru.html.erb

If the current locale is 'ru', then the about_ru.html.erb file will be used, if there is no matching file, the default about.html.erb file will be used.

Language Switching Tactics

And at the end some points about the language switching tactic. If you are experienced developer you probably do not need this part, but I would like to spell some words about it.

The best way here I think is to follow the general ideology, separate parameter variables and the urls formatting, just as you do with say same ID parameter. A good solution would be define a parameter name which will point to the desired language, say params[:lang], then as I showed in the previous article, you can use it in your application controller to switch the locale by a before filter.

class ApplicationController < ActionController::Base
init_gettext 'my_site'

before_filter :define_language

def define_language
case params[:lang]
when 'fr': set_locale 'fr_FR'
when 'ru': set_locale 'ru_RU'
else set_locale 'en_EN'
end
end
end

and then you left some options for youself how present it at your urls. You may use a simplest way like and left the gings as is

/articles/show/1 <- English
/articles/show/1?lang=fr <- French

or you can handle the language by routes so your pages were more caching friendly

map.connect ':controller/:action/:id'

map.connect ':lang/:controller/:action/:id',
:requirements => {
:lang => /(ru|de|fr)/
}, :lang => nil

----
/articles/show/1 <- English
/fr/articles/show/1 <- French

or later you may handle them by subdomains or something like that, whatever you choose your application code will not need changes.

--

Okay, think that is all what I had to say about using gettext with rails. Good luck!

Friday, July 18, 2008

Rails + Gettext Crash Course, Part 1

This article is a short guide to how use gettext with ruby-on-rails. If you do not know gettext is the standard internationalisation (i18n) library of the GNU project http://en.wikipedia.org/wiki/Gettext. And this is the first part of the two articles. The second one might be found here.

Since there are some of i18n plugins for rails why should you chose gettext?

For some reasons.

First as I said it is the standard for GNU. Standard means wide support several tools to work with it, optimisation, documentation, etc. Most of Linux programmes use gettext.

Second, one of the key features of gettext is ability to use real, correct strings. You don't write strange keys in your code, you just put usual English phrases instead, like that

<p><%= _('Some text here') %></p>
<p><%= _('Length: <i>(%{min} min)</i>') % { :min => @min_chars } %></p>

As you see this allows you easily use any placeholders or html formatting tags in here if you need so. Another point for gettext is that you don't have to keep in mind the translation issues during the development time. You just put your text as nothing happened and always have a default translation with normal usual looking strings.

After you have done with the development you can parse out all the strings which need to be translated with special util. You will have standard formed .po file which you can then translate with some special programs, where you can use spellchecking versioning and all the civilize life advantages.

Third, this stuff can do lots of things, localize numbers, dates, currencies, work with pluralization on native languages and so one. Take a look at the official site for getting more information http://www.gnu.org/software/gettext/gettext.html

So how do we use the stuff with rails?

Quite simple.

First of all you need to install gettext by itself and rubysupport aka gem. Installation of gettext depends on your platform. With linux it's pretty simple. Say something like

# emerge gettext
or
# apt-get install gettext

Once you have installed gettext support, you need to install the gettext gem.

# gem install gettext

After it is done, you need to include it into config/environment.rb file of your rails project.

require 'gettext/rails'

After this you can start develop your project and use the _('text') constructions where you need to put some text.

If you are using Rails 2.1, there's a bug which have not fixed yet. But you can easily fix it by saving the following code into a file config/initializers/gettext.rb

# the gettext missed method fix
module ActionView
class Base
delegate :file_exists?, :to => :finder unless respond_to?(:file_exists?)
end
end

Once you have done with the development and want to create some translation you need to do some preparations.

First you need to add two simple tasks to your Rakefile.

require 'gettext/utils'
desc "Update pot/po files to match new version."
task :updatepo do
GetText.update_pofiles(
"my_site",
Dir.glob("{app,lib}/**/*.{rb,rhtml,erb,rjs}"),
"my_site version"
)
end

desc "Create mo-files for L10n"
task :makemo do
GetText.create_mofiles(true, "po", "locale")
end

The first one will scan though your source code and parse out all the strings which need to be translated and put them all into a .po file. The second one will compile all your translations into a standard .mo files which gettext can use.

So, you say 'rake updatepo' in your console and this will create for you the file named 'po/my_site.pot', this is template of your internationalisation. You copy the file in translation directories like that.

po/
de_DE/my_site.po
fr_FR/my_site.po
ru_RU/my_site.po
my_site.pot

Then you translate the .po files with one of the translation programmes, say this one http://www.poedit.net. Under Linux and KDE you can use standard KBabel programme, or under Gnome you can use the gtrasnlator project. Certainly you can edit those files just as plain text if you like so. Many texteditors support them.

Once you have done with the translation, run the 'rake makemo' task in your console and it will create the 'locale' directory in your rails project folder with a standard structure like that

locale/
de_DE/LC_MESSAGES/my_site.mo
fr_FR/LC_MESSAGES/my_site.mo
ru_RU/LC_MESSAGES/my_site.mo

This is almost it. You only need to initiate it in your application controller now.

class ApplicationController < ActionController::Base
GetText.locale = 'en_EN' # <- default locale
init_gettext 'my_site'

before_filter :define_language

def define_language
# here you can switch the locale on fly
# say like that

case params[:lang]
when 'de': set_locale 'de_DE'
when 'fr': set_locale 'fr_FR'
when 'ru': set_locale 'ru_RU'
else set_locale 'en_EN'
end
end
end

As you see we have used non existing locale 'en_EN', if there is no some locale your default strings from the source code will be used. So you always have a fallback language.

This is pretty much it for the start.

But remember with gettext you not only put some translated text-labels in your application, you easily can create translations of whole template files, you can translate models, values, format numbers, dates and do lot of another useful things.

Monday, May 5, 2008

Order By Aggregations With ActiveRecord

The issue is following, say you have got a classical structure in two models

class Order < ActiveRecord::Base
has_many order_items

def total_due
order_items.to_a.sum(&:total_price)
end
end

class OrderItem < ActiveRecord::Base
belongs_to :order

# and it has two principal fields
# decimal :price
# integer :quantity

def total_price
price * quantity
end
end

As you see the orders don't have own total_due fields, instead of this each order can calculate the value depend on the aggregated items. So, that's cool, we follow all the good design habits and keep the things clean.

But when you retrieve/display the orders list there might be a situation when a customer would like to order the list by the total_due value. Quite a natural desire, but there's the problem, we don't have the total_due field in really. It's virtual and depend on the aggregated objects.

Yes, you may reorder the items after retrieving, manually, but if you have quite a lot of orders and use a pagination you'll get back to the problem anyway.

The example is pretty simple, but you see, there might be lots of similar situations when you have some calculations on an aggregated data and would like to order your lists depends on the virtual fields.

So, how do we handle that?

We use the :select option for the ActiveRecord find method. Usually with the option you specify a number of fields you would like to extract, to not suck up heavy ones when you don't want them. But with the same option you may specify additional fields to extract and use all the power of SQL expressions. Those new fields will be added to the instanced object temporary, you can read them but you can't save them.

In our case this might be something like that

:select => "SUM(order_items.price * order_items.quantity) as total_due"

In the case we are using the SQL function SUM, calculate the total-due for each order, and then each selected order will obtain the total_due attribute after extraction and you may use it for your sorting options.

Then, as you see we mentioned the 'order_items' column in the select option, to make it working we should add a tables join and the items grouping options. The overall instruction might look like that.

Order.find(:all,
:select => "SUM(order_items.price * order_items.quantity) as total_due, orders.*",
:joins => "INNER JOIN order_items ON order.id = order_items.order_id",
:group => "order.id",
:order => "total_due"
)

After this you will need to fix your Order model a little, to make it use the temporary field when it appears

class Order < ActiveRecord::Base
def total_due
self[:total_due] || order_items.to_a.sub(&:total_price)
end
end

Yes, that looks a little bit sqlish dirty for a rails application, but then it works and does what you need.

And there's another issue with the solution. You actually cannot use the :include option with the :select option at the same time. That's usually not a big issue, just note, if you specify the :include option, your :select option won't work.

Sunday, April 13, 2008

Rescue data from a reiserfs partition

Couple of days ago, I met a situation, when my /home partition, which was on reiserfs filesystem, all the sudden, got dead. It was not able to restore the partition with reiserfs utils, it didn't want to mount anymore, info said there only 563 Kb of 60 Gb data left. Not good.

I've spent a day rescuing the data, and managed to get back 99% of it (i belive), so now I share the experience.

The rule number one in such a situation is to calm down. Sit down, take a blank sheet of paper, a pencil and then in a nice friendly characters write the phrase "DON'T PANIC".

I'm serious, it's pretty easy to get jumpy and overreactive when "all of yours" suddenly getting disappeared. And surrely it's easy to broke something down completely. So, don't touch anything until you get back to the cool consciousness.

The second thing you need, is a complete copy of your damaged partition. For that you'll need another free partition with exact same size. If you have such space on another hard drive, create it there, or think about baying another one.

Once you have your new partition for the backup. You need to boot up on some kind of live-cd with a linux environment. I've used the ubuntu 7.10 live-cd, it's quite handy, understand most of the modern hardware, contains the gparted util, have a web-browser etc. So it's stuffed pretty good for our purpose.

When you have your live cd booted up, you may copy the partitions. There's a builtin prgramm called 'dd', which allows you to copy block devices byte by byte, one to another. So you run it like that.

$ sudo dd conv=noerror if=/dev/old of=/dev/new

Where the '/dev/old' and '/dev/new' are your damaged and backup partitions. The optional attribute 'conv=noerror' tells the commad to skip reading errors.

Optionally you may unlock the 'universe' repository and install the 'dd_rescue' prgramm, which I belive, a wrapper for the 'dd' command and provides some more resuce oriended functionality.

The main point is to create an exact copy of the aviable data from the damaged partition.

And note, depends on the conditions, this may take quite a long time. My 60G partition was copied in about 7 hours.

That's it. Once you have a copy block. You run the 'reiserfsck' on the _copy_ partition like that.

$ sudo reiserfsck --rebuild-tree -S /dev/new

Note the '-S' option. This tells the reiserfsck programm to scan the whole partition for the aviable data. It's important, don't miss it up.

This operation usually is quite fast. Depends on the size of your data, and its condition this will take some minutes.

After the reiserfsck pargamm have finished, mount your new partition and take a look how is it going. If your partition was not damaged too hard, most of the data and directories structure will be on the right places. And there will be the 'lost+found' directory, take a look in it too, there will be lots of directories and subdirectories named with numbers. The util put there the files which were recovered but which former place was not found. And you may find there some files which you have deleted recently. So browse throw the directories, you may find some valuable data there too.

This is pretty much it. In really it's qute a simple stuff. Just don't get scary, some bad blocks on your hard drive is not a big problem, most of your data usually safe untill the harddrive any-working.