Friday, 21 December 2007

Google map (gps) for UK on Mobile

Google has launched the UK-specific version of its popular Java mobile app - Google Maps mobile. Users in Britain can now see Tube stations, and use the local search. If you have a Java-enabled handset (almost all new phones support Java), you can download the UK version of Google Maps mobile from google.co.uk/gmm.

In the other news, Google finally added support for GPS to the latest version (v1.5.1) of Google Maps mobile. In the application press “0″ to quickly pin-point your location with a blue dot. Originally, Google promoted this feature as being exclusive for the Helio Drift. Now they’ve quietly released an update that should work on all major platforms. (via: Crave, WebWorkerDaily)

http://www.esato.com/board/viewtopic.php?topic=146481

http://amazegps.com/welcome.php?language=uk

Saturday, 8 December 2007

Troubleshooting Sudo

I happen to much prefer Ubuntu and Mac OS X's sudo model to the root/user one that's typical of most Linux distributions. You can read all about why Ubuntu uses sudo and all the pros and cons of that model at help.ubuntu.com/community/RootSudo.

The one thing I don't like about sudo is how fragile it is. If you don't know what you're doing (especially at the command-line), sometimes sudo can get broken. It doesn't happen very often, but it does happen. That's what this page is for.

If your sudo is "broken," meaning that you can't use the sudo command to temporarily gain administrative privileges, there are two files you should be aware of:

/etc/sudoers and /etc/group

The /etc/sudoers file should look the same for every Ubuntu user who hasn't fiddled with it:

# /etc/sudoers

#

# This file MUST be edited with the 'visudo' command as root.

#

# See the man page for details on how to write a sudoers file.

#

# Host alias specification

# User alias specification

# Cmnd alias specification

# Defaults

Defaults !lecture,tty_tickets,!fqdn

# User privilege specification

root ALL=(ALL) ALL

# Members of the admin group may gain root privileges

It basically says anyone who is root can do anything, and anyone in the administrative group (people who can sudo) can do anything (with a password).

Now, the /etc/group file will look different for every Ubuntu
installation. It specifies which groups each user belongs to. An
example of how it might look is here:

root:x:0:

daemon:x:1:

bin:x:2:

sys:x:3:

tty:x:5:

disk:x:6:

lp:x:7:cupsys

mail:x:8:

news:x:9:

uucp:x:10:

man:x:12:

proxy:x:13:

kmem:x:15:

dialout:x:20:firstuser,cupsys

fax:x:21:

voice:x:22:

cdrom:x:24:firstuser,haldaemon

floppy:x:25:firstuser,haldaemon

tape:x:26:

sudo:x:27:

audio:x:29:firstuser

dip:x:30:firstuser

www-data:x:33:

backup:x:34:

operator:x:37:

list:x:38:

irc:x:39:

src:x:40:

gnats:x:41:

utmp:x:43:

video:x:44:firstuser

sasl:x:45:

plugdev:x:46:firstuser,haldaemon

staff:x:50:

games:x:60:

users:x:100:

nogroup:x:65534:

dhcp:x:101:

syslog:x:102:

klog:x:103:

firstuser:x:1000:

scanner:x:105:firstuser,cupsys

crontab:x:107:

ssh:x:108:

messagebus:x:109:

haldaemon:x:110:

slocate:x:111:

For troubleshooting purposes, the most important line in the /etc/group file is the one in bold, which specifies who is in the admin group, and hence who has sudo privileges. Substitute your actual username for firstuser, of course.

Now, this begs the question, "How can I edit the /etc/group file if I don't have sudo permissions?"

The answer is something called recovery mode.

You know when you boot up, you get several options for how you want to
boot up? There's usually a kernel, recovery mode, and memtest at the
very least.

After you boot into recovery mode, you should be logged in as
root. Or, if you set a root password in your installation, you'll be
end up logged in as root.

Once
you're there, before you make any changes, it's a good idea to make
backup copies of your two corrupt files. Sure, they're incorrect, but
they're better than nothing, especially if you accidentally delete the
contents of the original files. To back them up, type

cp /etc/group /etc/group.old

cp /etc/sudoers /etc/sudoers.old

Then, to edit the files, use these commands:

sudo visudo

This command edits the /etc/sudoers file.

nano /etc/group

This command edits the /etc/group file.

To save in nano, you press Control-X (save), Y (confirm), and Enter (exit).

If you don't want to bother editing the /etc/group file, you can also issue this command:

If you are trying to fix the error where it says sudo is mode _____, should be 0440, then you'll want to type

chmod 0440 /etc/sudoers

When you're done, reboot, and you should be able to sudo again.

two ways to make a user sudo

$sudo adduser laser admin sudo adduser laser sudo, here 'sudo' can not make the user run sudo ability. =================== if group admin doesn't exist, you should edit /etc/sudoers login with root, if no root, run "passwd root" to create one.$vi /etc/sudoers

cp the last line of "root ALL......", paste it at the next line and change the root to your name. Done.

######################################

If you've used Linux for any amount of time, you might be used to
running programs as root directly whenever you need to install
packages, modify your system's configuration, and so on. Ubuntu employs
a different model, however. The Ubuntu installer doesn't set up a root
user -- a root account still exists, but it's set with a random
gksudo.

You probably already know how to use sudo -- just run sudo commandname .
But what about running GUI apps that you want to run as root (or
another user)? Simple -- use gksudo instead of sudo. For instance, if
you'd like to run Ethereal as root, just pop open a run dialog box (Alt-F2) and use gksudo ethereal.

By the way, if you really must do work as root, you can use sudo su -,
which will log you in as root. If you really, really want to have a
(i.e., without using sudo), then run passwd when logged
in as root, and set the password to whatever you want. I'd recommend
using the pwgen package to create a secure password not only for root
but for all your user accounts.

Wednesday, 5 December 2007

Top/free的使用及参数详解

1.作用

top命令用来显示执行中的程序进程，使用权限是所有用户。

2.格式

top [－] [d delay] [q] [c] [S] [s] [i] [n]

3.主要参数

d：指定更新的间隔，以秒计算。

q：没有任何延迟的更新。如果使用者有超级用户，则top命令将会以最高的优先序执行。

c：显示进程完整的路径与名称。

S：累积模式，会将己完成或消失的子行程的CPU时间累积起来。

s：安全模式。

i：不显示任何闲置(Idle)或无用(Zombie)的行程。

n：显示更新的次数，完成后将会退出top。

4.说明

top命令是Linux系统管理的一个主要命令，通过它可以获得许多信息。这里我们结合图1来说明它给出的信息。

top命令的显示 (图略)

PID（Process ID）：进程标示号 ( 每个 process 的 ID )

USER：进程所有者的用户名 ( 该 process 所属的使用者 )

PR：进程的优先级别 ( Priority 的简写，程序的优先执行顺序，越小越早被执行 )

NI：进程的优先级别数值 ( Nice 的简写，与 Priority 有关，也是越小越早被执行 )

VIRT：进程占用的虚拟内存值。

RES：进程占用的物理内存值。

SHR：进程使用的共享内存值。

S：进程的状态，其中S表示休眠，R表示正在运行，Z表示僵死状态，N表示该进程优先值是负数。

%CPU：该进程占用的CPU使用率。

%MEM：该进程占用的物理内存和总内存的百分比。

TIME＋：该进程启动后占用的总的CPU时间 ( CPU 使用时间的累加 )

Command：进程启动的启动命令名称，如果这一行显示不下，进程会有一个完整的命令行。

top命令使用过程中，还可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。

＜空格＞：立刻刷新。

P：根据CPU使用大小进行排序。

T：根据时间、累计时间排序。

q：退出top命令。

m：切换显示内存信息。

t：切换显示进程和CPU状态信息。

c：切换显示命令名称和完整命令行。

M：根据使用内存大小进行排序。

W：将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。

5.应用实例

ａ.作用

free命令用来显示内存的使用情况，使用权限是所有用户。

ｂ.格式

free [－b|－k|－m] [－o] [－s delay] [－t] [－V]

ｃ.主要参数

－b －k －m：分别以字节（KB、MB）为单位显示内存使用情况。

－s delay：显示每隔多少秒数来显示一次内存使用情况。

－t：显示内存总和列。

－o：不显示缓冲区调节列。

ｄ.应用实例

free命令是用来查看内存使用情况的主要命令。和top命令相比，它的优点是使用简单，并且只占用很少的系统资源。通过－S参数可以使用free命令不间断地监视有多少内存在使用，这样可以把它当作一个方便实时监控器。

＃free －b －s5

解读Linux操作系统内核源码的好方法

1．Linux核心源程序通常都安装在/usr/src/linux下，而且它有一个非常简单的编号约定：任何偶数的核心（例如2.0.30）都是一个稳定地发行的核心，而任何奇数的核心（例如2.1.42）都是一个开发中的核心。

2．核心源程序的文件按树形结构进行组织，在源程序树的最上层你会看到这样一些目录：

●Arch ：arch子目录包括了所有和体系结构相关的核心代码。它的每一个子目录都代表一种支持的体系结构，例如i386就是关于intel

cpu及与之相兼容体系结构的子目录。PC机一般都基于此目录；

●Include: include子目录包括编译核心所需要的大部分头文件。与平台无关的头文件在 include/linux子目录下，与 intel

cpu相关的头文件在include/asm-i386子目录下,而include/scsi目录则是有关scsi设备的头文件目录；

●Init： 这个目录包含核心的初始化代码(注：不是系统的引导代码)，包含两个文件main.c和Version.c，这是研究核心如何工作的一个非常好的起点。

●Mm ：这个目录包括所有独立于 cpu

●Kernel：主要的核心代码，此目录下的文件实现了大多数linux系统的内核函数，其中最重要的文件当属sched.c；同样，和体系结构相关的代码在arch/*/kernel中；

●Drivers： 放置系统所有的设备驱动程序;每种驱动程序又各占用一个子目录：如，/block

,所有的文件系统代码和各种类型的文件操作代码，它的每一个子目录支持一个文件系统，例如fat和ext2;

Scripts, 此目录包含用于配置核心的脚本文件等。

A、操作平台:

B、相关内核源代码分析:

1．系统的引导和初始化：Linux 系统的引导有好几种方式：常见的有 Lilo,

arch/i386/Kernel/setup.S， setup.S主要是进行时模式下的初始化，为系统进入保护模式做准备；此后，系统执行

head.S 中定义的一段汇编程序setup_idt ，它负责建立一张256项的 idt 表(Interrupt Descriptor

Table),此表保存着所有自陷和中断的入口地址;其中包括系统调用总控程序 system_call

/usr/src/linux/init/main.c中,它通过调用usr/src/linux/arch/i386/kernel/traps.c 中的一个函数

void __init trap_init(void) 把各自陷和中断服务程序的入口地址设置到 idt

set_system_gate(SYSCALL_VECTOR,&system_call); 把系统调用总控程序的入口挂在中断0x80上;

system_call

3.中断总控程序主要负责保存处理机执行系统调用前的状态,检验当前调用是否合法, 并根据系统调用向量，使处理机跳转到保存在 sys_call_table

/usr/src/linux/include/asm-386/unistd.h 中也定义了系统调用的用户编程接口;

4.由此可见 , linux 的系统调用也象 dos 系统的 int 21h 中断服务, 它把0x80 中断作为总的入口, 然后转到保存在

sys_call_table 表中的各种中断服务例程的入口地址 , 形成各种不同的中断服务;

arch/i386/boot/bootsect.S

arch/i386/Kernel/setup.S

init/main.c

arch/i386/kernel/traps.c

arch/i386/kernel/entry.S

arch/i386/kernel/irq.h

include/asm-386/unistd.h

C、对内核源码的修改：

1.在kernel/sys.c中增加系统服务例程如下：

{

int i=0,enddata=0;

while(i<=numdata)

enddata+=i++;

return enddata;

}

arch/i386/kernel/entry.S 中的最后几行源代码修改前为:

... ...

.long SYMBOL_NAME(sys_sendfile)

.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */

.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */

.long SYMBOL_NAME(sys_vfork) /* 190 */

.rept NR_syscalls-190

.long SYMBOL_NAME(sys_ni_syscall)

.endr

.long SYMBOL_NAME(sys_sendfile)

.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */

.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */

.long SYMBOL_NAME(sys_vfork) /* 190 */

.rept NR_syscalls-191

.long SYMBOL_NAME(sys_ni_syscall)

.endr

3. 把增加的 sys_call_table 表项所对应的向量,在include/asm-386/unistd.h

... ...

#define __NR_sendfile 187

#define __NR_getpmsg 188

#define __NR_putpmsg 189

#define __NR_vfork 190

4.测试程序(test.c)如下:

#include

#include

main()

{

int i,j;

do

while(scanf("%d",&i)==EOF);

printf("Total from 0 to %d is %d \n",i,j);

}

$gcc -o test test.c$./test

36

Total from 0 to 36 is 666

{

return -ENOSYS;

}

... ...

.long SYMBOL_NAME(sys_sendfile)

.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */

.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */

.long SYMBOL_NAME(sys_vfork) /* 190 */

... ...

... ...

#define __NR_sendfile 187

#define __NR_getpmsg 188 /* some people actually want streams */

#define __NR_putpmsg 189 /* some people actually want streams */

#define __NR_vfork 190

putpmsg 在内的好几个系统调用都是不进行任何操作的，即有待扩充的空调用；

Tuesday, 4 December 2007

Comand Line Process Bar for Java

As we all know python can print without change line. Now the following codes shows how to do it in Java.

###############################################
"""sc.py
This is a simple class to demonstrate the use of jythonc.
"""

import java.lang.String

class sc(java.lang.Object):
def __init__(self):
"""public sc() # constructor is not forced to add'@sig'
"""

def tprint(self,c='hello'):
"""@sig public void tprint(String c)
"""
print c,

if __name__ == '__main__':
sc1 = sc()
sc1.tprint('zhengxin')

################################################
// Simpleclasstest.java

import java.lang.*;

public class Simpleclasstest {
public static void main(String[] args) {
sc sc1 = new sc();
for (int i = 1;i<100; i++)
{ try { Thread.sleep(200); } catch (InterruptedException e) {};
sc1.tprint("--");
}
System.out.println('\n');
}
}
#########################################
What to do now:
$jythonc sc.py # to generate java class.$javac -cp /usr/share/jython/jython.jar:./jpywork Simpleclasstest.java # using Simpleclasstest.java to call the jython generated class.
$java -cp /usr/share/jython/jython.jar:.:./jpywork Simpleclasstest # run it. ========================================================= Here is the way to achieve it in pure Java. and this java Class can be called by matlab to show process bar. ######################################### //tryoutput.java public class tryoutput { String s; public void setStr(String s) { this.s = s; } public void tPrint() { try { Thread.sleep(200); } catch (InterruptedException e) {}; System.out.print(this.s); } public static void main(String[] args) { // TODO Auto-generated method stub tryoutput op = new tryoutput(); op.setStr("="); for ( int i=0; i<100; i++) { op.tPrint(); } } } ##################################### Comments: Here for both java and python, the loop can be put in the tprint methods. Same effect. python: import and Class and dir() Python: No matter what the current directory is, Python must import the things it need. --------------------------------------------------------- Java: If the class or jar is in the CLASSPATH, import will cause errors like: "import abc; something is expected" ############################ Import for Python: • What is imported is just the module name. If in the module a class is defined, to get a instance of the class, you must >>>import abc # here abc is the module file name >>>instance=abc.Cons() # here Cons is the class constructor; for jython, abc=Cons, it will looks like >>>instance=abc.abc() • >>>dir(instance) [] # this is just what you got when you want to check what methods is available for the object. If you want to achieve it, you should run: >>>dir(abc.Cons) # in Jython it should be: >>>dir(abc.abc) Monday, 3 December 2007 Notes for Unix Course Commands: • ls -R: to recursively descend subdirectory tress ls -i: to get inode number for each file. ls -l: can list 'link count'. This shows how many files are linked to one file ( same inode number) • find / -inum XXXXX -ls: here ls is similar to -print; using this way we can find what files are linked to same file (for hard link).$touch -m -t 200712030900 timewanted # generate a file with specified time stamp.
$find / -newer timewanted -ls # show the files modified after the specified time. find / -mount -name "XXXXXXX" -ls: here -mount means NOT scan mounted file system. Especially useful for NOT scan mounted iso files, mounted Windows file system and some network or mirrors storage. • 2> /dev/null: this always follows shell command to redirect standard error output. while "1>" for standard output redirection. /dev/null doesn't generate any file, just get rid of error messages. For example:$ls -il /bin/ls # we will get the inode number XXXand link count, if the ls has been hard linked to other files, use the following command find what they are; $find / -mount -inum XXX 2> /dev/null. # using this command we will not see the permission error messages. • ps ax | head -123 # head is used to show first 123 lines. • tail +123 # to show lines from 123 lines tail -123 # to show the last 123 liens tail -f /var/log/messages # to monitor the messages file in real time. • cp *.[ch] ~ # use regular expression to specify what kind of file you want to copy. Here means copy .c and .h files to home folder. • umask: displays or changes the permissions that are taken away, i.e., masked out, from the defaults requested at file creation. • ps: ps -e: processes of everybody ps e: command arguments in detail ps l: in long format, similar as ls -l. ps -o pid,state,args: to assign what information to output, here -o means options. ps -O pri: preloaded -o, pri is added to show basing on the default output. state: S=sleeping,R=running,T=stop(because S has assigned to sleeping, so use the second letter T for STOP) ppid: parent pid. from ps -l , the ppid can be got. it means all the process with same ppid are the child process of the process, whose pid is ppid. If kill this parent process, all the child process will be killed as well. • kill -SIG pid: totally33 kinds of Signal for pid. • job control: prog & # run a program in the background. jobs -l # list current background jobs. -l can return pids as well as job numbers. : move the current foreground job into the background and STOP it. bg %2: RESUME job number 2 in the background. fg %2: Resume job number 2 in the foreground. wait %2: wait job number 2 to complete. kill %2: terminate job number 2. • tar -tvf /the/tar/file.tar: list the contents in the tar file while not decompress it. • vi: ":file": return the some file information, including total lines. • awk: Command line text tool (especially edit file or texts with columns)$awk -F':' '{ printf "%-10s%5d\n", $1,$3 }' /etc/passwd
Here, printf "%-10s%5d\n", $1,$3 -- the action, it's the format string of two arguments to printf, in the case,$1 is the username column in the password file, '-' means left justified. ':' is the separator.$fs=$(mount | awk '$5 =="ext3" { print $3 }') Here, shows mounted file systems and we are interested in those whose file system typ is ext3, in which case we print the mount point ($3).

Regular Expression:

symbols meaning example matches
---------------------------------------------------------------
. any 1 char pean.t peanut
[] 1 character set waln[aeiou]t walnet
[-] 1 character range pec[a-l]n pecen
[^] not in set alm[^Oo] almend
* 0 or more instances penut peeeeenut
^ begin line ^begin beginning of line
$end line end$ line end
\ quote next n\-\[\$n-[$

.* any string n.*s newts;ns
[]* string from set ba[na]* banana
[ - - ] multiple ranges nu[m-os-u]s nuns

USING WITH "grep","sed"
--------------------------------
\{m\} m occurrences [m-os-u]\{4\} stun
\{m,\} m or more occurrences x[0-9]\{3,\}y x121345y
\{m,n\} m to n occurrences x[0-9]\{3,7\}y x1213458y

USING WITH "egrep","awk"
--------------------------------
? 0 or 1 instance chest?nut chesnut;chestnut
+ 1 or more instance p[ae]+nut paenut;peeenut
| alternate RE pattern Wal|Pea Wal or Pea
( ) RE group (Wal|Pea|Coco)nut walnut;Peanut;Coconut

REPLACEMENT STRING USING WITH "ex","sed"
--------------------------------

 save match $$..$$$$.*$$
\n nth saved match s/$$..$$/\2--\1/

Examples:
$echo TUNUTS | sed 's/$$..$$/\2--\1/' NUTS--TU$sed -e 's/abc/def/g' -e 's/hij/klm/g' ./where/the/file # In the file, use def to replace abc, and use klm to replace hij.

Shell Programming:

• '${varible}' is good practice • Judge statement: [[ ]] for string compare, including "abc" and numeric string "12", here x=9 and x="9" are same. (( )) for numerical compare. • Be careful of space in the judge statement. [[$x = 9 ]]. there are " space " around [ ] =, same with (( )).
• but when you assign x=9, there can not be space!!!!
• [[ $x -eq 9 ]] , here -eq just for [[]]. •$x=9
$[[$x == 9 ]]
$echo$? # here $? shows correct or not. or the command runs successfully or not. • shell scripts: exit can be put at the last line. if 'exit 9' at the last line. In the shell,$echo $? will return 9. • A shell script called 'test', after it runs,$./run , you can not get any variables generated in the script. Because it runs in the sub shell. $. ./run will give you the variable, because, '.' means run the script in the current shell. • Subshell. in scripts for f in$(ls | grep -v 'gz$') do ls -l${f)
done
###this script just shows the files except .gz files. Here sub shell similar to pipe.

  > In the past, I've been told that for every .c file, you should > have a corresponding .h file which will contain all the necessary > definitions, prototypes, etc... for the functions in the file. > Is this the case, or should we just use one global header file > that contains all the prototypes, externs, defines, etc...The rules are not carved in stone, and should be followed with a grain ofsalt in all specific cases, but here's the usual story:a) It's always a good idea to play safe against possible multiple inclusions  of the same .h file. This can happen if you #include "foo.h" ,"bar.h", and  bar.h has an "#include "foo.h" line itself.  The canonical way to prevent multiple inclusions is to wrap each header  with an #ifndef CONSTANT directive, and #define that constant in the file  (immediately after). Example:           /* This is myheader.h */          #ifndef _MYHEADER_          #define _MYHEADER_           /* All the rest of the header here */          #endif /* _MYHEADER_ */          /* End of myheader.h */   The preprocessor will access the "rest of the header" only the first time   the header is included. The second time the _MYHEADER_ constant will be   already defined, causing #ifndef to be false, and the "rest" to be skipped   up to the #endif /* _MYHEADER_ */ line, that is up to the end.b) .c files should contain relatively small sets of tightly related  functions. Their declarations go in a .h file with the same name, to  be included by all the other .c files that use those functions.c) Type definitions (typedef, struct) must go in .h files, as soon as they are  used by more than one .c file. Defined type names should visually suggest  that they are not base types (like int or float). An often used convention  is to write their names using caps:       typedef int* Foo;       typedef float GlobeTrotter[3];       typedef struct _BarfBeer {          int a,b;          struct _BarfBeer* next; /* For a linked list */       } BarfBeer;d) Preprocessor directives defining constants and macros go in .h files as  soon as the constants and macros are used by more than one function (it  annoys me to have to fish through a .c file for the definition of a macro,  and I'd much rather see it in a short .h). Constants used by just one  function are #define-d right before it in the .c file, and #undef-ined  immediately after. Defined constant names should be ALL_IN_CAPSe) Global variables are declared with the "extern" storage qualifier in .h  files, which are included by all the .c files that need those  globals. There must be only ONE definition for each global variable (i.e. a  declaration without "extern"), and it MUST be in a .c file. If you put it  in a header, you get a multiple definition error as soon as that header is  included by more than one .c file. It doesn't hurt, and greatly helps  code readability, to redeclare at the beginning of a function all extern  variables used by that funciton (of course using the "extern" storage  qualifier).f) If at all possible, do not include header files in header files, and let  only the .c guys do all the #include-ing.  A non flat'', hyerarchical inclusion structure is more suited to C++.P.S. A "storage qualifier" is a keyword specifying the type of storage needed    for a certain variable. Example of C storage qualifiers are: static,   extern, register, volatile.#######################################################

Extern Variables and Functions

Because a global variable may be defined in one file and referred to in other files, some means of telling the compiler that the variable is defined elsewhere may be needed. Otherwise, the compiler may object to the variable as undefined. This is facilitated by an extern declaration. For example, the declaration

extern int size; // variable declaration

informs the compiler that size is actually defined somewhere (may be later in this file or in another file). This is called a variable declaration (not definition) because it does not lead to any storage being allocated for size.

It is a poor programming practice to include an initializer for an extern variable, since this causes it to become a variable definition and have storage allocated for it:

extern int size = 10; // no longer a declaration!

If there is another definition for size elsewhere in the program, it will eventually clash with this one.

Function prototypes may also be declared as extern, but this has no effect when a prototype appears at the global scope. It is more useful for declaring function prototypes inside a function. For example:

double Tangent (double angle)

{

extern double sin(double); // defined elsewhere

extern double cos(double); // defined elsewhere

return sin(angle) / cos(angle);

}

The best place for extern declarations is usually in header files so that they can be easily included and shared by source files.

Sunday, 2 December 2007

jython call 3rd party java class file

------------------------------
Accessible Class
------------------------------
Every functions (including constructor) and the class declaration must start with public.

------------------------------
Jython call class Notes
------------------------------
For instance, if you want to initialize an object form your class, you should run
>>>gc = GetConf();
the '()' is needed! Just remember, python loves (), the basic function dir() must followed ().

------------------------------
------------------------------
1. in terminal, go to the folder where the class file is. then run jython,and import the name of the calss. Now you can get a instance of that.

2. at runtime, you could do:

>>> import sys>>> sys.path.append('/path/to/module')

A few rules about CLASSPATH and python.path:

• sys.path in the registry file -- Add here to enable importing from Java classes (.java), Java class libraries (.jar), and Jython/Python (.py).
• CLASSPATH -- Add here to enable importing from Java classes (.java) and Java class libraries (.jar), but not Jython/Python (.py).

Saturday, 1 December 2007

Matlab call java "class"

1. Every methods should be public, especially the constructor. Otherwise the class can not be called.
Programming only within java, not so strict. Even you don't need put any identifier in front classes and functions.

2. Matlab and Sun Java are not compatible completely, though 99% do, especially when Sun Java or Matlab update, issues always come out. But I found Matlab call the java classes generated by gcc-java(gcj) works much better.
When Matlab updates, it almost work on or for latest java jdk. Matlab 2007a can not call the java class generated by jdk 1.6.03, while Matlab 2007b can.

3. Remember the javaclasspath variable in Matlab. To use javaaddpath(pwd) for you Matlab functions. If new class file is added, run clear;clc; again to initialize the new class.

Put the class file in the static javaclasspath (which is set in /toolbox/local/classpath.txt), in this way it will much faster than javaaddpath(pwd). But you much also put the class file in the classpath of MCR, /toolbox/local/classpath.txt, in this file, there still saying "$matlabroot" things, but here$matlabroot is mean . Just put the class in the mcr classpath folder, no need to be same with .

4.Can not get the attributes from the returned object directly, you need to compose a getXXXX(){return XXXXXX} method by yourself.

5. mcc -m XX.m -a YY.txt
If the XX.m doesn't call java class (including Matlab embeded java functions, here try to use import less, which always cause error when the m-file is compiled), the YY.txt added by mcc without format changed will be able to be accessed, it is stored in XX_mcr/XX/. If not, the YY.txt can not be accessed. You must copy the YY.txt manually to the XX.exe folder.
Just be careful the added files when you mcc Matlab programs using java.

The attached code is to read config file abc.txt.
##################################
// GetConf.java
// GetConf.java
import java.util.*;
import java.io.*;

public class GetConf {
//the public is not necessary for Matlab, but for jython, this is essential.

String para;
Properties conf;

public GetConf() throws IOException{
conf = new Properties();
para = new String();
File file_name = new File("abc.txt");

FileInputStream conf_input;

try {
conf_input = new FileInputStream(file_name);
} catch (FileNotFoundException e) {
e.printStackTrace();
}

}

public String getOnePara(String pnm){
para = conf.getProperty(pnm);
para = para.trim();
return para;
}

public static void main(String[] args) throws IOException{
String pa = (new GetConf()).getOnePara("a");
System.out.println(pa);
}

}
##################################
Here is the config file abc.txt
-------------------------------------------------
# a comment
! a comment

a = a string
b = a string with escape sequences \t \\ \" \' \ (space) \u0123
c = a string with a continuation line \
continuation line
d.e = another string
------------------------------------------------

Thursday, 29 November 2007

The GNU Revision Control System is generally considered a tool for software development, but it is also useful for tracking revisions of text documents. This article explains how to include and format RCS keywords in LaTeX documents, and how to track document revisions using these keywords.

Most discussions of the GNU Revision Control System occur in the context of tracking source code revisions. But RCS can track revisions of any type of file, text or binary, provided that the diff utilities which generate RCS change files can handle binary data.

RCS seems ready-made for working with LaTeX input files. The pre-defined keyword identifiers built in to RCS are easy to format and print. They provide ready information that can include the document's author, its revision, filename, and, revision log entry. RCS also provides facilities for user-defined identifiers.

RCS is commonly included with the development software of Linux distributions. The latest source code version of RCS is available from ftp://prep.ai.mit.edu/pub/gnu and its mirror sites.

The ident(1) manual page has a list of the standard RCS keywords that are generated when documents are checked out by RCS. They include:

* $Author: lg$: The login name of the person who checked in the revision.
* $Date: 2002/10/09 22:24:18$: The date and time the document was checked in.
* $RCSfile: latex.html,v$ The basename and extension of the RCS file.
* $Id: latex.html,v 1.2 2002/10/09 22:24:18 lg Exp$: String containing the name of the RCS file, the revision number, date and time, author, state, and locker if any.
* $Revision: 1.2$: The document's revision number.
* $Log: latex.html,v$
* Revision 1.2 2002/10/09 22:24:18 lg
* Remove all lg_toc##.html; change hyperlinks to index.html
*
* Revision 1.1.1.1 2002/08/14 22:27:03 dan
* Preliminary.
*
* Revision 1.1.1.1 1997/09/14 15:01:51 schwarz
* Imported files
* The log message entered when the document was checked in.

These keywords are included verbatim in documents. They are expanded when the document is checked out with co(1).

One consideration that needs to be taken into account is that the keywords' dollar signs are interpreted by LaTeX (and TeX) as starting and ending math-mode typesetting. LaTeX and TeX will not generate an error when it encounters the dollar signs. However, because LaTeX and TeX typeset equations differently than normal text, the results can be unpredictable.

For example, including the $Id: latex.html,v 1.2 2002/10/09 22:24:18 lg Exp$ string at the top of the odd pages the commands

\markright{$Id: latex.html,v 1.2 2002/10/09 22:24:18 lg Exp$}

results in the expanded RCS $Id: latex.html,v 1.2 2002/10/09 22:24:18 lg Exp$ string to be printed at the top of the pages, but some of the keywords run together because of the way TeX formats the string. An alternative is to use the keywords of the individual identifiers, and separating them with the appropriate command. Here, the TeX command \hfil inserts the necessary space when the keyword strings are typeset in the running head.

\markright{$Date: 2002/10/09 22:24:18$\hfil$RCSfile: latex.html,v$\hfil$Revision: 1.2$}

The string given to the \markright command will be typeset with the date in the upper left of the page, the filename centered, and the revision number at the top right.

The \markright command is all that's needed for printing on one side of a sheet. For printing on both sides of the page, use the \markboth command.

\markboth{$Date: 2002/10/09 22:24:18$\hfil$RCSfile: latex.html,v$\hfil$Revision: 1.2$}{\thepage}

The first argument to \markboth prints the RCS information at the tops of the left-hand pages and the page number at the top of the right-hand pages. The identifier \thepage is a standard LaTeX variable which prints the page number.

The RCS log message can be placed anywhere in a document that the $Log: latex.html,v$ Revision 1.2 2002/10/09 22:24:18 lg Remove all lg_toc##.html; change hyperlinks to index.html Revision 1.1.1.1 2002/08/14 22:27:03 dan Preliminary. Revision 1.1.1.1 1997/09/14 15:01:51 schwarz Imported files keyword can be inserted. For example, to place a (short!) log message in the margin at the beginning of a document, put the command \marginpar{$Log: latex.html,v$ \marginpar{Revision 1.2 2002/10/09 22:24:18 lg \marginpar{Remove all lg_toc##.html; change hyperlinks to index.html \marginpar{ \marginpar{Revision 1.1.1.1 2002/08/14 22:27:03 dan \marginpar{Preliminary. \marginpar{ \marginpar{Revision 1.1.1.1 1997/09/14 15:01:51 schwarz \marginpar{Imported files \marginpar{} immediately after the \begin{document} command, or after the \maketile command if the document has a title page and you'd rather have the RCS log text annotating the body text of the document.

The RCS information can be included in the documents footer by using the fancyhdr package, which is available from any TeX archive site.

If you want to include the $Date: 2002/10/09 22:24:18$ and $Revision: 1.2$ keywords at the bottom of a page, you could include

\usepackage{fancyhdr}
\fancypagestyle{rcsfooters}{%
\fancyhf{}
\fancyfoot[L]{$Date: 2002/10/09 22:24:18$}
\fancyfoot[R]{$Revision: 1.2$}

in the document preamble; that is, before the \begin{document} command. At the point you want the RCS data to be typeset, insert the commands

\thispagestyle{rcsfooters}
\pagestyle{rcsfooters}

ident(1) also searches files for RCS keywords. Typing the command ident term-paper.tex for example, will print a list of the keywords and their values to standard output. It's a simple matter of typing ident *tex | grep "fred" - to search for the documents which were last checked out by user fred.

For further information, consult the manual pages of the various programs in the RCS package, and the rcsintro(1) manual page for an introduction to the RCS system.

Wednesday, 28 November 2007

Symbolic Operations in Matlab

Background Note:

Up to this point we have done purely numerical operations in Matlab. This is the traditional approach for solving problems on the computer, and much of the current computational work done in industry follows this approach. However, a relatively new capability (last 5-10 years or so) that is gaining popularity involves the use of symbolic operations directly on the computer. Computer programs that use these symbolic techniques are often referred to as computer algebra systems, and they are becoming quite powerful. In particular, Matlab’s Symbolic Math Toolbox offers this general capability within the Matlab environment by providing an interface to the Maple code (Maple is a commercial software package that emphasizes symbolic manipulations or computer algebra techniques). This set of labs will introduce some of the basic symbolic capability in Matlab, eventually leading up to the analytical solution of Ordinary Differential Equations directly on the computer. Many of the exercises given here are derived from the Matlab’s User’s Guide and you are encouraged to refer to that manual for further examples and guidance.

Define Some Symbolic Variables:

First define a bunch of symbolic variables: syms a1 b1 c1 a2 b2 c2 d2 A B C1 C2 x y t

Now let’s form some symbolic functions:

Mathematical Function
Matlab Syntax for Function

f1 = a1 + b1*x + c1*x^2

f2 = a2 + b2*x + c2*x^2 + d2*x^3

g = exp(A*t)*(C1*cos(B*t)+C2*sin(B*t))

u = 2*x*y^2 + sin(x+y)

Differentiation of Symbolic Functions:

Differentiate each of the above functions using Matlab’s diff command. For example, try diff(f1). What happened? Is the result correct? Do the same thing for the other functions. What happens when you type diff(u)? How do you get Matlab to take the partial derivative with respect to the variable y? Type help sym/diff to see the various options associated with taking symbolic derivatives.

We can also take higher order derivatives. For example diff(f1,2) takes the second derivative of f1(x). Try this for all the functions!

Can you show that the mixed partial derivatives of u(x,y) are equal? Take du/dx and du/dy as above and save the results as string variables. For example, try typing

dudx = diff(u,x); dudy = diff(u,y);.

Now take the first derivative of these symbolic variables, as follows:

uyx = diff(dudx,y); uxy = diff(dudy,x);

Are these latter two variables the same? They should be. Pretty neat stuff, don’t you think!!!

Integration of Symbolic Functions:

Using Matlab’s int function, perform the following integrals using f1(x):

Mathematical Operation
Matlab Syntax for Operation

I1 = int(f1)

I2 = int(f1, 0, 5)

Do these make sense? Check out the subs command. Now let a1 = 1, b1 = -2, and c1 = 1, and substitute these numerical constants into the symbolic expressions for I1 and I2, as follows:.

I1 = subs(I1,{a1 b1 c1},{1 -2 1}), I2 = subs(I2,{a1 b1 c1},{1 -2 1})

What are the values for the integrals I1 and I2? Why is I1 a function of x and I2 is simply a scalar number? Note also that the curly brackets in Matlab refer to cell arrays. The sequence given by the set, {a1 b1 c1},{1 -2 1}, replaces the numerical variables into the symbolic variables in sequence. The cell array simply let’s us make all three substitutions in one call to the subs command.

Try integrating and substituting values for the constants in the other functions. Note that with u(x,y), you can only integrate with respect to one variable at a time. For example,

Mathematical Operation
Matlab Syntax for Operation

Iu = int(int(u,x,0,pi),y,0,2*pi)

Pretty impressive!!! Could you do this integral by hand this fast? I certainly can’t…

Plotting Symbolic Functions:

Certainly we can also plot symbolic relationships. Since we have already defined the constants for use with f1(x), let’s use this function to do some simple plots. In particular, let’s plot f1(x), df1/dx, and over the range . We can do this as follows:

F1 = subs(f1,{a1 b1 c1},{1 -2 1}); D1 = diff(F1); I1 = int(F1);
Nx = 51; xp = linspace(0,5,Nx);
F1p = double(subs(F1,x,xp));
D1p = double(subs(D1,x,xp));
I1p = double(subs(I1,x,xp));
plot(xp,F1p,’r-‘,xp,D1p,’g--',xp,I1p,’b-.’),grid
title(‘Evaluating and Plotting Symbolic Functions’)
xlabel(‘X Values’),ylabel(‘Various Function Values’)
legend(‘Function’,’First Derivative’,’Integral’)

Solving Algebraic Equations:

We can also solve algebraic equations with Matlab. For example, what if we wanted to know the value of x where f1(x) = 3? With the above constants this problem becomes: find x such that

In Matlab, we can use the solve command: solve(x^2-2*x-2) or solve(F1 - 3).

We can also solve systems of algebraic equations. For example, the analytical solution to the following 2x2 system:

is given by:

S = solve(3*x + 2*y - 3,-2*x + y + 7); % this solves a simple set of 2x2 equations

S.x, S.y % this prints x and y to the screen

Solving Ordinary Differential Equations:

The real goal of the above discussion and examples with symbolic variables is to give enough background so that we can solve ODEs analytically on the computer. This will be pretty powerful capability if we can actually do this with a set of relatively simple commands. As a test, let’s give Matlab’s dsolve command a workout for a few different types of ODEs that we have treated thus far in the semester (be sure to type help dsolve to get a good idea of the various forms that can be used).

a. Solve the first order IVP:

dsolve(‘Dy + y/x = (2/x)*exp(2*x)’,’x’) % this gives the general solution

dsolve(‘Dy + y/x = (2/x)*exp(2*x)’,’y(1) = 0’,’x’) % this gives the unique solution

b. Solve the second order IVP:

Sh = dsolve('D2y - 4*y = 0','x'), pretty(simple(Sh)) % homogeneous soln
Sg = dsolve('D2y - 4*y = 4*x^2','x'), pretty(simple(Sg)) % general soln
Su = dsolve('D2y - 4*y = 4*x^2','y(0) = -1/2','Dy(0) = 4','x') % unique soln
pretty(simple(Su))

c. Solve the second order IVP:

Q1 = dsolve(‘D2y + 6*Dy +13*y = 10*sin(5*t)’, ’y(0) = 0’,’Dy(0) = 0’,’t’)
pretty(simple(Q1))

d. Re-solve the problem in Part c as a system of two 1st order ODEs, where z1 = y and z2 = dy/dt:

Q2 = dsolve(‘Dz1 =z2’,’Dz2 = -13*z1 -6*z2 + 10*sin(5*t)’, ’z1(0) = 0’,’z2(0) = 0’,’t’)
pretty(simple(Q2.z1)), pretty(simple(Q2.z2))

Final Note:

There is a lot of good stuff here. In particular, there are several examples that should make your life much easier in this course and in several of your other technical classes. You should do your best to understand the basic capability that is illustrated here -- it represents some pretty powerful mathematical analysis capability. You should also note that some of the examples from earlier in the semester (the Two Salty Tanks problem for example) give other illustrations of the use of computer algebra to solve a coupled set of first order differential equations for a real problem of interest. Also, a final Matlab demo will be given at the end of the semester illustrating how to take Laplace transforms and inverse Laplace transforms analytically using Matlab’s symbolic processing capability.

########
from: http://www.tmt.ugal.ro/crios/Support/ANPT/Curs/deqn/labs/mlabex_symbolic/mlabex_symbolic.html

unittest模块

unittest模块是用python编写的，其功能与junit一样，都是为了方便单元测试用的测试框架。
unittest模块是从python
2.1引入标准库的。它包含几个类：TestCase，TestSuite，TestResult，TextTestRunner等等。要建立自动测试，

Error，测试失败就Fail，共3种状态。比如：

 import uniittestimport ysfile #自定义的模块class TestZDYSFile(unittest.TestCase): def setUp(self): self.zd=ysfile.ZDYSFile('ysh1b1.09') def testGetYear(self): self.assertEqual(self.zd.getYear(),2005) def testGetLoca_bz(self): self.assertEqual(self.zd.getLoca_bz(),4)class TestPDYSZipFile(unittest.TestCase): def setUp(self): self.pd=ysfile.PDYSZipFile('pdysj09.zip') def testGetCdate(self): self.assertEqual(self.pd.getCdate(),'20050117')if __name__ == '__main__': #unittest.main() suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestZDYSFile)) suite.addTest(unittest.makeSuite(TestPDYSZipFile)) unittest.TextTestRunner(verbosity=2).run(suite)

unittest.main()是用来调用所有的测试实例，unittest.TestSuite()是用来组合相关的测

Compiling Python(Jython) and for Java

Another view: Jython is the extension language for Java.

Use jythonc. What is jythonc and what is its status?

jythonc transforms Python source code into Java source code then invokes a Java compiler to turn it into .class files. This allows Python to be integrated into Java in several places that regular Jython currently doesn't support. It also processes special annotations in docstrings on methods in Python code to determine the static type information to expose when turning a dynmically typed Python method into a statically typed Java method.

jythonc is unmaintained and will not be present in Jython-2.3. While jythonc handles all of the language features present in Jython 2.2, it doesn't support 2.3 features such as generators. As such, it is not recommended that new Jython projects make use of jythonc. It is only included in Jython-2.2 to support older users of jythonc and to allow access to a few features that are only provided by jythonc at the moment:

1. Running in a JVM with a classloader that will not load dynamically created classes
2. Declaring Java method signatures in Python code

While all of these features are planned for Jython-2.3, they are currently only available from jythonc. Most uses of the second feature, adding method declarations to docstrings, can be handled by declaring a Java interface to implement with a Python class. Each method in the Python implementation takes the types of the Java method it implements. Exposing the Python class as an instance of that type to Java code can be done as explained in Accessing Jython from Java Without Using jythonc and its followup, Simple and Efficient Jython Object Factories.

(See http://www.jython.org/Project/jythonc.html)

You can extend Java classes.

You can add (J)Python protocols to Java classes.

You will need to describe the signature of methods in order to make them callable from Java (in addition to Jython).

What jythonc does -- jythonc translates .py files into .java source code files, then compiles these to .class files.

With jythonc, you can also:

• Compile Jython (.py) to Java class files (.class).

• Compile Jython to Java source, then stop without compiling to .class files.

• Use a Java compiler different from the default: javac. See the help from jythonc:

--compiler path-C path    Use a different compiler than standard' javac.  If this is set to    NONE' then compile ends with .java.  Alternatively, you can set the    property python.jpythonc.compiler in the registry.

This option can also be set in your Jython registry file.

Java compatible classes - In order to implement a Java compatible class (that is, one that acts like a native Java class and can be called from Java), your Jython code must follow these rules:

• Inherit from a Java class or interface.
• Include only one class per module.
• Give the Jython class and the source file that contains it the same name.
• Place all code inside that Jython class.
• Include method signature hints (called sig-strings) -- Add a @sig line in the doc-string for each method.

How to use jythonc:

• Type jythonc --help for help.

• Compile your Jython code with:

jythonc mymodule.py
• To get help for jythonc, type:

$jythonc --help Some notes: • When your run jythonc, by default, the .java files are placed in a sub-directory ./jpywork. You can override this with the --workdir command line option. From jythonc --help: --workdir directory-w directory Specify working directory for compiler (default is ./jpywork) • When you run this resulting code from Java, the directory ./jpywork and the Jython jar file must be on your classpath. Example -- The following Jython code extends a Java class. Compile it with jythonc: # Foo.pyimport javaclass Foo(java.util.Date): def __init__(self): self.count = 0 def bar(self, incr=1): """@sig void bar(int incr)""" self.count += incr return self.count def toString(self): cnt = self.bar() return "Foo[" + java.util.Date.toString(self) + " " + cnt + "]" Example, continued -- Here is Java code to test the above. Compile it with javac and run it: // FooTest.javaimport Foo;public class FooTest { public static void main(String[] args) { Foo foo = new Foo(); System.out.println(foo); foo.bar(); foo.bar(43); System.out.println(foo); }} Notes: • Compile and run: $ javac FooTest.java$java FooTest • You will need jpywork on your classpath. So, you can compile and run it as follows: $ ../../Jython-2.2a/jythonc Foo.py$javac -classpath ../../Jython-2.2a/jython.jar:./jpywork FooTest.java$ java -classpath ../../Jython-2.2a/jython.jar:./jpywork FooTest

In order to implement a Java compatible class (that is, one that acts like a native Java class and can be called from Java), your Jython code must follow these rules:

• Inherit from a Java class or interface.
• Include method signature hints (called sig-strings).
• Give the Jython class and the source file it is in the same name.

Here is another simple example:

"""simpleclass.pyThis is a simple class to demonstrate the use of jythonc."""import java.lang.Objectclass simpleclass(java.lang.Object):    def __init__(self, name='The Horse With No Name'):        """public simpleclass(String name)        """        self.name = name        self.size = -1    def set_name(self, name):        """@sig public void set_name(String name)        """        self.name = name    def set_size(self, size):        """@sig public void set_size(int size)        """        self.size = size    def show(self):        """@sig public String show()        """        return 'name: %s  size: %s' % (self.name, self.size, )

And, a Java test harness for this simple example:

// simpleclasstest.javaimport simpleclass;public class simpleclasstest {    public static void main(String[] args) {    String s1;    simpleclass sc = new simpleclass();    s1 = sc.show();    System.out.println("1. " + s1);    sc.set_name("dave");    sc.set_size(4321);    s1 = sc.show();    System.out.println("2. " + s1);    }}

Notes:

• In order to produce a Java compatible class, our Jython class must inherit from a Java class. In this case, we use java.lang.Object, because we do not need to inherit any behavior.
• The methods set_name, set_size, and show each have sig-strings.

Put jpywork on your CLASSPATH, then use the following to compile and test the above:

$jythonc simpleclass.py$ javac simpleclasstest.java$java simpleclasstest1. name: The Horse With No Name size: -12. name: dave size: 4321 In the following example, we create a stand-alone Jar file, that is, one that can be executed as a script on a machine where Jython is not installed. Here is the Jython script: # test_jythonc.pyimport sysdef test(words): msgs = ['hi', 'bye'] for word in words: msgs.append(word) for msg in msgs: print msgdef main(): args = sys.argv[1:] test(args)if __name__ == '__main__': main() Compile and build a Jar file with the following: $ jythonc --all --jar mytest.jar test_jythonc.py

Run it as follows:

$java -jar mytest.jar hello goodbyehibyehellogoodbye Notes: • Note that our Jython script contains no class. jythonc will create a public class and a public static main function for us. • The --jar flag tells jythonc that we want the results placed in a Jar file (as opposed to placing it in the work directory ./jpywork). • The --all flag tells jythonc to include all Jython support in the Jar file, making it stand-alone. This enables us to run it on a system where Java is installed but Jython is not. 16.1 Calling Jython Code from Jython From Jython, you can run Jython and Python code. When you do so, you may run Java code that is in a super-class or is used by the Jython code. But, notice that, from Jython, you cannot call Python code that has been extended with C. 16.2 Calling Jython Code from Java Must compile Jython/Python to Java with jythonc. Must pay attention to method signatures. Define method signature in Jython in a doc string with @sig. Then look at the generated .java file. Other things to be aware of: • Must set classpath to include jpywork. • Must write a Java compatible class. See above. 16.3 Another example -- Jython-2.2a/Demo/javaclasses What this example shows: • How to write a class that can be compiled (with jythonc) and then called from Java. • How to write method signatures for Jython methods. • How to compile the the Jython code and the Java code. For example, I compiled and ran the example in Jython-2.2a/Demo/javaclasses with the following: $ rm -rf jpywork/$../../jythonc --package pygraph Graph.py$ javac -classpath .:../../jython.jar pygraph/PythonGraph.java\$ java -classpath .:../../jython.jar:jpywork pygraph.PythonGraph

From:http://www.rexx.com/~dkuhlman/jython_course_01.html#another-example-jython-2-2a-demo-javaclasses

Blogged with Flock

Overview

language, illustrated with a small working example. I argue the
benefits of marrying Java with the Python scripting language, and then
speculate why developers
have been slow to adopt this innovative technology.

What is Jython?

Jython is an implementation of
Python that is
written in pure Java.
This means that Jython offers all that any other implementation of
Python offers (see next section), but also provides access to the whole
range of Java library classes (such as Swing, JDBC, Java Cryptography,
Java Speech API, and so on). It also makes it very easy to write Python
code that integrates existing Java components. Conversely, it is easy
to write Jython components that can later be reused and integrated into
other Java-based systems. The benefit to the Java developer is rapid
application development without sacrificing functionality, robustness,
or the commercial respect afforded by Java.

Why Python?

Python is a general-purpose, object-oriented, scripting language. It
is a highly regarded language that is gaining in popularity because it
offers high productivity and therefore competitive advantage. It also
has a simple syntax that gives rise to readable (and maintainable)
programs.

The language itself contains most of the constructs and features
that you might expect, such as objects, functions (methods), procedural
loop constructs, and exception handling. The main feature for a C or
Java programmer is, arguably, the ease with which one can create and
manipulate lists and sequences of values. This, coupled with idioms of
functional programming such as mapping and filtering, make for a very
powerful core language.

A Jython Example

As I stated earlier, Jython is an implementation of Python that is
written in pure Java. This is such a powerful idea that I'm surprised
how little Jython has been recognised and adopted. Let me illustrate
the marriage of the two languages with a little example. Afterwards, we
can compare the equivalent source codes for Java and Jython. (If you
would like to try out the example for yourself and you do not already
have an installation of Jython, you can download it from the website at
www.jython.org.)

I will explain the example in terms of a session with the
interactive shell, so that you understand not only how the source code
works, but also how you might work with the Jython interpreter.

So let's start up Jython's interactive shell by typing 'jython' at the command line.
You should see something like the following:

C:\My Jython&gt;jythonJython 2.0 on java1.4.0 (JIT: null)Type "copyright", "credits" or "license" for more information.&gt;&gt;&gt;

Now type the following at the &gt;&gt;&gt; prompt:

import javax.swing as swing

Jython accepts the import, and simply displays the next prompt,
waiting for another line of input:

C:\My Jython&gt;jythonJython 2.0 on java1.4.0 (JIT: null)Type "copyright", "credits" or "license" for more information.&gt;&gt;&gt; import javax.swing as swing&gt;&gt;&gt;

The import statement allows us to use the shorter package name
'swing' as the name of the javax.swing package. We can now create an
instance of a JFrame, give it a title, make it visible, and assign it
to a variable, f, all in one line:

f=swing.JFrame(title="My Frame", visible=1)

There are several features of Jython that allow this line to be so
short. Firstly, we don't need to declare variables before using them.
(This can be a mixed blessing, as Jython is more willing to accept
typos.) Secondly, we don't use the Java keyword new for
creating an instance of a class. Thirdly, properties can be set on a
JavaBean at the time of its creation by passing them as keyword
arguments. Here, we are setting two properties: the name of the JFrame,
and its visibility. Note that Python does not have a Boolean type, as
in Java, so we must supply the visibility value as 0 (false) or 1
(true).

At this point, the JFrame is visible, so you can read its title, but it has no size.
To make the window bigger, you resize it by setting the size property of the object f:

f.size=(300,300)

There is quite a lot going on in this short line. Firstly, the dot
notation ('f.size'), combined with assignment, is a short hand for
setting the
value of a JavaBean property. We could have called the setSize() method directly on f (as in f.setSize(300,300)), but using the dot notation for setting property values can lead to more concise code.
Note that we did not explicitly create an instance of the java.awt.Dimension class
before assigning it to the size property. Jython knows to expect a java.awt.Dimension object, and
therefore passes the tuple (300, 300) as an argument to the constructor of the Dimension class to
create a new Dimension object. The newly created Dimension object is then set as the value of the
size property.

Our frame still doesn't do anything, so let's first create, and then add, a button:

b=swing.JButton("Push Me")f.contentPane.add(b)

You'll need to redraw the frame before the button becomes visible
on-screen. You can do this manually by resizing the frame with the
mouse, or programmatically by calling

f.repaint()

Now let's make the button print a message whenever it is pressed. First, we define a function that prints a message:

def printMessage(event):   print 'Ouch!'

Next, we associate that function with the button b.

b.actionPerformed=printMessage

And that's it! If you press the button, the console says 'Ouch!'.

We illustrate the differences between Java and Jython code for this example by listing the source
code for each.

First, the Java source code:

import javax.swing.JFrame;import javax.swing.JButton;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;public class MyExampleimplements ActionListener {        public void actionPerformed(ActionEvent e) {        System.out.println("Ouch!");    }        public static void main(String[] args) {        JFrame frame = new JFrame("My Frame");        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.setSize(300,300);        JButton button = new JButton("Push Me!");        frame.getContentPane().add(button);        ActionListener listener = new MyExample();        button.addActionListener(listener);        frame.setVisible(true);    }}

And now the Jython source code:

import javax.swing as swingdef printMessage(event):    print "Ouch!"        if __name__== "__main__":    frame=swing.JFrame(title="My Frame", size=(300,300))    frame.defaultCloseOperation=swing.JFrame.EXIT_ON_CLOSE;    button=swing.JButton("Push Me!", actionPerformed=printMessage)    frame.contentPane.add(button)    frame.visible=1

You can see how much shorter the Jython code is, even for such a
simple example. Think of the implications for the cost of code
development and maintenance!

If you have tried out this example for yourself, or already used
Jython, you will have noticed another great feature of the language -
the immediate feedback you get from the interpreter. Many programmers
criticize interpreted languages for executing slowly, but when it comes
to speed of code development the interpreter wins hands-down over a
compiler. The interactive nature of an interpreter means that you
detect some errors much earlier than you would with an
edit-compile-test loop. And if you can both interpret and compile code

Jython Reuse From Java

The example above has shown how you can access Java classes from
Jython. Now I should explain how you can use Jython code from Java.

The answer really is quite simple. Since Jython is an implementation
of Python in Java, it needs to compile the Python functions that you
write down to Java bytecode before it can run them. Normally it avoids
a lengthy compilation step by doing the compilation 'on the fly', but
you can also compile your Jython classes down to Java .class files or
.jar archives that you can place on the classpath of your 'master'
application.

You perform the compilation by using the jythonc compiler provided
with Jython. This compiler first generates Java source files from the
Jython code, then compiles them using a standard Java compiler. If you
generate .class files, then you need to remember to put the jython.jar
runtime on the Java classpath when you run the master application, as
the Java source files that jythonc generates have dependencies on the
Jython runtime. If you generate a jar file using jythonc, however,
there are options to include files from the Jython runtime within the
jar.

For example, if the Jython source code for the example given above is
contained in the file MyExample.py, then it can be jar'ed up with
the following command:

jythonc -c -j myjar.jar MyExample.py

This creates a jar file containing the compiled Java version of the Jython
code we wrote as well as files from the Jython runtime.

The jar file also contains a manifest, which makes the jar executable. You can run the jar by typing:

java -jar myjar.jar

Why Isn't Everybody Using Jython?

This is the hard part! Jython is an incredibly powerful tool, and I
think there are many developers out there who would love to use it,
if only they could. It's one of those few languages that delights
the developer, because the language is so powerful and you get results
quickly. However, it is still very much a 'niche' language,
used only by forward-thinking organisations and entrepreneurs.

Here are some of the possible reasons for the low adoption rate of Jython:

Two Technologies, One Developer
It won't have escaped your notice that to understand a Jython program
(or to be more precise a Jython program that uses Java classes)
you need a solid understanding of both Java and Python. This places
demands on the skills of the developer at a time when most managers
prefer to simplify code development by choosing the technology that
is the common denominator across their applications.
Learning Curve and Project Pressures
Most developers come to Jython from Java, so have to learn about Python.
They probably have to learn Python before being able to convince colleagues
and managers that Jython will save time in the long run. And the time to
learn a new language in the midst of project pressures and approaching
deadlines is simply not available. It?s a vicious circle that needs to be
broken, and I'm confident that for many, an investment in Jython will pay off.
Old Habits Die Hard

If you're a Java developer, you are probably quite satisfied developing Java.
It's a good, well established, programming language and you?re familiar with
the idioms, patterns and style of the language that make it elegant.
Why should you change? Well, I think you should at least consider using Jython,
because firstly, Python, too, is a good programming language with a strong
following. Secondly, a good developer should always be on the look-out for
ways of becoming more productive, and I believe Jython is a good candidate.
Lastly, technologies in the IT sector are always changing, so you should
constantly re-evaluate your technology choices to be sure that you use
by default because "that's what you do".
Perception of an "Experimental Technology"
Jython is not an "Experimental Technology" -
It is industrial-strength and stable. If you're not confident enough to
use it for your main application straight away, then use it for writing
test scripts and developing prototypes. Often, developers will begin with
the intention of writing a prototype in Jython and later migrating to Java,
only to find later that the migration is not necessary.
Jython is Slow
To say that Jython is unsuitable for your application because it is
an interpreted language and therefore too slow is almost certainly false.
There are very few applications these days for which execution speed is
such a major concern. And if you do find a bottleneck in your code you
can always migrate that section of code to Java as necessary. As a
developer, you should be more concerned about the speed of development
than the speed of execution, and in this respect, Jython is fast!

Conclusion

Jython is a technology that marries two disparate technologies,
Java and Python, seamlessly and to great effect.
Unfortunately, I believe it has largely been overlooked by developers.
Jython has much to offer, particularly to the Java developer community,
and offers the potential to speed up conventional Java development.

It has taken a while, but there are now a couple of good books about Jython on the market:

 Jython Essentials by Samuele Pedroni & Noel Rappin. Published by O'Reilly, 2002. See listing at Amazon.com or Amazon.co.uk Jython for Java Programmers by Robert Bill. Published by New Riders, 2002. See listing at Amazon.com or Amazon.co.uk