Setup Credit Installments Plan Dates using java.util.Calendar in Jython

2010/02/03

This blog shows an example on how Jython will make it easier for you to explore Java library or API.

In this sample I try to show how Jython could be used to learn a Java platform library or API interactively. Hopefully without going through the pain of code-compile-deploy-test cycles. After being familiar with certain library or API, we could come back the regular Java way to code.

In this blog I will pick a very common case. Nowadays, when we buy a house or car, a piece of land, or anything that is very expensive, seldom we will pay all full in cash. Usually we will apply for loan with banks or leasing companies. The bank or leasing company will then set up a installment that is scheduled regularly. They will choose a preset dates for the payments. Preset (or pre-agreed) dates could apply to payroll schedule, automated account posting, automated reminders, etc.

Java has a rich set of library or API almost for anything you need to. It’s the most comprehensive platform available in the market today. It runs in more devices than any other platforms (PC, servers, laptops, netbooks, handheld devices, smartphones, PDAs, game consoles, SIM cards, microcontrollers, etc.).

Back to topic, one way to do the preset installment is to use java.util.Calendar interface and one of its implementation: java.util.GregorianCalendar.

Because the class and interface that I mentioned above is part of Java Runtime libraries, it is automatically available for Jython as well (I am using Jython version 2.5.1, but it should be available on any versions of Jython).

from java.util import Calendar
from java.util import GregorianCalendar

def cal_to_str(c):
    year = str(c.get(Calendar.YEAR))
    month_int = c.get(Calendar.MONTH) + 1
    if month_int < 10:
        month = '0' + str(month_int)
    else:
        month = str(month_int)
    day_int = c.get(Calendar.DAY_OF_MONTH)
    if day_int < 10:
        day = '0' + str(day_int)
    else:
        day = str(day_int)
    return year + '-' + month + '-' + day

for i in range(12):
    cal = GregorianCalendar(2009,8 - 1,29)
    cal.add(Calendar.MONTH, i + 1)
    print('Installment #%d: %s' % ((i + 1), cal_to_str(cal)))

The execution yielded:

Installment #1: 2009-09-29
Installment #2: 2009-10-29
Installment #3: 2009-11-29
Installment #4: 2009-12-29
Installment #5: 2010-01-29
Installment #6: 2010-02-28
Installment #7: 2010-03-29
Installment #8: 2010-04-29
Installment #9: 2010-05-29
Installment #10: 2010-06-29
Installment #11: 2010-07-29
Installment #12: 2010-08-29

Take a look on how the library handled well the date on the month of February, which has the maximum day of month of 28 (because 2010 is not a leap year).


Spring Python 1.1.0.M1 Released

2010/02/01

SpringSource has has just announced last  week of a milestone release of SpringPython 1.1.0.M1. This announcement made aware about this project. There is a project that has nearly reached its 1.1 version that tries to develop Spring-like framework in Python. I would like to look into this project.

It is different from invoking Spring Java from Jython in  that, this project brings the concept of Spring framework into the CPython platform in general. Some of the configuration are really Pythonic!

I think I will explore more on this project.


Oracle Announced the Outline Strategy on Integration of Sun

2010/01/29

Oracle has announced  the outline strategy and its commitment  on Sun Microsystems integration into Oracle. It was in a Webcast and for those who missed it, could get it from the website.

This is the link from Oracle website.

We already noticed some additions on links in the Oracle Technology Website (http://otn.oracle.com) which includes newly added Sun’s technology portfolios.


EU Commission Approval of Sun Microsystems Acquisition by Oracle: Lesson Learned

2010/01/22

Yesterday James A. Goosling, the founder of Java platform, put a picture in his blog: “So long, old friend…”.
After the EU Commission approved Sun Microsystems (NASDAQ: JAVA) acquisition by Oracle Corp (NASDAQ: ORCL), Oracle expects that Russia and China will also accept it. The main foreseen obstacle to the agreement was the EU Commission approval. Now that it has been approved, the acquisition is expected to go smoothly.

Some people began speculating on the fate of open source projects, which nurtured by Sun, yet they don’t believe that Oracle will give enough support for those open source projects. One high profile fear was from Monty Widenius, the founder of MySQL, which after selling the company to Sun left MySQL (the company), and forked a new database project: MariaDB. He campaigned to prevent the acquisition of MySQL by Oracle. Now we see the result, it seems that he lose the campaign. Some voices also speculate about the fate of OpenOffice, Glassfish, etc after the acquisition.

This matter once again prove: “a technology is good, but we also need to make money”. Of course Sun Microsystems is not the first to go down, there were a lot of dead carcasses of open source companies ended up acquired by profitable commercial companies that sell their proprietary products.

Sun is highly respectable company, which produced a lot of very good products. All hail respect to the company that bred the Java technology and platform, which took over the world. Yet, after this high profile achievement, the company still need to make money to bring value to the shareholders.

Lesson Learned: Companies Need To Make Money In Order To Sustain the Business

I guess this serves as reminder for those people (including me) who wants to make a company based on sophisticated technology, either open source or closed source; take note, when we start a company, we also need to make money.

Now that Wikipedia site had grown that big, the non-profit model required it to campaign for more money to sustain its operation.


Setting Up Your Own Jython 2.5.1 Environment

2009/11/02

In this post I’ll show you how to setup your own Jython environment.

Prerequisite to this, you must have a Java Runtime Environment (JRE) installed in your system. Chances are when you already have browser running some Java applet or Java Web Start application, you already have JRE installed on your system.
Get the latest JRE from http://java.com/en/download/manual.jsp.

First you need to download a Jython binaries installer, currently the latest one is version 2.5.1, which you could download from this link.

After download completion you should have a file named jython_installer-2.5.1.jar, click on the file, or run from command line:

$ java -jar jython_installer-2.5.1.jar

Or in some other platform:

c:\> java -jar jython_installer-2.5.1.jar

Now you need to add you Jython path to your OS Path variable, so that the shell or command line interpreter is able to find Jython. In my sample Windows installation case:

C:\> set PATH=%PATH%;c:\opt\env\jython2.5.1

Alternatively, if you are running bash shell (assuming you installed Jython to /opt/env/jython2.5.1 folder):

$ export PATH=$PATH:/opt/env/jython2.5.1

Now you may proceed with the first invocation of Jython.

C:\> jython
*sys-package-mgr*: processing new jar, 'C:\opt\env\jython2.5.1\jython.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\resources.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\rt.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\jsse.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\jce.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\charsets.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\ext\dnsns.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\ext\localedata.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\ext\QTJava.zip'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\ext\sunjce_provider.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\ext\sunmscapi.jar'
*sys-package-mgr*: processing new jar, 'C:\Program Files\Java\jre6\lib\ext\sunpkcs11.jar'
Jython 2.5.1 (Release_2_5_1:6813, Sep 26 2009, 13:47:54)
[Java HotSpot(TM) Client VM (Sun Microsystems Inc.)] on java1.6.0_16
Type "help", "copyright", "credits" or "license" for more information.
>>>

The jython command line actually invoked a Windows batch file jython.bat, which
When first time invoked, Jython interpreter will activate sys-package-mgr to add standard Java library classes as Python package.

After the installation, just play around with simple thing such as:

Jython 2.5.1 (Release_2_5_1:6813, Sep 26 2009, 13:47:54)
[Java HotSpot(TM) Client VM (Sun Microsystems Inc.)] on java1.6.0_16
Type "help", "copyright", "credits" or "license" for more information.
>>> from java.lang import System
>>> System.out.println("Hello, world!")
Hello, world!
>>> System.out.println('Hello, world!')
Hello, world!
>>> System.currentTimeMillis()
1257145977410L
>>> from java.lang import String
>>> s = String("abc")
>>> s.toString()
u'abc'

Look at how System.out.println is able to receive both single quote and double quote Python string, and also the java.lang.String type by a Java class method is a Unicode string (u’abc’).


PyDev 1.5 on Eclipse Galileo 3.5 SR1

2009/10/21

I begin to have more time to explore the Eclipse Galileo Service Release 1 (Eclipse 3.5.1). This time I want to set it up for my Python development, using the PyDev plugin.

PyDev is an Eclipse plugin for Python language application development. It supports CPython, Jython and IronPython runtimes. It supports the interactive as well as non-interactive Python development on Eclipse IDE.

Eclipse IDE (and platform) has become the de facto industry standard IDE. More and more free software, open source software, and proprietary software makers build their systems on Eclipse platform. Galileo is the codename for 3.5 release, and now the latest one is the SR1 (Service Release 1).

There has been interesting development on PyDev since its last 1.4.7 version. PyDev has moved to be sheltered under the umbrella of Aptana. PyDev and PyDev Extension now has been merged and both now open source (previously the PyDev Extension, the advanced version of PyDev was not an open source).

The update site has been moved from domain www.fabioz.com (http://www.fabioz.com/pydev) to domain pydev.org (http://pydev.org/updates) . Aptana  This development looks good for me, means that PyDev now being maintained by its own organization, and hopefully in more serious efforts.

In Eclipse Galileo, you need to go to the menu and choose: Help > Install New Software…

eclipse-pydev-update-01

It will show the Install dialog.

eclipse-pydev-update-02

Click the [Add] button on the upper of menu dialog. You will get the “Add Site” dialog.

Type name and location.
Name: “PyDev Update  Site” (you can feel with any arbitrary name though)
Location: http://pydev.org/updates

eclipse-pydev-update-03

Back to the “Install” dialog, the previous “Add Site” will fill up the “Work with” field for you.

eclipse-pydev-update-04

Now tick the Checkbox “PyDev for Eclipse” under “PyDev”. You may also optionally tick the “Pydev Mylyn Integration”. In this example we don’t tick.

Click the [Next >] button. It will show you the Install Details:

eclipse-pydev-update-05

Proceed by clicking [Next >] button. Review Licenses dialog will be displayed.

eclipse-pydev-update-06

Click the radio button “I accept the terms of the license  agreement” when you are agree with the licenses. Proceed by clicking [Finish] button.

eclipse-pydev-update-08

You will see the progress bar. Somewhere around the progress, you will be asked whether to install software that contains unsigned content.
eclipse-pydev-update-09

Click [OK] to proceed (we have no choice as long as the provider of this plugin hasn’t signed the content).

eclipse-pydev-update-10

Click the [Yes] button to restart your Eclipse IDE.


Chardet Python Library: Determining Character Encoding of Text File or Text Stream

2009/09/15

Recently I have came into a disagreement with fellow programmer. He tried to create view simple codes in different programming languageshe knows: C, C++, Perl, Python, PHP, and Java (I think it’s for self-actualization, obviously not for money or wealth). It turns out to be he created XML parser codes on those (programming) languages.

The code doesn’t produce as expected, except of course in Python. He ascertained that it is because most those languages make use of libxml2 library (from GNU). He came into a conclusion that the Java library might also make use of the libxml2 library from GNU, which I believe most unlikely. Java wouldn’t normally pick GNU stuffs for its library. It really hit into my Java developer pride, and I need to prove that it is not the library that is incorrect, instead the input file is not correctly encoded.

Although in Western world most text files usually play along well most of the time, characters other than ordinary characters will be displayed incorrectly. Most of the case it will be displayed incorrectly in countries that uses special characters!

Since the first time I work in Singapore, I absorb it quickly that the ability to display these special characters are one important thing a web application should have, especially when they cater for the Asian market! You will see that they will require you to do i18n, display this in Traditional Chinese characters, in Simplified Chinese characters, Tamil characters, Thai characters, to name a few…

It brought me to this question:
If I have an arbitrary text file, how could I know which encoding the text uses?

I googled around and found  this: Universal Encoding Detector (chardet) library. The chardet site shows how to do it for web sites.

>>> import urllib
>>> urlread = lambda url: urllib.urlopen(url).read()
>>> import chardet
>>> chardet.detect(urlread("http://google.cn/"))
{'encoding': 'GB2312', 'confidence': 0.99}

>>> chardet.detect(urlread("http://yahoo.co.jp/"))
{'encoding': 'EUC-JP', 'confidence': 0.99}

Now it here comes the next question for me: if it is not a web site, but a file instead, how to detect the encoding?

So here is the solution:

>>> import chardet
>>> fileread = lambda filename: open(filename, "r").read()
>>> chardet.detect(fileread("italian-english.xml"))
{'confidence': 0.9899999999999999, 'encoding': 'utf-8'}

>>> chardet.detect(fileread("utf8_demo.txt"))
{'confidence': 0.9899999999999999, 'encoding': 'utf-8'}

So this way, I checked that the text file is most likely an UTF-8 encoded text.

By the way, the encoding detection engine library was derived from (or ported from) Mozilla auto-detection code, which has been widely used. So more or less I believe it is mature and powerful enough for most usages.

Another thing to note is that those codes above are using lambda notation, a feature of Python language borrowed from pure functional programming syntax.


Simple Swing Application on Jython 2.5

2009/09/03

I need to create a prototype GUI user interface in Java Swing. In order to make it faster I decided to create it on Jython. I have been using Java classes from Jython for quite sometimes, but I have never tried to create a Python-style implementation of certain Java interface.
In this part I will explain first how it works when using Java Swing objects from Jython.
The next part will deal with the implementation of Java interface.

In Jython, it’s very easy to create a Java Swing window.
This is an example:

from javax.swing import JFrame
mainFrame = JFrame("Hasta la vista, Baby!")
mainFrame.show()

On my Vista machine, it will display a small window that looks like this:

Default Swing's JFrame window without any parameters set

Ok. It is understood that we need to adjust the size of the frame so that i won’t look so ugly.

from javax.swing import JFrame
mainFrame = JFrame("Hasta la vista, Baby!")
mainFrame.setSize(400,300)
mainFrame.show()

That code should do the trick.

jframe-400x300

Ok. Now things to note on this code:

  • When it comes to JFrame or Window in Swing, closing the window doesn’t mean that the object is no longer there.
  • The window will only be disposed when you invoke the dispose() method.

Click the close button on the Swing frame/window or Alt-F4
Let’s what happens when while in the same Jython session, we type this:

mainFrame.show()

It will still show the window.
jframe-400x300

Try some more tricks, after closing the frame/window, type these into your Jython console session:

mainFrame.setSize(300,400)
mainFrame.setTitle("Buenos tardes, Mis Amigos!")
mainFrame.show()

buenos-tardes-300x400.


Merge of Redundant Methods in Python 3.x

2009/08/25

Python 3.x suppose to have a more structure structure and avoid redundant methods.
This is an example on how a redundant string manipulation/query methods were eliminated and only one preserved (only on str, removed from string library).

I tried this code section:

import string

string.find("abcdijfHOWDYckfj", "HOWDY")

Result:

7

While when running it on Python 3.1:

import string

string.find("abcdijfHOWDYckfj", "HOWDY")

The interpreter throws this error:

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

AttributeError: 'module' object has no attribute 'find'

I found out through the documentation that the string library is no longer supporting redundant methods provided on str in the string library.
Instead of the code above, we should use code below for Python 3.x:

str.find("abcdijfHOWDYckfj", "HOWDY")

Python 3.1 File I/O open() Is No Longer Binary Mode By Default

2009/08/20

After long holiday on my wedding preparation, D day and honeymoon, I returned back in shape.

Some things happened during the off days, such as the acquisition of SpringSource by VMWare, Inc.

I try to run my piece of XML parsing code like this in Python 3.1:

import xml.parsers.expat
import sys
import os.path

filename = "companies.xml"
parser = xml.parsers.expat.ParserCreate()
f = open(filename, "r")
parser.ParseFile(f)
f.close()

The code above throws an error like this:

TypeError: read() did not return a bytes object (type=str)

This source code works in Python 2.6, but failed when running on Python 3.1.

After comparing the manual for the built-in open() function between those 2 versions (2.6 and 3.x versions), I found out that there is a new feature in Python 3.x which is not backward compatibility (unlike transitions between 2.x versions, the transition from 2.x to 3.x may break the backward compatibility).

Python 3.x added the “t” for text, “b” for binary, “+” for updating (read/write) and “U” modifier to the open file mode.

It turns out to be that Python 3.1 no more handles file open as binary by default.Now the text (“t”) mode become default for Python 3.1 meanwhile Python 2.6 assume all file access are binary accesses. Python 3.x has implemented modes of more similarity to its C stdio library counterpart than its previous 2.6 version.

Since Python 3.x added additional parameter to the open() function, we must now specify “b” to make it binary access, so that the read() method will return bytes, otherwise it will return str.

import xml.parsers.expat
import sys
import os.path

xmlFilename = "companies.xml"
p = xml.parsers.expat.ParserCreate()
f = open(xmlFilename, "rb")
p.ParseFile(f)
f.close()

Now the ParseFile() method get what it asks for, a file handler with read() method that return bytes instead of str.