Wednesday, 5 December 2007

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

针对好多Linux 爱好者对内核很有兴趣却无从下口,本文旨在介绍一种解读linux内核源码的入门方法,而不是解说linux复杂的内核机制;

一.核心源程序的文件组织:

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

本文基于稳定的2.2.5源代码,第二部分的实现平台为 Redhat Linux 6.0。

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

体系结构的内存管理代码,如页式存储管理内存的分配和释放等;而和体系结构相关的内存管理代码则位于arch/*/mm/,例如arch/i386/mm/Fault.c

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

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

下为块设备驱动程序,比如ide(ide.c)。如果你希望查看所有可能包含文件系 统的设备是如何初始化的,你可以看drivers/block/genhd.c中的device_setup()。它不仅初始化硬盘,也初始化网络,因为 安装nfs文件系统的时候需要网络其他:

如, Lib放置核心的库代码; Net,核心与网络相关的代码; Ipc,这个目录包含核心的进程间通讯的代码; Fs

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

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

一般,在每个目录下,都有一个 .depend 文件和一个 Makefile

文件,这两个文件都是编译时使用的辅助文件,仔细阅读这两个文件对弄清各个文件这间的联系和依托关系很有帮助;而且,在有的目录下还有Readme

文件,它是对该目录下的文件的一些说明,同样有利于我们对内核源码的理解;

二.解读实战:为你的内核增加一个系统调用

虽然,Linux 的内核源码用树形结构组织得非常合理、科学,把功能相关联的文件都放在同一个子目录下,这样使得程序更具可读性。然而,Linux

的内核源码实在是太大而且非常复杂,即便采用了很合理的文件组织方法,在不同目录下的文件之间还是有很多的关联,分析核心的一部分代码通常会要查看其它的几个相关的文件,而且可能这些文件还不在同一个子目录下。

体系的庞大复杂和文件之间关联的错综复杂,可能就是很多人对其望而生畏的主要原因。 当然,这种令人生畏的劳动所带来的回报也是非常令人着迷的:你不仅可以从中学到很多的计算机的底层的知识(如下面将讲到的系统的引导),体会到整个操作系 统体系结构的精妙和在解决某个具体细节问题时,算法的巧妙;而且更重要的是:在源码的分析过程中,你就会被一点一点地、潜移默化地专业化;甚至,只要分析 十分之一的代码后,你就会深刻地体会到,什么样的代码才是一个专业的程序员写的,什么样的代码是一个业余爱好者写的。

为了使读者能更好的体会到这一特点,下面举了一个具体的内核分析实例,希望能通过这个实例,使读者对Linux的内核的组织有些具体的认识,从中读者也可以学到一些对内核的分析方法。

以下即为分析实例:

A、操作平台:

硬件:cpu intel Pentium II ;

软件:Redhat Linux 6.0; 内核版本2.2.5

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

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

Loadin引导和Linux的自举引导(bootsect-loader),而后者所对应源程序为arch/i386/boot/bootsect.S,它为实模式的汇编程序,限于篇幅在此不做分析;无论是哪种引导方式,最后都要跳转到

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

arch/i386/kernel/head.S (对经压缩后存放的内核要先执行 arch/i386/boot/compressed/head.S);

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

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

的入口地址;当然,除此之外,head.S还要做一些其他的初始化工作;

2.系统初始化后运行的第一个内核程序asmlinkage void __init start_kernel(void) 定义在

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

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

表中,其中系统调用总控程序system_cal就是中断服务程序之一;void __init trap_init(void) 函数则通过调用一个宏

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

其中SYSCALL_VECTOR是定义在 /usr/src/linux/arch/i386/kernel/irq.h中的一个常量0x80; 而

system_call

即为中断总控程序的入口地址;中断总控程序用汇编语言定义在/usr/src/linux/arch/i386/kernel/entry.S中;

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

表中的相应系统服务例程的入口; 从系统服务例程返回后恢复处理机状态退回用户程序;

而系统调用向量则定义在/usr/src/linux/include/asm-386/unistd.h 中;sys_call_table

表定义在/usr/src/linux/arch/i386/kernel/entry.S 中; 同时在

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

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

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

由以上源代码分析可知, 要增加一个系统调用就必须在 sys_call_table 表中增加一项 ,

并在其中保存好自己的系统服务例程的入口地址,然后重新编译内核,当然,系统服务例程是必不可少的。

由此可知在此版linux内核源程序中,与系统调用相关的源程序文件就包括以下这些:

arch/i386/boot/bootsect.S

arch/i386/Kernel/setup.S

arch/i386/boot/compressed/head.S

arch/i386/kernel/head.S

init/main.c

arch/i386/kernel/traps.c

arch/i386/kernel/entry.S

arch/i386/kernel/irq.h

include/asm-386/unistd.h

当然,这只是涉及到的几个主要文件。而事实上,增加系统调用真正要修改文件只有include/asm-386/unistd.h和arch/i386/kernel/entry.S两个。

C、对内核源码的修改:

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

asmlinkage int sys_addtotal(int numdata)

{

int i=0,enddata=0;

while(i<=numdata)

enddata+=i++;

return enddata;

}

该函数有一个 int 型入口参数 numdata , 并返回从 0 到 numdata 的累加值;

当然也可以把系统服务例程放在一个自己定义的文件或其他文件中,只是要在相应文件中作必要的说明;

2.把 asmlinkage int sys_addtotal( int) 的入口地址加到sys_call_table表中:

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 */

/* add by I */

.long SYMBOL_NAME(sys_addtotal)

.rept NR_syscalls-191

.long SYMBOL_NAME(sys_ni_syscall)

.endr

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

中进行必要申明,以供用户进程和其他系统进程查询或调用:

增加后的部分 /usr/src/linux/include/asm-386/unistd.h 文件如下:

... ...

#define __NR_sendfile 187

#define __NR_getpmsg 188

#define __NR_putpmsg 189

#define __NR_vfork 190

/* add by I */

#define __NR_addtotal 191

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

#include

#include

_syscall1(int,addtotal,int, num)

main()

{

int i,j;

do

printf("Please input a number\n");

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

if((j=addtotal(i))==-1)

printf("Error occurred in syscall-addtotal();\n");

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

}

对修改后的新的内核进行编译,并引导它作为新的操作系统,运行几个程序后可以发现一切正常;在新的系统下对测试程序进行编译(*注:由于原内核并未提供此系统调用,所以只有在编译后的新内核下,此测试程序才能可能被编译通过),运行情况如下:

$gcc -o test test.c

$./test

Please input a number

36

Total from 0 to 36 is 666

可见,修改成功;

而且,对相关源码的进一步分析可知,在此版本的内核中,从/usr/src/linux/arch/i386/kernel/entry.S

文件中对 sys_call_table 表的设置可以看出,有好几个系统调用的服务例程都是定义在/usr/src/linux/kernel/sys.c

中的同一个函数:

asmlinkage int sys_ni_syscall(void)

{

return -ENOSYS;

}

例如第188项和第189项就是如此:

... ...

.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 */

... ...

而这两项在文件 /usr/src/linux/include/asm-386/unistd.h 中却申明如下:

... ...

#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

由此可见,在此版本的内核源代码中,由于asmlinkage int sys_ni_syscall(void) 函数并不进行任何操作,所以包括 getpmsg,

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

但它们却仍然占用着sys_call_table表项,估计这是设计者们为了方便扩充系统调用而安排的;

所以只需增加相应服务例程(如增加服务例程getmsg或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.

C header definition and declaration

Structuring header files

  > 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 of
salt 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_CAPS

e) 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 ().

------------------------------
About Path
------------------------------
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.

3.2. About compiling
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);
conf.load(conf_input);
} 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

Headers in latex

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

\pagestyle{myheadings}
\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.

\pagestyle{myheadings}
\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.

\pagestyle{myheadings}
\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{}
\fancyhead[C]{thepage}
\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.

Powered by ScribeFire.

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

Scjp Study Guide 310-055

Science in Silico


To download the full version visit vuze.com

Powered by ScribeFire.

unittest模块

unittest模块是用python编写的,其功能与junit一样,都是为了方便单元测试用的测试框架。
unittest模块是从python
2.1引入标准库的。它包含几个类:TestCase,TestSuite,TestResult,TextTestRunner等等。要建立自动测试,
必须创建unittest.TestCase的子类。然后定义一连串的test测试函数。使用assertXXX来下断言。测试成功就ok,测试错误就
Error,测试失败就Fail,共3种状态。比如:



import uniittest


import 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()是用来组合相关的测
试实例的,用addTest方法添加测试实例。setUp和tearDown方法是用来建立必要的测试环境,例如变量,文件等。tearDown进行一些
扫尾工作。


Powered by ScribeFire.

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
  3. Loading Python classes dynamically from Java with Class.forName

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.py

import java

class 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.java

import 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.py

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

import java.lang.Object

class 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.java

import 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 simpleclasstest
1. name: The Horse With No Name size: -1
2. 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.py

import sys

def test(words):
msgs = ['hi', 'bye']
for word in words:
msgs.append(word)
for msg in msgs:
print msg

def 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 goodbye
hi
bye
hello
goodbye

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

For more information, see Jython-2.2a/Demo/javaclasses/readme.txt.



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

Blogged with Flock

Tuesday, 27 November 2007

What's Good About Jython?

Overview


In this article I introduce features of the Jython programming
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;jython
Jython 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;jython
Jython 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 MyExample
implements 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 swing

def 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
(as with Jython) then you get the best of both approaches.



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
your chosen technologies for the right reason, instead of 'choosing' them
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.


Related Reading:


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











cover


Jython Essentials by Samuele Pedroni & Noel Rappin. Published by O'Reilly, 2002.

See listing at Amazon.com
or Amazon.co.uk


cover


Jython for Java Programmers by Robert Bill. Published by New Riders, 2002.

See listing at Amazon.com
or Amazon.co.uk


Powered by ScribeFire.

Python的"字节码" pyc文件

pyc是python的二进制编译文件
pyc文件比py文件拥有更快的装载速度,但是执行速度没有区别。
但是对于程序员来说,转换为pyc文件最大的好处是可以隐藏源代码。

命令为

python -c "import compileall; compileall.compile_dir('py文件存放目录的路径')"

该命令可以为一个目录下的py文件生成pyc文件(包含子目录)

在windows平台上的路径书写方式为('D:/7ying/test')


Powered by ScribeFire.

如何“编译”Python程序

如何编译Python程序(或者如何由Python生成可执行文件)是一个非常常见的问题,总是有人问,列出来,google搜索的时候就可以看到了。如果还有人说"找不到相关资料",唯一的解释就是这个人太懒了,根本没有去找。

如果转载,请注明作者是牡蛎,出自http://blender.blogchina.com/523381.html。



0. Python(及其它高级的脚本语言)不存在把指令编译到本地代码的工具,但是总是可以发布可执行文件。

 
py2exe http://py2exe.sf.net
只支持windows平台,应该是大家听到最多的一个名字了,用户不少,所以有问题的话在它的mail list里面很容易找到答案。文档中提到了"无法找到某某code"、使用opengl等模块的问题

 
PyPackage http://codereactor.net/projects/pypack/index.html
我觉得py2exe等等工具还是罗嗦得像唐僧,需要在配置文件中写上需要的数据文件。作者完全无视这样一个事实:我需要发布可执行文件的时候,程序已经完工了,所有的数据文件就在主程序所在目录下,所以多数情况下,根本不用到别的地方搜索。现在终于有人站了出来,PyPackage实际上并不是一个程序打包的工具,而只是简化py2exe的操作,甚至可以自动调用InnoSetup 5制作安装文件——不过这个软件并不智能,会打包很多不需要的文件

 
Installer http://www.mcmillan-inc.com/installer_dnld.html
可以产生windows、linux平台的可执行文件,现在作者主页连不上去了,但是搜索一下可以在其它地方下载
自带一个小程序写配置文件,如果程序较复杂,还是需要手工修改这个配置文件。支持从py15以来的所有Python版本
2005年9月,冰冻牡蛎更新:Giovanni Bajo获得Gordon McMillan's Installer的授权、版权改变为GPL,并在http://pyinstaller.hpcf.upr.edu/继续开发PYinstaller。2006年9月更新:这里可以看到Gordon McMillan's的原始网站的镜像

 
Python自带的freeze.py(不过windows版本不带这个,你可以自己下载Python的源程序再找)。这个是我最不推荐的一种方法(为什么?自己看),不过如果你的Python程序要发布到其它工具不支持的平台上,可以考虑这个方法

 
新出来的Pyco http://www.pythonapocrypha.com/projects/pyco/
还没用过

 
Squeeze http://starship.python.net/crew/fredrik/ipa/squeeze.htm
还没用过,只支持Python 1.4

 
cx_Freeze http://starship.python.net/crew/atuining/cx_Freeze/
winodws、linux平台。简单的程序甚至都不需要写配置文件

 
Stand alone Python for Windows http://arctrix.com/nas/python/standalone.html
如果你不介意源程序太过"暴露"的话,用这个吧
会不会觉得Updated: Sun, 09 Apr 2000 18:39:54 -0600 扎眼?如果你看一看它的VC源代码,就不会这么想了——其实这是普遍适用于win系统的方法,无论是98、2000或者xp。也许也可以用到linux上——我不懂linux,如果真的可以这么做,还请告诉我。

 
py2app http://undefined.org/python/
支持linux平台的工具可能也支持mac os,或者直接使用这个py2app。具体就不知道了,只吃过苹果,还没玩过苹果呢

 
Movable Python http://www.voidspace.org.uk/python/movpy/
这个其实是使用py2exe制作的、可以放在U盘上的绿色Python。有使用py2app制作苹果版movpy和用cx_Freeze制作Linux版movpy的计划。懒到都不愿意学习py2exe、py2app或者cx_Freeze的人可以看看。

 
Shed Skin - A Python-to-C++ Compiler: 试验项目,windows上,连他的例子我都没有编译成功 :(。

 
Psyco: 给Python程序加速的东西,看不出对发布Python程序的直接好处,并且作者以后将致力于PyPy。

 
PyPy: 项目目标是纯Python实现的Python、速度比CPython快,将来可以帮助实现编译Python。

 
pyc: Python compiler in Python,一个用纯Python写的Python的bytecode编译器,可以优化输出的pyc文件。和PyPy一样,现在还看不出对发布Python程序的直接好处。只有py24的bytecode。pyc是pyvm这个新的python虚拟机的一部分。

 
Jungle: 使用GNU工具(as、ld和winres)把Python程序编译到windows的exe可执行文件。该可执行文件只使用基于python24的的pythonic.dll。猜测它支持的模块仅限于内部模块以及jungle.jgl列出的模块。只有可执行文件下载,而这个可执行文件也是用Jungle自己编译的。目前版本号都到1.10了,经常看0.xx的版本号,这个数字好大啊,娃哈哈。

 

另类的方法,对Python语言特性都还不是100%支持,众多的CPython模块也不可以使用,还有,我也没有试过:
for .NET的Python编译器(如Visual Python、IronPython),不过我可不喜欢为了一个芝麻大的软件安装.NET framework
用jython,然后用jbuilder、jsmooth、NativeJ之类的包裹一下,或者用gcj编译成本地代码

 

2006年11月26日,近来有些人问,如何保护python开发的商业软件/闭源软件。

我的观点是,纯Python程序,又不想用C语言(其实C语言程序也可以破解,所以最好的方法就是不发布任何程序,嘿嘿),可以试试pyobfuscate混淆源代码,增加可能被反编译获得的源代码的阅读难度。不过pyobfuscate也好久没有更新了,娃哈哈。而实际上,没必要考虑别人会获得源代码的问题。 考虑(尤其是在自己的程序还没有写出来的时候)别人会反编译自己的Python程序,有点杞人忧天。

在*nix下的话,似乎可以(我不用*nix,并不确定)使用Python自带的freeze.py,把源程序的字节码转换成C程序,然后使用GCC编译,这样应该看不到字节码了。在windows下,不知道怎么使用freeze.py,总报错——谁知道的话告诉我吧。但是如果想实现跨平台,使用freeze.py的方法似乎不可取。


首先我相信,目前没有软件可以很好反编译Python 2.4及之后的版本生成的字节码,所以采用新版本Python“编译”到可执行文件,是安全的。

其次,据我所知,目前最成熟的反编译软件只有decompyle。而不是象某些人为了夸大问题的重要性,而口吐莲花所说的“现在有很多Python的反编译软件”。而我不相信有人愿意花钱买这个“唯一的且很多的”反编译软件,理由有二
看看decompyle页面更新日期,是2004年。我猜测作者把这个软件商业化之后并不成功,并没有太多人需要反编译自己或者他人的Python程序。导致作者没有足够的收入或者兴趣继续完善了
有人愿意花钱去反编译一个还不存在地软件,或者一个不出名的程序?



次成熟的反编译软件是decompiler.py。但是它比商业软件decompyle差远了。我没有去做试验,是他自己的主页承认说有很多局限的。

最后,真诚请教那些有“很多”Python反编译程序的高手,两个问题:
subsystem.htm
这是将数独游戏和消除游戏结合起来的益智游戏,未注册的话,只能累积玩60分钟。这是Python+pygame制作的软件,使用py2exe发布,可否麻烦高手——别怕,我不要它的源程序——看看它的注册部分,整个注册机/注册码出来?
wingide
这个有名的Python商业ide,我不确定它是不是使用py2exe制作的,而且它的规模比较大。我对它的源代码有点兴趣,有人说看不到它的源代码,但是我觉得\bin\2.4\src.zip里面的一堆pyo,是如假包换的源代码的字节码,如果真是如此,麻烦高手在空余时间,反编译一份喽。

Friday, 23 November 2007

Bugatti Veyron top speed test (408Km/h)


To download the full version visit vuze.com

Blogged with Flock

解决Linux系统播放器MP3标签乱码的问题

在amarok 或者 banshee 等播放器中 导入的mp3 很多都是乱码。看起来很别扭,今天找到了解决的方法 找到了一款java编写的小程序。

  使用方法

  下载ID3iconv 0.2.1 Binary

  cd到 mp3文件夹 这个很关键 不cd进去 是不行的 会出错。
  执行命令 sudo java -jar ~/id3iconv-0.2.1.jar -e gbk -removev1 *.mp3

  如果 程序出错 很有可能是java环境的错误,可以配置一下环境。

  方法

  安装JAVA环境。

  sudo apt-get install sun-java6-jre

  安装JDK。

  sudo apt-get install sun-java6-jdk

  设置当前默认的java解释器。

  sudo update-alternatives --config java

  输入有包含"sun"的行的前面的数字。



Powered by ScribeFire.

Thursday, 22 November 2007

中国访问blogspot的方法

Crossonline below is my Blog ID, just change it to yours, it will work. Anything wrong, please comment to let me know, thanks.

  • pkblogs.com/crossonline

  • inblogs.net/crossonline

  • 更改C:\WINDOWS\system32\drivers\etc\hosts,添加 72.14.219.190 crossonline.blogspot.com
  • 最近部分地区的电信好像是又把blogspot.com给封了,至少在极速客那里很多人反应,河北网通这里还是好好的,可以正常访问。不过看到极速客提供的比较费神费力的修改Hosts的方法,我很乐意分享一下我是怎样访问被封杀的blogspot的。首先打开Notepad(或者其他的编辑器),写入如下内容:
    function FindProxyForURL(url,host){
    if(dnsDomainIs(host, ".blogspot.com")){
    return "PROXY 72.14.219.190:80";
    }
    }
    另 存为proxy.pac到C盘的根目录下,以Firefox为例,打开Firefox,依次点击Tools->Options-> Advanced->Network->Settings...->选中Automatic proxy configuration URL,在下面填写:
    file:///C:/proxy.pac
    ,再点Reload,再点Ok,一路 Ok下去,就可以了。这个方法的巧妙之处(其实一点都不巧妙啦)就在于不用像极速客介绍的那样修改一堆有的没的的Hosts,只要一个“.”就保证了所有 blogspot的子域名可以没有限制的访问(内含GFW关键字的除外),嗯,Enjoy。

    P.S. Linux用户应该不需要Linux版本了吧,照葫芦画瓢对与Linux用户来说应该是再简单不过了,XD

    下面有朋友提到Wordpress.com可不可以通过这种方式访问,回答是:当然可以!只需要把proxy.pac用记事本打开,修改为
    function FindProxyForURL(url,host){
    if(dnsDomainIs(host, ".blogspot.com")){
    return "PROXY 72.14.219.190:80";
    }
    if(dnsDomainIs(host, ".wordpress.com")){
    return "PROXY 72.232.101.41:80";
    }
    }
    然 后保存,重启浏览器就可以了。这个原理是利用了该域名的多服务器的特征,每个服务器对应一个IP,GFW只是封杀了其中的一个IP地址,默认的那个,其他 的还是好好的,所以可以用这种方法进行访问,但也取决于网站本身,比如vox.com之前还支持,后来其IP地址为“204.9.178.110”的服务 器修改了设置,所以上方法就不能用了。以此类推,同志们还可以去Hack一下Technorati等等其他好的网站的其他服务器的IP地址,这样照着修改 一下就能畅通无阻的访问了。此致,敬礼。
######################################
flickr的访问:
使用firefox和其插件access flickr.

Creating .deb-Packages With Checkinstall

Version 1.0

Author: Falko Timme <ft [at] falkotimme [dot] com>
Last edited 02/04/2005

Checkinstall is a nice tool to create simple .deb-packages that you can use in your local network (e.g. if you have to install the same piece of software on multiple computers running Debian). It lets you compile and install software from the sources like before, but with the difference that you end up with a simple Debian package which also means that you can easily uninstall the software you just compiled by running dpkg -r!

I will demonstrate the use of checkinstall by compiling and installing the anti-virus software ClamAV on a Debian system.

This howto is meant as a practical guide; it does not cover the theoretical backgrounds. They are treated in a lot of other documents in the web.

This document comes without warranty of any kind!

 

1 Install Checkinstall

It is as easy as 1-2-3:

apt-get install checkinstall

If your system tells you that it does not know a package called checkinstall then add the following line to /etc/apt/sources.list:

deb http://www.backports.org/debian/ woody checkinstall

and run

apt-get update

Then try again to install checkinstall.

 

2 Install ClamAV

We need the ClamAV sources . We will install the software from the /tmp directory.

cd /tmp
wget http://mesh.dl.sourceforge.net/sourceforge/clamav/clamav-0.81.tar.gz
apt-get install libgmp3 libgmp3-dev
groupadd clamav
useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav
tar xvfz clamav-0.81.tar.gz
cd clamav-0.81/
./configure --sysconfdir=/etc

(Please note: ./configure --help gives a list of all configuration options available.)

make

Now comes the main difference: instead of make install we run

checkinstall -D make install

Answer the question "The package documentation directory ./doc-pak does not exist.
Should I create a default set of package docs? [y]:"
with y.

Then enter a description for your package (e.g. ClamAV 0.81). A summary of the configuration options for your .deb-package will come up:

You can change them here or just hit enter to continue. Now ClamAV will be installed plus a Debian package will be created which you can find in the installation directory /tmp/clamav-0.81 as the final checkinstall summary states:

Now you can copy clamav-0.81_0.81-1_i386.deb to other Debian computers and run

dpkg -i /path/to/clamav-0.81_0.81-1_i386.deb

to install it. If you want to remove it, just run

dpkg -r clamav-0.81

This even works on the computer you compiled ClamAV on! This is a nice way to install software from the sources and remove it if you are unsatisfied with the result.

Blogged with Flock

My photo
London, United Kingdom
twitter.com/zhengxin

Facebook & Twitter