I l@ve RuBoard 
On to the nittygritty. The first object type on our tour is Python numbers. In general, Python's number types are fairly typical and will seem familiar if you've used just about any other programming language in the past. Python supports the usual numeric types (integer and floating point), constants, and expressions. In addition, Python provides more advanced numeric programming support, including a complex number type, an unlimited precision integer, and a variety of numeric tool libraries. The next few sections give an overview of the numeric support in Python.
Among its basic types, Python supports the usual suspects: both integer and floatingpoint numbers, and all their associated syntax and operations. Like C, Python also allows you to write integers using hexadecimal and octal constants. Unlike C, Python also has a complex number type (introduced in Python 1.4), as well as a long integer type with unlimited precision (it can grow to have as many digits as your memory space allows). Table 2.2 shows what Python's numeric types look like when written out in a program (i.e., as constants).
Constant 
Interpretation 

1234, 24, 0 
Normal integers (C longs) 
999999999999L 
Long integers (unlimited size) 
1.23, 3.14e10, 4E210, 4.0e+210 
Floatingpoint (C doubles) 
0177, 0x9ff 
Octal and hex constants 
3+4j, 3.0+4.0j, 3J 
Complex number constants 
By and large, Python's numeric types are straightforward, but a few are worth highlighting here:
Integers are written as a string of decimal digits. Floatingpoint numbers have an embedded decimal point, and/or an optional signed exponent introduced by an e or E. If you write a number with a decimal point or exponent, Python makes it a floatingpoint object and uses floatingpoint (not integer) math when it's used in an expression. The rules for writing floatingpoint numbers are the same as with C.
Plain Python integers (row 1) are implemented as C longs internally (i.e., at least 32 bits), and Python floatingpoint numbers are implemented as C doubles; Python numbers get as much precision as the C compiler used to build the Python interpreter gives to longs and doubles. On the other hand, if an integer constant ends with an l or L, it becomes a Python long integer (not to be confused with a C long) and can grow as large as needed.
The rules for writing hexadecimal (base 16) and octal (base 8) integers are the same as in C: octal constants start with a leading zero (0), and hexadecimals start with a leading 0x or 0X. Notice that this means you can't write normal baseten integers with a leading zero (e.g., 01); Python interprets them as octal constants, which usually don't work as you'd expect!
Python complex constants are written as realpart + imaginarypart, and terminated with a j or J. Internally, they are implemented as a pair of floatingpoint numbers, but all numeric operations perform complex math when applied to complex numbers.
Besides the builtin number types shown in Table 2.2, Python provides a set of tools for processing number objects:
+, *, >>, **, etc.
pow, abs, etc.
rand, math, etc.
We'll meet all of these as we go along. Finally, if you need to do serious numbercrunching, an optional extension for Python called Numeric Python provides advanced numeric programming tools, such as a matrix data type and sophisticated computation libraries. Because it's so advanced, we won't say more about Numeric Python in this chapter; see the examples later in the book and Appendix A. Also note that, as of this writing, Numeric Python is an optional extension; it doesn't come with Python and must be installed separately.
Perhaps the most fundamental tool that processes numbers is the expression : a combination of numbers (or other objects) and operators that computes a value when executed by Python. In Python, expressions are written using the usual mathematical notation and operator symbols. For instance, to add two numbers X and Y, we say X + Y, which tells Python to apply the + operator to the values named by X and Y. The result of the expression is the sum of X and Y, another number object.
Table 2.3 lists all the operator expressions available in Python. Many are selfexplanatory; for instance, the usual mathematical operators are supported: +, , *, /, and so on. A few will be familiar if you've used C in the past: % computes a division remainder, << performs a bitwise leftshift, & computes a bitwise and result, etc. Others are more Pythonspecific, and not all are numeric in nature: the is operator tests object identity (i.e., address) equality, lambda creates unnamed functions, and so on.
Operators 
Description 

Logical or ( y is evaluated only if x is false), anonymous function 

x and y 
Logical and (y is evaluated only if x is true) 
not x 
Logical negation 
sequence membership 

Bitwise or 

x ^ y 
Bitwise exclusive or 
x & y 
Bitwise and 
Shift x left or right by y bits 

Addition/concatenation, subtraction 

Multiplication/repetition, division, remainder/format 

Unary negation, identity, bitwise complement 

x[i], x[i:j], x.y, x(...) 
Indexing, slicing, qualification, function calls 
(...), [...], {...}, `...` 
Tuple, list, dictionary, conversion to string 
Table 2.3 is mostly included for reference; since we'll see its operators in action later, we won't describe every entry here. But there are a few basic points we'd like to make about expressions before moving on.
As in most languages, more complex expressions are coded by stringing together operator expressions in the table. For instance, the sum of two multiplications might be written as: A * B + C * D. So how does Python know which operator to perform first? When you write an expression with more than one operator, Python groups its parts according to what are called precedence rules, and this grouping determines the order in which expression parts are computed. In the table, operators lower in the table have higher precedence and so bind more tightly in mixed expressions. For example, if you write X + Y * Z, Python evaluates the multiplication first (Y * Z), then adds that result to X, because * has higher precedence (is lower in the table) than +.
If the prior paragraph sounded confusing, relax: you can forget about precedence completely if you're careful to group parts of expressions with parentheses. When you parenthesize subexpressions, you override Python precedence rules; Python always evaluates parenthesized expressions first, before using their results in enclosing expressions. For instance, instead of X + Y * Z, write (X + Y) * Z, or for that matter X + (Y * Z) to force Python to evaluate the expression in the desired order. In the former case, + is applied to X and Y first; in the latter, the * is performed first (as if there were no parentheses at all). Generally speaking, adding parentheses in big expressions is a great idea; it not only forces the evaluation order you want, but it also aids readability.
Besides mixing operators in expressions, you can also mix numeric types. For instance, you can add an integer to a floatingpoint number, but this leads to another dilemma: what type is the result梚nteger or floatingpoint? The answer is simple, especially if you've used almost any other language before: in mixed type expressions, Python first converts operands up to the type of the most complex operand, and then performs the math on sametype operands. Python ranks the complexity of numeric types like so: integers are simpler than long integers, which are simpler than floatingpoint numbers, which are simpler than complex numbers. So, when an integer is mixed with a floatingpoint, the integer is converted up to a floatingpoint value first, and then floatingpoint math yields the floatingpoint result. Similarly, any mixedtype expression where one operand is a complex number results in the other operand being converted up to a complex, and yields a complex result.
Although we're focusing on builtin numbers right now, keep in mind that all Python operators may be overloaded by Python classes and C extension types, to work on objects you implement. For instance, you'll see later that objects coded with classes may be added with + expressions, indexed with [i] expressions, and so on. Furthermore, some operators are already overloaded by Python itself: they perform different actions depending on the type of builtin objects being processed. For example, the + operator performs addition when applied to numbers, but (as we'll see in a moment) performs concatenation when applied to sequence objects such as strings and lists.^{[2]}
^{[2]} This is usually called polymorphism?/i>the meaning of an operation depends on the type of objects being operated on. But we're not quite ready for objectoriented ideas like this yet, so hold that thought for now.
Perhaps the best way to understand numeric objects and expressions is to see them in action. Let's fire up the interactive command line and type some basic, but illustrative operations.
First of all, let's exercise some basic math: addition and division. In the following interaction, we first assign two variables (a and b) to integers, so we can use them later in a larger expression. We'll say more about this later, but in Python, variables are created when first assigned; there is no need to predeclare the names a and b before using them. In other words, the assignments cause these variables to spring into existence automatically.
% python >>> a = 3 # name created >>> b = 4
We've also used a comment here. These were introduced in Chapter 1, but as a refresher: in Python code, text after a # mark and continuing to the end of the line is considered to be a comment, and is ignored by Python (it's a place for you to write humanreadable documentation for your code; since code you type interactively is temporary, you won't normally write comments there, but we've added them to our examples to help explain the code). Now, let's use our integer objects in expressions; as usual, expression results are echoed back to us at the interactive prompt:
>>> b / 2 + a # same as ((4 / 2) + 3) 5 >>> b / (2.0 + a) # same as (4 / (2.0 + 3)) 0.8
In the first expression, there are no parentheses, so Python automatically groups the components according to its precedence rules; since / is lower in Table 2.3 than +, it binds more tightly, and so is evaluated first. The result is as if we had parenthesized the expression as shown in the comment to the right of the code. Also notice that all the numbers are integers in the first expression; because of that, Python performs integer division and addition.
In the second expression, we add parentheses around the + part to force Python to evaluate it first (i.e., before the / ). We also made one of the operands floating point by adding a decimal point: 2.0. Because of the mixed types, Python converts the integer referenced by a up to a floatingpoint value (3.0) before performing the +. It also converts b up to a floatingpoint value (4.0) and performs a floatingpoint division: (4.0 / 5.0) yields a floatingpoint result of 0.8. If this were integer division instead, the result would be a truncated integer zero.
Besides the normal numeric operations (addition, subtraction, and so on), Python supports most of the numeric expressions available in the C language. For instance, here it's at work performing bitwise shift and Boolean operations:
>>> x = 1 # 0001 >>> x << 2 # shift left 2 bits: 0100 4 >>> x  2 # bitwise OR: 0011 3 >>> x & 1 # bitwise AND: 0001 1
In the first expression, a binary 1 (in base 2, 0001) is shifted left two slots to create a binary 4 (0100). The last two operations perform a binary or (0001  0010 = 0011), and a binary and (0001 & 0001 = 0001). We won't go into much more detail on bittwiddling here. It's supported if you need it, but be aware that it's often not as important in a highlevel language such as Python as it is in a lowlevel language such as C. As a rule of thumb, if you find yourself wanting to flip bits in Python, you should think long and hard about which language you're really using. In general, there are often better ways to encode information in Python than bit strings.^{[3]}
^{[3]} Usually. As for every rule there are exceptions. For instance, if you interface with C libraries that expect bit strings to be passed in, our preaching doesn't apply.
Now for something more exotic: here's a look at long integers in action. When an integer constant ends with an L (or lowercase l), Python creates a long integer, which can be arbitrarily big:
>>> 9999999999999999999999999999 + 1 OverflowError: integer literal too large >>> 9999999999999999999999999999L + 1 10000000000000000000000000000L
Here, the first expression fails and raises an error, because normal integers can't accommodate such a large number. On the other hand, the second works fine, because we tell Python to generate a long integer object instead.

C omplex numbers are a recent addition to Python. If you know what they are, you know why they are useful; if not, consider this section optional reading.^{[4]} Complex numbers are represented as two floatingpoint numbers梩he real and imaginary parts梐nd are coded by adding a j or J suffix to the imaginary part. We can also write complex numbers with a nonzero real part by adding the two parts with a +. For example, the complex number with a real part of 2 and an imaginary part of 3 is written: 2 + 3j. Some examples of complex math at work:
^{[4]} One of your authors is quick to point out that he has never had a need for complex numbers in some 15 years of development work. The other author isn't so lucky.
>>> 1j * 1J (1+0j) >>> 2 + 1j * 3 (2+3j) >>> (2+1j)*3 (6+3j)
Complex numbers also allow us to extract their parts as attributes, but since complex math is an advanced tool, check Python's language reference manual for additional details.
As mentioned above, Python also provides both builtin functions and builtin modules for numeric processing. Here are the builtin math module and a few builtin functions at work; we'll meet more builtins in Chapter 8.
>>> import math >>> math.pi 3.14159265359 >>> >>> abs(42), 2**4, pow(2, 4) (42, 16, 16)
Notice that builtin modules such as math must be imported and qualified, but builtin functions such as abs are always available without imports. Really, modules are external components, but builtin functions live in an implied namespace, which Python searches to find names used in your program. This namespace corresponds to the module called _ _builtin__. We talk about name resolution in Chapter 4; for now, when we say "module", think "import."
I l@ve RuBoard 