TechiWarehouse.Com


Top 3 Products & Services

1.
2.
3.

Dated: Aug. 12, 2004

Related Categories

Python Programming

INTRODUCTION:

Python is an interpreted, interactive, object-oriented programming language. Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing components together. Python's simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. Python supports modules and packages, which encourages program modularity and code reuse. The Python interpreter and the extensive standard library are available in source or binary form without charge for all major platforms, and can be freely distributed.

An interpreted, object-oriented programming language developed by Guido van Rossum. The name comes from one of van Rossum's favorite television shows, Monty Python's Flying Circus. Python is very portable since Python interpreters are available for most operating system platforms. Although Python is copyrighted, the source code is freely available, and unlike GNU software, it can be commercially re-sold.


History

Python TutorialPython is a portable, interpreted, object-oriented programming language. Its development started in 1990 at CWI in Amsterdam, and continues at CNRI in Reston, Va. The language has an elegant (but not over-simplified) syntax; a small number of powerful high-level data types are built in. Python can be extended in a systematic fashion by adding new modules implemented in a compiled language such as C or C++. Such extension modules can define new functions and variables as well as new object types.

The Python programming language provides an increasing amount of support for XML technologies. This document attempts to introduce some basic XML processing concepts to readers who have not yet started to use Python with XML, and it takes the form of a tutorial. It is assumed that the reader knows the basic terminology of XML and is comfortable with "XML as text".

The Python implementation is portable: it runs on many brands of UNIX, on Windows, DOS, OS/2,Mac, Amiga... If your favorite system isn't listed here, it may still be supported, if there's a C compiler for it. Ask around on comp.lang.python -- or just try compiling Python yourself.

 

Python with other Languages

Python is often compared to other interpreted languages such as Java, JavaScript, Perl, Tcl, or Smalltalk. Comparisons to C++, Common Lisp and Scheme can also be enlightening. In this section I will briefly compare Python to each of these languages. These comparisons concentrate on language issues only. In practice, the choice of a programming language is often dictated by other real-world constraints such as cost, availability, training, and prior investment, or even emotional attachment. Since these aspects are highly variable, it seems a waste of time to consider them much for this comparison.

Java

Python programs are generally expected to run slower than Java programs, but they also take much less time to develop. Python programs are typically 3-5 times shorter than equivalent Java programs. This difference can be attributed to Python's built-in high-level data types and its dynamic typing. For example, a Python programmer wastes no time declaring the types of arguments or variables, and Python's powerful polymorphic list and dictionary types, for which rich syntactic support is built straight into the language, find a use in almost every Python program. Because of the run-time typing, Python's run time must work harder than Java's. For example, when evaluating the expression a+b, it must first inspect the objects a and b to find out their type, which is not known at compile time. It then invokes the appropriate addition operation, which may be an overloaded user-defined method. Java, on the other hand, can perform an efficient integer or floating point addition, but requires variable declarations for a and b, and does not allow overloading of the + operator for instances of user-defined classes.

For these reasons, Python is much better suited as a "glue" language, while Java is better characterized as a low-level implementation language. In fact, the two together make an excellent combination. Components can be developed in Java and combined to form applications in Python; Python can also be used to prototype components until their design can be "hardened" in a Java implementation. To support this type of development, a Python implementation written in Java is under development, which allows calling Python code from Java and vice versa. In this implementation, Python source code is translated to Java bytecode (with help from a run-time library to support Python's dynamic semantics).

Javascript

Python's "object-based" subset is roughly equivalent to JavaScript. Like JavaScript (and unlike Java), Python supports a programming style that uses simple functions and variables without engaging in class definitions. However, for JavaScript, that's all there is. Python, on the other hand, supports writing much larger programs and better code reuse through a true object-oriented programming style, where classes and inheritance play an important role.

Perl

Python and Perl come from a similar background (Unix scripting, which both have long outgrown), and sport many similar features, but have a different philosophy. Perl emphasizes support for common application-oriented tasks, e.g. by having built-in regular expressions, file scanning and report generating features. Python emphasizes support for common programming methodologies such as data structure design and object-oriented programming, and encourages programmers to write readable (and thus maintainable) code by providing an elegant but not overly cryptic notation. As a consequence, Python comes close to Perl but rarely beats it in its original application domain; however Python has an applicability well beyond Perl's niche.

Tcl

Like Python, Tcl is usable as an application extension language, as well as a stand-alone programming language. However, Tcl, which traditionally stores all data as strings, is weak on data structures, and executes typical code much slower than Python. Tcl also lacks features needed for writing large programs, such as modular namespaces. Thus, while a "typical" large application using Tcl usually contains Tcl extensions written in C or C++ that are specific to that application, an equivalent Python application can often be written in "pure Python". Of course, pure Python development is much quicker than having to write and debug a C or C++ component. It has been said that Tcl's one redeeming quality is the Tk toolkit. Python has adopted an interface to Tk as its standard GUI component library. Tcl 8.0 addresses the speed issuse by providing a bytecode compiler with limited data type support, and adds namespaces. However, it is still a much more cumbersome programming language.

Smalltalk

Perhaps the biggest difference between Python and Smalltalk is Python's more "mainstream" syntax, which gives it a leg up on programmer training. Like Smalltalk, Python has dynamic typing and binding, and everything in Python is an object. However, Python distinguishes built-in object types from user-defined classes, and currently doesn't allow inheritance from built-in types. Smalltalk's standard library of collection data types is more refined, while Python's library has more facilities for dealing with Internet and WWW realities such as email, HTML and FTP. Python has a different philosophy regarding the development environment and distribution of code. Where Smalltalk traditionally has a monolithic "system image" which comprises both the environment and the user's program, Python stores both standard modules and user modules in individual files which can easily be rearranged or distributed outside the system. One consequence is that there is more than one option for attaching a Graphical User Interface (GUI) to a Python program, since the GUI is not built into the system.

C++
Almost everything said for Java also applies for C++, just more so: where Python code is typically 3-5 times shorter than equivalent Java code, it is often 5-10 times shorter than equivalent C++ code! Anecdotal evidence suggests that one Python programmer can finish in two months what two C++ programmers can't complete in a year. Python shines as a glue language, used to combine components written in C++.

Common Lisp and Scheme
These languages are close to Python in their dynamic semantics, but so different in their approach to syntax that a comparison becomes almost a religious argument: is Lisp's lack of syntax an advantage or a disadvantage? It should be noted that Python has introspective capabilities similar to those of Lisp, and Python programs can construct and execute program fragments on the fly. Usually, real-world properties are decisive: Common Lisp is big (in every sense), and the Scheme world is fragmented between many incompatible versions, where Python has a single, free, compact implementation. Moshe Zadka wrote a far better comparison with Scheme: Python vs. Scheme.

 

Graphical User Interface for Python

Tk

There's a neat object-oriented interface to the Tcl/Tk widget set, called Tkinter. It is part of the standard Python distribution and well-supported -- all you need to do is build and install Tcl/Tk and enable the _tkinter module and the TKPATH definition in Modules/Setup when building Python. This is probably the easiest to install and use, and the most complete widget set. It is also very likely that in the future the standard Python GUI API will be based on or at least look very much like the Tkinter interface.For more info about Tk, including pointers to the source, see the Tcl/Tk home page at http://www.scriptics.com/. Tcl/Tk is now fully portable to the Mac and Windows platforms (NT and 95 only); you need Python 1.4beta3 or later and Tk 4.1patch1 or later.
.

wxWindows:

There's an interface to wxWindows called wxPython. wxWindows is a portable GUI class library written in C++. It supports GTK, Motif, MS-Windows and Mac as targets. Ports to other platforms are being contemplated or have already had some work done on them. wxWindows preserves the look and feel of the underlying graphics toolkit, and there is quite a rich widget set and collection of GDI classes. See the wxWindows page at http://www.wxwindows.org// for more details. wxPython is a python extension module that wraps many of the wxWindows C++ classes, and is quickly gaining popularity amongst Python developers. You can get wxPython as part of the source or CVS distribution of wxWindows, or directly from its home page at http://alldunn.com/wxPython/.

COM has become a crucial part of the software infrastructure in the Windows 95 and Windows NT environments. But there are still plenty of uncertainties about the future. Will Microsoft succeed, for example, in making COM a viable multiplatform technology? Fitting Windows NT servers into existing enterprises will all but require that DCOM and other distributed services be available on non-Microsoft platforms.

The process has taken longer than expected, and while many organizations have made promises in this area, not much code is actually shipping. Meanwhile, both CORBA-based products and Java's RMI are successfully running in multi-OS environments today. The more time passes before multiplatform DCOM becomes a reality, the larger CORBA and RMI's lead will become.

Using Python as an Integration Language

Python is in use at many places as an integration language, used to glue together ("steer") existing components. The strategy here is to create Python extension modules (written in C/C++) that make the functionality of large components written in C/C++ available to the Python programmer. The extension ("glue") modules are required because Python cannot call C/C++ functions directly; the glue extensions handle conversion between Python data types and C/C++ data types and error checking, translation error return values into Python exception.

Using Python, better applications can be developed because different kinds of programmers can work together on a project. For example, when building a scientific application, C/C++ programmers can implement efficient numerical algorithms, while scientists on the same project can write Python programs that test and use those algorithms. The scientist doesn't have to learn a low-level programming language, and the C/C++ programmer doesn't need to understand the science involved.

Without Python, large amounts of C/C++ code often have to be written just to provide a flexible enough input mechanism so that scientists can feed the program its data, in all the variantions that are required for reasons of experimental setup (for instance). With Python, Python can be used to wrote a much more flexible input mechanism in a much shorter time, or Python itself can be the ultimate flexible input mechanism. As an extreme example, Lawrence Livermore National Laboratories is using Python to eventually replace a scripting language (BASIS) that was developed in house for the same purpose; BASIS started out as a simple input mechanism for Fortran programs, and gradually acquired many features of scripting languages (variables, conditionals, loops, procedures and so on) with increasing awkwardness.

Python Stability

Python is an advanced scripting language that is being used successfully to glue together large software components. It spans multiple platforms, middleware products, and application domains. Python is an object-oriented language with high-level data structures, dynamic typing, and dynamic binding. Python has been around since 1991, and has a very active user community

Like Tcl, Python is easily extensible with C/C++/Java code, and easily embeddable in applications. Python even uses Tk, the Tcl GUI toolkit, for a de-facto standard portable GUI toolkit. Unlike Tcl, however, Python supports object-oriented programming. Python programmers can create classes, use multiple inheritance, define methods, overload operators etc.

With the introduction of retrospective "bugfix" releases the stability of the language implementations can be, and is being, improved independently of the new features offered by more recent major or minor releases. Bugfix releases, indicated by a third component of the version number, only fix known problems and do not gratuitously introduce new and possibly incompatible features or modified library functionality.

JPython, Python and Java Integration

A new Python implementation written in 100% Pure Java, dubbed JPython, is currently under development; alpha releases are available for evaluation. JPython offers seamless scripting for Java. It is a full implementation of the Python language and standard library, adding direct access to the universe of Java classes. Java code can also use Python classes -- this is important for callbacks, for instance.

The main thrust for JPython is that it does for Java what Python already does for C and C++: to present programmers with more options in the trade-off between development time and execution time, by providing a more dynamic, more expressive alternative. JPython's integration with Java is superior to Python's integration with C/C++: due to Java's Reflection API, JPython can use arbitrary Java classes without the help of a wrapper generator such as SWIG. (C/C++ code must first be made available to Java through the Java native code interface; once it is callable from Java it is callable from JPython).

Python 3000?! Yes, that's the nickname for the next generation of the Python interpreter. The name may be considered a pun on Windows 2000, or a reference to Mystery Science Theatre 3000, a suitably Pythonesque tv show with a cult following. When will Python 3000 be released? Not for a loooooong time -- although you won't quite have to wait until the year 3000.

Originally, Python 3000 was intended to be a complete rewrite and redesign of the language. It would allow me to make incompatible changes in order to fix problems with the language design that weren't solvable in a backwards compatible way. The current plan, however, is that the necessary changes will be introduced gradually into the current Python 2.x line of development,with a clear transition path that includes a period of backwards compatibility support. .

So, don't expect the announcement of the release of Python 3000 any time soon. Instead, one day you may find that you are _already_ using Python 3000 -- only it won't be called that, but rather something like Python 2.8.7. And most of what you've learned in this book will still apply! Still, in the mean time references to Python 3000 will abound; just know that this is intentionally vaporware in the purest sense of the word. Rather than worry about Python 3000, continue to use and learn more about the Python version that you do have.

In the past year, Python has made great strides. We released Python 2.0, a big step forward, with new standard library features such as Unicode and XML support, and several new syntactic constructs, including augmented assignment: you can now write x += 1 instead of x = x+1. A few people wondered what the big deal was (answer: instead of x, imagine dict[key] or list[index]), but overall this was a big hit with those users who were already used to augmented assignment in other languages.

 

Using the Python Interpreter

Invoking the Interpreter

The Python interpreter is usually installed as /usr/local/bin/python on those machines where it is available; putting /usr/local/bin in your Unix shell's search path makes it possible to start it by typing the command python to the shell. Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local Python guru or system administrator. (E.g., /usr/local/python is a popular alternative location.)

Typing an end-of-file character (Control-D on Unix, Control-Z on DOS or Windows) at the primary prompt causes the interpreter to exit with a zero exit status. If that doesn't work, you can exit the interpreter by typing the following commands: "import sys; sys.exit()".

The interpreter's line-editing features usually aren't very sophisticated. On Unix, whoever installed the interpreter may have enabled support for the GNU readline library, which adds more elaborate interactive editing and history features. Perhaps the quickest check to see whether command line editing is supported is typing Control-P to the first Python prompt you get. If it beeps, you have command line editing; see Appendix A for an introduction to the keys. If nothing appears to happen, or if P is echoed, command line editing isn't available; you'll only be able to use backspace to remove characters from the current line.

The interpreter operates somewhat like the Unix shell: when called with standard input connected to a tty device, it reads and executes commands interactively; when called with a file name argument or with a file as standard input, it reads and executes a script from that file.

A third way of starting the interpreter is "python -c command [arg] ...", which executes the statement(s) in command, analogous to the shell's -c option. Since Python statements often contain spaces or other characters that are special to the shell, it is best to quote command in its entirety with double quotes.


.

Argument Passing

When known to the interpreter, the script name and additional arguments thereafter are passed to the script in the variable sys.argv, which is a list of strings. Its length is at least one; when no script and no arguments are given, sys.argv[0] is an empty string. When the script name is given as '-' (meaning standard input), sys.argv[0] is set to '-'. When -c command is used, sys.argv[0] is set to '-c'. Options found after -c command are not consumed by the Python interpreter's option processing but left in sys.argv for the command to handle.
.

Interactive Mode

When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (">>> "); for continuation lines it prompts with the secondary prompt, by default three dots ("... "). The interpreter prints a welcome message stating its version number and a copyright notice before printing the first prompt:

python Python 1.5.2b2 (#1, Feb 28 1999, 00:02:06) [GCC 2.8.1] on sunos5 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam

Error Handling

When an error occurs, the interpreter prints an error message and a stack trace. In interactive mode, it then returns to the primary prompt; when input came from a file, it exits with a nonzero exit status after printing the stack trace. (Exceptions handled by an except clause in a try statement are not errors in this context.) Some errors are unconditionally fatal and cause an exit with a nonzero exit; this applies to internal inconsistencies and some cases of running out of memory. All error messages are written to the standard error stream; normal output from the executed commands is written to standard output. Typing the interrupt character (usually Control-C or DEL) to the primary or secondary prompt cancels the input and returns to the primary prompt.2.1Typing an interrupt while a command is executing raises the KeyboardInterrupt exception, which may be handled by a try statement

.

Python's Strengths

Syntactically, Python code looks like executable pseudo code. Program development using Python is 5-10 times faster than using C/C++, and 3-5 times faster than using Java. In many cases, a prototype of an application can be written in Python without writing any C/C++/Java code. Often, the prototype is sufficiently functional and performs well enough to be delivered as the final product, saving considerable development time. Other times, the prototype can be translated in part or in whole to C++ or Java -- Python's object-oriented nature makes the translation a straightforward process.

The best approach is often to write only the performance-critical parts of the application in C++ or Java, and use Python for all higher-level control and customization. There are several anecdotes about applications that started out as pure C++ cpde to which Python was added as an extension language, where in each new version the percentage of the application written in Python increased, while also increasing the overall performance, functionality and reliability of the application. (E.g. Case Study: Python in a Commercial Environment, by Greg Stein, Microsoft, in Proceedings of the 6th International Python Conference, and the Alice VR project at UvA and CMU.)

Python has a strong presence on the web. It is suitable for CGI programming (on all platforms: Unix, Windows and Mac); there are interfaces to all major commercial databases. Python has a library that interfaces to the main Internet and web protocols, and has HTML parsing and generation toolkits. Python was a major implementation language for Infoseek when they were smaller. At least one company (Digital Creations) is selling a suite of server side tools using Python. And finally, Python has been used to implement a web browser (Grail).

Python is also well represented in the distributed systems world. It is one of the main languages supported by Xerox PARC's ILU (Inter-Language Unification; a CORBA compatible distributed object system), and many distributed applications have been built in Python using ILU. Python is also used by the Hector project at the University of Queensland, Australia.

.

Classes and objects

User-defined compound types

Having used some of Python's built-in types, we are ready to create a user-defined type: the Point. Consider the concept of a mathematical point. In two dimensions, a point is two numbers (coordinates) that are treated collectively as a single object. In mathematical notation, points are often written in parentheses with a comma separating the coordinates. For example, (0, 0) represents the origin, and (x, y) represents the point x units to the right and y units up from the origin. A natural way to represent a point in Python is with two floating-point values. The question, then, is how to group these two values into a compound object. The quick and dirty solution is to use a list or tuple, and for some applications that might be the best choice.

An alternative is to define a new user-defined compound type, also called a class. This approach involves a bit more effort, but it has advantages that will be apparent soon.

A class definition looks like this:
class Point :
pass Class definitions can appear anywhere in a program, but they are usually near the beginning (after the import statements).

This definition creates a new class called Point. The pass statement has no effect; it is only necessary because a compound statement must have something in its body.

By creating the Point class, we created a new type, also called Point. The members of this type are called instances of the type or objects. Creating a new instance is called instantiation. To instantiate a Point object, we call a function named (you guessed it) Point:

Attributes

We can add new data to an instance using dot notation:
 blank.x = 3.0

 blank.y = 4.0

This syntax is similar to the syntax for selecting a variable from a module, such as math.pi or string.uppercase. In this case, though, we are selecting a data item from an instance. These named items are called attributes. 

The following state diagram shows the result of these assignments:

The variable blank refers to a Point object, which contains two attributes. Each attribute refers to a floating-point number.  We can read the value of an attribute using the same syntax:

 print blank
.y 4.0

x = blank.x

 print x 3.0

The expression blank.x means, "Go to the object blankrefers to and get the value of x." In this case, we assign that value to a variable named x. There is no conflict between the variable x and the attribute x. The purpose of dot notation is to identify which variable you are referring to unambiguously.

You can use dot notation as part of any expression, so the following statements are legal:

print '(' + str(blank.x) + ', ' + str(blank.y) + ')'

distanceSquared = blank.x * blank.x + blank.y * blank.y

The first line outputs (3.0, 4.0); the second line calculates the value 25.0.

You might be tempted to print the value of blank itself:

 print blank

main Point instance at 80f8e70>

The result indicates that blank is an instance of the Point class and it was defined in __main__. 80f8e70is the unique identifier for this object, written in hexadecimal (base 16). This is probably not the most informative way to display a Point object. You will see how to change it shortly.

 As an exercise, create and print a Point object, and then use id to print the object's unique identifier. Translate the hexadecimal form into decimal and confirm that they match.



Instances as parameters

You can pass an instance as a parameter in the usual way. For example:

def printPoint(p):

  print '(' + str(p.x) + ', ' + str(p.y) + ')'

printPoint takes a point as an argument and displays it in the standard format. If you call printPoint(blank), the

output is (3.0, 4.0).

As an exercise, rewrite the distance function from Section 5.2 so that it takes two Points as parameters instead of four numbers.

 Sameness

The meaning of the word "same" seems perfectly clear until you give it some thought, and then you realize there is more to it than you expected.

For example, if you say, "Chris and I have the same car," you mean that his car and yours are the same make and model, but that they are two different cars. If you say, "Chris and I have the same mother," you mean that his mother and yours are the same person. * Note So the idea of "sameness" is different depending on the context.

When you talk about objects, there is a similar ambiguity. For example, if two Points are the same, does that mean they contain the same data (coordinates) or that they are actually the same object?

To find out if two references refer to the same object, use the == operator. For example:

p1 = Point()

p1.x = 3

p1.y = 4

p2 = Point()

p2.x = 3

p2.y = 4

p1 == p2

0

Even though p1 and p2 contain the same coordinates, they are not the same object. If we assign p1 to p2, then the two variables are aliases of the same object:

p2 = p1

p1 == p2

1

This type of equality is called shallow equality because it compares only the references, not the contents of the objects. To compare the contents of the objects     deep equality     we can write a function called samePoint:

def samePoint(p1, p2) :

  return (p1.x == p2.x) and (p1.y == p2.y)

Now if we create two different objects that contain the same data, we can use samePoint to find out if they represent the same point.

p1 = Point()

p1.x = 3

p1.y = 4

p2 = Point()

p2.x = 3

p2.y = 4

samePoint(p1, p2)

Of course, if the two variables refer to the same object, they have both shallow and deep equality.

Rectangles

Let's say that we want a class to represent a rectangle. The question is, what information do we have to provide in order to specify a rectangle? To keep things simple, assume that the rectangle is oriented either vertically or horizontally, never at an angle.

There are a few possibilities: we could specify the center of the rectangle (two coordinates) and its size (width and height); or we could specify one of the corners and the size; or we could specify two opposing corners. A conventional choice is to specify the upper-left corner of the rectangle and the size. Again, we'll define a new class:

class Rectangle:

pass

And instantiate it:

box = Rectangle()

box.width = 100.0

box.height = 200.0

This code creates a new Rectangle object with two floating-point attributes. To specify the upper-left corner, we can embed an object within an object!

box.corner = Point()

box.corner.x = 0.0;

box.corner.y = 0.0;

The dot operator composes. The expression box.corner.x means, "Go to the object box refers to and select the attribute named corner; then go to that object and select the attribute named x." 

 Instances as return values

Functions can return instances. For example, findCentertakes a Rectangle as an argument and returns a Point that contains the coordinates of the center of the Rectangle:

def findCenter(box):

  p = Point()

  p.x = box.corner.x + box.width/2.0

  p.y = box.corner.y + box.height/2.0

  return p

To call this function, pass box as an argument and assign the result to a variable:

center = findCenter(box)

 printPoint(center)

(50.0, 100.0)

Objects are mutable

We can change the state of an object by making an assignment to one of its attributes. For example, to change the size of a rectangle without changing its position, we could modify the values of width and height:

box.width = box.width + 50

box.height = box.height + 100

We could encapsulate this code in a method and generalize it to grow the rectangle by any amount:

def growRect(box, dwidth, dheight) :

box.width = box.width + dwidth

box.height = box.height + dheight

The variables dwidth and dheight indicate how much the rectangle should grow in each direction. Invoking this method has the effect of modifying the Rectangle that is passed as an argument.

For example, we could create a new Rectangle named boband pass it to growRect:

 bob = Rectangle()

 bob.width = 100.0

 bob.height = 200.0

 bob.corner = Point()

 bob.corner.x = 0.0;

 bob.corner.y = 0.0;

 growRect(bob, 50, 100)

While growRect is running, the parameter box is an alias for bob. Any changes made to box also affect bob.As an exercise, write a function named moveRect that takes a Rectangle and two parameters named dx and dy. It should change the location of the rectangle by adding dxto the x coordinate of corner and adding dyto the y coordinate of corner.

Copying

Aliasing can make a program difficult to read because changes made in one place might have unexpected effects in another place. It is hard to keep track of all the variables that might refer to a given object.  Copying an object is often an alternative to aliasing. The copy module contains a function called copy that can duplicate any object:

 import copy

 p1 = Point()

 p1.x = 3

 p1.y = 4

 p2 = copy.copy(p1)

 p1 == p2

0

samePoint(p1, p2)

1

Once we import the copy module, we can use the copy method to make a new Point. p1 and p2 are not the same point, but they contain the same data.

To copy a simple object like a Point, which doesn't contain any embedded objects, copy is sufficient. This is called shallow copying.

For something like a Rectangle, which contains a reference to a Point, copy doesn't do quite the right thing. It copies the reference to the Point object, so both the old Rectangle and the new one refer to a single Point.

This is almost certainly not what we want. In this case, invoking growRect on one of the Rectangles would not affect the other, but invoking moveRect on either would affect both! This behavior is confusing and error-prone.

Fortunately, the copy module contains a method named deepcopy that copies not only the object but also any embedded objects. You will not be surprised to learn that this operation is called a deep copy.

b2 = copy.deepcopy(b1)

Now b1 and b2 are completely separate objects.

We can use deepcopy to rewrite growRect so that instead of modifying an existing Rectangle, it creates a new Rectangle that has the same location as the old one but new dimensions:

 def growRect(box, dwidth, dheight) :

  import copy

  newBox = copy.deepcopy(box)

  newBox.width = newBox.width + dwidth

  newBox.height = newBox.height + dheight

  return newBox

 An an exercise, rewrite moveRect so that it creates and returns a new Rectangle instead of modifying the old one. Glossary

Class

A user-defined compound type. A class can also be thought of as a template for the objects that are instances of it. instantiate To create an instance of a class. instance

An object that belongs to a class. object  A compound data type that is often used to model a thing or concept in the real world.

Constructor

A method used to create new objects.

attribute

One of the named data items that makes up an instance. shallow equality  Equality of references, or two references that point to the same object. deep equality Equality of values, or two references that point to objects that have the same value.  shallow copy

To copy the contents of an object, including any references to embedded objects; implemented by the copyfunction in the copy module.

deep copy  To copy the contents of an object as well as any embedded objects, and any objects embedded in them, and so on implemented by the deepcopy function in the copy module.


Functions

Function calls

You have already seen one example of a function call
: type("32")
type 'string'
The name of the function is type, and it displays the type of a value or variable. The value or variable, which is called the argument of the function, has to be enclosed in arentheses. It is common to say that a function "takes" an argument and "returns" a result.

The result is called the return value.
Instead of printing the return value, we could assign it to a variable:
betty = type("32")
print betty
As another example, the id function takes a value or a variable and returns an integer that acts as a unique identifier for the value:

id(3)
134882108
betty = 3
id(betty)
134882108

Every value has an id, which is a unique number related to where it is stored in the memory of the computer. The id of a variable is the id of the value to which it refers.
.

String

A compound data type

So far we have seen three types: int, float, and string. Strings are qualitatively different from the other two because they are made up of smaller pieces     characters.

Types that comprise smaller pieces are called compound data types. Depending on what we are doing, we may want to treat a compound data type as a single thing, or we may want to access its parts. This ambiguity is useful.
The bracket operator selects a single character from a string.

fruit = "banana"

letter = fruit[1]

print letter

The expression fruit[1] selects character number 1 from fruit. The variable letter refers to the result. When we

display letter, we get a surprise:

a

The first letter of "banana" is not a. Unless you are a computer scientist. For perverse reasons, computer scientists always

start counting from zero. The 0th letter ("zero-eth") of "banana" is b. The 1th letter ("one-eth") is a, and the 2th ("two-eth")

letter is n.

If you want the zero-eth letter of a string, you just put 0, or any expression with the value 0, in the brackets:

letter = fruit[0]

print letter

b
The expression in brackets is called an index. An index specifies a member of an ordered set, in this case the set of characters in the string. The index indicates which one you want, hence the name. It can be any integer expression.

Length

The len function returns the number of characters in a string:

fruit = "banana"

len(fruit)

6

To get the last letter of a string, you might be tempted to try something like this:

length = len(fruit)

last = fruit[length]       # ERROR!

That won't work. It causes the runtime error IndexError: string

index out of range. The reason is that there is no 6th letter in "banana". Since we started counting at zero, the six letters are numbered 0 to 5. To get the last character, we have to subtract 1 from length:

length = len(fruit)

last = fruit[length-1]

Alternatively, we can use negative indices, which count backward from the end of the string. The expression fruit[-1] yields the last letter, fruit[-2] yields the second to last, and so on.

Traversal and the for loop

A lot of computations involve processing a string one character at a time. Often they start at the beginning, select each character in turn, do something to it, and continue until the end. This pattern of processing is called a traversal. One way to encode a traversal is with a while statement:

index = 0

while index < len(fruit):

  letter = fruit[index]

  print letter

  index = index + 1

 

This loop traverses the string and displays each letter on a line by itself. The loop condition is index < len(fruit), so when index is equal to the length of the string, the condition is false, and the body of the loop is not executed. The last character accessed is the one with the index len(fruit)-1, which is the last character in the string.

As an exercise, write a function that takes a string as an argument and outputs the letters backward, one  per line. Using an index to traverse a set of values is so common that Python provides an alternative, simpler syntax     the for loop:

for char in fruit:

print char

 

Each time through the loop, the next character in the string is assigned to the variable char. The loop continues until no characters are left.

The following example shows how to use concatenation and a for loop to generate an abecedarian series. "Abecedarian" refers to a series or list in which the elements appear in alphabetical order. For example, in Robert McCloskey's book Make Way for Ducklings, the names of the ducklings are Jack, Kack, Lack, Mack, Nack, Ouack, Pack, and Quack. This loop

outputs these names in order:

prefixes = "JKLMNOPQ"

suffix = "ack"

for letter in prefixes:

print letter + suffix

The output of this program is:

Jack

Kack

Lack

Mack

Nack

Oack

Pack

Qack

 

When known to the interpreter, the script name and additional arguments thereafter are passed to the script in the variable sys.argv, which is a list of strings. Its length is at least one; when no script and no arguments are given, sys.argv[0] is an empty string. When the script name is given as '-' (meaning standard input), sys.argv[0] is set to '-'. When -c command is used, sys.argv[0] is set to '-c'. Options found after -c command are not consumed by the Python interpreter's option processing but left in sys.argv for the command to handle.

Conditionals and recursion

The modulus operator

The modulus operator works on integers (and integer expressions) and yields the remainder when the first operand is divided by the second. In Python, the modulus operator is a percent sign (%). The syntax is the same as for other operators:

quotient = 7 / 3
print quotient
2
remainder = 7 % 3
print remainder

1

So 7 divided by 3 is 2 with 1 left over.

The modulus operator turns out to be surprisingly useful. For example, you can check whether one number is divisible by another   if x % y is zero, then x is divisible by y.

Also, you can extract the right-most digit or digits from a number. For example, x % 10 yields the right-most digit of x (in base 10). Similarly x % 100yields the last two digits.

Boolean expressions

A boolean expression is an expression that is either true or false. In Python, an expression that is true has the value 1, and an expression that is false has the value 0.

The operator == compares two values and produces a boolean expression:
>>> 5 == 5
1
>>> 5 == 6
0

In the first statement, the two operands are equal, so the expression evaluates to 1 (true); in the second statement, 5 is not equal to 6, so we get 0 (false).

The == operator is one of the comparison operators; the others are:

      x != y               # x is not equal to y

      x > y                # x is greater than y

      x < y                # x is less than y

      x >= y               # x is greater than or equal to y

      x <= y               # x is less than or equal to y

Although these operations are probably familiar to you, the Python symbols are different from the mathematical symbols. A common error is to use a single equal sign (=) instead of a double equal sign (==). Remember that = is an assignment operator and == is a comparison operator. Also, there is no such thing as =< or =>.

Logical operators

There are three logical operators: and, or, and not. The semantics (meaning) of these operators is similar to their meaning in English. For example, x > 0 and x < 10 is true only if x is greater than 0 and less than 10.
n%2 == 0 or n%3 == 0 is true if either of the conditions is true, that is, if the number is divisible by 2 or 3.

Finally, the not operator negates a boolean expression, so not(x > y) is true if (x > y) is false, that is, if x is less than or equal to y.

Strictly speaking, the operands of the logical operators should be boolean expressions, but Python is not very strict. Any nonzero number is interpreted as "true."

>>>  x = 5

>>>  x and 1

1

>>>  y = 0

>>>  y and 1

0

In general, this sort of thing is not considered good style. If you want to compare a value to zero, you should do it explicitly.

Conditional execution

In order to write useful programs, we almost always need the ability to check conditions and change the behavior of the

program accordingly. Conditional statements give us this ability. The simplest form is the if statement:

if x > 0:

  print "x is positive"

The boolean expression after the if statement is called the condition. If it is true, then the indented statement gets executed. If not, nothing happens. Like other compound statements, the if statement is made up of a header and a block of statements:

HEADER:

FIRST STATEMENT

  ...

LAST STATEMENT

The header begins on a new line and ends with a colon (:). The indented statements that follow are called a block. The first unindented statement marks the end of the block. A statement block inside a compound statement is called the body of the statement.

There is no limit on the number of statements that can appear in the body of an if statement, but there has to be at least one. Occasionally, it is useful to have a body with no statements (usually as a place keeper for code you haven't written yet). In that case, you can use the pass statement, which does nothing.

Alternative execution

A second form of the if statement is alternative execution, in which there are two possibilities and the condition determines

which one gets executed. The syntax looks like this:

if x%2 == 0:

  print x, "is even"

else:

print x, "is odd"

If the remainder when x is divided by 2 is 0, then we know that x is even, and the program displays a message to that effect. If

the condition is false, the second set of statements is executed. Since the condition must be true or false, exactly one of the

alternatives will be executed. The alternatives are called branches, because they are branches in the flow of execution.

As an aside, if you need to check the parity (evenness or oddness) of numbers often, you might "wrap" this code in a function:

def printParity(x):

  if x%2 == 0:

  print x, "is even"

else:

print x, "is odd"

For any value of x, printParity displays an appropriate message. When you call it, you can provide any integer expression as an argument.

printParity(17)

printParity(y+1)

Chained conditionals

Sometimes there are more than two possibilities and we need more than two branches. One way to express a computation likethat is a chained conditional:

 

if x < y:

print x, "is less than", y

elif x > y:

print x, "is greater than", y

else:

print x, "and", y, "are equal"

elif is an abbreviation of "else if." Again, exactly one branch will be executed. There is no limit of the number of elif statements but only a single (and optional) else statement is allowed and it must be the last branch in the statement:

if choice == 'A':

  functionA()

elif choice == 'B':

  functionB()

elif choice == 'C':

  functionC()

else:

  print "Invalid choice."

 

Each condition is checked in order. If the first is false, the next is checked, and so on. If one of them is true, the corresponding branch executes, and the statement ends. Even if more than one condition is true, only the first true branch executes.

As an exercise, wrap these examples in functions called compare(x, y) and    dispatch(choice).

Nested conditionals

One conditional can also be nested within another. We could have written the trichotomy example as follows:

if x == y:

  print x, "and", y, "are equal"

else:

  if x < y:

    print x, "is less than", y

  else:

    print x, "is greater than", y

The outer conditional contains two branches. The first branch contains a simple output statement. The second branch contains another if statement, which has two branches of its own. Those two branches are both output statements, although they could have been conditional statements as well.

Although the indentation of the statements makes the structure apparent, nested conditionals become difficult to read very quickly. In general, it is a good idea to avoid them when you can.

Logical operators
often provide a way to simplify nested conditional statements. For example, we can rewrite the following code using a single conditional:

if 0 < x:

  if x < 10:

    print "x is a positive single digit."

 

The print statement is executed only if we make it past both the conditionals, so we can use the and operator:

if 0 < x and x < 10:

  print "x is a positive single digit."

These kinds of conditions are common, so Python provides an alternative syntax that is similar to mathematical notation:

if 0 < x < 10:

  print "x is a positive single digit."

This condition is semantically the same as the compound boolean expression and the nested conditional. Click here for

The return statement

The return statement allows you to terminate the execution of a function before you reach the end. One reason to use it is if

you detect an error condition:

import math

def printLogarithm(x):

  if x <= 0:

    print "Positive numbers only, please."

    return

  result = math.log(x)

  print "The log of x is", result

The function printLogarithm takes a parameter named x. The first thing it does is check whether x is less than or equal to

0, in which case it displays an error message and then uses return to exit the function. The flow of execution immediately

returns to the caller, and the remaining lines of the function are not executed.

Remember that to use a function from the math module, you have to import it.

Recursion

We mentioned that it is legal for one function to call another, and you have seen several examples of that. We neglected to

mention that it is also legal for a function to call itself. It may not be obvious why that is a good thing, but it turns out to be one

of the most magical and interesting things a program can do. For example, look at the following function:

def countdown(n):

  if n == 0:

    print "Blastoff!"

  else:

    print n

    countdown(n-1)

countdown expects the parameter, n, to be a positive integer. If n is 0, it outputs the word, "Blastoff!" Otherwise, it outputs n and then calls a function named countdown     itself     passing n-1 as an argument.

What happens if we call this function like this:

countdown(3)

 

The execution of countdown begins with n=3, and since n is not 0, it outputs the value 3, and then calls itsel. The execution of countdown begins with n=2, and since n is not 0, it outputs the value 2, and then calls itself. The execution of countdown begins with n=1, and since n is not 0, it outputs the value 1, and then calls itself...

The execution of countdown begins with n=0, and since n is 0, it outputs the word,

"Blastoff!" and then returns.

The countdown that got n=1 returns.

The countdown that got n=2 returns.

The countdown that got n=3 returns.

 

And then you're back in __main__ (what a trip). So, the total output looks like this:

3

2

1

Blastoff!

As a second example, look again at the functions newLine and threeLines:

def newline():

  print

def threeLines():

  newLine()

  newLine()

  newLine()

Although these work, they would not be much help if we wanted to output 2 newlines, or 106. A better alternative would be this:

def nLines(n):

  if n > 0:

    print

    nLines(n-1)

This program is similar to countdown; as long as n is greater than 0, it outputs one newline and then calls itself to output n-1 additional newlines. Thus, the total number of newlines is 1 + (n - 1) which, if you do your algebra right, comes out to n. The process of a function calling itself is recursion, and such functions are said to be recursive.

Input and Output

There are several ways to present the output of a program; data can be printed in a human-readable form, or written to a file for future use. This chapter will discuss some of the possibilities.

Fancier Output Formatting

So far we've encountered two ways of writing values: expression statements and the print statement. (A third way is using the write() method of file objects; the standard output file can be referenced as sys.stdout.Often you'll want more control over the formatting of your output than simply printing space-separated values. There are two ways to format your output; the first way is to do all the string handling yourself; using string slicing and concatenation operations you can create any lay-out you can imagine. The standard module string contains some useful operations for padding strings to a given column width; these will be discussed shortly. The second way is to use the % operator with a string as the left argument. The % operator interprets the left argument much like a sprintf()-style format string to be applied to the right argument, and returns the string resulting from this formatting operation.

One question remains, of course: how do you convert values to strings? Luckily, Python has ways to convert any value to a string: pass it to the repr() or str() functions, or just write the value between reverse quotes (``, equivalent to repr()).

The str() function is meant to return representations of values which are fairly human-readable, while repr() is meant to generate representations which can be read by the interpreter (or will force a SyntaxError if there is not equivalent syntax). For objects which don't have a particular representation for human consumption, str() will return the same value as repr(). Many values, such as numbers or structures like lists and dictionaries, have the same representation using either function. Strings and floating point numbers, in particular, have two distinct representations.

Some examples:

s = 'Hello, world.'

str(s)

'Hello, world.'

`s`

"'Hello, world.'"

str(0.1)

     '0.1'

     `0.1`

     '0.10000000000000001'

     x = 10 * 3.25

     y = 200 * 200

     s = 'The value of x is ' + `x` + ', and y is ' + `y` + '...'

     print s

     The value of x is 32.5, and y is 40000...

     # Reverse quotes work on other types besides numbers:

     p = [x, y]

     ps = repr(p)

     ps

     '[32.5, 40000]'

     # Converting a string adds string quotes and backslashes:

     hello = 'hello, world\n'

     hellos = `hello`

     print hellos

     'hello, world\n'

     # The argument of reverse quotes may be a tuple:

     `x, y, ('spam', 'eggs')`

     "(32.5, 40000, ('spam', 'eggs'))"

 

Here are two ways to write a table of squares and cubes:

import string

for x in range(1, 11):

     ...     print string.rjust(`x`, 2), string.rjust(`x*x`, 3),

     ...     # Note trailing comma on previous line

     ...     print string.rjust(`x*x*x`, 4)

     ...

      1   1    1

      2   4    8

      3   9   27

      4  16   64

      5  25  125

      6  36  216

      7  49  343

      8  64  512

      9  81  729

     10 100 1000

for x in range(1,11):

     ...     print '%2d %3d %4d' % (x, x*x, x*x*x)

     ...

      1   1    1

      2   4    8

      3   9   27

      4  16   64

      5  25  125

      6  36  216

      7  49  343

      8  64  512

      9  81  729

     10 100 1000

(Note that one space between each column was added by the way print works: it always adds spaces between its arguments.)

This example demonstrates the function string.rjust(), which right-justifies a string in a field of a given width by padding it with spaces on the left. There are similar functions string.ljust() and string.center(). These functions do not write anything, they just return a new string. If the input string is too long, they don't truncate it, but return it unchanged; this will mess up your column lay-out but that's usually better than the alternative, which would be lying about a value. (If you really want truncation you can always add a slice operation, as in "string.ljust(x, n)[0:n]".) There is another function, string.zfill(), which pads a numeric string on the left with zeros. It understands about plus and minus signs:

import string

 string.zfill('12', 5)

     '00012'

   string.zfill('-3.14', 7)

     '-003.14'

   string.zfill('3.14159265359', 5)

     '3.14159265359'

Using the % operator looks like this:

import math

  print 'The value of PI is approximately %5.3f.' % math.pi

    The value of PI is approximately 3.142.

If there is more than one format in the string, you need to pass a tuple as right operand, as in this example:

table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}

for name, phone in table.items():

   ...     print '%-10s ==> %10d' % (name, phone)

     ...

     Jack       ==>       4098

     Dcab       ==>       7678

     Sjoerd     ==>       4127

Most formats work exactly as in C and require that you pass the proper type; however, if you don't you get an exception, not a core dump. The %s format is more relaxed: if the corresponding argument is not a string object, it is converted to string using the str() built-in function. Using * to pass the width or precision in as a separate (integer) argument is supported. The C formats %n and %p are not supported. If you have a really long format string that you don't want to split up, it would be nice if you could reference the variables to be formatted by name instead of by position. This can be done by using form %(name)format, as shown here:

   table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}

    print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table

     Jack: 4098; Sjoerd: 4127; Dcab: 8637678

This is particularly useful in combination with the new built-in vars() function, which returns a dictionary containing all local variables.

Reading and Writing Files

open() returns a file object , and is most commonly used with two arguments: "open(filename, mode)".

     f=open('/tmp/workfile', 'w')

     print f

     <open file '/tmp/workfile', mode 'w' at 80a0960>

The first argument is a string containing the filename. The second argument is another string containing a few characters describing the way in which the file will be used. mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it's omitted.

On Windows and the Macintosh, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it'll corrupt binary data like that in JPEGs or .EXE files. Be very careful to use binary mode when reading and writing such files. (Note that the precise semantics of text mode on the Macintosh depends on the underlying C library being used.)

Methods of File Objects

The rest of the examples in this section will assume that a file object called f has already been created. To read a file's contents, call f.read(size), which reads some quantity of data and returns it as a string. size is an optional numeric argument. When size is omitted or negative, the entire contents of the file will be read and returned; it's your problem if the file is twice as large as your machine's memory. Otherwise, at most size bytes are read and returned. If the end of the file has been reached, f.read() will return an empty string ("").

f.read()

   'This is the entire file.\n'

f.read()

     ''
f.readline() reads a single line from the file; a newline character (\n) is left at the end of the string, and is only omitted on the last line of the file if the file doesn't end in a newline. This makes the return value unambiguous; if f.readline() returns an empty string, the end of the file has been reached, while a blank line is represented by '\n', a string containing only a single newline.

readline()

     'This is the first line of the file.\n'

f.readline()

     'Second line of the file\n'

f.readline()

     ''
f.readlines() returns a list containing all the lines of data in the file. If given an optional parameter sizehint, it reads that many bytes from the file and enough more to complete a line, and returns the lines from that. This is often used to allow efficient reading of a large file by lines, but without having to load the entire file in memory. Only complete lines will be returned.

  f.readlines()

     ['This is the first line of the file.\n', 'Second line of the file\n']

f.write(string) writes the contents of string to the file, returning None.

     f.write('This is a test\n')

f.tell() returns an integer giving the file object's current position in the file, measured in bytes from the beginning of the file.To change the file object's position, use "f.seek(offset, from_what)". The position is computed from adding offset to a reference point; the reference point is selected by the from_what argument. A from_what value of 0 measures from the beginning of the file, 1 uses the current file position, and 2 uses the end of the file as the reference point. from_what can be omitted and defaults to 0, using the beginning of the file as the reference point.

  f=open('/tmp/workfile', 'r+')

  f.write('0123456789abcdef')

  f.seek(5)     # Go to the 6th byte in the file

  f.read(1)       

     '5'

  f.seek(-3, 2) # Go to the 3rd byte before the end

  f.read(1)

     'd'

When you're done with a file, call f.close() to close it and free up any system resources taken up by the open file. After calling f.close(), attempts to use the file object will automatically fail.

f.close()

f.read()

     Traceback (most recent call last):

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

     ValueError: I/O operation on closed file

File objects have some additional methods, such as isatty() and truncate() which are less frequently used; consult the Library Reference for a complete guide to file objects.

Debugging

Different kinds of errors can occur in a program, and it is useful to distinguish among them in order to track them down more quickly:

Syntax errors are produced by Python when it is translating the source code into byte code. They usually indicate that  there is something wrong with the syntax of the program. Example: Omitting the colon at the end of a def statement yields the somewhat redundant message SyntaxError: invalid syntax.

Runtime errors are produced by the runtime system if something goes wrong while the program is running. Most runtime  error messages include information about where the error occurred and what functions were executing. Example: An   infinite recursion eventually causes a runtime error of "maximum recursion depth exceeded."

Semantic errors are problems with a program that compiles and runs but doesn't do the right thing. Example: An  expression may not be evaluated in the order you expect, yielding an unexpected result.

The first step in debugging is to figure out which kind of error you are dealing with. Although the following sections are organized by error type, some techniques are applicable in more than one situation.

Syntax errors

Syntax errors are usually easy to fix once you figure out what they are. Unfortunately, the error messages are often not helpful.The most common messages are SyntaxError: invalid syntax and SyntaxError: invalid token, neither of which is very informative.

On the other hand, the message does tell you where in the program the problem occurred. Actually, it tells you where Python noticed a problem, which is not necessarily where the error is. Sometimes the error is prior to the location of the error message, often on the preceding line.
If you are building the program incrementally, you should have a good idea about where the error is. It will be in the last line you added.

If you are copying code from a book, start by comparing your code to the book's code very carefully. Check every character. At the same time, remember that the book might be wrong, so if you see something that looks like a syntax error, it might be. Here are some ways to avoid the most common syntax errors:

1.Make sure you are not using a Python keyword for a variable name.

2.Check that you have a colon at the end of the header of every compound statement, including for, while, if, and  def statements.

3.Check that indentation is consistent. You may indent with either spaces or tabs but it's best not to mix them. Each level should be nested the same amount.

4.Make sure that any strings in the code have matching quotation marks.

5.If you have multiline strings with triple quotes (single or double), make sure you have terminated the string properly. An unterminated string may cause an invalid token error at the end of your program, or it may treat the following part of the program as a string until it comes to the next string. In the second case, it might not produce an error message at all!

6.An unclosed bracket     (, {, or [     makes Python continue with the next line as part of the current statement.  Generally, an error occurs almost immediately in the next line.

7.Check for the classic = instead of == inside a conditional.

If nothing works, move on to the next section.. can't get my program to run no matter what I do.If the compiler says there is an error and you don't see it, that might be because you and the compiler are not looking at the same code. Check your programming environment to make sure that the program you are editing is the one Python is trying to run. If you are not sure, try putting an obvious and deliberate syntax error at the beginning of the program. Now run (or import) it again. If the compiler doesn't find the new error, there is probably something wrong with the way your environment is set up.

If this happens, one approach is to start again with a new program like "Hello, World!," and make sure you can get a known program to run. Then gradually add the pieces of the new program to the working one.

Runtime errors

Once your program is syntactically correct, Python can import it and at least start running it. What could possibly go wrong? My program does absolutely nothing.

This problem is most common when your file consists of functions and classes but does not actually invoke anything to start execution. This may be intentional if you only plan to import this module to supply classes and functions.

If it is not intentional, make sure that you are invoking a function to start execution, or execute one from the interactive prompt.

My program hangs.

If a program stops and seems to be doing nothing, we say it is "hanging." Often that means that it is caught in an infinite loop or an infinite recursion.

If there is a particular loop that you suspect is the problem, add a print statement immediately before the loop that says "entering the loop" and another immediately after that says "exiting the loop." Run the program. If you get the first message and not the second, you've got an infinite loop. Most of the time, an infinite recursion will cause the program to run for a while and then produce a "RuntimeError:   Maximum recursion depth exceeded" error. If that happens, go to the "Infinite Recursion" section below.  If neither of those steps works, start testing other loops and other recursive functions and methods.      If that doesn't work, then it is possible that you don't understand the flow of execution in your program.

Infinite Loop

If you think you have an infinite loop and you think you know what loop is causing the problem, add a print statement at the end of the loop that prints the values of the variables in the condition and the value of the condition.

For example:

while x > 0 and y < 0 :

  # do something to x

  # do something to y

print  "x: ", x

  print  "y: ", y

  print  "condition: ", (x > 0 and y < 0)

Now when you run the program, you will see three lines of output for each time through the loop. The last time through theloop, the condition should be false. If the loop keeps going, you will be able to see the va lues of x and y, and you might figure out why they are not being updated correctly. Infinite Recursion

Most of the time, an infinite recursion will cause the program to run for a while and then produce a Maximum recursion depth exceedederror.

If you suspect that a function or method is causing an infinite recursion, start by checking to make sure that there is a base case. In other words, there should be some condition that will cause the function or method to return without making a recursive invocation. If not, then you need to rethink the algorithm and identify a base case. If there is a base case but the program doesn't seem to be reaching it, add a print statement at the beginning of the functionor method that prints the parameters. Now when you run the program, you will see a few lines of output every time the function or method is invoked, and you will see the parameters. If the parameters are not moving toward the base case, you will get some ideas about why not.

Flow of Execution

If you are not sure how the flow of execution is moving through your program, add print statements to the beginning of each function with a message like "entering function foo," where foo is the name of the function Now when you run the program, it will print a trace of each function as it is invoked.

When I run the program I get an exception.

If something goes wrong during runtime, Python prints a message that includes the name of the exception, the line of the program where the problem occurred, and a traceback.

The traceback identifies the function that is currently running, and then the function that invoked it, and then the function that invoked that, and so on. In other words, it traces the path of function invocations that got you to where you are. It also includes the line number in your file where each of these calls occurs.

The first step is to examine the place in the program where the error occurred and see if you can figure out what happened.These are some of the most common runtime errors:

NameError

You are trying to use a variable that doesn't exist in the current environment. Remember that local variables are local.     You cannot refer to them from outside the function where they are defined.
TypeError

There are several possible causes:

You are trying to use a value improperly. Example: indexing a string, list, or tuple with something other than an  integer. There is a mismatch between the items in a format string and the items passed for conversion. This can happen if either the number of items does not match or an invalid conversion is called for. You are passing the wrong number of arguments to a function or method. For methods, look at the method  definition and check that the first parameter is self. Then look at the method invocation; make sure you are     invoking the method on an object with the right type and providing the other arguments correctly.

KeyError

You are trying to access an element of a dictionary using a key value that the dictionary does not contain.

AttributeError

You are trying to access an attribute or method that does not exist.

IndexError

The index you are using to access a list, string, or tuple is greater than its length minus one. Immediately before the site of the error, add a print statement to display the value of the index and the length of the array. Is the array the right size?  Is the index the right value?

.

Conclusion

Python can fulfill an important integration role in the design of large applications with a long life expectancy.Because Python has existing interfaces to so many different components in very different application domains, Python is ideal for oddball integration tasks. It can link a commercial database to number-crunching code; it can add a graphical user interface to a network management tool; it can send email from a virtual reality application. It allows a fast response to changes in user requirements that require adapting the higher-level application logic without changing the fundamental underlying components.

Finally, Python is well integrated with the Windows platforms. Python programs can interact with COM and DCOM services, and can even implement new COM and DCOM services (which is not possible using Visual Basic!). Python can also be used as a scripting engine in Microsoft's Active Scripting architecture script name is given as '-' (meaning standard input), sys.argv[0] is set to '-'. When -c command is used, sys.argv[0] is set to '-c'. Options found after -c command are not consumed by the Python interpreter's option processing but left in sys.argv for the command to handle

.Return to the top of the page

Now that you've gotten free know-how on this topic, try to grow your skills even faster with online video training. Then finally, put these skills to the test and make a name for yourself by offering these skills to others by becoming a freelancer. There are literally 2000+ new projects that are posted every single freakin' day, no lie!


Previous Article

Next Article


Bryans's Comment
thanks for the recursive definition explanation. it was very easy to understand!
26 Sat Feb 2011
Admin's Reply:

Happy to hear that Bryans.




balu's Comment
this material is not sufficient
13 Mon Sep 2010
Admin's Reply:

Expect more soon