Saturday, November 10, 2007

/. party




I went to /. party at Cambridge. Slashdot 10th anniversary party. Few geeks showed up, but quality not quantity that matters. It was awesome, and off course Cambridge is a beautifull city. Plenty of students, bicycles and beautiful buildings, excellent plays to live in. Cheers.

Sunday, September 23, 2007

haskell meeting




Last Thursday I went on London HUG meeting. There were two speeches, one about finger trees, and other about games in Haskell. You can see me on both videos. Cheers.

Wednesday, September 12, 2007

haskell on Mac




I have to take my words back in terms of edgy development on Mac, in respect to Haskell. Basically thru macports system it is possible to install Haskell in version 6.6.1 or even development version 6.7 witch is really edgy now. And it is as easy as on Linux:

sudo port install ghc

or ghc-devel for 6.7 version. I was really surprised when I find out that really cool package hoc. It was created for Haskell version 6.1, of course it works perfectly for my needs – you can use it with the newer version but you can only use procedures that existed in version 6.6.1, but it means that sooner or later I will face problems. Any way, be aware that macports will additionally install ncurses-5.6, gmp-4.2.1, perl-5.8.8, readline-5.2, ghc-6.6.1. Do you see what I see Perl, what is this guy doing here. It reminds me this RoR installation - it installs PHP and actually uses it to do configuration tasks; how weird is that? By the way Instant Rails is the most common way to install RoR on windows.

Going back to main topic installation of all GHC dependencies will take a while, so be patient. If you never wrote anything in Haskell be sure to see if GHC is really the thing that you want. Basically majority of programs written for HUGS will not run on GHC and vice versa. It reminds me (again) about scheme, if you use guile your programs will probably not work on MIT/GNU Scheme or DrScheme. You will have to modify your code. Oh, well - life is taft.

But again don't you feel that it is sad. You program in a language that is understood only by a few, and you are unable to share it with all of those who understand it?

Saturday, September 8, 2007

Mac the return




I‘ve been trying to configure Mac for the last few days. I‘m in a middle of the python development and I had to install py-unit on Mac, and then integrate it with Eclipse. There is a darwin port of py-unit so I did a little research to find out what is the difference between fink and darwin. The only think that I can say is that it worked. PyUnit is running fine.

For some time on I was willing to give a git one more shot. Last time when I tried it (1.5 year ago), I did not enjoy it. It just didn't suit my needs. To be honest I did not spent too much time then to read about all the benefits that it brings. Few days ago I finally managed to watch Linus speech at dev days about git. Linus made some strong point, and I totally agree with him there, but also this speech did not answer few questions: why git merge code so well, why does it better than subversion. Also a thought about SHA1 was really interesting, I am not a security guru, I have a very basic knowledge about that, but I enjoy math and I spend a lot of time researching math issues, any way Linus said that SHA1 is the best hash that is available on a market. That's interesting, why is that? I have to do some bigger research on that subject.

I don't think that distributed source code management systems (SCMS) is something that I need now - working on my own projects, or with a few friends, but in the old days (when the Earth was young, and mountains small) it was just a thing that I would needed. I was most curious to find out how branches and merges are implemented in git, how many tools support it (plugins, GUIs and so on). I am using a subversion to run my local projects, I thought that it would be a good idea to use both SCMS systems at this same time, cause it will give me some picture witch one is faster, easier to do simple stuff, and more advanced ones. To install git on Mac:


curl http://kernel.org/pub/software/scm/git/git-1.5.0.5.tar.gz -O
tar -zxf git-1.5.0.5.tar.gz
pushd git-1.5.0.5
make configure
./configure --prefix=/usr/local
make all
sudo make install


Then add to .profile file:


export PATH=${PATH}:/usr/local/bin



Simple, but still I would prefer to use fink or darwin ports, unfortunately I did not find git project in those repositories.

There is a dmg for subversion
. Unfortunately current version of subversion is 1.4.5 and mentioned dmg is for version 1.4.4, but still it is not that bad. In order to run svn you have to add /usr/local/bin to your PATH, just like it was done fore git. In other words if you done it for git you don't have to do anything, but if you are reading this article to configure subversion on your Mac be sure to do this also.

If you are looking for a GUI for subversion to run on Mac be sure to try svnx. It is really simple to create a repository in svn, and to add an existing project to it.


svnadmin create /Users/sagasu/worek/subversion/repositories/myProjectRepository
svn import /Users/sagasu/workspaces/workspace/myProject file:///Users/sagasu/worek/subversion/repositories/myProjectRepository -m "initial import"


to use git is also easy, but I was only able to create a repository in a path above source that I wanted to add. I spent some time trying to figure out if I can create a repository anywhere I want, I did not find this information.


git config --global user.name "Your Name"
git config --global user.email my@email.com

git init
git add .
git commit


And we are ready to rock and roll.

Saturday, September 1, 2007

Some thoughts about Mac




I've been playing with my new Mac for the last few days. I've been really surprised. I thought that it will be much easier to do all this stuff that I do on my Ubuntu. Unfortunately it is not. I've been trying to run pygames cause lately I've been adding an Arabic language support to one of games that runs on that engine. Guess what? By default Mac ships with python version 2.3, this is so old. Now days we have version 2.5. It's getting even worst, I would like to upgrade my python to never version, but there is no package management system that would be up to day. There is fink but it doesn't have a new python also. I was able to find .dmg for python 2.5 and it installed without any problems. Unfortunately to run pygame you need to take care of some dependencies - PIL, SDL, PyObjc and so on, because there is no package manager I had to surf thru the web and find all the packages by hand. Good news is that they worked - installed without and problems. Then you have to compile pygame by hand - it reminds my of GNU/Linux 10 years before, I had to do exactly this same. I've compiled pygame by hand cause I wanted to run on python2.5, there is .dmg for pygame working on python2.4. To compile by hand I had to find source code, find dependencies, and compile just to find out that I've missed some dependencies. Dependencies have dependencies and this cycle never ended. Let's face it this sucks. Not many people use pygame so I thought that I could install eclipse here. So again I've checked the Java version - 1.5.0_07, but I would like to have 1.6 update 2, unfortunately this version is not ready for Mac. What about Jave EE, it's getting even worst, forget about it! There is no way I'm going to play with different frameworks on Mac cause everything here is just a pain in the ass, from the easy development point of view. I understand that it is fun to program on Mac in Haskell, SML or hacking RoR but I just can't see how to develop some java apps on new engines (I mean edgy). Mac has also a good side, I truly enjoy all the gadgets, iLife set - not including iTunes - I prefer Amarok - and again trying to make it work under Mac is painful. I really think that Mac is a good environment for desktop. It has MS Office (the app that I miss on Linux), and all this apps for movie, music and picture gameplay. And everything looks nice, and works out of box (I mean camera, Skype ...).

Conclusion. I'm going to install Ubuntu as my development system and use Mac just to play with my pictures and movies. I hope that in the next 3-5 years Mac will be ready for up to date development (edgy). Well it is ready to up to date development if you like to spend a lot of time trying to compile things, or developing on Windows is a thing that turns you on.

I've played also with dual boot. It is really easy to run Windows on Macbook Pro, but here goes the real problem - overheating. When I started an app that uses plenty of CPU resources on Windows I was scared almost to death. Macbook was so hot and fans were running really fast and really loud but were still unable to cool the darn thing down (temperature over 70° C). I've heard recently on /. about Macbook that catches on fire and burned a house. This is an extreme but it made me thinking how gamers can use Macbook pro, I just can't imagine running WoW for more then 2 hours and still be brave enough to keep it going. Don't get me wrong, the machine will hold it for more then 2 hours I'm just concerned how long will it take till something will really brake down. Macbooks are pretty expensive and I would be really sad if I would overheat my box and had to replace motherboard and CPU for a new one. I would have to think about some system (system of fans or cold water) to dock my Mackbook. This system would have to cool it down. As for now I will try to not overheat it.

Overheating is not a new thing to Apple; do you remember firmware updates last year? I thought that from that time on Apple would be more serious and cool laptops better, but as far as I can judge “it is not like that”. I’ve been interested how hot are apple products developed for a desktop use. Do they get so hot also? I’ve read on blogs that gamers don’t have problems in running games on non laptop machines, but they are not saying if the cover is hot or not. Especially I’ve been interested in the newest product.

To sum things up I would like to say that I truly enjoy hacking this system. It is a fun thing to do when you return to your home after work. Just like in old days, so many things to discover, and so many paths to take. I feel like I’m young again.

Friday, July 27, 2007

World is full of bugs




It happens to me pretty often. I'm up to something. Doing some research, playing with a new technology or just using a system that should work. And then when you really need something, you find out that that feature is buggy. In my flat in London I'm using D-link router to connect to the internet. I'm using a WiFi connection, with mac address filtering. My D-link router looses (somehow???) a safe list. The list of mac addresses that should be allowed to use WiFi connection. Then you have to go to router, connect to it by cable and re-add your mac address to the safe list once again. Sound simple, unfortunately there is a problem. The problem is called software bug, or laziness. I'm using web interface to configure my router. Unfortunately software that runs there was written to support only IE, in some cases. And this part is really interesting, cause majority of functionality is working under Firefox, Safari or you call it. Unfortunately not the functionality responsible for the modification of the safe list. Operating systems that I hold on my computer change in time (always doing something). Sometimes I have a working version of windows sometimes I do not. The only operating system that is working all the time is my Ubuntu. I was trying to use IE for GNU/Linux to modify the safe list, and it worked. I would not be myself if I did not write software that would run not only on IE but also on other thin clients. First thing to do is to see what the problem is. Firebug showed me that javascript engine can not find any element by it's id:


function jslSetValue(variable,value)
{
document.getElementById(variable).value=document.getElementById(value).value;
}


I've search the web to find out if somebody had already reported D-link with the problem, or did D-Link created any software update for that router model. I did not find anything. I've reengineered JavaScript that is used in that web interface and I've send it to D-link, maybe they will use my code instead of the current one. Now don't laugh I always send corrected code to the producer, unfortunately not very often I receive any reply. I can even bet that D-Link is not going to do anything with my code, they will just /dev/null it. But if even one per 20 companies that you send a code to will replay and thank you it is worth a try. If you face this same problem as I do there is a more simple way to quick fix your problem. After loading "Wireless Management" page just type in your URL:


javascript:document.forms.uiSetForm.uiPostAddMacAddress.value="00-1b-77-27-ca-72";


where 00-1b-77-27-ca-72 is your mac. And hit enter. Then hit history.back button in your browser. Then click "Add", now you will notice in a JavaScript console that there are bugs on the page, then click the "Apply button". Vuala your mac is added.

For smart ones, don't try to use 00-1b-77-27-ca-72 mac near my flat, it won't work cause it is just an example, I don't use it.

There are some interesting things about this particular pice of software. You may say that it is not a bug but producer simply just not want to support anything else besides IE. If it is true then why did they write JavaScript so some functionality will work on Firefox and some will not? Next interesting thing is the design. You probably noticed that they extracted some very simple logic into separate functions. I truly enjoy that. It also means that somebody did either a good design or refactored that software in a really nice manner. Why then he did not check if all the functionality works on different then IE thin clients? I'll never known. Whatever guess I'll take I'll still be just a child living in the big world. The world that I can never truly understand.

Tuesday, July 24, 2007

First Agile achivement




I've managed to do it. I like to describe my work as a contractor. I'm reassigned from project to project to do some job, achieve some goals. In my current work environment I've noticed a huge stagnation and frustration of the development team. They are using old technologies, old tools, old systems. They do not have any visionary person who would be able to push them forward. Don't get me wrong, people who work here were open to try something new, there wasn't just any person to show them a different way. Show what possibilities do they have, explain why by using some technique they can increase their performance. And then they faced me. So far organisation that I've described did not used any methodology, they were unorganised, did not have any deadlines, did not estimate their work, at least in a core of the development team. Because you could feel that they need some help I took some steps in order to push them forward. I've suggested agile as a methodology that might be helpful for them. I've provided them with tools to measure daily activity, explained basic agile concepts. I was really glad to see that a group of people is starting to work as a team, they organize themselves. Separate sprint from new activities assigned by product owner. Sprint is taking over their work. Now they estimate, they can see results of their work. What is more important their bosses also can see their work.

You can not became an agile user from day to day. This process takes time. What a great pleasure is to guild people through that way. See that it works for them. Then you can start corrections, explain why something should be done differently, suggest different tools. Today I was glad to see their retrospection presentation that was send to their bosses. One of the most beautiful things that one can experience is too see joy of the work that was done. And I saw it today, joy, proud, hope for better tomorrow. I just hope that I'll be able to guild them well. I do my best. As for today I attache pictures of their sprint blackboard. Keep your fingers crossed for us - the team.













Sunday, July 22, 2007

Orcas Subversion and SharePoint




I've moved to London, and I've been working on some ancient technologies lately. But what bothers me the most is the stagnation. If you stop discover the world surrounding you, you loose entire passion that you have. At least it happens to me. Anyway I've been playing a little bit with new Orcas and LINQ features; I was trying to write web parts using those technologies. Unfortunately I've hit the wall, as I see it is possible and I mange to go forward, but every step you take takes you to next challenge. The problem is that there is no plug-in for web parts for Orcas, and it makes a little bit harder to do all the tasks that you usually do when you develop in MS VS 2005. Any way I give up, but will give it a next shot next day. One thing that I've discovered is small number of blogs that describe VS projects done on a Subversion system. Hej, what’s going on, don't tell me that you still use VSS !!!.

Integrating already existing project with Subversion

I've decided to describe how easy it is to integrate your VS and subversion system. There are many ways to install Subversion on a windows box, I usually use one click project, and because it is the simplest way I know. Installation is pretty strait forward. Next thing to do is to download the VS plug-in. The only one I use is ankh, it will do the job. Here you can see some screens of how it looks like. Installation of plug-in is again really simple. Just be sure not to install repository in the default location, sooner or later everything stops working if there is " " spacebar in a location path (just like in string "Program Files"). To create a new repository I use my GNU/Emacs eshell, but you can use normal cmd shell. Just type:


svnadmin create C:\worek\subversionRepositories\myProject


and a repository is ready to be used. Now I import a project to that repository. I simply navigate to the directory where I keep my VS projects I click on my project then:


TortoiseSVN->import


in URL I specify a path to the repository:

file:///C:/worek/subversionRepositories/myProject

Then I can checkout that project to any location, and when I run a solution file Ankh plug-in asks me if I like to enable Ankh for that solution. Now my VS project is integrated with subversion.

I hope that I'll be able to add some value to my current project (at work). And I will manage to break through the stagnation in my current environment. After all life is just a bowl of cherries.

Bon App├ętit

Sunday, May 20, 2007

Scala




What is scala? Well folks, it is a statically typed programming language. It is based on OOP paradigm, and it's pretty pure on that - everything is an object, it smells like java here. But java is cheating, and as for now, I can't see any cheating from scala's syntax point of view. What's on my mind is that java distinguishes primitive types from reference types, and also functions are not objects. Right, what is so great about scala? Well, you can run scala from your java and .NET code! Can you see that, this is true write once run everywhere, you don't have to choose between .NET and Java anymore. Scala was pretty much at the end of the list of stuff that I was going to write about, but recently it was used on JavaOne, so I thought that it might be good to write about it now. Scala was developed by Martin Odersky's group. Before that time Martin was the author of current java compiler. Some people saids that this language is the java of the 21 century, SUN cannot change java syntax to scala cause it has to keep the backwards compatibility with java.

You can import any java library to scala and you can import any scala library to java. That's a big plus. It reminds me some presentation from JavaOne in 2006 when somebody said that SUN is promoting java not as a language but as a framework. It means that java has a huge number of frameworks that one can use, it also have many tools, and apps already written - just look at those application servers. What it really sucks on is the language itself - it miss so many things. Lets' go back to scala.

Scala has some functional language specific features but it is NOT a functional language. I've read in a few places that it is, but it is not. Scala is an imperative language!!! If you are interested of what it exactly has, be sure to read this short summary.

Personally I do not like the syntax of it sometimes. For example functions:


def foo(callback: () => unit) {
...
}


what's that, just look at this thing. Why not call callback a function, or do something like this:

def foo(function bar){
...
}


I know, it's because we want to show what we are returning. It's all because of strong typing. Otherwise strong typing purists would scream that it might be confusing, just like they did with type inference in java. But why not to do a literal for that? Or some AI for the compiler - actually this kind of AI is already implemented, cause compiler can guess a return type for methods:


class Foo(bar: double) {
def buzz() = bar
}


Here, I don't have to specify a return type. For those of you who didn't cache that one I'm a week type languages supporter, I just hate to write more than I really have to. And this syntax is quite alike anonymous function syntax so I won't say any bad word anymore.

Let's rock and roll
First thing to do is to configure your favorite environment. Scala's distribution ships with modes for many general use apps. As for 2.4.0 version it binds to: a2ps, emacs, gedit, intellij, jedit, kate, scite, vim, xcode. They are installed in the ${SCALLA_INSTALL_DIR}/share/scala/misc/scala-tool-support. Notice that it's not very common that a tool supports intellij in a standard distribution and not eclipse. Fear not, eclipse plugin is located here. Here is my configuration for GNU/Emacs.

(defvar utils-dir "/home/sagasu/worek")
(setenv "SCALA_HOME" (concat utils-dir "/scala"))
(setenv "PATH" (concat (getenv "PATH")
":" (getenv "SCALA_HOME") "/bin"))
(require 'scala-mode-auto)


Scala and Maven
As for now there is no scala plugin for maven that is ready to use. Google is sponsoring creation of a plugin. So, it's not in any maven repository but you can build it yourself. Grab it from subversion repository:

svn checkout http://maven-scala-plugin.googlecode.com/svn/trunk/ maven-scala-plugin

and build

cd maven-scala-plugin
mvn install


now we can add following lines to our maven project (pom.xml file) in order to compile any scala program:


<build>
<plugins>
<plugin>
<groupId>scala</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<id>scala-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<uncheckedWarnings>true</uncheckedWarnings>
<deprecationWarnings>true</deprecationWarnings>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>scala</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<id>scala-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Thursday, May 10, 2007

Date Parsing and Formating in Java




Sounds simple. There is SimpleDateFormat you may say, or GenericTypeValidator. What's the problem then? Well folks, both libraries are not good enough to parse/format dates.

So we want to allowed users to input dates only in a format "yyyy-MM-dd" or "yyy-MM-dd HH:mm".

Let’s write a unit test for that:


import java.util.Date;

import junit.framework.TestCase;

public class DateTimeFormatTest extends TestCase{
public void testParseDate() throws Exception {
Date date = DateTimeFormat.parseDate("2005-01-01", DateTimeFormat.getDateFormat());
assertNotNull(date);

}
}


OK, now let's write a class:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.validator.GenericTypeValidator;

public class DateTimeFormat {
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
private static final String DATE_FORMAT = "yyyy-MM-dd";

public static Date parseDate(String dateValue, String format) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
Date aParsedDate = null;
try {
aParsedDate = simpleDateFormat.parse(dateValue);
} catch (ParseException e) {
return null;
}
return aParsedDate;
}

public static String getDateFormat() {
return DATE_FORMAT;
}

public static String getDateTimeFormat() {
return DATE_TIME_FORMAT;
}

}


So now if we run a test it succeeds. Let's add additional tests.

date = DateTimeFormat.parseDate("2005-01-aa", DateTimeFormat.getDateFormat());
assertNull(date);

date = DateTimeFormat.parseDate("2005/01/01", DateTimeFormat.getDateFormat());
assertNull(date);



Hey, it's working again. But wait, what about this one:


date = DateTimeFormat.parseDate("2005-01-01 12:12", DateTimeFormat.getDateFormat());
assertNull(date);

Ups, tests don’t pass. Now there is a way that we can tell SimpleDateFormat to be more strict, just add this line

simpleDateFormat.setLenient(false);

unfortunately it won't work. I guess using this kind of parsing is not a good idea :>

But now let's use GenericTypeValidator. We write a test:

public void testValidatorParseDate() throws Exception {
Date date = DateTimeFormat.validatorParseDate("2005-01-01", DateTimeFormat.getDateFormat());
assertNotNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-aa", DateTimeFormat.getDateFormat());
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005/01/01", DateTimeFormat.getDateFormat());
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-01 12:12", DateTimeFormat.getDateFormat());
assertNull(date);
}



and we add a method to the class:


public static Date validatorParseDate(String dateValue, String format) {
Date aParsedDate = GenericTypeValidator.formatDate(dateValue, format, true);
return aParsedDate;
}



Hey this one works. Now add additional test case:


date = DateTimeFormat.validatorParseDate("2005-1-1-1", DateTimeFormat.getDateFormat());
assertNull(date);


Ups again failure. This same thing happens to the next test:


date = DateTimeFormat.validatorParseDate("2005-11-11 1:1:1", DateTimeFormat.getDateTimeFormat());
assertNull(date);


Again using this parser is not a good idea, but it's better then SimpleDateFormat. What to do then? I use regexps, but by using them I force myself to write additional regexp for every date pattern that I allow. In showed example I've only used two date patterns "yyyy-MM-dd HH:mm" and "yyyy-MM-dd" but I used to deal with systems with more then 8 date patterns and it gets pretty messy their, witch means that I have to use some more complicated techniques in order to create a good looking code. Now after refactoring, both classes looks as follow:

import java.util.Date;

import junit.framework.TestCase;

public class DateTimeFormatTest extends TestCase{

public void testValidatorParse() throws Exception {
String dateFormat = DateTimeFormat.getDateFormat();
String dateFormatRegexp = DateTimeFormat.getDateFormatRegexp();

Date date = DateTimeFormat.validatorParse("2005-01-01", dateFormat, dateFormatRegexp);
assertNotNull(date);

date = DateTimeFormat.validatorParse("2005-01-1", dateFormat, dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.validatorParse("2005-01-01", DateTimeFormat.getDateTimeFormat(), dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.validatorParse("2005-01-01", dateFormat, DateTimeFormat.getDateTimeFormatRegexp());
assertNull(date);

date = DateTimeFormat.validatorParse("2005-01-01 12:12", DateTimeFormat.getDateTimeFormat(), DateTimeFormat.getDateTimeFormatRegexp());
assertNotNull(date);
}

public void testParse() throws Exception {
String dateFormat = DateTimeFormat.getDateFormat();
String dateFormatRegexp = DateTimeFormat.getDateFormatRegexp();

Date date = DateTimeFormat.parse("2005-01-01", dateFormat, dateFormatRegexp);
assertNotNull(date);

date = DateTimeFormat.parse("2005-01-1", dateFormat, dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.parse("2005-01-01", DateTimeFormat.getDateTimeFormat(), dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.parse("2005-01-01", dateFormat, DateTimeFormat.getDateTimeFormatRegexp());
assertNull(date);

date = DateTimeFormat.parse("2005-01-01 12:12", DateTimeFormat.getDateTimeFormat(), DateTimeFormat.getDateTimeFormatRegexp());
assertNotNull(date);
}

public void testParseDate() throws Exception {
Date date = DateTimeFormat.parseDate("2005-01-01");
assertNotNull(date);

date = DateTimeFormat.parseDate("2005-01-aa");
assertNull(date);

date = DateTimeFormat.parseDate("2005/01/01");
assertNull(date);

date = DateTimeFormat.parseDate("2005-01-01 12:12");
assertNull(date);

date = DateTimeFormat.parseDate("2005-01-01 12:12");
assertNull(date);

date = DateTimeFormat.parseDate("2005-1-1-1");
assertNull(date);
}

public void testParseDateTime() throws Exception {
Date date = DateTimeFormat.parseDateTime("2005-01-01 11:11");
assertNotNull(date);

date = DateTimeFormat.parseDateTime("2005-11-11 1:1:1");
assertNull(date);

date = DateTimeFormat.parseDateTime("2005-11-11 9:11");
assertNull(date);

date = DateTimeFormat.parseDateTime("2005-11-11");
assertNull(date);
}

public void testValidatorParseDate() throws Exception {
Date date = DateTimeFormat.parseDate("2005-01-01");
assertNotNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-aa");
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005/01/01");
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-01 12:12");
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005-1-1-1");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 1:1:1");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 11:11");
assertNotNull(date);
}

public void testValidatorParseDateTime() throws Exception {
Date date = DateTimeFormat.validatorParseDateTime("2005-01-01 11:11");
assertNotNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 1:1:1");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 9:11");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11");
assertNull(date);
}
}



And the main class

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.validator.GenericTypeValidator;

public class DateTimeFormat {
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String DATE_FORMAT_REGEXP = "^[0-9]{4}-[0-9]{2}-[0-9]{2}$";
private static final String DATE_TIME_FORMAT_REGEXP = "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$";

/**
* @param dateValue
* @param format
* @param regexp
* @return parsed date if dateValue matches format and regexp, else null
*/
public static Date validatorParse(String dateValue, String format, String regexp) {
Date parsedDate = GenericTypeValidator.formatDate(dateValue, format, true);
return matchRegexp(dateValue, regexp, parsedDate);
}

/**
* @param dateValue
* @param regexp
* @param parsedDate
* @return parsedDate if dateValue matches regexp, else null
*/
private static Date matchRegexp(String dateValue, String regexp, Date parsedDate) {
if(!dateValue.matches(regexp)){
return null;
}
return parsedDate;
}

/**
* @param dateValue
* @return date parsed by SimpleDateFormat
*/
public static Date parseDate(String dateValue) {
return parse(dateValue, getDateFormat(), getDateFormatRegexp());
}

/**
* @param dateTimeValue
* @return date parsed by SimpleDateFormat
*/
public static Date parseDateTime(String dateTimeValue) {
return parse(dateTimeValue, getDateTimeFormat(), getDateTimeFormatRegexp());
}

/**
* @param dateTimeValue
* @return date parsed by GenericTypeValidator
*/
public static Date validatorParseDateTime(String dateTimeValue) {
return validatorParse(dateTimeValue, getDateTimeFormat(), getDateTimeFormatRegexp());
}

/**
* @param dateValue
* @return date parsed by GenericTypeValidator
*/
public static Date validatorParseDate(String dateValue) {
return validatorParse(dateValue, getDateFormat(), getDateFormatRegexp());
}

/**
* @param dateValue
* @param format
* @param regexp
* @return parsed date if dateValue matches format and regexp, else null
*/
public static Date parse(String dateValue, String format, String regexp) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
simpleDateFormat.setLenient(false);
Date parsedDate = null;
try {
parsedDate = simpleDateFormat.parse(dateValue);
} catch (ParseException e) {
return null;
}
return matchRegexp(dateValue, regexp, parsedDate);
}

public static String getDateFormat() {
return DATE_FORMAT;
}

public static String getDateTimeFormat() {
return DATE_TIME_FORMAT;
}

public static String getDateFormatRegexp() {
return DATE_FORMAT_REGEXP;
}

public static String getDateTimeFormatRegexp() {
return DATE_TIME_FORMAT_REGEXP;
}

}


Because both SimpleDateFormat and GenericTypeValidator need to be enhanced in order to work properly I'll stick with SimpleDateFormat, mainly because I don't have to use huge apache library in order to parse anything. Two things bother me. Why do I have to write my own validator, and why there is no way in java to remove this redundancy that I see in tests. I'll live it for the future investigation.

Saturday, May 5, 2007

Ruby and GTK2




I've been using for a while Zenity as a simple framework to provide user interaction on my local machine. Few of my family members also use my computer and it is easier for them to use UI, then to remember all the magic words, not to mention terminal. So, my Internet provider likes to drop the connection, maybe not very often but it happens. It's really suspicious when you are doing some research and it's 2:30 am and then suddenly your ISP declines your connections. Perhaps they are doing some cleaning at that hour, maybe it is worth investigating, but as for now never mind. Right, clearly I need a tool that will show what's the status of the connection - do I need to reconnect or I'm connected but the traffic is really bad. Zenity happens to be a great tool, it's easy to use and you can create some user interaction really easy. Because I like to do new things I've decided to check out ruby GTK2 library for that. And Yes I was inspired by the recent news that Microsoft is going to include Iron Ruby in .NET framework. Here is my impression of that.

Because it is my first post about ruby let me just remind you that there is a mod for GNU Emacs. Now, you have to install additional libraries in order to use GKT2 from a ruby. I'm using Ubuntu and dependencies are pretty big, but it's as easy to install additional stuff as typing


sudo apt-get install ruby-gnome2


If you are not familiar with ruby and GTK2 a great tutorial can be found here. And in terms of API documentation be sure to try rbbr or web API documentation.

In terms of code ruby bindings to GTK are like any other bindings to GTK. This is definitely not the best way of creating UI. In terms of UI i strongly agree with Steve Yegge. Now let's get back to the ruby. Here is a code that I came up with:


require 'gtk2'

class InternetConnection


def initialize()
@connection_status = "You a_re not connected to the Internet"
end

def checkStatus()
commandOutput = `ifconfig`
if commandOutput.index("ppp0") != nil then
@connection_status = "You a_re connected to the Internet"
else
@connection_status = "You a_re not connected to the Internet"
end
end

def disconnect()
command = `xterm -e "sudo killall pppd"`
checkStatus()
end

def connect()
command = `xterm -e "sudo pppd call speedtch"`
checkStatus()
end

def run()
table = Gtk::Table.new(3, 4, true);


image_apple_green = Gtk::Image.new("apple-green.png")
image_apple_red = Gtk::Image.new("apple-red.png")
image_status = Gtk::Image.new("tennis-ball.png")

checkStatus()
b_status = Gtk::Button.new(@connection_status, use_underline = true)
b_status.set_image(image_status)
b_status.signal_connect("clicked"){
checkStatus()
}

b_connect = Gtk::Button.new("C_onnect to the Internet", use_underline = true)
b_connect.set_image(image_apple_green)
b_connect.signal_connect("clicked") {
connect()
}

b_disconnect = Gtk::Button.new("_Disconnect from the Internet", use_underline = true)
b_disconnect.set_image(image_apple_red)
b_disconnect.signal_connect("clicked") {
disconnect()
}

b_close = Gtk::Button.new(Gtk::Stock::CLOSE)
b_close.signal_connect("clicked") {
Gtk.main_quit
}

window = Gtk::Window.new
window.signal_connect("delete_event") {
Gtk.main_quit
false
}

table.attach_defaults(b_status, 0, 4, 0, 1 )
table.attach_defaults(b_connect, 0, 2, 1, 2 )
table.attach_defaults(b_disconnect, 2, 4, 1, 2 )
table.attach_defaults(b_close, 1, 3, 2, 3 )

window.border_width = 10
window.add(table)
window.show_all

Gtk.main
end

end



And it looks like that:

Thursday, May 3, 2007

Unit Testing with Groovy




So we know what the Groovy is and how to eat it. Now it is time to do something useful in terms of methodology. I'm agilist and the thing that I do after knowing constructors and reductors is how to test it. Again Groovy is really helpful, and easy to use. So, you don't need to add additional libraries or do some hacking to use tests in Groovy - they are provided in a default installation. By the default installation i mean get a Groovy from local ftp untar it and there it is ready to be used. So here is a simple example:

Create a class Square.groovy

class Square{
def square(x) {x*x}
}


Create a class SquareTest.groovy

import Square

class SquareTest extends GroovyTestCase{

void testSquare(){
Square square = new Square()
assertEquals( square.square(3),9)
}
}


be sure that both classes are in one catalog. In a command line just type:

groovy SquareTest.groovy


and see the result - everything is fine. It is the easiest xUnit framework that I've seen.
One thing about classes in Groovy - they are public by default, same as methods.

Now let's say that we want to create a framework in maven or we already have one and we want to add some Groovy classes or Groovy test classes. This task is more complicated - because of maven, it is a good tool but sometimes when you search in a xml files for a bug it it terrible, I hate it, but again it is like 200 times better then ant.

so to create a maven project (I'm using maven 2.*) just type:

mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app


Now goto my-app and edit pom.xml add:

<dependency>
<groupid>groovy</groupid>
<artifactid>groovy-all</artifactid>
<version>1.0</version>
<scope>test</scope>
</dependency>


create a folder groovy in my-app/src/main directory and in the my-app/src/test. In other words just in this same place as java folder. And put a *.groovy class there. Go back to the my-app directory, and run:

mvn groovy:compile


to compile main classes.

mvn groovy:testCompile


to compile test classes.

You might ask "Cool, but is there a way to compile classes just by calling normal mvn install or mvn compile?". Yes there is, just add this code to your pom.xml file:


<build>
<plugins>
<plugin>
<groupid>org.codehaus.mojo</groupid>
<artifactid>groovy-maven-plugin</artifactid>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>


Now every time you compile or run tests also groovy classes are going to be included.

Wednesday, April 25, 2007

Old world of Java





I've been coding in Java language for some time now. To be honest I many times complained about features that it just doesn't have. It's really easy to pick some things that are missing there. Hey, but it is going to be better. Recently I've been reading Neal's blog and as I can clearly see it is going to happen. The world of Java is going to receive plenty of goodies in a new Dolphin release, but why wait. Groovy, Nice, SISC-scheme of course are already there. They are not fully featured but they do have "the meat". I don't have to say that sic-scheme is my favorite one, but it is also the most scary one for the typical Java developer so lets begin with something easier - Groovy.

Groovy workspace

This framework is really easy to use and it has a pretty good documentation. So it has plugins for Eclipse, Idea, Emacs, JDeveloper and plenty other editors. Be aware that it is really hard (and I do mean it) to create a good plugin for a highly dynamic language (take a look at those for Ruby, thats what I call fun) so be prepared that sometimes they have hard time telling you what attributes or methods some object has. Right, First cool thing is literals for lists and maps (no need to construct a class). Finally I can create a list just by typing:

By the string "->" I mean "returns".


foo = [1, 3, 4, "sigma", "lambda"]
foo[1] -> 3
foo[3] -> "sigma"


And yes lists are polymorphic just as dictionaries called maps here.


bar = [123:4, "gamma":"omega", "pi":3.14]

bar["gamma"] -> "omega"
bar[123] -> 4


or in a shorter way

bar.gamma -> "omega"

unfortunately when you try to execute

bar.123 an error will accure


This syntaxt is much more modern and in my opinion much better then typical construction with "new" prefix. Im also glad that dynamic and static typing is supported - hey, maybe one day I will be able to do all the tricks that I can do with VB.NET language (now don't laugh it's sad but it is true), but as for now Groovy is not quite yet there.

Next thing that I really missed from python was the string agility, basicly I could use " or ' character as a string and If I wanted to create some complicated string I could just put it into """ block. And here it is ready to use in groovy.


name = "Basho Matsuo"

someXML = """
Fallen sick on a journey,
In dreams I run wildly
Over a withered moor.
${name}
"""



Next sexy thing to investigate is a support for closers - Ladies and Gentlemens finally, Java stops to look like Logo language and introduce some meat that makes your job easier.