Sunday, October 28, 2007

Coding tricks

Dont make any assumptions about the compiler behavior

There are many version of compilers exist in the market. Even if all are bound to some standards, it will better to go through the compiler manual first. There are coding statements about which we can predict the behaviour and its totally depending on the compiler.

For example consider the following code snippet:

array[ i ] = i++;

What could be result of above statement ? Will the assignment statement execute first or 'i' will be incremented by one and then assignment happens ?


The behaviour of the above expression is undefined and depends on the compiler. So there are two options and compiler will choose any one of them. In such cases, it will be error prone to make assumption about the code execution. The Standard does not require that a compiler make an obvious choice, and some compilers don't. In this case, not only do we not know whether a[i] or a[i+1] is written to, it is possible that a completely unrelated cell of the array (or any random part of memory) is written to, and it is also not possible to predict what final value i will receive.

So best way is "Avoid the writting of such kind of code whose behaviour is not predictable". Still you wan to take risk then make sure what compiler will think rather than using your own intelligancy. This kind of code will not be portable.


Be familiar with your compiler
Becoming familiar with compiler settings will help in reducing the errors as well as amount of time invested in development. Use the settings that is most suitable for your application. Specifically while you are working on embedded system then depending the IDE (and so integrated compiler) you choose, u may have some additional features along with the IDE. There will be some default settings for compiler, but it may not provide you the best option for your application. Also there may be some code optimization option in compliler by which you can optimize your code in different different ways.

Now come to the point. Here, i will describe the mistake proofing techniques by which one can avoid bugs while coding an application.

1.'if' Statement for constant comparison

This is a matter of coding style while using 'if' statement to compare certian variable value with some constant. Follwoing are then ways you can write this comparision statement:

if (input_temp == SET_TEMPERATURE_VAL) {

// ............. do some calculations ........


}

another way is


if (SET_TEMPERATURE_VAL == input_temp) {

// ............. do some calculations ........


}

So, which one is better ? It seems that first style is good one. Second style is looking something weirg. But i will preffer to use second option because its an mistake proof statlement.

Why ? How ?

Suppose if one is using the first style and by mistake statement is written as:

if (input_temp = SET_TEMPERATURE_VAL) {

// ............. do some calculations ........


}

Now you can imagine the disaster of above code statement. IF condition will always be evaluated as TRUE. Irrespective of input_temp value, the conditional statement becomes an assignment statement and always evaluated as TRUE. So finally code may crash and developer may invest his/her time in finding out such buggy portion of the code.

[Note: if SE_TEMPERATURE_VAL is defined as 0x00, then condition will evaluated as zero - Øystein Pettersen]


In case of second style, even if you forget to use ==, compiler will give an error as constant can not be assiged to another value.

if (SET_TEMPERATURE_VAL = input_temp) {

// ............. do some calculations ........


}

2. Operator Precedence

If an expression consists of more than one operation then either devide the entire operation statement in small operations or use ( ) to make sure that the operations are performed correctly.

Consider the following simple code snippet:

temp = old_temp + cur_temp * TEMP_COEF ;

Assume TEMP_COEF = 4, old_temp = 2 and cur_temp = 10, then what should be the value of 'temp' ?

The above expression will be evaluated as temp = 2 + 10 * 4. This would result in the temp = 42.

Opssss ..... Does it go wrong ? Predicated result should temp = 48. Then ???

This is due to the operator precedence. Multiplication operation will perform first than addition as ' * ' operator has higher precedence than ' + '. So be careful while using multiple operators in a single code expression. If you are aware of operator precedence and desire result shoud be evaluated as 42 then above expression is ok, but still it sometimes make confusion for new developer. So either one should provide the comment for perticular formula or enclosed the small operations. Based on the operation required, above code snippet can be re-written as:

temp = old_temp + (cur_temp * TEMP_COEF) ; // To avoid the confusion

temp = (old_temp + cur_temp) * TEMP_COEF ; // To avoid the mistake in calculation

// For Simplicity


temp = old_temp + cur_temp ;

temp *= TEMP_COEF ;

It may also happen in conditional statement used multiple operations for checking conditions as:

if ( time = read_rtc() != set_time) {

// ......... do some operations ..............


}


3. Assertion

C language provides two very much helpful standard predefined macros for error message generation called __FILE__ and __LINE__. As these are standard macros, they are available with all compilers that implement those standards. __FILE__ and __LINE__ were both standardized by ANSI C; they may not be supported by (really) old compilers.


__FILE__ : This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in #include or as the input file name argument. For example, "/usr/local/include/myheader.h" is a possible expansion of this macro.

__LINE__ : This macro expands to the current input line number, in the form of a decimal integer constant. While we call it a predefined macro, it's a pretty strange macro, since its “definition” changes with each new line of source code.

These macros are very much helpful in displaying the error message whenever unpredictable event happens. Especially while writting the code for embedded system where it will be difficult to debug an application run-time, then these macro can provide the great amount of help in debugging. In embedded system where you may have small LCD display or some display device where you can print the error message with the help of display interface routines.

Suppose for a temperature monitoring routine, you are expecting that the input temperature value should not be greater than MAX_TEMP, otherwise it indicates inconsistancy in the system. One of the possible implementation of such kind of function is shown as below:

void monitor_temperature (unsinged char input_temp) {

if (input_temp > MAX_TEMP) {

display_error ("Temperature Error", __LINE__, __FILE__);

// ............. Take corrective action .............


}

display_error( ) routine may display the error message, name of the source file where above routine is written and line number of the display_error routine in the source file. So one can goto this location and debug the code.




4. Checking the return code of Standard library functions

It is quite common to ignore the error return codes of standard library functions. It will be dangerous to ignore the return code by assuming that these functions will always return true. If one forgets to provide check for return code then it may crash your application.

Consider the example of malloc which is a part of standard C library function. malloc( ) is used to dynamically allocate the memory at run-time. The prototype of malloc is as below:

void *malloc(size_t size);

malloc( ) returns either a pointer to an uninitialised newly-allocated space for an object of size size, or NULL if it fails to allocate the requested amount of memory. Ignoring the return code of malloc( ) may crash the system.

Consider the follwoing code snippet which tries to allocate space for 100 elements of an array of int type:

int *stk_ptr = malloc(100 * sizeof (int));


if (NULL == stk_ptr) {

// .......Memory could not be allocated ..........

// ...........Take corrective action ..............
}

Suppose malloc is not able to allocate the requested amount of memory, then it will return a NULL pointer. If programmer doen't provide check for return type of malloc which is NULL and tries to use NULL pointer assuming that it points to allocated memory, then program may crash.

So it is a good practice to check the return type of standard library function for failure and take corrective action to handle the situation.


5. Going beyond the array limit

There are some conditions where one initializes an array elements or copy a series of data from one location to an array. Consider the following code snippet:

unsinged char input_buffer[10];
unsigned char i;

for (i = 0; i <=10; i++) {
input_buffer[i] = in_port(); // Error: Read 11 bytes of data instead of 10
}


Above code is expected to read 10 data byte from input port and assign it to input_buffer from 0 to 9 location of it. But due to error in comparision statement in 'for' loop, code will try to assign 11th byte at input_buffer[10] location which may be used by another variable. So this type of mistake will lead to crash the system and it may take considerable amount of time to debug the error.

There are some tools exist which will help in reducing this kind of mistake. PC-Lint is one the tool which can help in avoiding such errors.

Valgrind is another tool that can help in detecting common memory management errors. Valgrind is closely tied to the architecture of the operating system. Currently, it's only supported on Linux x86 machines with kernels from the 2.2.x and 2.4.x series and glibc 2.1.x or 2.2.x.

Friday, October 26, 2007

Making your own Operating System

This tutorial covers the whole processing of creating your own tiny operating system. It includes booting
module and kernel.


Making your own Operating System

Required tools:

emu8086 - assembler,
tutorial and emulator

RawWrite for Windows

Usually, when computer starts it will try to load 512 bytes
from sector 1, head 0, cylinder 0 from floppy drive A
to 0000h:7C00h and give it control.
If this fails, a hard drive is used.

This tutorial covers the booting from floppy drive, the same principle is
used to boot from hard drive. Using floppy drive has several advantages:


You can keep your existing operating system (Windows, DOS...).


It is easy to modify the boot record of a floppy drive.

Example of a simple boot program:


; directive to create BOOT file:
#MAKE_BOOT#

; Boot record is loaded at 0000:7C00,
; so inform compiler to make required
; corrections:
ORG 7C00h

; load message address into SI register:
LEA SI, msg

; teletype function id:
MOV AH, 0Eh

print: MOV AL, [SI]
CMP AL, 0
JZ done
INT 10h ; print using teletype.
INC SI
JMP print

; wait for 'any key':
done: MOV AH, 0
INT 16h

; store magic value at 0040h:0072h:
; 0000h - cold boot.
; 1234h - warm boot.
MOV AX, 0040h
MOV DS, AX
MOV w.[0072h], 0000h ; cold boot.

JMP 0FFFFh:0000h ; reboot!

new_line EQU 13, 10

msg DB 'Hello This is My First Boot Program!'
DB new_line, 'Press any key to reboot', 0


Copy the above example to emu8086 source editor and
press [Compile and Emulate] button.
Emulator automatically loads ".boot" file to 0000h:7C00h.

You can run it just like a regular program, or you can use
Virtual Drive menu to Write 512 bytes at 7C00h to Boot Sector
of virtual floppy drive (FLOPPY_0 file in emulator's folder).

After writing your program to virtual floppy drive, you can select
Boot from Floppy from Virtual Drive menu.

If you are curious, you may write
the virtual floppy (FLOPPY_0) or ".boot" file to real floppy and
boot your computer from it, I recommend
using "RawWrite for Windows" from:

http://uranus.it.swin.edu.au/~jn/linux

(note that this is not MS-DOS compatible boot sector,
so it's better to use and empty floppy, although it should be
IBM (MS-DOS) formatted).

".boot" files are limited to 512 bytes (sector size), so if your
Operation System is going to grow over this size you should use boot program
to load data from other sectors. A good example of tiny Operating System can
be downloaded here:

micro-os_loader.asm

micro-os_kernel.asm

emu8086.inc

To create extensions for your Operating System (over 512 bytes), you can use
".bin" files (select "BIN Template" from "File" -> "New" menu).

To write ".bin" file to virtual floppy select "Write .bin file to floppy..."
from "Virtual Drive" menu of emulator:



You can also use this to write ".boot" files.

Sector at:


cylinder: 0

sector: 1

head: 0


is a boot sector!

A typical floppy drive structure:



Floppy disk has 2 sides, and there are 2 heads for each side (0..1), these
heads are moving above the disk.

Each side has 80 cylinders (0..79).
Each cylinder has 18 sectors (1..18).
Each sector has 512 bytes.
Total size of floppy disk is: 2 x 80 x 18 x 512 = 1,474,560 bytes.

Thursday, October 25, 2007

UNIX Tutorial

is made up of three parts; the kernel, the shell and the programs.

The kernel
The kernel of UNIX is the hub of the operating system: it allocates time and memory to programs and handles the filestore and communications in response to system calls.

As an illustration of the way that the shell and the kernel work together, suppose a user types rm myfile (which has the effect of removing the file myfile). The shell searches the filestore for the file containing the program rm, and then requests the kernel, through system calls, to execute the program rm on myfile. When the process rm myfile has finished running, the shell then returns the UNIX prompt % to the user, indicating that it is waiting for further commands.

The shell
The shell acts as an interface between the user and the kernel. When a user logs in, the login program checks the username and password, and then starts another program called the shell. The shell is a command line interpreter (CLI). It interprets the commands the user types in and arranges for them to be carried out. The commands are themselves programs: when they terminate, the shell gives the user another prompt (% on our systems).

The adept user can customise his/her own shell, and users can use different shells on the same machine. Staff and students in the school have the tcsh shell by default.

The tcsh shell has certain features to help the user inputting commands.

Filename Completion - By typing part of the name of a command, filename or directory and pressing the [Tab] key, the tcsh shell will complete the rest of the name automatically. If the shell finds more than one name beginning with those letters you have typed, it will beep, prompting you to type a few more letters before pressing the tab key again.

History - The shell keeps a list of the commands you have typed in. If you need to repeat a command, use the cursor keys to scroll up and down the list or type history for a list of previous commands.


Files and processes
Everything in UNIX is either a file or a process.

A process is an executing program identified by a unique PID (process identifier).

A file is a collection of data. They are created by users using text editors, running compilers etc.

Examples of files:

a document (report, essay etc.)
the text of a program written in some high-level programming language
instructions comprehensible directly to the machine and incomprehensible to a casual user, for example, a collection of binary digits (an executable or binary file);
a directory, containing information about its contents, which may be a mixture of other directories (subdirectories) and ordinary files.

The Directory Structure
All the files are grouped together in the directory structure. The file-system is arranged in a hierarchical structure, like an inverted tree. The top of the hierarchy is traditionally called root (written as a slash / )



In the diagram above, we see that the home directory of the undergraduate student "ee51vn" contains two sub-directories (docs and pics) and a file called report.doc.

The full path to the file report.doc is "/home/its/ug1/ee51vn/report.doc"

Starting an UNIX terminal
To open an UNIX terminal window, click on the "Terminal" icon from the drop-down menus.





An UNIX Terminal window will then appear with a % prompt, waiting for you to start entering commands.



Wednesday, October 24, 2007

CSRF Attacks

CSRF Attacks

Quick note -- Okay, this is my first article so please bare with me. I still have so much to learn about computer security (I'm only just 16) so any suggestions or false information noticed should be placed in a comment or PM'd to me, thanks =]

In this article I will be explaining what a CSRF attack is and how it can be used at a basic level.

Basics
CSRF stands for Cross-Site Request Forgery. An CSRF attack is an action upon a web application by an authenticated user. However, the user is unaware that he/she has performed this action.

There is more than one way of performing the attack.

Conditions

1. The user is logged in at the time of attack.
2. The user actually visits the attacker's page whilst logged in.
3. The attacker must know EXACTLY what data the target server expects to be passed in order to construct a malicious URL.

Constructing the malicious URL

Let's say that this URL, when clicked after logging into a bank system, transfers 100 pounds into Bob's account:
http://www.bank.com/moneytransfer.jsp?command=transfer&destinationuser=Bob&src=mysavings&amount=100

A malicious URL would look like this...

http://www.bank.com/moneytransfer.jsp?command=transfer&destinationuser=Attacker&src=mysavings&amount=10000

You'll notice that the value of destination user has been changed to the attacker (who would have an account on this site) and the value has been changed to 10,000.
This is the example URL I will be using throughout the article.

NB: There is probably no bank server in existence who's security is this basic, I am only using this as an example.

Methods

Method 1 - Creating a link:

1. The attacker must first construct a malicious URL.
2. The attacker will then place the URL in, say, < a href= > tags to create a link containing the malicious URL.
3. The attacker may then post this link into guestbooks, email it to the user etc so that the victim clicks on the link and the URL is successfully processed.

Method 2 - Storing the attack on the site:

1. The attacker will use the malicious URL constructed in Method 1.
2. They will place this in, say, tags.
3. The attacker will then store the attack in a field that accepts HTML (for example, a guestbook [I'm not suggesting all guestbooks are vulnerable to this though])
4. When the victim/user visits this page whilst logged in, the result is the same as the previous 2 methods.

Method 3 – Using XSS with CSRF (credit to Kane for this part):

Let’s say that there is a website that uses POST to edit information on the website. Using the earlier described methods, CSRF isn’t an option. So we can use XSS to assist us in sending the POST data.

Example:
http://www.target.com/change.php
Form data: 'name', 'password'
You could upload this onto a guestbook:

CODE :








Examples

Example for Method 1:

Here is an example using the < a href= > tags to create a malicious link:

CODE :

Click here


Clicking on the link by an authenticated use on the bank server WHILST HE/SHE IS LOGGED IN will result in 10,000 pounds being transfered to the attacker's account.

Example for Method 2:

Here is an example using the tags to be used to store in a field that accepts HTML:

CODE :




This could be placed inside a guestbook and when the 'image' loads, the request will be made to the server.

Example (real world):

The infamous MySpace attack used both XSS and CSRF to analyse and send a friend request to anyone who was viewing the page containing the attack, it also spread to their friends list and so on. Due to the friends list being so enormous, the MySpace server was temporarily crashed.

Conclusion

There a few conclusions that can be drawn from this article:

1. That CSRF is based mainly on social engineering (in order to actually get the user to visit the page, click the malicious link needed to carry out the attack).
2. When CSRF is successful, it can be devastating.
3. When hidden in or using .htaccess, the CSRF is executed without the user's knowledge.

Tuesday, October 23, 2007

Setting up Apache-PHP on windows.

Step 1 : Downloading required files.

apache server binaries : httpd.apache.org
php binaries : www.php.net

Step 2 : Install apache server.
Installing apache server is pretty much simple, and same as any other installation.
Just enter a network domain name and server name and some email id (someone@microsoft.com).
Then choose a installation directory : for reference i am using "C:\".
Note that a directory called apache2 will be created under C:\ .
So "C:\apache2\" is our directory.
Verify your installation by taking your browser and visiting http://127.0.0.1 or http://localhost.
You will see a page that confirms your apache installation.

Step 3 : Configuring apache
Now goto "C:\Apache2\conf\".
Open the file "httpd.conf" in any text editor.
Lines beginning with # are comments .. just read them to know how to tweak apache.
Change the DocumentRoot property to the folder which is the root of the site.


## DocumentRoot: The directory out of which you will serve your# documents. By default, all requests are taken from this directory, but# symbolic links and aliases may be used to point to other locations.#DocumentRoot "C:/public_html/"
and after that a few lines under ..
## This should be changed to whatever you set DocumentRoot to.### Possible values for the Options directive are "None", "All",# or any combination of:# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews## Note that "MultiViews" must be named *explicitly* --- "Options All"# doesn't give it to you.## The Options directive is both complicated and important. Please see# http://httpd.apache.org/docs-2.0/mod/core.html#options# for more information.# Options Indexes FollowSymLinks## AllowOverride controls what directives may be placed in .htaccess files.# It can be "All", "None", or any combination of the keywords:# Options FileInfo AuthConfig Limit# AllowOverride None## Controls who can get stuff from this server.# Order allow,deny Allow from all
So C:\public_html\ is the server root. ie http://localhost/ = C:\public_html.
After this is done test the configuration by executing (command line):
C:\Apache2\bin>apache -t
If the syntax is right you will get a "Syntax OK" message.

Step 4 : Installing php
To install php, just extract or copy the "PHP" folder to C:\Apache2\ so that C:\Apache2\PHP is created.

Step 5 : configuring PHP
Copy the "php.ini-recommended" file from C:\apache2\php\ to C:\apache2\
Rename it to "php.ini".

Add 2 lines to the end of the file httpd.conf:

LoadModule php5_module C:/apache2/php/php5apache2.dll AddType application/x-httpd-php .php

Test the php installation by making a php file.

test.php


Access the test.php (http://localhost/test.php) from your browser. If you see the source code, installation has failed.
If you see the php info file . PHP installation was successful.
Test the apache server configuration (mentioned above) to find out the error.

Saturday, October 20, 2007

Why 'Pragma: no-cache' appear on the html page while it shouldn't?

Perl allows for using compiler directives called pragmas. These pragmas are processed before any other commands or directives. Basically, you can think of pragmas as special instructions to the interpreter that are run before anything else. One such pragma is the no-cache instruction.

Usually, programmers use the no-cache pragma when a script or a program automatically generates the page. In such cases, it's necessary to always use the page generated by the program at that time, instead of a previously generated page. For example, if you go to Yahoo! News and then revisit it an hour later, you'd like the updated news and not the stale news from an hour ago. In order to tell the browser not to keep any old copies of the page in cache, you send it this no-cache pragma.

The form you are trying to fill out, however, most likely has an error in the program or script that handles the form submission. There are usually two kinds of instructions you can send to the browser from your script. The first kind are private messages (headers) to the browser, telling it how to behave or control various other aspects of the browser functionality (e.g., you might want to use the no-cache directive, set or delete cookies, etc.). The second kind of instructions are the actual HTML code. These are preceded by the Content-type: text/html statement (followed by two newlines to indicate the end of the headers) which prepares the browser and tells it that whatever is coming next is all HTML and it should use whatever rules it has for displaying that code. The problem that likely occured in this instance is that instead of passing the no-cache pragma directly to the browser as the very first instruction, the programmer has accidentally preceded it with a Content-type: text/html statement.

So instead of the browser interpreting the directive correctly as a pragma, it now thinks that that line is just another line of HTML code (in this case, plain text) and pops it out directly to the browser window. The only thing you can do in this case is contact the webmaster and inform him/her of the problem and wait for them to fix it.

Wednesday, October 17, 2007

MS-DOS Basics

The Command Prompt

When you first turn on your computer, you will see some cryptic information flash by. MS-DOS displays this information to let you know how it is configuring your computer. You can ignore it for now. When the information stops scrolling past, you'll see the following:

C:\>

This is called the command prompt or DOS prompt. The flashing underscore next to the command prompt is called the cursor. The cursor shows where the command you type will appear.

If your command prompt looks like the sample command prompt above, skip to the following section, "Typing a Command."

If your command prompt does not look like the example, type the following at the command prompt, and then press ENTER:

cd \

Note that the slash leans backward, not forward. You will learn more about the cd command later in the tutorial. If your command prompt still doesn't look like the example, type the following at the command prompt, and then press ENTER:

prompt $p$g

Your command prompt should now look like the example.

Typing a Command

This section explains how to type a command at the command prompt and demonstrates the "Bad command or file name" message.

To type a command at the command prompt
Type the following at the command prompt (you can type the command in either uppercase or lowercase letters):
nul

If you make a typing mistake, press the BACKSPACE key to erase the mistake, and then try again.

Press ENTER.
You must press ENTER after every command you type.

The following message appears:

Bad command or file name

The "Bad command or file name" message appears when you type something that MS-DOS does not recognize. Because nul is not a valid MS-DOS command, MS-DOS displays the "Bad command or file name" message.

Now, type the following command at the command prompt:
ver

The following message appears on your screen:

MS-DOS version 6.22

The ver command displays the version number of MS-DOS.

Continue to the next section, where you will use the dir command to view the contents of a directory.

Viewing the Contents of a Directory

In this section, you will view the contents of a directory by using the dir command. The dir command stands for "directory."

To view the contents of a directory
Type the following at the command prompt:
dir

A list similar to the following appears:

Volume in drive C is MS-DOS_6.22
Volume Serial Number is lE49-15E2
Directory of C:\

WINDOWS < DIR > 09-08-92 10:27p
TEMP < DIR > 05-15-92 12:09p
CONFIG SYS 278 09-23-92 10:50a
COMMAND COM 53014 09-18-92 6:00a
WINA20 386 9349 11-11-91 5:00a
DOS < DIR > 09-02-92 4:23p
AUTOEXEC BAT 290 09-23-92 10:54a

7 file(s) 62931 bytes
8732672 bytes free
This is called a directory list. A directory list is a list of all the files and subdirectories that a directory contains. In this case, you see all the files and directories in the main or root directory of your drive. All the files and directories on your drive are stored in the root directory.

Changing Directories

Look at the list on your screen. All the names that have < DIR > beside them are directories. You can see a list of the files in another directory by changing to that directory, and then using the dir command again. In this case, you will change to the DOS directory.

Before you begin this section, make sure you have a directory named DOS by carrying out the following procedure.

To make sure you have a directory named DOS
1. Look through the directory list on your screen for a line that looks similar to the following:

DOS < DIR > 09-02-92 4:23p

2. If you see a line like this, you have a directory named DOS. Skip to the next procedure, "To change from the root directory to the DOS directory."

If you do not see a line in the directory list indicating that you have a directory named DOS, type the following at the command prompt:

dir /s memmaker.exe

You will see a message that includes a line such as the following:

Directory of C:\DIRNAME

If the name that appears in place of DIRNAME is DOS, you have a DOS directory. Skip to the next procedure.

If the name that appears in place of DIRNAME is not DOS, substitute the name that appears for DOS throughout this tutorial. For example, if the name that appears in place of DIRNAME is MSDOS, type msdos whenever you are instructed to type dos.

To change from the root directory to the DOS directory
To change directories, you will use the cd command. The cd command stands for "change directory."

Type the following at the command prompt:
cd dos

The command prompt changes. It should now look like the following:

C:\DOS>

The command prompt shows which directory you are in. In this case, you know you successfully changed to the DOS directory because the command prompt displays the directory's name. Now the current directory is DOS.

Next, you will use the dir command to view a list of the files in the DOS directory.

To view a list of the files in the DOS directory
Type the following at the command prompt:
dir

A list of the files in the DOS directory appears, but scrolls by too quickly to read. You can modify the dir command so that it displays only one screen of information at a time.

To view the contents of a directory one screen at a time
Type the following at the command prompt:
dir /p

One screen of information appears. At the bottom of the screen, you will see the following message:

Press any key to continue . . .

2. To view the next screen of information, press any key on your keyboard. Repeat this step until the command prompt appears at the bottom of your screen.

When you typed the dir command this time, you included the /p switch after the command. A switch modifies the way MS-DOS carries out a command. Generally, a switch consists of a forward slash (/) that is followed by one or more letters or numbers. When you used the /p switch with the dir command, you specified that MS-DOS should pause after it displays each screen of directory list information. The p actually stands for "page"

Another helpful switch you can use with the dir command is the /w switch. The /w switch indicates that MS-DOS should show a wide version of the directory list.

To view the contents of a directory in wide format
Type the following at the command prompt:
dir /w

The directory list appears, with the filenames listed in wide format. Note that only filenames are listed. No information about the files' size or date and time of creation appears.

If the directory contains more files than will fit on one screen, you can combine the /p and /w switches as follows:
dir /w /p

Large DOS programs ... breaking the 640K limit ?

>
> I am fairly new to DOS OS C programming. DOS OS appears to possess a 640K
> memory limit.
>

MicroSoft Disk Operating System (MSDOS) was developed
to work with the popular microprocessors of the time,
primarily Intel's 8088. (and to a lesser degree their 8086)
Early PCs were limited to the 1MB of memory which
8088 could address. From that 1MB, the highest 384K was
reserved for ROM, leaving 640K to be shared by applications
and the OS scratchpad.


Check out the brief explanations at:
http://www.tafe.sa.edu.au/institutes/torrens-
valley/programs/eit/pcsupport/xmsmem.htm

or the more detailed ones at;
http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?protected+mode
http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?extended+memory
http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=EMS

Pay special attention to the explanation of paging at:
http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?paging
it mostly talks about paging in the traditional sense
-- i.e., swapping blocks of memory into RAM for execution
or manipulation ... then back to disk (secondary storage)
to free up the "page" of memory for reuse.

The EMS, XMS, etc schemes are variants on the theme.
Instead of swapping pages to/from disk, they use special
hardware to swap pages from RAM which is not directly
accessible by the CPU.

Another hyperlinked set of explanations is at:
http://www.electric-words.com/dict/e/ems.html


All of these measures, amount to a convoluted, complicated, SLOW
alternative to the more obvious solution: building a CPU with a
larger direct-addressing capacity. (more address lines)
That's exactly what Intel did.
But other vendors were able to devise the EMS/XMS/etc workarounds
quickly -- while developing the next generation of processors
took Intel a bit longer.

How was the very first C language compiler made (rather compiled) ?

Dennis Ritchie (one of the creators of C) has a very informative article about the history of the C language. The origins of the language lie with BCPL, invented in the 60's by Martin Richards with system programming in mind. Ken Thompson then wrote a language B, first using a different compiler, then writing a new compiler for B in B itself.

C grew out of attempts to improve B. In Ritchie's words, "In 1971 I began to extend the B language by adding a character type and also rewrote its compiler to generate PDP-11 machine instructions instead of threaded code. Thus the transition from B to C was contemporaneous with the creation of a compiler capable of producing programs fast and small enough to compete with assembly language." Later on, Richie had extended the language enough to consider it distinct from B and deserving of a new name. The C language was born.

So which came first, the compiler or the language? As Ritchie puts it, the transition was contemporaneous. The evolution of C from B came from cycles of creating a compiler written in the language, modifying the language slightly, and writing new compilers.

By the time C was complete in 1973, the compiler was definitely also written in C, and was the language used not only for the compiler but was also powerful enough to rewrite the kernel for Unix on the PDP-11.

Tuesday, October 16, 2007

Increasing the karma ratings on Orkut

Continued ...
"http://www.orkut.com/setKarma?cat=0&val=1&gid=FR[friends id here]/[your id here]"
Eg: "http://www.orkut.com/setKarma? cat=0&val=1&gid=FRUS00000000000/US00123456789"

The above illustrates the page you have to make your friend to access to make he/she your fan.

The same can be modified to increase (can decrease also) your cool, sexy and trusty karma ratings. The cat=0 in the URL specifies the fan function.

cat=1 : stands for trusty rating.
cat=2 : stands for cool rating.
cat=3 : stands for sexy rating.

The next GET parameter val=1 has to be modified as :
val = 0: for 0 rating
val = 1: for 1
val = 2: for 2
val = 3: for full rating.

So our final URL for full trusty rating is :
"http://www.orkut.com/setKarma?cat=1&val=3&gid=FR[friends id here]/[your id here]"
Eg: "http://www.orkut.com/setKarma? cat=1&val=3&gid=FRUS00000000000/US00123456789"

for Cool rating :
"http://www.orkut.com/setKarma?cat=2&val=3&gid=FR[friends id here]/[your id here]"
Eg: "http://www.orkut.com/setKarma? cat=2&val=3&gid=FRUS00000000000/US00123456789"

for Sexy rating :
"http://www.orkut.com/setKarma?cat=3&val=3&gid=FR[friends id here]/[your id here]"
Eg: "http://www.orkut.com/setKarma? cat=3&val=3&gid=FRUS00000000000/US00123456789"

When you are giving all these three in the same page, the 3 get requests must not be sent to the server together. Leave a time delay of about 100ms between each of the GET requests.
You can accomplish this in javascript by the following this template:


function fn(index){ var links=new Array("Link 1 for cool/trusty/sexy/fan", "etc fill in"); var i= new Image(); i.src = links[index]; if(index != Count) { window.setTimeout("fn("+(index+1)+")",100); } else window.location = "Somewhere"; //Redirect to a nice page.}

Hope this works for you ....

XPM File format Making codes

Intro
XPM or XPixMap is a bitmap format in unix based systems. It is a relatively easy format to understand, XPM files have a format similar to a C source code of a string array.



/* XPM */static char * var name[] = {"","","" //etc....};

The first line is XPM in standard C comments. Second is an array declaration with a valid token as variable name.
The array index 0 [0] : contains the following %d %d %d %d [%d %d] [%d]
which are :
Width,Height,Number of colors, Characters Per Pixel, optional X & Y Hotspots, optional XPM Extension.
The array indexes 1-> number of colors indicates the color section.
The strings in these section take the following format :
%s %s %s
The first contains the characters that represent the pixels. The number of characters used to represent a pixel is given by Characters Per Pixel field in array[0].
The second string represents control characters that defines what the following field is about.
switch(control character)
{
case 'm' : Mono color
case 's' : Symbolic name
case 'c' : Color value
case 'g4': 4 Level Gray Scale
case 'g' : Grayscale
}

the third string is then
a color name eg: black
a # followed by RGB Hex
a % followed by HSV Hex
a symbolic name
a "None" indicating a transparent.

The rest of the section contains the actual pixels. With each (Character Per Pixel) representing a pixel on the screen. Each string is width pixels long and there will be height number of strings.

There might be an optional XPM Extension following the pixels.

Examples:
/* XPM */static char * plaid[] ={/* plaid pixmap *//* width height ncolors chars_per_pixel */"22 22 4 2 0 0 XPMEXT",/* colors */" c red m white s light_color","Y c green m black s ines_in_mix","+ c yellow m white s lines_in_dark ","x m black s dark_color ",/* pixels */"x x x x x x x x x x x x + x x x x x "," x x x x x x x x x x x x x x x x ","x x x x x x x x x x x x + x x x x x "," x x x x x x x x x x x x x x x x ","x x x x x x x x x x x x + x x x x x ","Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ","x x x x x x x x x x x x + x x x x x "," x x x x x x x x x x x x x x x x ","x x x x x x x x x x x x + x x x x x "," x x x x x x x x x x x x x x x x ","x x x x x x x x x x x x + x x x x x "," x x x x Y x x x "," x x x Y x x "," x x x x Y x x x "," x x x Y x x "," x x x x Y x x x ","x x x x x x x x x x x x x x x x x x x x x x "," x x x x Y x x x "," x x x Y x x "," x x x x Y x x x "," x x x Y x x "," x x x x Y x x x ","XPMEXT ext1 data1","XPMEXT ext2","data2_1","data2_2","XPMEXT ext3","data3","XPMEXT","data4","XPMENDEXT"};

Another one :

/* XPM */static char * example_xpm[] = {"24 20 3 1"," c None",". c #0000FF","+ c #FF0000"," "," .. "," .... "," ......++++++++ "," .........+++++++ "," ..........+++++++ "," ............++++++ "," .............++++++ "," ..............++++ "," +.............+++ "," ++.............++ "," +++.............+ "," +++++............. "," ++++++.............. "," ++++++++............ "," +++++++++........... "," +++++++++......... "," ++++++++++....... "," ++++++++++..... "," +++++++++ ... "};

Monday, October 15, 2007

Python Basics Coding Part4

Classes and OOP
Python supports OOP and classes to an extent, but is not a full OOP language. A class is a collection of variables and functions working with these variables. Classes are defined somewhat similarly to Java, but differences include self being used in place of this and constructors being named __init__ instead of classname. Also note that self must be used every time a class-wide variable is referenced and must be the first argument in each function's argument list, including the constructor. In addition, functions and constructors cannot be overloaded, but as discussed above, do support default arguments instead. Like functions, a class must be defined before it can be instantiated. In Python, all class members are public.
Initializing vars: Only constant initializers for class variables are allowed (n = 1). To initialize variables with non-constant values, you must use the constructor. You cannot declare unitialized variables.
Encapsulation: Python does not really support encapsulation because it does not support data hiding through private and protected members. However some pseudo-encapsulation can be done. If an identifier begins with a double underline, i.e. __a, then it can be referred to within the class itself as self.__a, but outside of the class, it is named instance._classname__a. Therefore, while it can prevent accidents, this pseudo-encapsulation cannot really protect data from hostile code.
Inheritence: Python allows classes to be extended (see right) by adding the base class name in parenthesis after the derived class name: class Derived(Base):. The child class takes all the variables and functions from the parent class and can extend that class by adding additional variables and adding or overriding functions. If class B extends class A, then A or B can be used anywhere an A is expected, but only B can be used where a B is expected because it contains additional information/methods not found in A. In addition, Python supports multiple inheritence: class Derived(Base1, Base2, Base3):
Abstract classes: Abstract classes and interfaces are not supported in Python. In Python, there is no difference between an abstract class and a concrete class. Abstract classes create a template for other classes to extend and use. Instances can not be created of abstract classes but they are very useful when working with several objects that share many characteristics. For instance, when creating a database of people, one could define the abstract class "Person", which would contain basic attributes and functions common to all people in the database. Then child classes such as "SinglePerson", "MarriedCouple", or "Athlete" could be created by extending "Person" and adding appropriate variables and functions. The database could then be told to expect every entry to be an object of type "Person" and thus any of the child classes would be a valid entry. In Python, you could create a class Person and extend it with the child classes listed above, but you could not prevent someone from instantiating the Person class.
Parent: The parent keyword is not supported by Python, but you can call methods from the base classes directly: BaseClass.method_name(self, arguments) (see right).
Constructors: Constructors are fuctions that are automatically called when you create a new instance of a class. They can be used for initialization purposes. A function is a constructor when it has the name __init__. When extending classes, if a new constructor is not defined, the constructor from the parent class is used (see right). When an object of type RectWithPerimeter is created, the constructor from Rectangle is called. If however, I were to add a function in RectWithPerimeter with the name __init__ , then that function would be used as its constructor.
Comparing Objects: Objects can be compared using the == and != operators. Two objects are equal only if they are the same instance of the same object. Even if two objects have the same attributes and values and are instances of the same class, they are not equal if the are separate instances.
Example Class:
class Rectangle:
#Optionally define variable width
width = 0
#Constructor with default arguments
def __init__(self, width = 0, height = 0):
self.width = width
self.height = height
#functions
def setWidth(self, width):
self.width = width
def setHeight(self, height):
self.height = height
def getArea(self):
return self.width * self.height

arect = Rectangle() #create a new Rectangle with dimensions 0x0.
arect.setWidth(4)
arect.setHeight(6)
print arect.getArea()
-> 24
rect2 = Rectangle(7,3) #new Rectangle with dimensions 7x3.

Extended Class:
class RectWithPerimeter(Rectangle):
#add new functions
def getPerimeter(self):
return 2*self.height + 2*self.width
def setDims(self, width, height):
#call base class methods from Rectangle
Rectangle.setWidth(self, width)
Rectangle.setHeight(self, height)
arect = RectWithPerimeter(6,5) #Uses the constructor from Rectangle because no new constructor is provided to override it.
print arect.getArea() #Uses the getArea function from Rectangle and prints 30.
print arect.getPerimeter() #Uses getPerimeter from RectWithPerimeter and prints 22.
arect.setDims(4,9) #Use setDims to change the dimensions.



File I/O
Opening Files: file open(string filename, string mode):
open can be used to open files for reading, writing, and appending. It binds a named file object to a stream that can then be used to read/write data. Possible modes include:
'r': Open for reading.
'w': Open for writing. Any existing data will be overwritten.
'a': Open for writing. New data will be appended to existing data.
'b': Use this flag when working with binary files (e.g. 'rb').
Checking Files: Python supports several methods of checking if a file exists and checking its properties:
bool os.access(string path, int mode): returns TRUE if the filename exists and matches the mode query. The mode query can be any of the following constants:
os.F_OK: test the existence of path
os.R_OK: tests if path exists and is readable
os.W_OK: tests if path exists and is writable
os.X_OK: tests if path exists and is executable
File Operations: Python also supports file operations such as renaming and deleting files. And of course any shell command can be excecuted via os.system.
bool os.system(string command): attempts to execute the supplied shell command and returns true if the command executed.
bool chmod(string path, int mode): Changes the permissions of path to mode. Mode should be defined as an octal (i.e. 0644 or 0777).
list listdir(string path): Returns a list containing all the files in the current directory. The special entries "." and ".." are not included.
bool mkdir(string pathname [, int mode]): Makes a directory pathname with permissions mode (e.g. mkdir('new_dir', 0700);)
bool remove(String filename): Deletes filename
bool rename(string oldname, string newname): Renames a file
bool symlink(string target, string link): Creates a symbolic link to the existing target with name link.
Reading Files: Files can be read by several methods.
string read([int length]): Reads up to a specified number of bytes from the file into a string. It will read until it encounters EOF or the specified length is reached (default is all data).
string readline([int length]): Reads one entire line from a file, or up to length bytes, into a string. Reading stops when length bytes have been read or a newline or EOF is reached. A trailing newline character is kept in the string (but may be absent on the last line of the file).
list readlines([int sizehint]): Reads from a file using readline() until EOF and returns a list containing the lines read. If sizehint is present, whole lines totaling approximately sizehint bytes are read.
EOF: end-of-file is reached when read or readline returns an empty string. while (s != ""):
s = f.readline()
do_something

Writing to files: Files that have been opened for writing with open can be written to by two methods.
void write(string string): Writes the contents of string to the file. Does not append a newline character to the string. Only strings can be written so other datatypes must be converted to strings.
void writelines(list data): Writes a list or array of strings to the file. Newlines will not be added between the elements of the list/array.
Concurrency: File locking is available through the flock method in the fcntl module. Though be warned, flock does not work reliably on all operating systems. Therefore you may want to develop your own semaphores instead. The syntax is: flock(fileDescriptor fd, int operation), where the file descriptor can be obtained by calling the fileno() method of a file object and operation can be LOCK_SH to acquire a shared lock (reader), LOCK_EX to acquire an exclusive lock (writer), LOCK_UN to release a lock, or LOCK_NB if you don't want flock to block while locking.
Serializing Objects: An object can be serialized with methods in the pickle module. This will create a string representation of the object that can be stored in a file and later reconstructed into the object. In this way, ints, floats, or any object can be written to a file in addition to strings. If the object is an instance of a class, that class must be defined or imported in the python program that unserializes the object (i.e. if you have an object of type A in a.py, serialize it, write it to a file, and on b.py you read it back in from the file, then class A must be defined in b.py or included via import a to unserialize the object. An easy solution is to put the definition of class A in a file to be imported in both a.py and b.py). Arrays can be serialized as well. If you have an object x, you can serialize it and save it to a file:
f = open("file.dat","wb")
pickle.dump(x,f)
f.close()
It can then be unserialized and restored by:
f = open("file.dat","rb")
y = pickle.load(f)
f.close()

Sockets: To use sockets in Python, import socket . A server socket can then be opened with:
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mySocket.bind(('', 2727))
mySocket.listen(1)
The first line creates a socket object. The second line binds the socket to an address. In this case, '' is a symbolic name meaning localhost and we select port 2727. The address parameter should be in the form of a tuple as shown above. Finally, the third line listens for connections made to a socket. The argument is the maximum number of queued connections. Now that a server socket is open, we need to be able to accept data:
conn, addr = mySocket.accept()
print 'Connected with ', addr
while True:
data = conn.recv(1024)
if not data: break
print data
conn.send("Data received")
conn.close()
The accept() method accepts a connection and returns a pair (conn, address), where conn is a new socket object usable to send and receive data on the connection and address is the address bound to the socket on the other end (client side) of the connection. We then enter a loop and receive data from the client using the recv(bufsize) method. recv returns a string of the data received with a maximum amount of data specified by bufsize. If data is false, we break out of the loop. Otherwise we print the data and use send(string) to send a message back to the client.
Now our server is complete, but we need a client-side socket:
cSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cSocket.connect(("polaris.astro.ufl.edu","2727"))
The first line of course creates a socket object. The second line is similar to bind except that it connects to an existing server socket specified by the address. Note that ("localhost", 2727) would be another valid address. Now we need to send and receive data:
cSocket.send("Hello world!")
data = cSocket.recv(1024)
cSocket.close()
print data
send and recv work just the same as they do in the server socket. We send data to the server ("Hello world!"), receive the response ("Data received"), close the connection (which causes data to become false on the server program and terminate the loop), and print out the data.

Examples:
file = open("data/teams.txt","rb")
team = "nonempty"
while (team != ""):
team = file.readline()
if (team != ""): print team[:-1] #get rid of extra newline character
file.close()

file = open("data/teams.txt","rb")
team = file.readlines()
file.close()

list = ["Florida","Clemson","Duke"]
file = open("data/teams.txt","wb")
for j in list: file.write(j+"\n")
file.close()

import pickle, fcntl
player = Player("J.J. Redick", "Duke", 4)
file = open("data/players.txt", "a")
fcntl.flock(file.fileno(), fcntl.LOCK_EX)
pickle.dump(player, file)
fcntl.flock(file.fileno(), fcntl.LOCK_UN)
file.close()



Images in Python
FITS files: Python supports FITS files via the module pyfits. Once this module has been imported, you can read and write FITS files. FITS files are read and stored in and HDUList object, which has two components: header and data. The header is a list-like object and data is usually an array. To read in a FITS file, use
HDUList open(string): open a filename

info(): print a summary of the objects in the file.
Note that FITS files can have what are called multiple extensions-- multiple images and/or headers in a single file. info will list all objects in the file, their name, type, cards (number of entries in the header), dimensions, and format (i.e., Int16 or Float32).

Now that you have a FITS object, you can access its header and data. Since each object within a file can have its own header and data, you would access the primary header as x[0].header and the data as x[0].data.

Headers:You can print the entire header by calling the x[0].header.ascardlist() method. You can access individual elements in the header directly by keyword (x[0].header['NAXIS1']) or by index (x[0].header[3]). If you know that a keyword is already present in the header, you can update its value using the same notation:
x[0].header['NAXIS1'] = 265
But if the keyword might not be present and you want to add it if it isn't, use the update() method instead:
x[0].header.update('NAXIS1',265)

Data: Since the data is an array, you can use any numarray methods on it. The data can thus be accessed using slice notation as well.
print shape(x[0].data)
print x[0].data[0:5,0:5]

Writing FITS Files: Once the data and header have been modified, you can write them back to a new FITS file using writeto(string). This writes to a new file and closes that file, but further operations can still be done on the data in memory. Note that if a file exists with the specified name, it will NOT be overwritten and an error will be raised. To close the input file, use x.close(). Examples:
x = pyfits.open("NGC3031.fits")
x.info()

-> Filename: NGC3031.fits
No. Name Type Cards Dimensions Format
0 PRIMARY PrimaryHDU 6 (530, 530) UInt8
print x[0].header.ascardlist()

-> SIMPLE = T
BITPIX = 8
NAXIS = 2
NAXIS1 = 530
NAXIS2 = 530
HISTORY Written by XV 3.10a
print x[0].header['NAXIS1']
-> 530
print x[0].header[3]
-> 530

print x[0].data[3,0:5]
-> [11 11 11 9 9]

x[0].data[3,0:3] = array([0,0,0])
print x[0].data[3,0:5]
-> [0 0 0 9 9]

x[0].data += 5 #using numarray to operate on entire array
print x[0].data[3,0:5]
-> [ 5 5 5 14 14]

x.writeto("new_file.fits")
x.close()



Guess My Number
Here is the code for Guess My Number in Python, a program that generates a random number between 1 and 100 and asks the user to guess it. It will tell the user if the number is higher or lower after each guess and keep track of the number of guesses.
#!/usr/bin/python
import random, math
random.seed()
x = math.floor(random.random()*100)+1
z = 0
b = 0
while x != z:
b=b+1
z = input("Guess My Number: ")
if z < x: print("Higher!")
if z > x: print("Lower!")
print("Correct! " + str(b) + " tries.")

Python Basics Coding Part3

Conditionals
if:
if expr: statement

if-else:
if expr: statement1
else: statement2

if-elseif: if expr: statement1
elif expr: statement2
else: statement3

Multiple elifs can be included in the same if statement. There is no switch or case statement so multiple elifs must be used instead. While parenthesis are not required around the expression, they can be used.
Examples:
if a > b: print "a is greater than b";

if (a > b):
print "a is greater than b"
print "blocks are defined by indentation"
elif (a < b):
print "a is less than b"
else:
print "a is equal to b"




Loops
for: for var in range(start [,stop [,inc]]): statements
Not unsimilar to IDL and basic, except for the range statement. var can be any variable. The range statement can take start and stop values, and an increment.
while: while expr: statements
Executes statements while the expression is true.
continue: continue
Skips the rest of the body of the loop for the current iteration and continue execution at the beginning of the next iteration.
break: break
Ends the execution of the current loop.
else: else
for and while loops can both have else clauses, which are executed after the loop terminates normally by falsifying the conditional, but else clauses are not executed when a loop terminates via a break statement.
foreach: for x in array: statements
Loops over the array given by array. On each iteration, the value of the current element is assigned to x and the internal array pointer is advanced by one.
Examples:
for j in range(10): print "Value number " + str(j) +" is "+value[j]

for j in range(10,0,-2):
x = x + j
print x

while (b < a):
print "b is less than a."
b=b+1

for j in range(0,10):
while(k < j):
print "j = " + str(j) + " k = "+str(k)
if (j == 1): break
k=k+1
print "j equals k or j equals 1"

a = ["abc","def","ghi"]
for x in a:
print x



Functions
Definition: Functions in Python are defined with the following syntax:
def funct(arg_11, arg_2, ..., arg_n):
print "This is a function."
return value
Any Python code, including other function and class definitions, may appear inside a function. Functions may also be defined within a conditional, but in that case the function's definition must be processed prior to its being called. Python does not support function overloading but does support variable number of arguments, default arguments, and keyword arguments. Return types are not specified by functions.
Arguments: Function arguments are passed by value so that if you change the value of the argument within the function, it does not get changed outside of the function. If you want the function to be able to modify non-local variables, you must declare them as global in the first line of the function. Note that if you declare any variables as global, that name cannot be reused in the argument list, i.e. this would cause an error:
function double(x):
global x
x = x*2
return
double(x)
Instead this could be done
function double(n):
n = n * 2
return n
x = double(x)
Or
function doubleX():
global x
x = x * 2
return
doubleX()

Default Arguments: A function may define default values for arguments. The default must be a constant expression or array and any defaults should be on the right side of any non-default arguments.
def square(x = 5):
return x*x
If this function is called with square(), it will return 25. Otherwise, if it is called with square(n) , it will return n^2.
Variable length argument lists: Variable length arguments are supported by being wrapped up in a tuple. Before the variable number of arguments, zero or more normal arguments may occur:
def var_args(arg1, arg2, *args):

Keyword arguments: Functions can also be called using arguments of the form keyword = value:
def player(name, number, team="Florida"):
print(name + "wears number " + str(number) + "for " + team)
player("Matt Walsh", 44)
player(number = 44, name = "David Lee")
player("Anthony Roberson", number = 1)
player(name = "J.J. Redick", number = 4, team = "Duke")

Return: Values are returned from the function with the return command: return var. You can not return multiple values, but that can be achieved by returning an array or object. Return immediately ends execution of the function and passes control back to the line from which it was called.
Variable Functions: Python supports the concept of variable functions. That means that if a variable can point to a function instead of a value. Objects within a method can be called similarly.
def test():
print 'This is a test.'
var = test
var() #this calles test()
var = circle.setRadius
var(3) #this calls circle.setRadius(3)

Python Basics Codings Part2

Arrays
Arrays in basic Python are actually lists that can contain mixed datatypes. However, the numarray module contains support for true arrays, including multi-dimensional arrays, as well as IDL-style array operations and the where function. To use arrays, you must import numarray or from numarray import *. Unfortunately, numarray generally only suports numeric arrays. Lists must be used for strings or objects. By importing numarray.strings and numarray.objects, you can convert string and object lists to arrays and use some of the numarray features, but only numeric lists are fully supported by numarray.
Creating lists: A list can be created by defining it with []. A numbered list can also be created with the range function which takes start and stop values and an increment.
list = [2, 4, 7, 9]
list2 = [3, "test", True, 7.4]
a = range(5) #a = [0,1,2,3,4]
a = range(10,0,-2) #a = [10,8,6,4,2]
An empty list can be initialized with [] and then the append command can be used to append data to the end of the list:
a=[]
a.append("test")
a.append(5)
print a
-> ['test', 5]
Finally, if you want a list to have a predetermined size, you can create a list and fill it with None's:
a=[None]*length
a[5] = "Fifth"
a[3] = 6
print len(a)
-> 10
print a
-> [None, None, None, 6, None, 'Fifth', None, None, None, None]

Removing from lists: The pop method can be used to remove any item from the list:
a.pop(5)
print a
-> [None, None, None, 6, None, None, None, None, None]

Creating arrays: An array can be defined by one of four procedures: zeros, ones, arange, or array. zeros creates an array of a specified size containing all zeros:
a = zeros(5) #a=[0 0 0 0 0]
ones similarly creates an array of a certain size containing all ones:
a = ones(5) #a=[1 1 1 1 1]
arange works exactly the same as range, but produces an array instead of a list:
a = arange(10,0,-2) #a = [10 8 6 4 2] And finally, array can be used to convert a list to an array. For instance, when reading from a file, you can create an empty list and take advantage of the append command and lists not having a fixed size. Then once the data is all in the list, you can convert it to an array:
a = [1, 3, 9] #create a list and append it
a.append(3)
a.append(5)
print a
-> [1, 3, 9, 3, 5]
a = array(a)
print a
-> [1 3 9 3 5]

Multi-dimensional lists: Because Python arrays are actually lists, you are allowed to have jagged arrays. Multi-dimensional lists are just lists of lists:
a=[[0,1,2],[3,4,5]]
print a[1]
-> [3, 4, 5]
s = ["Lee", "Walsh", "Roberson"]
s2 = ["Williams", "Redick", "Ewing", "Dockery"]
s3 = [s, s2]
print s3[1][2]
-> Ewing

Multi-dimensional arrays: However, numarray does support true multi-dimensinoal arrays. These can be created through one of five methods: zeros, ones, array, arange, and reshape. zeros and ones work the same way as single dimensions except that they take a tuple of dimensions (a comma separated list enclosed in parentheses) instead of a single argument:
a = zeros((3,5))
a[1,2] = 8
print a
-> [[0 0 0 0 0]
[0 0 8 0 0]
[0 0 0 0 0]]
b = ones((2,3,4)) #create a 2x3x4 array containing all ones.

array works the same way as for 1-d arrays: you can create a list and then convert it to an array. Note with multi-dimensional arrays though, trying to use array to convered a jagged list into an array will cause an error. Lists must be rectangular to be able to be converted to arrays.
s = ["Lee", "Walsh", "Roberson", "Brewer"]
s2 = ["Williams", "Redick", "Ewing", "Dockery"]
s3 = [s, s2]
s4 = array(s3)
print s4 + "test"
-> [['Leetest', 'Walshtest', 'Robersontest', 'Brewertest'],
['Williamstest', 'Redicktest', 'Ewingtest', 'Dockerytest']]
print s4[:,1:3]
-> [['Walsh', 'Roberson'],
['Redick', 'Ewing']]
arange also works the same as with 1-d arrays except you need to pass the shape parameter:
a = arange(25, shape=(5,5)),br> And finally, reshape can be used to convert a 1-d array into a multi-dimensional array. To create a 5x5 array with the elements numbered from 0 to 24, you could use:
b = arange(25)
b = reshape(b,5,5)

Array Dimensions and Subscripts: When creating a multi-dimensional array, the format is ([[depth,] height,] width). Therefore, when accessing array elements in a two dimensional array, the row is listed first, then the column. When accessing an element of a two-dimensional list, the following notation must be used: list[i][j]. However, two dimensional arrays can also use the notation: array[i,j]. In fact, this is the preferred notation of the two for arrays because you cannot use wildcards in the first dimension of the array[i][j] notation (i.e., array[1:3][4] would cause an error whereas array[1:3,4] is valid).

Wildcards can be used in array subscripts using the : , which is known as slicing. This is similar to IDL, with one major difference: if a=[0 1 2 3 4 5], in IDL a[1:4] = [1 2 3 4], but in Python, a[1:4] = [1 2 3]. In Python, when slicing array[i:j], it returns an array containing elements from i to j-1. Just like with strings, indices of arrays can be negative, in which case they count from the right instead of the left, i.e. a[-4:-1] = [2 3 4]. A : can also specify the rest of the elements or up to element, or all elements and arrays or lists can be used to subscript other arrays:
print a[:3] #[0 1 2]
print a[4:] #[4 5]
print a[:] #[0 1 2 3 4 5]
print a[[1,3,4]] #[1 3 4]
Note that slicing in python does not create a new array but just a pointer to the original array. b=a[0:10] followed by b[0] = 5 also changes a[0] to 5. To avoid this, use b = copy(a[0:10])
Array Operators:
Concatenation:

Lists: a + b
For Lists, the + operator appends the list on the right (b) to the list on the left.
a = ["Roberson", "Walsh"]
b = ["Lee", "Humphrey"]
-> a+b = ["Roberson", "Walsh", "Lee", "Humphrey"]

Arrays: concatenate((a,b)[,axis])
For arrays, use the numarry function concatenate. It also allows you to specify the axis when concatenating multi-dimensional arrays.
b = arange(5)
print concatenate((b, arange(6)))
-> [0 1 2 3 4 0 1 2 3 4 5]
b=reshape(b,5,1)
print concatenate((b,a),axis=1)
-> [[0 0 0 0]
[1 0 0 0]
[2 0 8 0]
[3 0 0 0]
[4 0 0 0]]

Equality: a == b and Inequality: a != b
For lists, these work the same as for scalars, meaning they can be used in if statments. For arrays, they return an array containing true or false for each array element.

Array Functions: All functions but len are for arrays only
len: returns the length of a list/array.
s = ["Lee", "Walsh", "Roberson", "Brewer"]
print len(s) #4

argmax([axis]): returns the index of the largest element in a 1D array or an array of the largest indices along the specified axis for a multi-dimensional array.
a = array([[1,6,9], [2,4,0], [7,4,8]])
print a.argmax(1)
-> [2 1 2]

argmin([axis]): returns the index of the smallest element in a 1D array or an array of the smallest ndices along the specified axis for a multi-dimensional array.
b = array([2,4,7,1,3,-1,5])
print b.argmin()
-> 5

argsort([axis]): returns an array of indices that allow access to the elements of the array in ascending order.
print b.argsort()
-> [5 3 0 4 1 6 2]
print b[b.argsort()]
-> [-1 1 2 3 4 5 7]
print a.argsort(1)
-> [[0 1 2]
[2 0 1]
[1 0 2]]

astype(type): returns a copy of the array converted to the specified type.
a = a.astype('Float64')
b = b.astype('Int32')

copy(): returns a copy of the array.
c = a[:,2].copy()
print c
-> [9 0 8]

diagonal(): for multi-dimensional arrays, returns the diagonal elements of the array, where the row and column indices are equal.
print a.diagonal()
-> [1 4 8]

info(): prints informations about the array which may be useful for debugging.

max(): returns the largest element in the array
print a.max()
-> 9

mean(): returns the average of all elements in an array
print a.mean()
-> 4.55555555556

min(): returns the smallest element in the array
print b.min()
-> -1

nelements(): returns the total number of elements in the array
print a.nelements()
-> 9

product(array [,axis]): returns the product of an array or an array of the products along an axis of an array.
print product(b)
-> -840
print product(a,1)
-> [ 54 0 224]

reshape(array, shape): function that changes the shape of an array. But the new shape must have the same size as the old shape, otherwise an error will occur.
c = reshape(a, 9)
a = reshape(c,(3,3))

resize(shape): shrinks/grows the array to a new shape. Can be called as a method (replaces old array) or a function. The new shape does not have to be the same size as the old shape. If it is smaller, values will be cut off, and it if is bigger, values will repeat.
a.resize(5)
print a
-> [1 6 9 2 4]
a.resize(2,6)
print a
-> [[1 6 9 2 4 0]
[7 4 8 1 6 9]]
c = resize(a,(2,2))
print c
-> [[1 6]
[9 2]]

shape(array): returns the dimensions of the array in a tuple
print shape(a), shape(b), shape(a)[0]*shape(a)[1]
-> (3,3) (7,) 9

sort(array [,axis]): returns an array containing a copy of the data in the array and the elements sorted in increasing order. In the case of a multi-dimensional array, the data will be sorted along one axis and not across the whole array.
print sort(b)
-> [-1 1 2 3 4 5 7]
print sort(a)
-> [[1 6 9]
[0 2 4]
[4 7 8]]
print sort(a,0)
-> [[1 4 0]
[2 4 8]
[7 6 9]]

stddev(): returns the std deviation of all elements in the array
print a.stddev()
-> 3.16666666667

sum(): Can be called as a method or a function. The behavior is identical for 1-d arrays. But for multi-dimensional arrays, calling as a method returns the sum of the entire array, whereas calling it as a function allows you to specify an axis and returns an array with the sums along that axis.
print a.sum()
-> 41
print sum(a)
-> [10 14 17]
print sum(a,1)
-> [16 6 19]

trace(): Returns the sum of the diagonal elements of an array
print a.trace()
-> 13

type(): returns a string containing the type of the array.
print a.type()
-> Int32

tolist(): returns a list containing the same data as the array.
c = a.tolist()

transpose(): Can be called as a method (replaces old array) or a function. Returns the transpose of the array.
a.transpose()
b = transpose(a)

where(expr, 1, 0): Similar to the IDL where function. Returns an array of the same size and dimensions containing 1 if the condition is true and 0 if the condition is false. Any value may be substituted for 1 and 0, but they are the recommended values (i.e. true, false) so that compress can be used to extract values from the array: compress(mask_array, data_array).
c = where(b > 2, 1, 0)
print c
-> [0 1 1 0 1 0 1]
print compress(c,b)
-> [4 7 3 5]
c = where(a > 2, 1, 0)
print c
-> [[0 1 1]
[0 1 0]
[1 1 1]]
print compress(c,a)
-> [6 9 4 7 4 8]

Python Basics Codings Part1

About Python: Python is a high level scripting language with object oriented features.
Syntax
Python programs can be written using any text editor and should have the extension .py. Python programs do not have a required first or last line, but can be given the location of python as their first line: #!/usr/bin/python and become executable. Otherwise, python programs can be run from a command prompt by typing python file.py. There are no braces {} or semicolons ; in python. It is a very high level language. Instead of braces, blocks are identified by having the same indentation.
#!/usr/bin/python
if (x > y):
print("x is greater than y")
x = x -1
else:
print("x is less than or equal to y")
Comments are supported in the same style as Perl:
print("This is a test") #This is a comment.
#This is also a comment. There are no multi-line comments.



Variables and Datatypes
Variables in Python follow the standard nomenclature of an alphanumeric name beginning in a letter or underscore. Variable names are case sensitive. Variables do not need to be declared and their datatypes are inferred from the assignment statement.
Python supports the following data types:
boolean
integer
long
float
string
list
object
None
Example:
bool = True
name = "Craig"
age = 26
pi = 3.14159
print(name + ' is ' + str(age) + ' years old.')
-> Craig is 26 years old.
Variable Scope: Most variables in Python are local in scope to their own function or class. For instance if you define a = 1 within a function, then a will be available within that entire function but will be undefined in the main program that calls the function. Variables defined within the main program are accessible to the main program but not within functions called by the main program.
Global Variables: Global variables, however, can be declared with the global keyword.
a = 1
b = 2
def Sum():
global a, b
b = a + b
Sum()
print(b)
-> 3


Statements and Expressions
Some basic Python statements include:
print: Output strings, integers, or any other datatype.
The assignment statement: Assigns a value to a variable.
input: Allow the user to input numbers or booleans. WARNING: input accepts your input as a command and thus can be unsafe.
raw_input: Allow the user to input strings. If you want a number, you can use the int or float functions to convert from a string.
import: Import a module into Python. Can be used as import math and all functions in math can then be called by math.sin(1.57) or alternatively from math import sin and then the sine function can be called with sin(1.57).
Examples:
print "Hello World"
print('Print works with or without parenthesis')
print("and single or double quotes")
print("Newlines can be escaped like\nthis.")
print("This text will be printed"),
print("on one line becaue of the comma.")
name = raw_input("Enter your name: ")
a = int(raw_input("Enter a number: "))
print(name + "'s number is " + str(a))
a = b = 5
a = a + 4
print a,b
9 5
Python expressions can include:
a = b = 5 #The assignment statement
b += 1 #post-increment
c = "test"
import os,math #Import the os and math modules
from math import * #Imports all functions from the math module



Operators and Maths
Operators:
Arithmatic: +, -, *, /, and % (modulus)
Comparison: ==, !=, <, >, <=, >=
Logical: and, or, not
Exponentiation: **
Execution: os.system('ls -l')
#Requires import os

Maths: Requires import math
Absolute Value: a = abs(-7.5)
Arc sine: x = asin(0.5) #returns in rads
Ceil (round up): print(ceil(4.2))
Cosine: a = cos(x) #x in rads
Degrees: a = degrees(asin(0.5)) #a=30
Exp: y = exp(x) #y=e^x
Floor (round down): a = floor(a+0.5)
Log: x = log(y); #Natural Log
x = log(y,5); #Base-5 log
Log Base 10: x = log10(y)
Max: mx = max(1, 7, 3, 4) #7
mx = max(arr) #max value in array
Min: mn = min(3, 0, -1, x) #min value
Powers: x = pow(y,3) #x=y^3
Radians: a = cos(radians(60)) #a=0.5
Random #: Random number functions require import random
random.seed() #Set the seed based on the system time.
x = random() #Random number in the range [0.0, 1.0)
y = randint(a,b) #Random integer in the range [a, b]

Round: print round(3.793,1; #3.8 - rounded to 1 decimal
a = round(3.793,0) #a=4.0
Sine: a = sin(1.57) #in rads
Square Root: x = sqrt(10) #3.16...
Tangent: print tan(3.14)# #in rads



Strings
Strings can be specified using single quotes or double quotes. Strings do not expand escape sequences unless it is defined as a raw string by placing an r before the first quote: print 'I\'ll be back.'.
print r'The newline \n will not expand'
a = "Gators"
print "The value of a is \t" + a
-> The value of a is Gators
If a string is not defined as raw, escapes such as \n, \r, \t, \\, and \" may be used.
Optional syntax: Strings that start and end with """ may span multiple lines: print """
This is an example of a string in the heredoc syntax.
This text can span multiple lines
"""
String Operators:
Concatenation is done with the + operator.
Converting to numbers is done with the casting operations:
x = 1 + float(10.5) #$x=11.5, float
x = 4 - int("3") #$x=1, int
You can convert to a string with the str casting function:
s = str(3.5)
name = "Lee"
print name + "'s number is " + str(24)

Comparing Strings:
Strings can be compared with the standard operators listed above: ==, !=, <, >, <=, and >=.
String Functions:
s = "Go Gators! Come on Gators!"

Extracting substrings: Strings in Python can be subscripted just like an array: s[4] = 'a'. Like in IDL, indices can be specified with slice notation i.e., two indices separated by a colon. This will return a substring containing characters index1 through index2-1. Indices can also be negative, in which case they count from the right, i.e. -1 is the last character. Thus substrings can be extracted like
x = s[3:9] #x = "Gators"
x = s[:2] #x = "Go"
x = s[19:] #x = "Gators!"
x = s[-7:-2] #x = "Gator"
However, strings are immutable so s[2] = 'a' would cause an error.

int count(sub [,start[,end]]): returns the number of occurances of the substring sub in the string
x = s.count("Gator") #x = 2

boolean endswidth(sub [,start[,end]]): returns true if the string ends with the specified substring and false otherwise:
x = s.endswith("Gators") #x = False

int find(sub [,start[,end]]): returns the numeric position of the first occurance of sub in the string. Returns -1 if sub is not found.
x = s.find("Gator") #x = 3
x = s.find("gator") #x = -1

string join(array): combines elements of the string array into a single string and returns it. The separator between elements is the string providing this method.
a = ['abc','def','ghi']
t = "--"
x = t.join(a) #x = abc--def--ghi

int len(string): returns the length of the string
x = len(s) #x = 26

string lower(): returns a version of a string with all lower case lettters.
print s.lower() #go gators! come on gators!

string replace(old, new [,count]): returns a copy of the string with all occurances of old replaced by new. If the optional count argument is given, only the first count occurances are replaced.
x = s.replace("Gators","Tigers",1) #x = Go Tigers! Come on Gators!

int rfind(sub [,start[,end]]): same as find but returns the numeric position of the last occurance of sub in the string.
x = s.rfind("Gator") #x = 19

array split([sep [,maxsplit]]): splits a single string into a string array using the separator defined. If no separator is defined, whitespace is used. Consecutive whitespace delimiters are then treated as one delimiter. Optionally you can specify the maximum number of splits so that the max size of the array would be maxsplit+1.
a = s.split() #a=['Go', 'Gators!', 'Come', 'on', 'Gators!']

boolean startswidth(sub [,start[,end]]): returns true if the string starts with the specified substring and false otherwise:
x = s.startswith("Go") #x = True

string strip([chars]): returns a copy of the string with leading and trailing characters removed. If chars (a string) is not specified, leading and trailing whitespace is removed.
string upper(): returns a version of a string with all upper case lettters.

Friday, October 12, 2007

amazing Perl "one liner"

I am working on the most mysterious Perl expressions that I can find. In the book "Effective Perl Programming" (old, but useful in this regard), I found these 2 "one liners" to determine which is the lesser between 2 numbers;

first: [ $a => $b ] -> [ $b <= $a ]
second: ( $a, $b )[ $b <= $a ]

The second (that the book defines as "less elegant"!?) was inmediate: create a list of two elements, and index the array with 0 or 1 (depending if b is > or < than a). Fine.

The first instead deeply intrigued me (I was sure that there was a typo, until I executed it and I saw it working). Finally I could deconstruct it as:
[ $a => $b ] # reference to an array with elements $a, $b
# here the => is using the hash "syntactic
# sugar" for ... comma !

[ $a => $b ] -> [ $b <= $a ]
# this part derefs the reference to point to the
# array just created! (with index 0 or 1, as per
# previous solution).

What is my question? assuming that my interpretation above is right (I still am not sure!), how can Perl determines that in the first part, ( i.e. [ $a => $b ]), the "=>" is the comma, and not the relational operator?

Of course, one could say: well, if we took it as the relat operator (as the underwriter did for quite a while and going nowhere with it!), it would not work, because the list so created would contain only one element (0 or 1), while it is being indexed by an index that has 2 values! (aside from the fact that we lose the values of $a and $b).
But this is human (and let's confess it, empyric and opportunistic) reasoning; how Perl does it?

thanks for anyone with the "light",
raul


Posted by raul (raul), 11 August 2005
Of course, I saw the "light" only after the posting. The relational operator for "greater or equal" is (conveniently) ">=" , not =>, so there is no confusion with the "hash comma"!
Aarrgh!
raul


Posted by admin (Graham Ellis), 11 August 2005
Welcome, Raul, and glad you got it sorted. There are just a few times that Perl is overclever in what it can do ... you're not the first (and you won't be the last) to be caught between

=> (a synonym for , )
>= (greater than or equal to, numerically)

History of the World Wide Web

1.4. History of Java
At first glance, it may appear that Java was developed specifically for the world wide web. However, interestingly enough, Java was developed independently of the web, and went through several stages of metamorphosis before reaching its current status of de facto programming language for the world wide web. Below is a brief history of Java since its infancy to its current state.


1.4.1 Oak
According the Java FAQ, [Harold] Bill Joy, currently a vice president at Sun Microsystems, is widely believed to have been the person to conceive of the idea of a programming language that later became Java. In late 1970's, Joy wanted to design a language that combined the best features of MESA and C. In an attempt to re-write the UNIX operating system in 1980's, Joy decided that C++ was inadequate for the job. A better tool was needed to write short and effective programs. It was this desire to invent a better programming tool that swayed Joy, in 1991, in the direction of Sun's "Stealth Project" - as named by Scott McNealy, Sun's president. [Harold]

In January of 1991, Bill Joy, James Gosling, Mike Sheradin, Patrick Naughton (formerly the project leader of Sun's OpenWindows user environment), and several other individuals met in Aspen, Colorado for the first time to discuss the ideas for the Stealth Project. The goal of the Stealth Project was to do research in the area of application of computers in the consumer electronics market. The vision of the project was to develop "smart" consumer electronic devices that could all be centrally controlled and programmed from a handheld-remote-control-like device. According to Gosling, "the goal was ... to build a system that would let us do a large, distributed, heterogeneous network of consumer electronic devices all talking to each other." With this goal in mind, the stealth group began work. [O'Connell]

Members of the Stealth Project, which later became known as the Green Project, divided the tasks amongst themselves. Mike Sheradin was to focus on business development, Patrick Naughton was to begin work on the graphics system, and James Gosling was to identify the proper programming language for the project. Gosling who had joined Sun in 1984, had previously developed the commercially unsuccessful NeWS windowing system as well as GOSMACS - a C language implementation of GNU EMACS. He began with C++, but soon after was convinced that C++ was inadequate for this particular project. His extensions and modifications to C++ (also know as C++ ++ --), were the first steps towards the development of an independent language that would fit the project objectives. He named the language "Oak" while staring at an oak tree outside his office window! The name "Oak" was later dismissed due to a patent search which determined that the name was copyrighted and used for another programming language. According to Gosling, "the Java development team discovered that Oak was the name of a programming language that predated Sun's language, so another name had to be chosen." [O'Connell] [Harold]

"It's surprisingly difficult to find a good name for a programming language, as the team discovered after many hours of brainstorming. Finally, inspiration struck one day during a trip to the local coffee shop" Gosling recalls. Others have speculated that the name Java came from several individuals involved in the project: James gosling, Arthur Van hoff, Andy bechtolsheim. [McCarthy]

There were several criteria that Oak had to meet in order to satisfy the project objective given the consumer electronics target market. Given the wide array of manufacturers in the market, Oak would have to be completely platform independent, and function seamlessly regardless of the type of CPU in the device. For this reason, Oak was designed to be an interpreted language, since it would be practically impossible for a complied version to run on all available platforms. To facilitate the job of the interpreter, Oak was to be converted to an intermediate "byte-code" format which is then passed around across the network, and executed/interpreted dynamically. [O'Connell] [Harold] [McCarthy]

Additionally, reliability was of great concern. A consumer electronics device that would have to be "rebooted" periodically was not acceptable. Another important design objective for Oak would then have to be high reliability by allowing the least amount of programmer-introduced errors. This was the motivation for several important modification to C++. The concepts of multiple-inheritance and operator overloading were identified as sources of potential errors, and eliminated in Oak. Furthermore, in contrast to C++, Oak included implicit garbage collection thereby providing efficient memory utilization and higher reliability. Finally, Oak attempted to eliminate all unsafe constructs used in C and C++ by only providing data structures within objects. [O'Connell] [McCarthy]

Another essential design criterion was security. By design, Oak-based devices were to function in a network and often exchange code and information. Inherently, security is of great concern in a networked environment, especially in an environment as network dependent as the conceived Oak-based systems. For this reason, pointers were excluded in the design of Oak. This would theoretically eliminate the possibility of malicious programs accessing arbitrary addresses in memory. [O'Connell] [McCarthy]

If Oak were to be widely accepted and used within the consumer electronics industry, it would have to be simple and compact, so that the language could be mastered relatively easily, and development would not be excessively complex. Some would argue that Oak/Java is C++ done right, but the jury is still out on that...

In April of 1991, Ed Frank, a SPARCstation 10 architect, joined the green project. He led the project's hardware development effort. In two months, they developed the first hardware prototype known as star-seven (*7). The name *7 was somewhat demonstrative of the project's objective. *7 was the key combination to press on any telephone to answer any other ringing telephone on their network. In the meantime, Gosling was beginning work on the Oak interpreter. By August of 1991, the team had a working prototype of the user interface and graphical system which was demonstrated to Sun's co-founders Scott McNealy and Bill Joy. [O'Connell]

Development of Oak, the green OS, the user interface, and the hardware continued through the summer of 1992. In September of that year, the *7 prototype was complete and demonstrated to McNealy and Joy. The prototype was a PDA-like (personal digital assistant) device that Gosling described as a "handheld remote control." Patrick Naughton proclaimed that "in 18 months, we did the equivalent of what 75-people organizations at Sun took three years to do -- an operating system, a language, a toolkit, an interface, a new hardware platform, ..." [O'Connell]

While impressive, the market was not conducive to this type of technology, as later demonstrated by Apple's Newton PDA. The Green project's business planner, Mike Sheradin, and hardware designer, Ed Frank had envisioned a technology similar to that of Dolby Labs which would become the standard for the consumer electronics products. [O'Connell]


1.4.2 FirstPerson
In November of 1992, the Green Project is incorporated under the name FirstPerson. Given Java's lack of success in the consumer electronics industry, the company's direction was somewhat uncertain. Under Sun's influence, the company began re-evaluating its mission.

In early 1993, Time-Warner issued an RFP (request for proposal) for a set-top box operating system and interactive, video-on-demand technology. FirstPerson identified this area as a new target market, and began working in that direction. However, despite FirstPerson's great efforts, SGI was granted the contract by Time-Warner. By mid 1993 Sun began negotiating with 3DO to provide a Java-based OS for their set-top box. The negotiations were, however, unsuccessful and a deal was never made. FirstPerson was left on its own without any viable business prospects. Another attempt by the company to market its interactive TV technology fails when in February of 1994 a public launching of their products is canceled. [O'Connell]

A Sun higher level review of FirstPerson determines the interactive TV market to be immature in 1994. FirstPerson then shifts its focus yet again. Business plans are submitted to Sun's executives for developing Oak-based on-line and CD-ROM applications. Sun's response was not favorable, and FirstPerson was dissolved. Most of FirstPerson's employees moved to Sun Interactive to digital video data servers. However, a few individuals from FirstPerson still pursued the objective of finding a home for Java in a networked desktop market. [O'Connell]


1.4.3 Java and the World Wide Web
In June of 1994, Bill Joy started the "Liveoak" project with the stated objective of building a "big small operating" system. In July of 1994, the project "clicked" into place. Naughton gets the idea of putting "Liveoak" to work on the Internet while he was playing with writing a web browser over a long weekend. Just the kind of thing you'd want to do with your weekend! This was the turning point for Java. [O'Connell]

The world wide web, by nature, had requirements such as reliability, security, and architecture independence which were fully compatible with Java's design parameters. A perfect match had been found. By September of 1994, Naughton and Jonathan Payne (a Sun engineer) start writing "WebRunner," a Java-based web browser which was later renamed "HotJava." By October 1994, HotJava is stable and demonstrated to Sun executives. This time, Java's potential, in the context of the world wide web, is recognized and the project is supported. Although designed with a different objective in mind, Java found a perfect match in the World Wide Web. Many of Java's original design criteria such as platform independence, security, and reliability were directly applicable to the World Wide Web as well. Introduction of Java marked a new era in the history of the web. Information provides were now given the capability to not only deliver raw data, but also the applications that would operate on the data.

Sun formally announced Java and HotJava at SunWorld `95. Soon after, Netscape Inc. announced that it would incorporate Java support in their browser. This was a great triumph for Java since it was now supported by the most popular browser in the world. Later, Microsoft also announced that they would support Java in their Internet Explorer web browser, further solidifying Java's role in the World Wide Web.

Thursday, October 11, 2007

How do you do a time delay in C++?

There are several approaches to a time delay.

The simplest, easiest, and least reliable is to do a series of nested loops,
for example:

int x,y;
for(x = 0; x < 2000; x++)
{
for(y = 0; y < 2000000; y++)
{
}
}

Then adjust x and y until the time is about right. This is not reliable
because the delay will be different on different machines.


A better way is to use the time function, for example, to delay 3 seconds:


time_t start_time, cur_time;

time(&start_time);
do
{
time(&cur_time);
}
while((cur_time - start_time) < 3);

This works well, but will not allow delays in anything other than 1 second
intervals.


If you need finer resolution, you can use the clock function:

clock_t start_time, cur_time;
start_time = clock();
while((clock() - start_time) < 3 * CLOCKS_PER_SEC)
{
}

Unfortunately, the clock function does not work with all compilers and
operating systems. If it returns -1, the clock function is not available.

There are several other functions that can be used. For Windows computers,
there are _ftime, Sleep(), and QueryPerformanceCounter() functions, as well
as the sytem timer.

What is a best computer a Power Mac or a Pentium 66 mhz ?

Both systems offer or rather have their points, I would in the area
of Pentium class look at the mhz units as opposed to the 60/66 units if
possible, the early "Mercury Chipset" is not as "high performance as the
"Neptune chip set. Also the recent Triton set is fine and geared for a
greater mass appeal if we call it that as opposed to the Neptune set, though
Triton as many limitations in the high power user area, I would go for the
Neptune set. As far as the Mac go, I would wait for Apple to decide what
they want to do, it is a good chance that they will switch to PCI architec-
ture, I would wait for this, or look into a Mac clone. The power PC chip
though in my opinion functions rather poorly in that platform as opposed to
an IBM RS6000 unit. Keep in mind as far as taking something apart/building/
design,...and high performance mods the Mac is a limited platform, as
compared to CISC or Intel Architecture. It is apparent that there are fewer
and fewer developers in the Mac area, since the return is so small. The
actual point of RISC processing in the power Mac is questionable for most
users, the majority of SW is integer based so the fpu/npu system is of less
importance as it is in math/engineering or imaging related programs hopes
this sheds so light on the subject .

Tuesday, October 9, 2007

Perl - cPanel V3 and the @INC

Modifying @INC in a SCRIPT
use Module;

is executed during compile time so if you modify the @INC array at run time it will not be reflected back in the compile time. So if you have to include any more include locations in the @INC inside a script, give it inside the BEGIN { }block.



BEGIN{ push @INC,"location";}
The BEGIN blocks are executed during compile time. So @INC is updated at compile time and the use module are correctly searched for in the updated directories.

cPanel-v3 Script
my $homedir = (getpwuid($>))[7];my $n_inc = scalar @INC;for (my $i = 0; $i < $n_inc; $i++ ) { if (-d $homedir . '/perl' . $INC[$i]) { unshift(@INC,$homedir . '/perl' . $INC[$i]); $n_inc++; $i++; }}

This script dint work for me much, so I manually included the include locations into the BEGIN segment.

#! /usr/bin/perl -wBEGIN {unshift @INC,"/home/directory/perl/usr/lib/perl5/site_perl/5.8.7/";}...

Introduction to Windows - Programming for Windows

History - DOS
Disk Operating System aka DOS was one of the earlier operating systems, it was a single task system, where the whole system and the OS was devoted to executing a single program and was basically a text based OS.

With the advent of the Windows Operating System, multiple process or applications could be run and it became a graphical OS (interface). So in order to support new features the basic structure of C/C++ programs changed from the main(){...} procedure to
something of a program as shown below and the a new compiler is required for compiling and generating Windows Executables, Visual C++ is such an example.



/*Program toDisplay a Window on WindowsTest Compiled using Visual C++*/#include LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);char szWinName[] = "MyWin";int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgs,int nWinMode){ HWND hwnd; MSG msg; WNDCLASSEX wcl; wcl.cbSize = sizeof(WNDCLASSEX); wcl.hInstance = hInstance; wcl.lpszClassName = szWinName; wcl.lpfnWndProc = WindowFunc; wcl.style = 0; wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcl.hIconSm = NULL; wcl.hCursor = LoadCursor(NULL, IDC_ARROW); wcl.lpszMenuName = NULL; wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); if(!RegisterClassEx(&wcl)) return 0; hwnd = CreateWindow(szWinName,"Windows XP",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL); ShowWindow(hwnd,nWinMode); UpdateWindow(hwnd); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WindowFunc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam){ switch(message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,message,wparam,lparam); } return 0;}

Windows OS Skeleton
Windows is called so because all things you see on your desktop is broken into small Windows. A Window can have many child windows, parent window, and many other windows on the same level.

Getting Started to Windows Programming in C(++)?
A minimal Windows program must have atleast 2 functions

WinMain()
WindowFunc()


the WinMain() Function
The WinMain() function is the entry point to your program, i.e, the execution of your program starts with WinMain().
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgs,int WinMode)

The WinMain function must

Define a window class

Register the class (RegisterClassEx)

Create Window (CreateWindowEx)

Display Window (ShowWindow)

Get the message loop running(while(GetMessage(...)))



The contents in italics is the functions used for doing the specified actions. Check them out in the code.

the Window Procedure
The window Procedure is the link between your program and windows. It is the window procedure that windows calls to send messages to your application.

Monday, October 8, 2007

Perl Script to Login to Orkut

Perl Script to Login to Orkut
Finally
Succeeded in making the Perl Script that logs you into Orkut! Signing into Orkut is much more than a simple POST, Google is always clever so that they make things complex for automating the login process. Anyway here is the complex script, ..

Algorithm




Goto www.orkut.com

Check whether the title is Home.

If not find the source of login page IFRAME

Fill the username and password and submit the FORM.

Find the follow link from the next page.

Goto the followlink and GET the redirect page URL

Goto the redirect page

Goto Orkut.com/home.aspx

Your done.



Note:
Tested on Linux (FC6, Perl 5.8.8)
The following script is for linux, Will run on Windows too but the ANSI coloring may not work...
Windows Program is given below the program for Linux (without ANSI coloring).
For Linux (with ANSI coloring)
use WWW::Mechanize;use HTTP::Cookies;use HTTP::Request::Common;$cj=HTTP::Cookies->new(file => "cookie.jar",autosave=>1,ignore_discard=>1);$mech = WWW::Mechanize->new(cookie_jar => $cj);@prc = ("\e[0m\n","[\e[1;31mFAILED\e[0m]","[\e[2;32m OK \e[0m]\n"); print "\n\e[31;1mG\e[0mmail iD : "; $email = ; print "\e[31;1mP\e[0massword : \e[97m"; $pass = ; print $prc[0]; chomp $email;chomp $pass;RELOGIN: for($i=3; $i>=0;$i--) { printf("\e[2m%-60s","GET /Home.aspx"); $mech->get("http://www.orkut.com/Home.aspx"); last if($mech->success()); printf("%10s",$prc[1]); print "\e[2;37m Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; if($mech->title =~ m/orkut.*home/i) { print "\n\e[34mAlready Logged In",$prc[0]; $cnt =~ m/(.*)\@gmail.com<\/b>/; print "\nLogout $1?[n] : "; $com=;chomp $com; if($com eq "y") { logout; goto RELOGIN; } else { return; } } $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; printf("\e[2m%-60.59s","Parsing for Login Page "); #print $cnts; if($cnt !~ m/id='liframe'.*?src='(.*)'/) { printf("%10s",$prc[1]); print "\e[2;37m Login page URL Not Found!\nTry Again OR Update the script! ".$prc[0]; return; } print $prc[2]; $url = $1; $j=3;REDO: for($i=3;$i>=0;$i--) { printf("\e[2m%-60.59s","GET $url"); $mech->get($url); last if($mech->success()); printf("%10s",$prc[1]); print "\e[2;37m Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; $mech->form_number(1); $mech->field("Email",$email."\@gmail.com"); $mech->field("Passwd",$pass); printf("\e[2m%-60.59s","Logging In ... "); $mech->click("null"); $j--; if($j && !$mech->success()) { printf("%10s\n",$prc[1]); goto REDO; } return unless($j); $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; if(!$mech->find_link(text => "click here to continue")) { printf("%10s",$prc[1]); print "\n\e[31;1mWrong Usename or Password!",$prc[0]; return; } print $prc[2]; for($i=3;$i>=0;$i--) { printf("\e[2m%-60.59s","Continuing ..."); $mech->follow_link(text => "click here to continue"); last if($mech->success()); printf("%10s",$prc[1]); print "\e[2;37m Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; printf("\e[2m%-60s","Parsing REDIRECT URL"); $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; if($cnt !~ m/location.replace\("(.*)"\)/) { printf("%10s",$prc[1]); print "\n\e[31;1mRedirect script missing!",$prc[0]; return; } $url = $1; $url =~ s/\\u003d/=/g; print $prc[2]; for($i=3;$i>=0;$i--) { printf("\e[2m%-60.59s","GET $url"); $mech->get($url); last if($mech->success()); printf("%10s",$prc[1]); print "\e[2;37m Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; print "\e[34mLogged In!\e[0m"; exit 0;sub logout{ printf("\e[0;2m%-60s","Parsing Logout"); if(!$mech->find_link(text => "Logout")) { printf("%10s",$prc[1]); print "\n\e[31;1mNot Logged In?",$prc[0]; return; } print $prc[2]; for($i=3;$i>=0;$i--) { printf("\e[2m%-60.59s","Logging Out ..."); $mech->follow_link(text => "Logout"); last if($mech->success()); printf("%10s",$prc[1]); print "\e[2;37m Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2];}


For windows:


use WWW::Mechanize;use HTTP::Cookies;use HTTP::Request::Common;$cj=HTTP::Cookies->new(file => "cookie.jar",autosave=>1,ignore_discard=>1);$mech = WWW::Mechanize->new(cookie_jar => $cj);@prc = ("\n","[FAILED]","[ OK ]\n"); print "\nEmail iD : "; $email = ; print "Password : \e[97m"; $pass = ; print $prc[0]; chomp $email;chomp $pass;RELOGIN: for($i=3; $i>=0;$i--) { printf("%-60s","GET /Home.aspx"); $mech->get("http://www.orkut.com/Home.aspx"); last if($mech->success()); printf("%10s",$prc[1]); print " Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; if($mech->title =~ m/orkut.*home/i) { print "\nAlready Logged In",$prc[0]; $cnt =~ m/(.*)\@gmail.com<\/b>/; print "\nLogout $1?[n] : "; $com=;chomp $com; if($com eq "y") { logout; goto RELOGIN; } else { return; } } $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; printf("%-60.59s","Parsing for Login Page "); #print $cnts; if($cnt !~ m/id='liframe'.*?src='(.*)'/) { printf("%10s",$prc[1]); print "Login page URL Not Found!\nTry Again OR Update the script! ".$prc[0]; return; } print $prc[2]; $url = $1; $j=3;REDO: for($i=3;$i>=0;$i--) { printf("%-60.59s","GET $url"); $mech->get($url); last if($mech->success()); printf("%10s",$prc[1]); print " Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; $mech->form_number(1); $mech->field("Email",$email."\@gmail.com"); $mech->field("Passwd",$pass); printf("%-60.59s","Logging In ... "); $mech->click("null"); $j--; if($j && !$mech->success()) { printf("%10s\n",$prc[1]); goto REDO; } return unless($j); $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; if(!$mech->find_link(text => "click here to continue")) { printf("%10s",$prc[1]); print "\nWrong Usename or Password!",$prc[0]; return; } print $prc[2]; for($i=3;$i>=0;$i--) { printf("%-60.59s","Continuing ..."); $mech->follow_link(text => "click here to continue"); last if($mech->success()); printf("%10s",$prc[1]); print "Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; printf("%-60s","Parsing REDIRECT URL"); $cnt = $mech->response->as_string; $cnt =~ s/\n|\s+/ /g; if($cnt !~ m/location.replace\("(.*)"\)/) { printf("%10s",$prc[1]); print "\nRedirect script missing!",$prc[0]; return; } $url = $1; $url =~ s/\\u003d/=/g; print $prc[2]; for($i=3;$i>=0;$i--) { printf("%-60.59s","GET $url"); $mech->get($url); last if($mech->success()); printf("%10s",$prc[1]); print " Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2]; print "Logged In!"; exit 0;sub logout{ printf("%-60s","Parsing Logout"); if(!$mech->find_link(text => "Logout")) { printf("%10s",$prc[1]); print "\nNot Logged In?",$prc[0]; return; } print $prc[2]; for($i=3;$i>=0;$i--) { printf("%-60.59s","Logging Out ..."); $mech->follow_link(text => "Logout"); last if($mech->success()); printf("%10s",$prc[1]); print "\e[2;37m Retry (",$i,")".$prc[0] if($i); } return if($i<=0); print $prc[2];}

Saturday, October 6, 2007

Sorting Algorithm - Hypercard

Could you tell me the fastest sorting algorithm? I am using
Hypercard. I need to sort fields that are about 125 entries in length. I am
using an algorithm that I think is called boolean. Is there a faster method?
Right now it takes about 7-8 minutes to sort on a Mac Classic 2. If you
could explain the principle behind the algorithm I think I could extrapolate
the code into hypertalk.

An entire chapter of NUMERICAL RECIPES is devoted to sorting
algorithms. The authors say that the "straight insertion" method is adequate
for small (<50) sorts, and they strongly recommend the "heapsort" for larger
jobs. I will list the C code for the straight insertion:
for( j=2; j<=N; j++ )
{
a = arr[j];
i = j - 1;
while( i>0 && arr[i]>a )
{
arr[i+1] = arr[i];
i--;
}
arr[i+1] = a;
} /* end for loop */

An added caveat: the C code in NUMERICAL RECIPES assume that array indices
start at 1 NOT 0 !!



Response #: 2 of 2
Author: Clayton S. Ferner
Text: The fastest sorting algorithm depends on what you are sorting.
But, in general, quicksort and heapsort are about the fastest you can do.
Insertion sort is efficient for small lists, but quicksort and heapsort will
out perform it as the input gets larger and larger. Here is the Pascal-like
pseudo code for quicksort:
quicksort (Array, left, right);
begin
if left < right then begin
q := partition (Array, left, right);
quicksort (Array, left, q);
quicksort (Array, q + 1, right);
end;
end;
partition (Array, left, right) : integer;
begin
pivot := Array[left];
i := pivot - 1;
j := right + 1;
while true do begin
repeat j := j - 1 until Array[j] <= pivot;
repeat i := i + 1 until Array[i] >= pivot;
if i < j then begin
temp := Array[i];
Array[i] := Array[j];
Array[j] := temp;
end else
return j;
end;
end;

Quicksort has the disadvantage of having very bad performance on an array that
is already sorted. However, there exists an algorithm called
Random_Quicksort which overcomes this for the most part. Also, quicksort is
recursive. There does exist a version which is nonrecursive which I can give
to you if you need.



.

Object Oriented Programming (OOP).

How does object oriented programming work? Specifically, what separates C
form C++? Why does it seem necessary that one understand OOP before trying
to program in Windows?


Well, they are similar in that both use the C language. They are different
in that C++ expands on C. In Object Orientated Programming (OOP), you create
objects. These objects are used to create new objects. Then your programs
call these objects. If you want to improve a program, you just need to
change the objects, not the whole program.
Windows is big on OOP's because it uses large classes of objects. You make
calls to create a window of x,y or you create a scroll list, etc. You do
not need to design these objects, you just use them. Then if the object is
ever redone, you just need to recompile.
There is more to OOP, but I hope this helps.

What is a good compiler for learning C?

Which C language program is the best for a beginner? Some are
telling me Borland Turbo C++. I have a book by Herbert Schildt called "Teach
Yourself C". I have had previous experience in C programming in college (and
BASIC or course), but I have pretty much forgotten most of it (it was my last
semester, Party, Party, Party and then some). Any suggestions would be
appreciated.

Borland C is how I started. I found it pretty easy. Learn C first
then go on to C++ if you plan on large programming projects where the
advantages of Object Oriented Programming become important.

I think that the type of compiler is less important than a good
ext. The only thing I would really consider important in choosing a compiler
package is the debugger, esp. for C!
True, true. Another consideration is ANSI standard code,
depending on your applications.

Wednesday, October 3, 2007

use ARCHIE on the Internet

1. Telnet to an archie server (you may have done that already).
2. login archie.
3. at this point you could type help to get that servers commands.
4. or you could type prog followed by a space and a filename.
5. at this point you could print this list from your telecom buffer or..
6. have it sent to you. To have the list mailed to you type mail followed by
your e-mail address.
7. when finished leave gracefully by typing exit.
All of this will tell you where a file is. If you do not know where the
nearest archie server is, then try these: archie.mcgill.ca or archie.ans.net
or archie.rutgers.edu and send e-mail to one to get the command list. Just
type help in the body of the message. I hope this helps.

UNIX library

I have a question about UNIX. I found that there are lots of
files with .so suffix in usr/lib directory. What does it mean? I need
libX11.a, but I do not have it. I have libX11.so and libX11.so.5.0. Are they
related? Could I transfer .so to .a? How would I do that?

".so" means "shareable object", and you can use a .so file inplace
of a .a file if you tell the linker it is ok. On the Sun, you do this by
specifying the "-Bdynamic" switch to the linker, ld. In general, type "man
ld" or "man cc" to find out what to do.

Monday, October 1, 2007

BUS, BIOS, and Light-based computers

was reading the response to the "686 Problem". What is a "BUS"?
What is "BIOS"? Do these terms apply to the new generation of light-based
processors being researched?


BUS - This is the term used to describe the path taken by data
between memory, peripherals, and the processors. Each path has a BUS. BIOS -
This stands for Basic Input and Output Services. This information tells the
computer what peripherals are connected (memory, mass storage, etc.) for basic
input and output.

PC Questions. PC, EISA, LOCAL BUS, QIC-80

I have some questions about PC's. What is EISA, LOCAL BUS, and
Micro Channel? For QIC-80 Tape Driver, should I remove one of FD if I want to
add a QIC-80 Driver. If I have an ESDI HD, could I add a SCSI HD or Syquest
HD? For SCSI control, what is Direction Kit, master Kit, SVP, and DNK?

This will be a multi-part answer. ISA, EISA, MCA, and Local Bus:
All of these are 'BUSes'. On the inside of a computer, data must flow between
I/O devices (hard disk, video, etc.), memory (special I/O device or mass
storage), ROM (hard coded instructions), and the CPU. Data is passed between
these devices via a 'BUS.' When a PC is purchased, many times the processor
will be referred to as 16 bit or 32 bit. For example, a 386dx is a 32 bit
processor. This means it internally operates at 32 bits and can also access
memory at 32 bits. This memory addressing is done over a 32 bit 'BUS.' The
memory bus is dedicated for just accessing memory. ISA (Industry Standard
Architecture), EISA (Extended Industry Standard Architecture), and MCA
(MicroChannel Arch.) refer to a different type of bus called the I/O bus.
Usually, all peripherals on a PC are attached to the I/O bus or the expansion
bus. Items like the disk controllers, video, and communication ports
traditionally plug into the expansion bus. The key to ISA, EISA, and MCA is
data size and compatibility. ISA is the most common. The original PC's
(XT's) were built by IBM using an 8 bit bus. As their popularity grew,
companies began to make clones. Then Intel released the 16 bit 286 chip, and
IBM and its competitors developed the 16 bit bus. These IBM compatible
companies created a standard called the ISA standard which basically means a
16 bit bus. Intel then came out with the 32 bit 386dx chip, allowing for the
expansion of the bus. (NOTE: Some machines have 386dx chips, but use the ISA
16 bit bus.) Up to this point, the companies selling compatibles were really
compatible. A device that could plug into an IBM, could plug into a
compatible. These compatible companies developed EISA, a 32 bit bus standard.
The problem is that IBM went its own way and developed the MCA, its
proprietary 32 bit bus. No big deal, right? Wrong! EISA accepts ISA boards.
In other words, if you have a video board in a 286 (ISA) machine, it will
work in an EISA machine. But, MCA is not compatible with any of its previous
buses (ISA or EISA). Because of this and the fact that only IBM and its
closest companies were making components for MCA, prices were not driven down
by competition. Meanwhile, EISA could use the huge selection of ISA devices
already available. Importantly, the EISA standard was written by a group of
companies instead of one. This has made EISA pricing a little more
competitive. Recently, IBM has released a line of computers that have used
the ISA and EISA, I believe, that are competitively priced to compatibles.
LOCAL BUS: Video has, in past systems, used the expansion bus to transport its
data and the CPU to do its processing. LOCAL BUS is a bus that is designed to
help relieve the bottleneck of data flow over the expansion bus by creating
its own video bus. I believe this bus has the ability to access memory
directly, without burdening the CPU. This step is importanttoward creating a
more user friendly Graphical User Interface (GUI) - OS/2 and Windows - which
take a lotof processing for video. As for the Quarter Inch Cartridge (QIC) -
80 driver: That depends on what type of controller it requires. You can get
all types: IDE, SCSI, Parallel, ... This is really specific for the type of
QIC you get. SCSI and ESDI Hard disk: You can add an SCSI drive if you have
an ESDI, but you need to have a new controller for the SCSI. The SCSI drive
will not work with a ESDI controller. Syquest: Usually Syquest HD are SCSI
devices. If you add an SCSI controller, you can have up to 7 SCSI, depending
on the controller (some only allow 2 devices). An ST506, IDE, and ESDI hard


disks all only allow a max of 2 of the same devices per controller. A SCSI
controller will allow a max of 7 devices for one controller. But, be careful,
not all SCSI devices work on all controllers and not all controllers will
allow 7 devices. As for the other SCSI questions, I need more information.
Where or what are these related to? Setup of a SCSI device? I am not
familiar with these terms.