| Newsletter Index | Quick-Tip Index | Search Newsletters |
Loopmark listings quiet
Vector registers grow cold
The truck is coming
by:
Tom Baring,
Erstwhile "Vector Specialist"
(Never a poet)
ARSC Faculty Joint Appointment Miho Aoki and retired ARSC staff member Bill Brody both have works on display in:
"POLARities: Aesthetics / Experiments / Observations"
"POLARities" features recent works by a selection of Alaskan artists exploring the connection between science and technology and the artists' inspiration and creative processes. It is on view at the UA Museum of the North from September 16 through October 29, 2006. See:
http://www.uaf.edu/museum/exhibit/special.html
This is presented in conjunction with the October 2006 AAAS Arctic Science Conference in Fairbanks, Alaska. The artists will discuss their work as one session of this conference:
http://www.arcticaaas.org/meetings/sessions.html#session2
[[ Thanks to Lee Higbie of ARSC for this tutorial. ]]
The topic today is:
Fortraners be wary: Java is case sensitive and statements end with a semicolon. It is much like C, with most basic syntax taken directly from C. The biggest difference between Java and C/C++ syntax is the removal of many of the error-prone constructs such as automatic type conversion, use of non-Boolean data types as Boolean, and easily changing pointer values.
Gee, sounds pretty good so far. Next, the devilish details. Coming from an imperative language background, for me the biggest conceptual hurdle for using an object oriented programming language is that the most important "arguments" to most functions are part of the object, not arguments to the function. Syntactically they precede the function name ("method" name, actually) and don't look at all like arguments. E.g., In Fortran you might say this:
call draw_rectangle (x1, y1, x2, y2, red, blue)
where the fifth parameter is for the border color and the sixth is for the center color. In
Java, this becomes:
rectangle.draw (red, blue);
where the rectangle "object" has a draw "method" that uses the rectangle's internal variables
for its corners. In effect, the rectangle knows where it is and draws itself.
If you want to draw nr rectangles, you might have this in Fortran:
do i = 1, nr
call draw_rectangle (x1(i), y1(i), x2(i), y2(i), red, blue)
enddo ! end do loop on i drawing rectangles
The Java code would more likely look like:
for (int i = 0; i < nr; i++)
{
rectangles[i].draw(red, blue);
} // end for loop on i
drawing rectangles (A minor safety feature in the above Java sample is that the scope of i is the
loop. Java encourages variables to be declared only for the block where they are required, often
only inside a single statement.)
Here are eight additional differences between Java and C++ (or Fortran).
Java has no explicit pointers. Object names are pointers but they allow no manipulation. They can be subscripted or arrayed, but Java programmers typically don't even think of them as pointers any more than Fortran programmers think of common-block names as pointers.
Variables can be subscripted with any number of subscripts, but the language is really intended only for singly subscripted Arrays. Each array subscript uses its own brackets and the lower bound is always 0. Subscript references cannot be out of range. If an array subscript is not within the declared or implicit range, an interrupt will be generated. I have found no way to disable this feature.
Except in a few specific situations, there is no automatic type conversion. For example:
int i = 1;
...
if (i) { ..... // Wrong!
This must be written as something like:
if (i==1) { ....
Type conversion, called "casting" in Java as in C, must be explicit in all non-trivial situations. It is denoted by putting the new type in parens:
float f1, f2 = 1; // Permissible. Java will cast 1 to 1.0
double d1, d2 = 0; // Permissible. Java will cast 0 to 0.0
f1 = d1; // Illegal, precision might be lost
f2 = (float) d1; // Okay. Casting tells the compiler it's okay
d2 = f1; // Permissible. RHS higher precision than LHS
Starting with Java 1.5, also called Java 5, when you declare a collection of some type of data, you should declare the type so the compiler can verify that the operations are legal. In older versions you have to explicitly cast the result to the new type. In Java 5:
Vector <String> vecStrings = new Vector <String> ();
With this declaration, javac, the Java compiler, can verify that any assignment to a
vecStrings component is a String. Previous to Java 5, the declaration would lack the angle bracket
type declaration and to use one of the elements of the Vector you had to cast the result from an
Object to a String:
String str = (String) vecStrings.elementAt(i);
(In this older Java, you could store any type of object into vecStrings and would only
discover the error at execution time when the cast failed. A vector is a collection like an array,
but it can grow arbitrarily and must be accessed with specific methods like the elementAt method
used above; it does not use subscripts.)
There are scores of packages in Java, the standard ones are listed at http://java.sun.com/j2se/1.5.0/docs/api/, but there is no include capability. A class or all the classes in a package can be imported, which means they can be referenced by their simple name. Ugh, that's confusing; some examples should help. Most programs begin with a series of imports:
import java.higbie.*; // to access any class of the package higbie
import java.higbie.Debug; // imports only my Debug class
with either of these statements preceding the class statement, I can use Debug like any other
declared name:
Debug deb = new Debug (args);
If the package higbie is not imported, then the declaration would have to be
higbie.Debug deb = new higbie.Debug(args);
and every time I wanted to reference Debug, I would have to use the fully qualified name,
higbie.Debug.
Blocks are delineated by braces. For example, whenever more than a single statement is under control of a for or an if statement, the statements must be enclosed in braces. Most commonly you'll see something like:
for (int i = 0; i < max; i++) {
...
} // end for loop over i
or,
if (condition) {
...
} // end if condition
Braces are similarly used to delineate the statements of methods and classes. In one of the
few bits of context-sensitive syntax in Java, they are also used to initialize arrays. In that
special case, because they are part of a single statement, a semicolon is required afterward:
int [ ] iarray = {3, 1, 4, 1, 5, 9, 2, 3};
Here the bracket pair [ ] indicates that an array (subscripted variable) is being declared.
Java has 50 keywords and two other reserved words. For example, goto is a reserved word but is not a part of the language. You cannot use goto as a variable, but goTo is fine.
A method can declare that it generates ("throws," in Java) an exception, and any user of that method must either deal with the exception or pass it up the calling hierarchy where it will have to be vetted.
For example many I/O methods can throw exceptions for missing files or attempting to access something that doesn't exist. Users of any of these methods must provide code to catch the exception or their code will not compile. If they chose to pass the exception to their caller, then the caller must also vet ("catch," in Java) it. For most of the GUIs that control scientific/engineering applications this is not particularly important. It is important on large team projects, where an unvetted exception could result in a lost customer bank deposit, say.
One final note on syntax. There are three types of comments in Java.
A double slash introduces a comment that extends to the end of the line. This is one of the few places where an end-of-line character is significant.
A /* starts a comment that ends on the first */ encountered. This means that double slash comments can be nested inside /*
.. */ comments but not other /* ... */ comments. If you commonly remove code from execution by commenting it out, they you should predominantly use // comments.
/** ... */ comments. For the compiler, javac, these are just like the /* ... */ comments. However there is another tool, javadoc, that produces standardized code documentation. All the descriptions on Sun's web page, ...j2se/1.5.0/docs/api/, are produced with javadoc. Like javac, javadoc checks the code as well as the javadoc comments. Thus, at some level, it ensures that documentation is up-to-date. If a /** ... */ comment describes a method and its argument list does not agree with with the method's actual list, a diagnostic will be generated.
--
In this installment, I've covered some of the major differences between the syntax of Java and that of C++ and Fortran. For the next chapter I will present a "Hello Bill" program -- with a button.
A:[[ I'm curious what other people use for their shell prompt setting.
[[ (Your prompt is set via the "PS1" environment variable under
[[ sh/ksh/bash and via the "prompt" variable under csh/tcsh.)
#
# Thanks to Jed Brown:
#
I like color prompts. This one gives me lots of information, but
doesn't take a huge number of characters. From my .bashrc
| # Some useful escape sequences
| bold="\[\033[;1m\]" nbold="\[\033[;0m\]"
| normal="\[\033[0m\]"
| red="\[\033[31m\]"
| green="\[\033[32m\]"
| yellow="\[\033[33m\]"
| magenta="\[\033[35m\]"
| cyan="\[\033[36m\]"
|
| # shows command number, return value in magenta if nonzero, username in
| # yellow, host in red, tty in cyan, path in green
| PS1="\#$bold$magenta\$([ \$? -eq 0 ] || echo -n \" \$?\")$nbold $yellow\u$red\h$cyan\l $green\w$normal\\$ "
Slightly off topic, but we can also put useful things in our title bars:
| case "$TERM" in
| xterm*|rxvt*)
| PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD/$HOME/~}\007"'
| ;;
| screen)
| # With this escape sequence, screen can put the current command in its title bar.
| # Make sure to include in .screenrc the following line
| # shelltitle "$ |"
| if [ $UID -ne 0 ]; then
| PROMPT_COMMAND='echo -ne "\033k\033\134"'
| fi
| ;;
| *)
| ;;
| esac
#
# Rich Griswold
#
I use ZSH (http://zsh.sourceforge.net/) for my shell, and I have
two prompts depending on whether I'm using a console or an xterm.
The second prompt is basically the same as the first, without the
prompt colorization (which some consoles don't support) and the xterm
title bar hack. These prompts work in ZSH 4.0 and later.
case $XTERM in
xterm* | aixterm | dtterm | hpterm)
export PS1=
$'%{\e]0;%(#.ROOT .)%m:%~\a\e[1;%(#.31.32)m%}%~ %(?.:\).:\() > %{\e[0m%}'
;;
*)
export PS1="%(#.ROOT .)%m:%~ %(?.:).:() > "
;;
esac
Explanation:
${ Start escaped string
\e]0; Escape to change the xterm title bar
%(#.ROOT .) Print the text "ROOT " if running as root
%m Print the machine name
: A literal
%~ Print the path, using ~ for the home directory
\a Ends the xterm title bar escape
\e[1; Escape to change the text color
%(#.31.32)m Use red text if running as root and green otherwise
%} End the escaped string
%~ Print the path, using ~ for the home directory
%(?.:\).:\() Print :) if the last command was successful and
:( if the last command failed (non-zero return code)
> A literal
%{ Start another escaped string
\e[0m Reset the text color to the default
%} End the escaped string
#
# Greg Newby
#
Here's a fancy prompt I've used for years for csh variants. From my
.cshrc:
# This works well, but some portable systems change their
# hostname when using DHCP:
set hn=`hostname -s`
# This one won't change:
set hn='aquila'
# Set the "$prompt" variable, and make an alias to set the prompt,
# at the same time:
alias sp 'set prompt="${hn}(`whoami`) [\\!] `dirs|sed -e '\''s| .*||'\'' -e '\''s|.*[^/]\(/[^/]*/[^/]*\)|..\1|'\''` } "'
# This insures that the directory section of the prompt is set
# whenever I change directories:
alias cd 'cd \!*;sp'
# This sets the prompt in my .cshrc
sp
So, here's my prompt when I'm in my home directory:
aquila(newby) [1015] ~ }
A little explanation:
I like to have multiple terminal windows open. Rather than using
different colored terminal backgrounds or something similar, I just
have the prompt show me which system I'm on. I have the prompt show
my username, also, in case I have used "su" to become another user.
Note that I run the "whoami" command before every prompt, so you might
skip this if you don't ever change usernames.
In the square brackets is the history number. In csh, I can use "!1015"
to rerun command #1015...this is a nice feature when the command you
want is still on your screen.
Demystifying the whole prompt:
${hn} is the hostname
`whoami` inserts the username ($USER is often the same)
\\! inserts the current history number
dirs lists the current directory
|sed ... transforms the current directory to just take the
three last parts of the director path, if it's long
} is just a divider (followed by a space) between the prompt
and what you type
The directory listing is a nice feature, since otherwise you might
end up with very long directory paths as you navigate a Unix system.
One of the most common problems that new (and more experienced!) people
have with Unix/Linux is keeping track of which directory they are in.
This prompt helps address that challenge.
Even so, the directory component can sometimes push the active
part of your prompt far to the right of your screen.
I also use zsh, which is a shell with many characteristics of
bash/ksh/tcsh. Since many systems assume you have a more direct
descendant of sh or csh, zsh isn't a good choice for ARSC's large
systems, where some of the general settings for all users won't take
effect with zsh.
For the curious, this is the prompt I use with zsh:
PS1=$'%{\e[1;36m%}%m(%n) %~ [%!] > %{\e[1;0m%}'
It has a similar output as my csh example above. The main difference
is that it also uses ANSI color, so my prompt is cyan (but the commands
I type are white). Using different prompt colors on different systems
might help keep all of those terminal windows separate...
And a bonus answer, to issue 344:
A:[[ I have an existing library written in C/C++ that I would like to
[[ call from a python script. Is there a way to call this existing
[[ code without reimplementing the code in python?
#
# Thanks to Martin Luthi, who's catching up on old email:
#
There are many ways of doing this.
o There is the ctypes module, that allows to directly link into *.dll
(Windows) or *.so (Unix) libraries (part of Python 2.5., external
module for older versions)
http://starship.python.net/crew/theller/ctypes/
o SWIG (as already mentioned) http://www.swig.org
o SIP http://www.riverbankcomputing.co.uk/sip/
o Boost Python (for C++ libraries, quite heavyweight)
http://www.boost.org/libs/python/doc/
o weave (great for snippets of C code that get directly embedded in
Python source code): http://wiki.python.org/moin/weave
Here's a comparison:
http://www.boost.org/libs/python/doc/comparisons.html
Also take a look at the Python website:
http://docs.python.org/ext/ext.html
Q: I use the Unix system call:
int getgroups (int gidsetlen, gid_t *gidset)
This stores a list of values of type gid_t into the simple, C-style
array, gidset. However, I'm using C++, and want to use the vector
container class from the Standard Template Library to operate on
the list.
Generalizing the question, what's the best way to copy a simple array
into an STL vector object? Is this as good as it gets?
for (int i = 0; i < numberOfArrayElements; i++)
{
theVector.push_back ( theArray[i] );
}
[[ Answers, Questions, and Tips Graciously Accepted ]]
Contact:
Thomas J. Baring ARSC Web Specialist ph: 907-450-8619 Donald Bahls ARSC User Consultant ph: 907-450-8674 Arctic Region Supercomputing Center University of Alaska Fairbanks PO Box 756020 Fairbanks AK 99775-6020
Send comments and questions to the current editors using this Contact Form.Email Subscriptions:
| Newsletter Index | Quick-Tip Index | Search Newsletters |
Arctic Region Supercomputing Center
PO Box 756020, Fairbanks, AK 99775 | voice: 907-474-6935 | email:
home | search | about | support | news | science | resources