Sunday, July 13, 2008

Numerology with Ruby

This is a simple Numerology calculator written in ruby. Just a pass time program while learning ruby.
This will give you the value of the given name and date (date of birth)
Usage:
./numerology.rb <your_name> <date> <month> <year>


#!/usr/bin/env ruby
class Numerology
@name
@date
@month
@year
$map = {'A' => 1, 'J' =>1, 'I' =>1, 'Y' => 1, 'Q' => 1,
'B' => 2, 'K' => 2, 'R' => 2,
'S' =>3, 'C' =>3, 'L' =>3, 'G' => 3,
'T' => 4, 'D' => 4, 'M' => 4,
'E' =>5, 'N' => 5, 'X' =>5, 'H' => 5,
'U' => 6, 'V' => 6, 'W'=>6,
'O' =>7, 'Z' => 7,
'F' =>8, 'P' => 8 ,
' ' => '' #for removing spaces
}

def initialize(name,date,month,year)
if name.nil? or name.empty?
raise "Please provide a name"
end
@name = name.upcase
@date = date.to_i
@month = month.to_i
@year = year.to_i
if @date == 0 or @month == 0 or @year == 0
raise "Please provide a valid date"
end
end

def calculate
puts "Name : #{@name} \n"
puts "Date : #{@date}/#{@month}/#{@year} \n"
sum = 0

#old version
#~ Range.new(0,@name.length).each do|n|
#~ #puts "char at #{n} = #{@name[n]}"
#~ #print @name[n]
#~ case @name[n]
#~ when ?A , ?J , ?I , ?Y , ?Q then sum = sum + 1
#~ when ?B , ?K , ?R then sum = sum + 2
#~ when ?S , ?C, ?L, ?G then sum = sum +3
#~ when ?T, ?D, ?M then sum = sum +4
#~ when ?E, ?N, ?X, ?H then sum = sum + 5
#~ when ?U, ?V, ?W then sum = sum + 6
#~ when ?O, ?Z then sum = sum + 7
#~ when ?F, ?P then sum = sum +8
#~ end
#~ while sum > 9
#~ sum = sum_digits(sum)
#~ end
#~ end

#replace the chararcters with thier numberic equivalent
#map contains key value pairs - A : 1, B : 2....
#replace each char (key in map) in the string with the value from the map
$map.each do |k,v|
@name.gsub!(k, v.to_s)
end

#find the sum of digits until the sum is single digit
sum = @name.to_i
while sum > 9
sum = sum_digits(sum)
end

#calculate sum value for date of birth
dateSum = @date + @month + @year
while dateSum > 9
dateSum = sum_digits(dateSum)
end

print "Name value :#{sum}\n"
print "Date value :#{dateSum}\n"

end

private
#sum the digits of the given number
def sum_digits(num)
sum = 0
quotient = num
while quotient > 0
#puts "sum : #{sum}, reminder: #{reminder}, quotient: #{quotient}"
reminder = quotient % 10
quotient = quotient / 10
sum = sum + reminder
end
return sum
end
end


if __FILE__ == $0
begin
num = Numerology.new(ARGV[0],ARGV[1],ARGV[2],ARGV[3])
num.calculate
rescue => ex
puts "Error : #{ex.message}"
end
end

Friday, March 28, 2008

Komodo may be the choice now....

I have been looking for an open source feature rich IDE for dynamic languages such as Python, ruby and Javascript. Now that ActiveState has released an opensource version of its Komodo, that may be become a primary choice for dynamic languages.

http://www.activestate.com/Products/komodo_ide/komodo_edit.mhtml

No more pydev - a huge junk of java for editing python files.

Thanks a lot ActiveState....

Sunday, February 10, 2008

GWT - FlexTable with frozen header

DataGrids displaying a huge set of data with header for each column would be better usable with its header row frozen.
Plain HTML tables, with frozen header are very simple to create.

  1. Create THEAD and TBODY elements.
  2. For TBODY element's style set overflow: auto or scroll;
  3. Set fixed size for the TBODY element
In GWT, a table created using either using Grid or FlexTable, creates only TBODY element and no THEAD element.
So to render a table with frozen header, in GWT we'll have to extend either Grid or FlexTable with a THEAD element and a few getter and setter methods for accessing the THEAD columns.



package name.aanand.magix.client;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;


public class DataGrid extends FlexTable {

private Element head;
private Element headerTr;

public DataGrid() {
super();
head = DOM.createTHead();
headerTr = DOM.createTR();
DOM.insertChild(this.getElement(), head, 0);
DOM.insertChild(head, headerTr, 0);
Element tBody = getBodyElement();
DOM.setElementAttribute(tBody, "style", "overflow:auto;text-align: left;");
DOM.setElementAttribute(head, "style", "text-align: left;");

}

public void setHeight(String height) {
DOM.setElementAttribute(getBodyElement(), "height", height);
}

public void setHeader(int column,String text){
prepareHeader(column);
if (text != null) {
DOM.setInnerText(DOM.getChild(headerTr, column), text);
}
}

private void prepareHeader(int column) {
if (column < 0) {
throw new IndexOutOfBoundsException(
"Cannot create a column with a negative index: " + column);
}
int cellCount = DOM.getChildCount(headerTr);
int required = column + 1 - cellCount;
if (required > 0) {
addCells(head, 0, required);
}
}


public void setHeaderWidget(int column, Widget widget) {
prepareHeader(column);
if (widget != null) {
widget.removeFromParent();
// Physical attach.
DOM.appendChild(DOM.getChild(headerTr, column), widget.getElement());

adopt(widget);
}
}

private native void addCells(Element table, int row, int num)/*-{
var rowElem = table.rows[row];
for(var i = 0; i < num; i++){
var cell = $doc.createElement("td");
rowElem.appendChild(cell);
}
}-*/;

Monday, November 12, 2007

Buggy IE

IE fails to parse <script> content if its in XHTML shorthand format that is <script src="some.js" type="text/javascript" />.
But works fine in Firefox and other mozilla based browsers.

To fix this one has expand the tag as follows:

<script src="some.js" type="text/javascript">
</script>

I checked it with IE 6, may be in version 7 it could be working..

Blogged with Flock

Sunday, November 04, 2007

GWT and its package names

Recently I and my friend came across a silly bug that took nearly half a day for us to find a solution for it. The bug that i encountered is with the GWTCompiler.

We had some compilation problems when we started writing an Async interface for one of our services. The error log said that the Proxy class that was generated by GWT for deferred binding had some errors.
It pointed out at some line and read com.google was not resolved. But the snapshot of the file was pretty clean and had no errors.
At first i thought it was some classpath problem, but after fighting and struggling with it for about 2 hours or so my friend suddenly popped up with a doubt, eyeing at the Async interface's method which had a parameter named com.

That's it; it is not able to resolve packages, if there is any variable declared with same name as the package.

For example

//imports
public interface MyServiceAsync{
public void save(SomeType com, CallBack c);
}

This Async interface will produce errors while compiling. So make sure that you don't name the variables with any package names.

Friday, October 12, 2007

Class.forName("fully.qualified.ClassName").newInstance() in GWT

In Java, when we design something to work generically like loading a plugin Class or something like that, we use the classloader to load some arbitrary class and instantiate it using the Class.newInstance() (Assuming that our Class has a Zero argument constructor) or using the constructors through the Class's getConstructor method.

This feature cannot be used in GWT, as you may all know that the client code (JavaScript) is statically generated. There is no Classloader or no Class.newInstance() or no reflection at all in Javascript. So to provide very least feature of instantiating a Class by knowing its classname, here is a tip that you may like.

We may not require all the Class types to be available for dynamic instantiation. So we are gonna mark the required Class types as Instantiable (A marker interface).
Now, we need some factory class which has a method newInstance(String className), using which we can create an instance of specified classname.



1 package name.aanand.gwt.client;

2

3
/**

4 * Platform factory to create instance of any {@link Instantiable} type.

5 * @author aanandn

6 *

7 */

8 public interface Factory {

9 Instantiable getInstance(String className);

10 }




Now we are gonna create a Class called ReflectiveFactory which is defined as follows...


1 package name.aanand.gwt.client;

2

3

4 /**

5 * Factory class for instantiating any {@link Instantiable} type by providing

6 * the fully qualified Class name.

7 * @author aanandn

8 *

9 */

10 public class ReflectiveFactory implements FactoryWrapper{

11 }


The ReflectiveFactory implements an interface called FactoryWrapper which is again a marker interface to identify the factory classes for which Wrapper implementations or Proxies have to be generated. Now we are ready with our base interfaces. And here begins how its achieved...

First have a singleton class which instantiates our Factory like this:

factory = (Factory) GWT.create(ReflectiveFactory.class);

and return this factory whenever its asked for.

Now you may wonder, how will it work without any real code in the ReflectiveFactory. So here is the explaination of how its gonna work.

  1. We are going to extend the GWT compiler to generate a wrapper or proxy for each of the Classes which implement FactoryWrapper.
  2. The generator should create a new class with name Wrapper, which implements Factory.
  3. In the case of ReflectiveFactory, first we are going to get all the Instantiable types.
  4. And finally generate the method newInstance(String className), conditionally returning one of the Reflectables based on the specified className.
To extend GWTCompiler we need to add an entry in our module XML as follows:


1 <module>
2
3 -- Inherit the core Web Toolkit stuff. -->
4 <inherits name='com.google.gwt.user.User'/>
5
6 -- Specify the app entry point class. -->
7 <entry-point class='name.aanand.gwt.client.MainEntryPoint'/>
8
9
<generate-with class="name.aanand.gwt.generator.FactoryGenerator" >
10
<when-type-assignable class="name.aanand.gwt.client.FactoryWrapper" />
11
</generate-with>
12
13
</module>
14



The FactoryGenerator class should extend the abstract class Generator and implement its method
public String generate(TreeLogger logger, GeneratorContext context, String typeName)

Simple implemenation of FactoryGenerator is given below:



1 package name.aanand.gwt.generator;

2

3 import java.io.PrintWriter;

4

5 import com.google.gwt.core.ext.Generator;

6 import com.google.gwt.core.ext.GeneratorContext;

7 import com.google.gwt.core.ext.TreeLogger;

8 import com.google.gwt.core.ext.UnableToCompleteException;

9 import com.google.gwt.core.ext.typeinfo.JClassType;

10 import com.google.gwt.core.ext.typeinfo.NotFoundException;

11 import com.google.gwt.core.ext.typeinfo.TypeOracle;

12 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;

13 import com.google.gwt.user.rebind.SourceWriter;

14

15 public class FactoryGenerator extends Generator {

16

17 public String generate(TreeLogger logger, GeneratorContext context,

18 String typeName) throws UnableToCompleteException {

19 logger.log(TreeLogger.INFO, "Generating source for " + typeName, null);

20 TypeOracle typeOracle = context.getTypeOracle();

21

22 JClassType clazz = typeOracle.findType(typeName);

23 if (clazz == null) {

24 logger.log(TreeLogger.ERROR, "Unable to find metadata for type '"

25 + typeName + "'", null);

26 throw new UnableToCompleteException();

27 }

28

29 try {

30 logger.log(TreeLogger.INFO, "Generating source for "

31 + clazz.getQualifiedSourceName(), null);

32

33 JClassType reflectableType = typeOracle

34 .getType("name.aanand.gwt.client.Instantiable");

35 SourceWriter sourceWriter = getSourceWriter(clazz, context, logger);

36 if (sourceWriter != null) {

37 sourceWriter.println("public "

38 + reflectableType.getQualifiedSourceName()

39 + " newInstance(String className) {");

40 JClassType[] types = typeOracle.getTypes();

41 int count = 0;

42 for (int i = 0; i < types.length; i++) {

43 if (types[i].isInterface() == null

44 && types[i].isAssignableTo(reflectableType)) {

45 if (count == 0) {

46 sourceWriter.println(" if(\""

47 + types[i].getQualifiedSourceName()

48 + "\".equals(className)) {"

49 + " return new "

50 + types[i].getQualifiedSourceName() + "();"

51 + "}");

52 } else {

53 sourceWriter.println(" else if(\""

54 + types[i].getQualifiedSourceName()

55 + "\".equals(className)) {"

56 + " return new "

57 + types[i].getQualifiedSourceName() + "();"

58 + "}");

59 }

60 count++;

61 }

62 }

63 sourceWriter.println("return null;");

64 sourceWriter.println("}");

65 sourceWriter.commit(logger);

66 logger.log(TreeLogger.INFO, "Done Generating source for "

67 + clazz.getName(), null);

68 return clazz.getQualifiedSourceName() + "Wrapper";

69 }

70 } catch (NotFoundException e) {

71 e.printStackTrace();

72 }

73 return null;

74

75 }

76

77 public SourceWriter getSourceWriter(JClassType classType,

78 GeneratorContext context, TreeLogger logger) {

79

80 String packageName = classType.getPackage().getName();

81 String simpleName = classType.getSimpleSourceName() + "Wrapper";

82 ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(

83 packageName, simpleName);

84 composer.addImplementedInterface("name.aanand.gwt.client.Factory");

85 PrintWriter printWriter = context.tryCreate(logger, packageName,

86 simpleName);

87 if (printWriter == null) {

88 return null;

89 } else {

90 SourceWriter sw = composer.createSourceWriter(context, printWriter);

91 return sw;

92 }

93 }

94

95 }

96




Now compile your code with GWTCompiler and start using as shown below:

Factory factory = (Factory) GWT.create(ReflectiveFactory.class);
factory.newInstance("fully.qualified.Classname");

Thats all folks!

Monday, October 08, 2007

Simple Key Mappings for VIM

These are very simple key-mappings for VIM 7.0 and above, to play with tabs (or tab pages).


 5 set nu!

 6 set wrap!

 7 color desert

 8 set guioptions+=b

 9 :map <C-N> <M>:tabnew<CR>

10 :map <S-TAB> <M>:tabnext<CR>

11 :map <C-F4> <M>:tabclose!<CR>

12 :map <C-O> <M>:browse tabnew<CR>


All are command mode shortcuts.

CTRL-N  -  creates a new tab page.
CTRL-O  -  Opens a file in a new tab page.
CTRL-F4 - Closes current tab page

SHIFT-TAB - rotates through the tab pages.

Happy Vimming!