ProgrammingforNon Programmers
ProgrammingforNon Programmers
Release 2.5.1
Steven F. Lott
2 Getting Started 13
2.1 About Computers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 About Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3 Let There Be Python: Downloading and Installing . . . . . . . . . . . . . . . . . . . . . . . . 30
2.4 Two Minimally-Geeky Problems : Examples of Things Best Done by Customized Software . 39
2.5 Why Python is So Cool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3 Using Python 49
3.1 Instant Gratification : The Simplest Possible Conversation . . . . . . . . . . . . . . . . . . . 49
3.2 IDLE Time : Using Tools To Be More Productive . . . . . . . . . . . . . . . . . . . . . . . . 59
i
6.5 While We Have More To Do : The for and while Statements . . . . . . . . . . . . . . . . . 147
6.6 Becoming More Controlling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
6.7 Turning Python Loose with More Sophisticated Scripts . . . . . . . . . . . . . . . . . . . . . 167
ii
16 Appendix 1 : Debugging 543
16.1 Let There Be Python: Downloading and Installing . . . . . . . . . . . . . . . . . . . . . . . . 543
16.2 Instant Gratification : The Simplest Possible Conversation . . . . . . . . . . . . . . . . . . . 543
16.3 IDLE Time : Using Tools To Be More Productive . . . . . . . . . . . . . . . . . . . . . . . . 545
16.4 Simple Arithmetic : Numbers and Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
16.5 Better Arithmetic Through Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
16.6 Extra Functions: math and random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
16.7 Special Ops : Binary Data and Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
16.8 Peeking Under the Hood . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
16.9 Seeing Results : The print Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
16.10 Expressions, Constants and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
16.11 Assignment Bonus Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
16.12 Can We Get Your Input? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
16.13 Truth and Logic : Boolean Data and Operators . . . . . . . . . . . . . . . . . . . . . . . . . 548
16.14 Making Decisions : The Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 548
16.15 Processing Only When Necessary : The if Statement . . . . . . . . . . . . . . . . . . . . . . 548
16.16 While We Have More To Do : The for and while Statements . . . . . . . . . . . . . . . . . 549
16.17 Becoming More Controlling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
16.18 Turning Python Loose with More Sophisticated Scripts . . . . . . . . . . . . . . . . . . . . . 551
16.19 Adding New Verbs : The def Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
16.20 Common List Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
16.21 The Unexpected : The try and except statements . . . . . . . . . . . . . . . . . . . . . . . 554
16.22 Looping Back : Iterators, the for statement, and the yield statement . . . . . . . . . . . . . 555
16.23 Collecting Items : The set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
16.24 External Data and Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
16.25 Files II : Some Examples and Some Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
16.26 Files III : The Grand Unification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
16.27 Defining New Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
16.28 Inheritance, Generalization and Specialization . . . . . . . . . . . . . . . . . . . . . . . . . . 558
16.29 Additional Classy Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
16.30 Special Behavior Requires Special Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
16.31 Module Definitions – Adding New Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
16.32 Fixed-Point Numbers : Doing High Finance with decimal . . . . . . . . . . . . . . . . . . . 560
16.33 Time and Date Processing : The time and datetime Modules . . . . . . . . . . . . . . . . . 561
16.34 Text Processing and Pattern Matching : The re Module . . . . . . . . . . . . . . . . . . . . 561
16.35 Wrapping and Packaging Our Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
17 Bibliography 563
17.1 Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
17.2 Computer Science . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
17.3 Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
17.4 Languages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
17.5 Project Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
17.6 Problem Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Bibliography 569
iii
iv
Part I
1
Programming for Non-Programmers, Release 2.5.1
Legal Notice This work is licensed under a Creative Commons License. You are free
to copy, distribute, display, and perform the work under the following conditions:
• Attribution. You must give the original author, Steven F. Lott, credit.
• Noncommercial. You may not use this work for commercial purposes.
• No Derivative Works. You may not alter, transform, or build upon this work.
For any reuse or distribution, you must make clear to others the license terms of this work.
3
Programming for Non-Programmers, Release 2.5.1
4
CHAPTER
ONE
PREFACE
The Walrus and the Carpenter – Lewis Carroll “The time has come,” the Walrus said,
“To talk of many things:
Of shoes – and ships – and sealing-wax –
Of cabbages – and kings –
And why the sea is boiling hot –
and whether pigs have wings.”
You’ll need to read this book when you have the following three things happening at the same time:
• You have a problem to solve that involves data and processing.
• You’ve found that the common desktop tools (word processors, spread sheets, databases, organizers,
graphics) won’t really help. You’ve found that they require too much manual pointing and clicking, or
they don’t do the right kinds of processing on your data.
• You’re ready to invest some of your own time to learn how to write customized software that will solve
your problem.
You’ll want to read this book if you are tinkerer who likes to know how things really work. For many people,
a computer is just an appliance. You may not find this satisfactory, and you want to know more. People
who tinker with computers are called hackers, and you are about to join their ranks.
Python is what you’ve been looking for. It is an easy-to-use tool that can do any kind of processing on any
kind of data. Seriously: any processing, any data. Programming is the term for setting up a computer to
do the processing you define on your data. Once you learn the Python language, you can solve your data
processing problem.
Our objective is to get you, a non-programming newbie, up and running. When you’re done with this book,
you’ll be ready to move on to a more advanced Python book. For example, a book about the Python
libraries. You can use these libraries can help you build high-quality software with a minimum of work.
This book is about many things. The important topics include Python, programming, languages, data,
processing, and some of the skills that make up the craft of programming. We’ll talk about the core
intellectual tools of abstraction, algorithms and the formality of computer languages. We’ll also touch on
math and logic, statistics, and casino games.
5
Programming for Non-Programmers, Release 2.5.1
Python. Python is a powerful, flexible toolbox and workbench that can help solve your data processing
problem. If you need to write customized software that does precisely what you want, and you want that
software to be readable, maintainable, adaptable, inexpensive and make best use of your computer, you need
Python.
Here’s a very important distinction:
• Python is a program that does data processing.
• You control the Python program using the Python programming language.
What does this distinction mean? First, there is an opportunity for us to confuse Python (the program) and
Python (the language). We’ll attempt to be as clear as we can on the things the Python program does when
you give it commands in the Python Language. For people very new to computers, this raises questions like
“what is a programming language?” and “why can’t it just use English?” and “what if I’m not good with
languages?” We’ll return to these topics in Concepts FAQ’s. For now, we’ll emphasize the point that the
Python language is more precise than English, but still very easy to read and write.
The other thing that the distinction between program and language means is that we will focus our efforts
on learning the language. The data processing we want to perform will be completely defined by a sequence
of statements in the Python language. Learning a computer language isn’t a lot different from learning a
human language, making our job relatively easy. We’ll be reading and writing Python in no time.
Programming. When we’ve written a sequence of Python statements, we can then use that sequence over
and over again. We can process different sets of data in a standard, automatic fashion. We’ve created a
program that can automate data processing tasks, replacing tedious or error-prone pointing and clicking in
other software tools. Also, we can create programs that do things that other desktop tools can’t do at all.
The big picture is this: the combination of the Python program plus a unique sequence of Python language
statements that we create can have the effect of creating a new application for our computer. This means
that our new application uses the existing Python program as its foundation. The Python program, in turn,
depends on many other libraries and programs on your computer. The whole structure forms a kind of
technology stack, with your program on top, controlling the whole assembly.
Languages. We’ll look at three facets of a programming language: how you write it, what it means, and the
additional practical considerations that make a program useful. We’ll use these three concepts to organize
our presentation of the language. We need to separate these concepts to assure that there isn’t a lot of
confusion between the real meaning and the ways we express that meaning.
The sentences “Xander wrote a tone poem for chamber orchestra” and “The chamber orchestra’s tone poem
was written by Xander” have the same meaning, but express it different ways. They have the same semantics,
but different syntax. For example, in one sentence the verb is “wrote” , in the other sentence it is “was written
by” : different forms of the verb to write. The first form is written in active voice, and second form is called
the passive voice. Pragmatically, the first form is slightly clearer and more easily understood.
The syntax of the Python language is covered here, and in the Python Reference Manual [PythonRef]. Python
syntax is simple, and very much like English. We’ll provide many examples of language syntax. We’ll also
provide additional tips and hints focused on the newbies and non-programmers. Also, when you install
Python, you will also install a Python Tutorial [PythonTut] that presents some aspects of the language, so
you’ll have at least three places to learn syntax.
The semantics of the language specify what a statement really means. We’ll define the semantics of each
statement by showing what it makes the Python program do to your data. We’ll also be able to show
where there are alternative syntax choices that have the same meaning. In addition to semantics being
covered in this book, you’ll be able to read about the meaning of Python statements in the Python Reference
Manual [PythonRef], the Python Tutorial [PythonTut], and chapter two of the Python Library Reference
[PythonLib].
In this book, we’ll try to provide you with plenty of practical advice. In addition to breaking the topic
into bite-sized pieces, we’ll also present lots of patterns for using Python that you can apply to real-world
6 Chapter 1. Preface
Programming for Non-Programmers, Release 2.5.1
problems.
Extensions. Part of the Python technology stack are the extension libraries. These libraries are added
onto Python, which has the advantage of keeping the language trim and fit. Software components that you
might need for specialized processing are kept separate from the core language. Plus, you can safely ignore
the components you don’t need.
This means that we actually have two things to learn. First, we’ll learn the language. After that, we’ll look
at a few of the essential libraries. Once we’ve seen that, we can see how to make our own libraries, and our
own application programs.
1.3 Audience
Programming and Computer Skills. We’re going to focus on programming skills, which means we have
to presume that you already have general computer skills. You should fit into one of these populations.
• You’re new to both computers and programming. We’ve tried to be as detailed as we can be so that
you will be able to follow along gain some basic programming skills. Since we can’t cover all of the
relevant computer skills, you may need some additional support to be successful.
• You have good computer skills, but you want to learn to program. You are our target crew. Welcome
aboard.
• You have some programming experience, and you want to learn Python. You’ll find that most of
Getting Started is something you can probably skim through. We’ve provided some advanced material
that you may find interesting.
What skills will you need? How will we build up your new skills?
Skills You’ll Need. This book assumes an introductory level of skill with any of the commonly-available
computer systems. Python runs on almost any computer; because of this, we call it platform-independent.
We won’t presume a specific computer or operating system. Some basic skills will be required. If these are
a problem, you’ll need to brush up on these before going too far in this book.
• Can you download and install software from the internet? You’ll need to do this to get the Python
distribution kit from http://www.python.org. We’ll go through this procedure in some detail. However,
if you’ve never downloaded and installed software before, you may need some help with that skill.
• Do you know how to create text files? We will address doing this using a program called IDLE, the
Python Integrated Development Environment. We will also talk about doing this with a garden-variety
text editor like Notepad, TEXTPAD or BBEdit. If you don’t know how to create folders and files,
or if you have trouble finding files you’ve saved on your computer, you’ll need to expand those skills
before trying to do any programming.
• Do you know some basic algebra? Some of the exercises make use of some basic algebra. A few will
compute some statistics. We shouldn’t get past high-school math, and you probably don’t need to
brush up too much on this.
How We Help. Newbie programmers with an interest in Python are our primary audience. We provide
specific help for you in a number of ways.
• Programming is an activity that includes the language skills, but also includes design, debugging and
testing; we’ll help you develop each of these skills.
• We’ll address some of the under-the-hood topics in computers and computing, discussing how things
work and why they work that way. Some things that you’ve probably taken for granted as a user
become more important as you grow to be a programmer.
1.3. Audience 7
Programming for Non-Programmers, Release 2.5.1
• We won’t go too far into software engineering and design. We need to provide some hints on how
software gets written, but this is not a book for computer professionals; it’s for computer amateurs
with interesting data or processing needs.
• We cover a few of the most important modules to specifically prevent newbie programmers from
struggling or – worse – reinventing the wheel with each project. We can’t, however, cover too much in
a newbie book. When you’re ready for more information on the various libraries, you’re also ready for
a more advanced Python book.
When you’ve finished with this book you should be able to do the following.
• Use the core language constructs: variables, statements, exceptions, functions and classes. There are
only twenty statements in the language, so this is an easy undertaking.
• Use the Python collection classes to work with more than one piece of data at a time.
• Use a few of the Python extension libraries. We’re only going to look at libraries that help us with
finishing a polished and complete program.
A Note on Clue Absorption. Learning a programming language involves accumulating many new and
closely intertwined concepts. In our experience teaching, coaching and doing programming, there is an upper
limit on the “Clue Absorption Rate” . In order to keep below this limit, we’ve found that it helps to build up
the language as ever-expanding layers. We’ll start with a very tiny, easy to understand subset of statements;
to this we’ll add concepts until we’ve covered the entire Python language and all of the built-in data types.
Our part of the agreement is to do things in small steps. Here’s your part: you learn a language by using it.
In order for each layer to act as a foundation for the following layers, you have to let it solidify by doing small
programming exercises that exemplify the layer’s concepts. Learning Python is no different from learning
Swedish. You can read about Sweden and Swedish, but you must actually use the language to get it off the
page and into your head. We’ve found that doing a number of exercises is the only way to internalize each
language concept. There is no substitute for hands-on use of Python. You’ll need to follow the examples
and do the exercises. As you can probably tell from this paragraph, we can’t emphasize this enough.
The big difference between learning Python and learning Swedish is that you can immediately interact with
the Python program, doing real work in the Python language. Interacting in Swedish can more difficult.
The point of learning Swedish is to interact with people: for example, buying some kanelbulle (cinnamon
buns) for fika (snack). However, unless you live in Sweden, or have friends or neighbors who speak Swedish,
this interactive part of learning a human language is difficult. Interacting with Python only requires a
working computer, not a trip to Kiruna.
Also, your Swedish phrase-book gives you little useful guidance on how to pronounce words like sked (spoon)
or sju (seven); words which are notoriously tricky for English-speakers like me. Further, there are some
regional accents within Sweden, making it more difficult to learn. Python, however, is a purely written
language so you don’t have subtleties of pronunciation, you only have spelling and grammar.
This book falls into fourteen distinct parts. To manage the clue absorption rate, the parts are organized in
a way that builds up the language in layers from simple, central concepts to more advanced features. Each
part introduces a few new concepts. Programming exercises are provided to encourage further exploration
of each layer.
Some programming languages (like Pascal or Basic) were specifically designed to help teach programming.
Most other programming languages (like Python) are designed for doing the practical work of solving infor-
mation processing problems. One consequence of this is that Python is a tightly integrated whole. Some
features of the language will have both simple and advanced semantics. In many cases some simple-looking
8 Chapter 1. Preface
Programming for Non-Programmers, Release 2.5.1
features will actually depend on some more advanced parts of the language. This forces us to revisit some
subjects several times, first for an introduction, then for more in-depth treatment.
Chickens and Eggs. One subtext woven into this book is the two-sided coin labeled “data processing” .
The processing side of the coin reflects the imperative-voice verb statements in the Python language. This
active sense of “first do this, then do that” is central to programming. On the other side of the coin, we
have the data side, which includes numbers, strings of letters, related groups of values, lists of values and
relationships between values. Often, when we think of computer data, we think of files. The way we structure
our data is also central to programming.
Since they’re both central, and hopelessly intertwined, Data and Processing have a chicken-and-egg relation-
ship. We could cover either of these topics first and get to the other second. In this book, we had to choose
and we elected to look at processing first, and then, in Getting Our Bearings, switching over to the data
side.
The other topics that weave through this book are the design, debugging and testing skills you’ll need to
grow. We’ll develop these skills through hands-on use, so each chapter has five kinds of information.
• Concepts, including details on how you say it and what it means.
• Hands-on Examples, showing what happens when you do it.
• Debugging Tips, showing what to look for when something goes wrong.
• Exercises, so you can tackle problems on your own. The book doesn’t have solutions, since that would
reduce the exercises to looking up the answer and typing it in. For help, you can see the author’s web
site, http://homepage.mac.com/s_lott/books/index.html.
• Additional material to point you toward a deeper understanding.
Some Big Problems. There are a couple of problems that we’ll use throughout this book to show how you
use Python. Both problems are related to casino games. We don’t embrace gambling; indeed, as you work
through these sample problems, you’ll see precisely how the casino games are rigged to take your money. We
do, however, like casino games because they are moderately complex and not very geeky. Really complex
problems require whole books just to discuss the problem and its solution. Simple problems can be solved
with a spreadsheet. In the middle are problems that require Python.
We’ll provide some of the rules for Roulette in Two Minimally-Geeky Problems : Examples of Things Best
Done by Customized Software as well as some of the rules for Craps. We’ll look at a couple of interesting
casino gambling problems in this chapter that will give us a representative problem that we can solve with
Python programming.
Getting Started. Getting Started introduces the basics of computers, languages and Python. About
Computers defines the basic concepts we’ll be working with. About Programs will more fully define a program
and the art of programming. Let There Be Python: Downloading and Installing covers installation of Python.
Two Minimally-Geeky Problems : Examples of Things Best Done by Customized Software gives an overview
of two problems we’ll use Python to solve. Why Python is So Cool provides some history and background
on Python.
Using Python. Using Python introduces using Python and the IDLE development environment. We’ll
cover direct use of Python in Instant Gratification : The Simplest Possible Conversation. We’ll cover IDLE
in IDLE Time : Using Tools To Be More Productive.
Additional sections will add depth to this material as we explore more of the language. Turning Python
Loose With a Script shows how to control Python with a script of statements. Turning Python Loose with
More Sophisticated Scripts will make use of the Python control statements for more sophisticated scripts.
Processing. Arithmetic and Expressions introduces the basic features of the Python language. Simple
Arithmetic : Numbers and Operators includes the basic arithmetic operations and numeric types. Better
Arithmetic Through Functions introduces the most useful built-in functions. Special Ops : Binary Data and
Operators covers some additional operators for more specialized purposes. Peeking Under the Hood has some
additional topics that may help you get a better grip on how Python works.
Programming Essentials introduces the essential programming constructs for input, processing and output.
Seeing Results : The print Statement shows how to do output with the print statement. Turning Python
Loose With a Script shows how to control Python with a script of statements. Expressions, Constants
and Variables introduces variables and the assignment statement. We’ll cover some additional assignment
topics in Assignment Bonus Features, including multiple assignment and how to make best use of the Python
shell. Can We Get Your Input? shows the two simple input functions.
Some Self-Control introduces the various ways to control which statements execute. Truth and Logic :
Boolean Data and Operators adds truth and conditions to the language. We’ll look at comparisons in
Making Decisions : The Comparison Operators. Processing Only When Necessary : The if Statement adds
conditional and While We Have More To Do : The for and while Statements adds iterative processing
statements. In Becoming More Controlling we’ll cover some additional topics in control. Turning Python
Loose with More Sophisticated Scripts will make use of these control statements for more sophisticated scripts.
Organizing Programs with Function Definitions shows how to define functions to organize a program. Adding
New Verbs : The def Statement introduces the basic function definition and use. From there we’ll look at
Extra Functions: math and random. Flexibility and Clarity : Optional Parameters, Keyword Arguments
adds some useful features to these basic. A Few More Function Definition Tools describes concepts like
returning multiple values.
After introducing some basic types of collections in the next part, we’ll return to the language topics in
Additional Processing Control Patterns. This will add exceptions in The Unexpected : The try and except
statements and generators in Looping Back : Iterators, the for statement, and the yield statement.
Course Change. Programming is all about data and processing. Up to this point, we’ve focused on
processing. From this point forward, we’ll focus on data. Since these are two sides of the same coin, there’s
no absolute separation, it’s only a matter of focus. Getting Our Bearings will clarify this relationship between
data and processing.
Data. We’ll start covering the data side of data processing in Basic Sequential Collections of Data, which
is an overview of the sequential collections. Collecting Items in Sequence extends the data types to include
various kinds of sequences. These include Sequences of Characters : str and Unicode, Doubles, Triples,
Quadruples : The tuple and Flexible Sequences : the list. We’ll look at some additional topics in Common
List Design Patterns.
We’ll revisit some processing elements in Additional Processing Control Patterns. This will include The
Unexpected : The try and except statements as well as Looping Back : Iterators, the for statement, and the
yield statement.
We’ll cover more data structures in More Data Collections. We’ll look at the set in Collecting Items : The
set. Mappings : The dict describes mappings and dictionaries. We’ll use the map and sequence structures in
Defining More Flexible Functions with Mappings. External Data and Files covers the basics of files. Files II
: Some Examples and Some Modules covers several closely related operating system ( OS ) services. Files III
: The Grand Unification presents some additional material on files and how you can use them from Python
programs.
Organization and Structure. Data + Processing = Objects describes the object-oriented programming
features of Python. Objects: A Retrospective reviews objects we’ve already worked with. Then we can exam-
ine the basics of class definitions in Defining New Objects. In Inheritance, Generalization and Specialization
we’ll introduce a very significant technique for simplifying programs. Additional Classy Topics describes
some more tools that help simplify class definition.
We’ll take a first look at how we can write classes that look like Python’s built-in classes in Special Behavior
Requires Special Methods. New Kinds of Numbers: Fractions and Currency shows how we can build very
useful kinds of numbers. We can create more sophisticated collections using the techniques in Creating New
Types of Collections.
10 Chapter 1. Preface
Programming for Non-Programmers, Release 2.5.1
Modules : The unit of software packaging and assembly describes modules, which provide a higher-level
grouping of class and function definitions. It also summarizes selected extension modules provided with
the Python environment. Module Definitions – Adding New Concepts provides basic semantics and syntax
for creating modules. It also covers the organization of the available Python modules. Essential Modules :
The Python Library surveys the modules you’re most likely to use. We’ll look at how to handle currency
in Fixed-Point Numbers : Doing High Finance with decimal. Time and Date Processing : The time and
datetime Modules defines the time and calendar modules. Text Processing and Pattern Matching : The re
Module shows how to do string pattern matching and processing.
Some of the commonly-used modules are covered during earlier chapters. In particular the math and random
modules are covered in The math Module – Trig and Logs and the string module is covered in Sequences
of Characters : str and Unicode. Files II : Some Examples and Some Modules touches on many more
file-handling modules.
Fit and Finish. We finish talking about the fit and finish of a completed program in Fit and Finish:
Complete Programs. The basics of a complete program are covered in Wrapping and Packaging Our Solution.
Many species of programs are described in Architectural Patterns – A Family Tree.
Here is how we’ll show Python programs in the rest of the book. The programs will be in separate boxes,
in a different font, often with numbered “callouts” to help explain the program. This example is way too
advanced to read in detail (it’s part of Mappings : The dict) it just shows what examples look like.
combo = { }
for i in range(1,7):
for j in range(1,7):
roll= i+j
combo.setdefault( roll, 0 )
combo[roll] += 1
for n in range(2,13):
print "%d %.2f%%" % ( n, combo[n]/36.0 )
1. This line creates a Python dictionary, a map from key to value. In this case, the key will be a roll, a
number from 2 to 12. The value will be a count of the number of times that roll occurred.
1. This line assures that the rolled number exists in the dictionary. If it doesn’t exist, it will default, and
will be assigned frequency count of 0.
1. This line prints each member of the resulting dictionary.
The output from the above program will be shown as follows:
2 0.03%
3 0.06%
4 0.08%
5 0.11%
6 0.14%
7 0.17%
8 0.14%
9 0.11%
10 0.08%
11 0.06%
12 0.03%
We will use the following type styles for references to a specific Class, method() , attribute, which includes
both class variables or instance variables.
Sidebars
When we do have a significant digression, it will appear in a sidebar, like this.
Tip: Tips
There will be design tips, and warnings, in the material for each exercise. These reflect considerations and
lessons learned that aren’t typically clear to starting OO designers.
1.7 Acknowledgements
I have to thank all of the people at my employer, CTG, for giving me so many decades of opportunities to
practice the craft of programming.
12 Chapter 1. Preface
CHAPTER
TWO
GETTING STARTED
This part provides some necessary background to help non-programming newbies get ready to write their
own programs. If you have good computer skills, this section may be all review. If you are very new to
computers, our objective is to build up your skills by providing as complete an introduction as we can.
Computing has a lot of obscure words, and we’ll need some consistent definitions.
We’ll start with the big picture. In About Computers we’ll provide a list of concepts that are central to
computers, programs and programming. In About Programs we’ll narrow our focus to programs and how we
create them.
In Let There Be Python: Downloading and Installing we’ll describe how to install Python. You’ll need to
choose just one of Windows Installation, Macintosh Installation or GNU/Linux and UNIX Overview. This
chapter has the essential first step in starting to build programs: getting our tools organized.
We’ll describe two typical problems that Python can help us solve in Two Minimally-Geeky Problems :
Examples of Things Best Done by Customized Software. We’ll provide many, many more exercises and
problems than just these two. But these are representative of the problems we’ll tackle.
We also provide some history and background to help show why Python is so cool. If you are already
convinced that Python is your tool of choice, you can skip Why Python is So Cool. If you’ve heard about
Visual Basic, Java or C++ and wonder why Python is better, you might find something helpful in that
section. It involves some computer-science jargon; you’ve been warned.
Our job as a programmer is to write statements in the Python language that will control our computer
system. This chapter describes the basic topics of what a computer is and how we set up a computer
to perform a task. We need to be perfectly clear on what computing is so that you can be successful in
programming a computer to solve your problems.
In Hardware Terminology we’ll provide a common set of terms, aimed at newbies who will soon become
programmers. The computer industry has a lot of marketing hype, which can lead to confusing use of terms.
Worse, the computer industry has some terminology that is intended to pave the way toward ease of use,
but are really just stumbling blocks.
In Software Terminology we’ll move away from the terminology for purely tangible things and look at the
less tangible world of software.
13
Programming for Non-Programmers, Release 2.5.1
We’ll build on the terminology foundation in What is a Program? and define a program more completely.
This is, after all, our goal, and we’ll need to have it clearly defined so we can see how we’re closing in on it.
We want to define some terms that we’ll be using throughout the book. We’re going to build up our Python
understanding from this foundational terminology. In the computer world, many concepts are new, and we’ll
try to make them more familiar to you. Further, some of the concepts are abstract, forcing us to borrow
existing words and extend or modify their meanings. We’ll also define them by example as we go forward in
exploring Python.
This section is a kind of big-picture road map of computers. We’ll refer back to these definitions in the
sections which follow.
The first set of definitions are things we lump togther under “hardware”, since they’re mostly tangible things
that sit on desks and require dusting. The next section has definitions that will include “software”: those
intangible things that don’t require dusting.
Computer, Computer System Okay, this is perhaps silly, but we want to be very clear. We’re talking
about the whole system of interconnected parts that make up a computer. We’re including all the
Devices, incluing displays and keyboards and mice. We’re drawing a line between our computer and
the network that interconnects it to other computers.
A computer is a very generalized appliance. Without software, it’s just a lump of parts. Even with the
general softare components we’ll talk about in Software Terminology, it doesn’t do anything specific.
We reserve the term “application software” for that software that applies this very general system to
our specific needs.
Inside a computer system there are numerous electronic components, one of which is the processor,
which controls most of what a computer does. Other components include memory.
It helps to think of two species of computers: your personal computer – desktop or laptop – sometimes
called a “client” and shared computers called “servers”. When you are surfing a web site, you are using
more than one computer: your personal computer is running the web browser, and one or more server
computers are responding to your browser’s requests. Most of the internet things you see involve your
desktop and a server somewhere else.
We do need to note that we’re using the principle of abstraction. A number of electronic devices are all
computers on which we can do Python programming. Laptops, desktops, iMacs, PowerBooks, clients,
servers, Dells and HP’s are all examples of this abstraction we’re calling a computer system.
Device, Peripheral Device We have a number of devices that are part of our computers. Most devices
are plugged into the computer box and connected by wires, putting them on the periphery of the
computer. A few devices are wireless; they connect using Bluetooth, WiFi (IEEE 802.11) or infrared
( IR) signals. We call the connection an interface.
The most important devices are hidden within the box, physically adjacent to the central processor.
These central items are memory (called random-access memory, RAM) and a disk. The disk, while
inside the box, is still considered peripheral because once upon a time, disks were huge and expensive.
The other peripheral devices are the ones we can see: display, keyboard and mouse. After that are
other storage devices, including CD‘s, DVD‘s, USB drives, cameras, scanners, printers, drawing tablets,
etc. Finally we have network connections, which can be Ethernet, wireless or a modem. All devices
are controlled by pieces of software called drivers.
Note that we’ve applied the abstraction principle again. We’ve lumped a variety of components into
abstract categories.
Memory, RAM The computer’s working memory (Random-Access Memory, or RAM) contains two things:
our data and the processing instructions (or program) for manipulating that data. Most modern
computers are called stored program digital computers. The program is stored in memory along with
the data. The data is represented as digits, not mechanical analogies. In contrast, an analog computer
uses mechanical analogs for numbers, like spinning gears that make an analog speedometer show
the speed, or the strip of metal that changes shape to make an analog meat thermometer show the
temperature.
The central processor fetches each instruction from the computer’s memory and then executes that
instruction. We like to call this the fetch-execute loop that the processor carries out. The processor
chip itself is hardware; the instructions in memory are called software. Since the instructions are stored
in memory, they can be changed. We take this for granted every time we double click an icon and a
program is loaded into memory. The data on which the processor is working must also be in memory.
When we open a document file, we see it read from the disk into memory so we can work on it.
Memory is dynamic: it changes as the software does its work. Memory which doesn’t change is called
Read-Only Memory (ROM).
Memory is volatile: when we turn the computer off, the contents vanish. When we turn the computer
on, the contents of memory are random, and our programs and data must be loaded into memory from
some persistent device. The tradeoff for volatility is that memory is blazingly fast.
Memory is accessed “randomly”: any of the 512 million bytes of my computer’s memory can be accessed
with equal ease. Other kinds of memory have sequential access; for example, magnetic cassette tapes
must be accessed sequentially.
For hair-splitters, we recognize that there are special-purpose computing devices which have fixed
programs that aren’t loaded into memory at the click of a mouse. These devices have their software in
read-only memory, and keep only data in working memory. When our program is permanently stored
in ROM, we call it firmware instead of software. Most household appliances that have computers with
ROM.
Disk, Hard Disk, Hard Drive We call these disk drives because the memory medium is a spinning mag-
netizable disk with read-write heads that shuttle across the surface; you can sometimes hear the clicking
as the heads move. Individual digits are encoded across the surface of the disk; grouped into blocks
of data. Some people are in the habit of calling them “hard” to distinguish them from the obsolete
“floppy” disks that were used in the early days of personal computing.
Our various files (or “documents”) inluding our programs and our data will – eventually – reside
on some kind of disk or disk-like device. However, the operating system interposes some structure,
discipline and protocol between our needs for saving files and the vagaries of the disk device. We’ll
look at this in Software Terminology and again in Working with Files.
Disk memory is described as “random access”, even though it isn’t completely random: there are
read-write heads which move across the surface and the surface is rotating. There are delays while the
computer waits for the heads to arrive at the right position. There are also delays while the computer
waits for the disk to spin to the proper location under the heads. At 7200 RPM’s, you’re waiting less
than 1/7200th of a second, but you’re still waiting.
Your computer’s disk can be imagined as persistent, slow memory: when we turn off the computer,
the data remains intact. The tradeoff is that it is agonizingly slow: it reads and writes in milliseconds,
close to a million times slower than dynamic memory.
Disk memory is also cheaper than RAM by a factor of at almost 1000: we buy 500 gigabytes (500
billion bytes, or 500,000 megabytes) of disk for $100; the cost of 512 megabytes of memory.
Human Interface, Display, Keyboard, Mouse The human interface to the computer typically consists
of three devices: a display, a keyboard and a mouse. Some people use additional devices: a second
display, a microphone, speakers or a drawing tablet are common examples. Some people replace the
mouse with a trackball. These are often wired to the computer, but wireless devices are also popular.
In the early days of computers – before the invention of the mouse – the displays and keyboards could
only handle characters: letters, numbers and punctuation. When we used computers in the early days,
we spelled out each command, one line at a time. Now, we have the addition of sophisticated graphical
displays and the mouse. When we use computers now, we point and click, using graphical gestures as
our commands. Consequently, we have two kinds of human interfaces: the Command-Line Interface
(CLI), and the Graphical User Interface (GUI).
A keyboard and a mouse provide inputs to software. They work by interrupting what the computer is
doing, providing the character you typed, or the mouse button you pushed. A piece of software called
the Operating System has the job of collecting this stream of input and providing it to the application
software. A stream of characters is pretty simple. The mouse clicks, however, are more complex events
because they involve the screen location as well as the button information, plus any keyboard shift
keys.
A display shows you the outputs from software. The display device has to be shared by a number
of application programs. Each program has one or more windows where their output is sent. The
Operating System has the job of mediating this sharing to assure that one program doesn’t disturb
another program’s window. Generally, each program will use a series of drawing commands to paint the
letters or pictures. There are many, many different approaches to assembling the output in a window.
We won’t touch on this because of the bewildering number of choices.
Historically, display devices used paper; everything was printed. Then they switched to video tech-
nology. Currently, displays use liquid crystal technology. Because displays were once almost entirely
video, we sometimes summarize the human interface as the Keyboard-Video-Mouse ( KVM).
In order to keep things as simple as possible, we’re going to focus on the command-line interface. Our
programs will read characters from the keyboard, and display characters in an output window. Even
though the programs we write won’t respond to mouse events, we’ll still use the mouse to interact with
the operating system and programs like IDLE.
Other Storage, CD, DVD, USB Drive, Camera These storage devices are slightly different from the
internal disk drive or hard drive. The differences are the degree of volatility of the medium. Packaged
CD‘s and DVD‘s are read-only; we call them CD Read-Only Memory ( CD-ROM). When we burn our
own CD or DVD, we used to call it creating a Write-Once-Read-Many ( WORM) device. Now there
are CD-RW devices which can be written (slowly) many times, and read (quickly) many times, making
the old WORM acronym outdated.
Where does that leave Universal Serial Bus USB drives (known by a wide variety of trademarked names
like Thumb Drive™or Jump Drive™) and the memory stick in our camera? These are just like the
internal disk drive, except they don’t involve a spinning magnetized disk. They are slower, have less
capacity and are slightly more expensive than a disk.
Our operating system provides a single abstraction that makes our various disk drives and “other
storage” all appear to be very similar. When we look at these devices they all appear to have folders
and documents. We’ll return to this unification in Files III : The Grand Unification.
Scanner, Printer These are usually USB devices; they are unique in that they send data in one direction
only. Scanners send data into our computer; our computer sends data to a printer. These are a kind
of storage, but they are focused on human interaction: scanning or printing photos or documents.
The scanner provides a stream of data to an application program. Properly interpreted, this stream of
data is a sequence of picture elements (called “pixels” ) that show the color of a small section of the
document on the scanner. Getting input from the scanner is a complex sequence of operations to reset
the apparatus and gather the sequence of pixels.
A printer, similarly, accepts a stream of data. Properly interpreted, this stream of data is a sequence
of commands that will draw the appropriate letters and lines in the desired places on the page. Some
printers require a sequence of pixels, and the printer uses this to put ink on paper. Other printers use
a more sophisticated page description language, which the printer processes to determine the pixels,
and then deposits ink on paper. One example of these sophisticated graphic languages is PostScript.
Network, Ethernet, Wireless, WiFi, Dial-up, Modem A network is built from a number of cooper-
ating technologies. Somewhere, buried under streets and closeted in telecommunications facilities is
the global Internet: a collection of computers, wires and software that cooperates to route data. When
you have a cable-modem, or use a wireless connection in a coffee shop, or use the Local Area Network
(LAN) at school or work, your computer is (indirectly) connected to the Internet. There is a physi-
cal link (a wire or an antenna), there are software protocols for organizing the data and sharing the
link properly. There are software libraries used by the programs on our computer to surf web pages,
exchange email or purchase MP3‘s.
While there are endless physical differences among network devices, the rules, protocols and software
make these various devices almost interchangeable. There is stack of technology that uses the principle
of abstraction very heavily to minimize the distinctions among wireless and wired connections. This
kind of abstraction assures that a program like a web browser will work precisely the same no matter
what the physical link really is. The people who designed the Internet had abstraction very firmly in
mind as a way to allow the Internet to expand with new technology and still work consistently.
Hardware terminology is pretty simple. You can see and touch the hardware. You’re rarely confused by the
difference between a scanner and a printer.
Software, on the other hand, is less tangible. Programming is the act of creating new software. This
terminology is perhaps more important than the hardware terminology above.
Note that Software is essential for making our computer do anything. The varius components and devices –
without software – are inert lumps of plastic and metal.
Operating System The Operating System ( OS) ties all of the computer’s devices together to create a
usable, integrated computer system. The operating system includes the software called device drivers
that make the various devices work consistently. It manages scarce resources like memory and time by
assuring that all the programs share those resources. The operating system also manages the various
disk drives by imposing some organizing rules on the data; we call the organizing rules and the related
software the file system.
The operating system creates the desktop metaphor that we see. It manages the various windows; it
directs mouse clicks and keyboard characters to the proper application program. It depicts the file
system with a visual metaphor of folders (directories) and documents (files). The desktop is the often
shown to you by a program called the “finder” or “explorer”; this program draws the various icons and
the dock or task bar.
In addition to managing devices and resources, the OS starts programs. Starting a program means
allocating memory, loading the instructions from the disk, allocating processor time to the program,
and allocating any other resources in the processor chip.
Finally, we have to note that it is the OS that provides most of the abstractions that make modern
computing possible. The idea that a variety of individual types of devices and components could
be summarized by a single abstraction of “storage” allows disk drives, CD-ROM‘s, DVD-ROM‘s and
thumb drives to peacefully co-exist. It allows us to run out and buy a thumb drive and plug it into
our computer and have it immediately available to store the pictures of our trip to Sweden.
Program, Application, Software A program is started by the operating system to do something useful.
We’ll look at this in depth in What is a Program? and What Happens When a Program “Runs?”.
Since we will be writing our own programs, we need to be crystal clear on what programs really are
and how they make our computer behave.
There isn’t a useful distinction between words like “program”, “command”, “application”, “application
program”, and “application system”. Some vendors even call their programs “solutions”. We’ll try to
stick to the word program. A program is rarely a single thing, so we’ll try to identify a program with
the one file that contains the main part of the program.
File, Document, Data, Database, the “File System” The data you want to keep is saved to the disk
in files. Sometimes these are called documents, to make a metaphorical parallel between a physical
paper document and a disk file. Files are collected into directories, sometimes depicted as metaphorical
folders. A paper document is placed in a folder the same way a file is placed in a directory. Computer
folders, however, can have huge numbers of documents. Computer folders, also, can contain other
folders without any practical limit. The document and folder point of view is a handy visual metaphor
used to clarify the file and directory structure on our disk.
This is so important that Working with Files is devoted to how our programs can work with files.
Boot Not footwear. Not a synonym for kick, as in “booted out the door.” No, boot is used to describe a
particular disk as the “boot disk”. We call one disk the boot disk because of the way the operating
system starts running: it pulls itself up by it’s own bootstraps. Consider this quote from James Joyce’s
Ulysses: “There were others who had forced their way to the top from the lowest rung by the aid of
their bootstraps.”
The operating system takes control of the computer system in phases. A disk has a boot sector (or
boot block) set aside to contain a tiny program that simply loads other programs into memory. This
program can either load the expected OS, or it can load a specialized boot selection program (examples
include BootCamp, GRUB, or LiLo.) The boot program allows you to control which OS is loaded.
Either the boot sector directly loads the OS, or it loads and runs a boot program which loads the OS.
The part of the OS that is loaded into memory is just the kernel. Once the kernel starts running, it
loads a few handy programs and starts these programs running. These programs then load the rest of
the OS into memory. The device drivers must be added to the kernel. Once all of the device drivers
are loaded, and the devices configured, then the user interface components can be loaded and started.
At this point, the “desktop” appears.
Note that part of the OS (the kernel) loads other parts of the operating system into memory and
starts them running. It pulls itself up by its own bootstraps. They call this bootstrapping, or booting.
The kernel will also load our software into memory and start it running. We’ll depend heavily on this
central feature of an OS.
In Software Terminology we provided a kind of road map to computers. Here, we’re going to look a little
more closely at these things called “programs”.
What – Exactly – is the Point? The essence of a program is the following: a program sets up a computer
to do a specific task. We could say that it is a program which applies a general-purpose computer to a specific
problem. That’s why we call them “application programs”; the programs apply this generalized computer
appliance to definite data processing needs.
There is a kind of parallel between a computer system running programs and a television playing a particular
TV show. Without the program, the computer is just a pile of inert electronics. Similarly, if there is no
TV show, the television just sits there showing a blank screen. (When I was a kid, a TV with no program
showed a flickering “noise” pattern. Modern TV’s don’t do this, they just sit there.)
We’re going to focus on two parts of a program: data and processing. We’ll be aiming at programs which
read and write files of data, much like our ordinary desktop tools open and save files. We aren’t excluding
game programs or programs that control physical processes. A game’s data is the control actions from the
player plus the description of the game’s levels and environments. The processing that a game does matches
the inputs, the current state and the level to determine what happens next. An interactive game, however,
is considerably more complex than a program to evaluate a file that has a list of our stocks.
Program Varietals. At this point, we need to make a distinction between some varieties of programs:
specifically, a binary executable and a script. A binary executable or binary application is a program that
takes direct control computer’s processor. We call it binary because it uses the binary codes specific to
the processor chip inside the computer. If you haven’t encountered “binary” before, see Binary Codes.
Most programs that you buy or download fit this description. Most of the office applications you use are
binary executables. A web browser, for example, is a binary executable, as is the python program (named
python.exe in Windows.)
Your operating system (for example, Windows or GNU/Linux or MacOS) is a complex collection of binary
executables. These operating system programs don’t solve any particular problem, but they enable the
computer to be used by non-engineers.
A binary executable’s direct control over the processor is beneficial because it gives the best speed and uses
the fewest resources. However, the cost of this control is the relative opacity of the coded instructions that
control the processor chip. The processor instruction codes are focused on the electronic switching arcana
of gates, flip-flops and registers. They are not focused on data processing at a human level. If you want to
see how complex and confusing the processor chip can be, go to Intel or AMD’s web site and download the
technical specifications for one of their processors.
One subtlety that we have to acknowledge is that even the binary applications don’t have complete control
over the entire computer system. Recall that the computer system loads a kernel of software when it starts.
All of the binary applications outside this kernel do parts of their work by using program fragments provided
by the kernel. This important design feature of the operating system assures that all of the application
programs share resources politely. One of the kernel’s two jobs is to coordinate among the application
programs. If every binary application simply grabbed resources willy-nilly, one badly behaved program
could stop all other programs from working. Imagine the tedium of quitting your browser to make notes in
your word processor, then quitting your word processor to go back to your web browser.
The other of the kernel’s two jobs is to embody the abstraction principle and make a wide variety of processors
have a nearly identical set of features.
Layers of Abstraction. Let’s take a close look at our metaphor again. We said there is a strong parallel
between a computer running a program and a TV playing a particular TV show. We now have two layers
of meaning here:
• The whole computer system running programs – in a very broad sense – is like a TV playing a particular
show. This is the most abstract view, combining many concepts together.
• At a more detailed view, we have a composite concept of computer system plus Operating System. It
is this hardware-plus-software device which runs our application programs. Here, our TV metaphor
starts to break down because we don’t have to get a kernel TV show that allows our TV to watch a
specific channel. Our TV is complete by itself. Our computer, however, can’t do anything without
some software. And we need some kernel of OS software to help us run our desired application software.
Binary Codes
Binary codes were invented by the inhabitants of the planet Binome, the Binome Individual uniTs, or
BITs. These creates had two hands of four fingers each, giving them eight usable digits instead of the
ten that most Earthlings have. Unlike Earthlings, who use their ten fingers to count to ten, the BITs
use only their right hands and can only count to one.
If their hand is down, that’s zero. If they raise their hand, that’s one. They don’t use their left hands
or their fingers. It seems like such a waste, but the BITs have a clever work-around
If a BIT want to count to a larger number, say ten, they recruit three friends. Four BITs can then
chose positions and count to ten with ease. The right-most position is worth 1. The next position to
the left is worth 2. The next position is worth 4, and the last position is worth 8.
The final answer is the sum of the positions with hands in the air.
Say we have BITs named Alpha, Bravo, Charlie and Delta standing around. Alpha is in the first
position, worth only 1, and Delta is in the fourth position, worth 8. If Alpha and Charlie raise their
hands, this is positions worth 1 and 4. The total is 5. If all four BITs raise their hands, it’s 8+4+2+1,
which is 15. Four BITs have 16 different values, from zero (all hands down) to 15 (all hands up).
Delta (8) Charlie (4) Bravo (2) Alpha (1) total
down down down down 0
down down down up 1
down down up down 2
down down up up 2+1=3
down up down down 4
down up down up 4+1=5
down up up down 4+2=6
down up up up 4+2+1=7
up down down down 8
up down down up 8+1=9
up down up down 8 + 2 = 10
A party of eight BITs can show 256 different values from zero to 255. A group of thirty-two BITs can
count to over 4 billion.
The reason this scheme works is that we only have two values: on and off. This two valued (binary)
system is easy to build into electronic circuits: a component is either on or off. Internally, our processor
chip works in this binary arithmetic scheme because its fast and efficient.
Our programs (and our data) reside in two places. When we’re using a program, it must be stored in memory.
However, memory is volatile, so when we’re not using a program, it must reside on a disk somewhere. Since
our disks are organized into file systems, we find these programs residing in files.
When we look at the various files on our computer, we’ll see a number of broad categories.
1. Applications or Programs. These are executable files, they will control the computer-plus-operating
system abstract machine. There are two kinds of programs:
(a) Binary Executable programs use the processor chip’s binary codes. We use these, but won’t be
building them.
(b) Script programs use a script language like Python. We’ll build these.
2. Documents. Our OS associates each document with a program. This is a convenient short-cut for us,
and allows us to double-click the document and have the proper program start running.
When we use the Finder’s Get Info to look at the detailed information for an application icon in MacOS or
GNU/Linux, we can see that our application program icons are marked “executable” and the file type will
be “application” . In Windows, a binary executable program must have a file name that ends with .exe (or
.com, but this is rare).
Starting A Program. Our various operating systems give us several user interface actions that will load
a program into memory so that we can start to use it. Since starting a program is the primary purpose of
an operating system, there are many ways to accomplish this.
• Double click an application icon
• Double click a document icon
• Single click something in the dock or task bar
• Click on a run... menu item in the Start... menu
• Use the Windows Command Prompt; in GNU/Linux or the MacOS it is called a terminal. Through
the terminal window we interact with a shell program that allows us to type the name of another
program to have that started.
All of these actions are just different ways to get the operating system to locate the binary executable, load
it into memory and give it the resources to do its unique task.
All of these choices boil down to two overlapping paths to a starting a binary executable:
• From the application icon. In this case, we clicked the icon that represents the binary application
itself. The OS loaded the binary application and started it. Once started, some programs will open a
blank document, some will give you a window that lets you pick what you want to do. Others may have
saved a preferences file that identifies what document you last worked with and open that document
for you when they start. This varies a great deal, there is no single rule to capture the wide variations
in start-up behavior of programs.
• From a document icon. In this case, we clicked on an icon that represents a document; the document
is associated with a specific binary program. The OS uses this association to find and start the
appropriate program. The OS also provides the binary program with the name of the document file we
clicked so that the program can open the document for you. This provides the easy-to-use experience
of clicking on your document and being able to make changes to it.
It helps to inventory the various devices and interfaces on your computer system. Start with the
central processor (which may hang behind the display on some iMac’s), and work your way around
your desktop to identify each part.
Use your word processor to write down all of the computer system parts. You’ll need a folder for your
Python programming projects. Create that folder; this inventory will be the first file in that folder.
2. Get Info/Properties.
Find your web browser application. You may have a desktop shortcut, or a MacOS dock icon, a
Windows start menu icon or a Windows toolbar icon for your browser.
In Windows, you can ask for the properties of an application icon. If it is a short cut, you can use the
Find Target... button to locate the real application file. With MacOS, you can use control-click to
get information on a particular icon.
In the MacOS, you can ask for the information about an application icon. In the MacOS Finder, you
can click on an application icon and then use the File Get Info... to get information on an icon.
3. Get Info/Properties.
Locate a file you made with your favorite word processor. The first exercise in this section was an
opportunity to make a new document file.
In Windows, you can ask for the properties of a document icon. If it is a short cut, you can use the
Find Target... button to locate the real application file. With MacOS, you can use control-click to
get information on a particular icon. The properties name the application that is associated with this
document. In Windows, you can see the Type of File and Opens With information about the file.
Using MacOS, you can ask for information about a document icon. In the MacOS Finder, you can
click on an application icon and then use the File Get Info... to get information on an icon. The
information has a Kind description. The Open With label shows the application that will open this
document.
Our job as a programmer is to create programs, which are statements in the Python language. When we run
those programs, they will control our computer system to do the data processing we specified. This chapter
takes a closer look at what a program really is and what is means to “run” a program. This will lead us to
the program named python (or python.exe) and how we control it with statements in the Python language.
We’ll look closely at what our computer does when it runs a program in What Happens When a Program
“Runs?”. Based on this, we can look at the Python program in The Python Program and What It Does.
Our job, as programmer, is examined in What is Programming?.
We’ll provide a little bit of advanced material in So How Do They Create Binary Executables?. This advanced
material may not help you learn the Python language. However, for some people, it fills in some necessary
background on how the Python program really works. We’ll also answer some questions in Concepts FAQ’s.
In What is a Program? we looked at what a program is. Here we’ll look at what it means when the operating
system runs a program. After this, we can revisit Python, and define what a script program is in The Python
Program and What It Does.
Computer use is a goal-directed activity. When we’re done using our software, we’ve finished some task and
(hopefully) are happy and successful. We can call this a state change. Before we ran our program, we were
in one mental state: we were curious about something or needed to get some data processing done. After
we ran our program, we were in a different mental state of happy and successful. For example, we got the
total value of our stock portfolio from a file of stock purchases.
We like this “state of being” view of how programs work. We can think of many things as state changes.
When we clean our office, it goes from a state of messy to a state of clean (or, in my case, less messy). When
we order breakfast at the coffee shop we go through a number of state changes: from hungry to waiting for
our toast, to eating our toast, to full and ready to start the day.
Let’s work backwards to see what had to happen to get us to a happy and successful state of being.
Success!. The program has done the desired job, cleaned up, and we are back looking at the operating
system interface (the Finder, Explorer or a Terminal prompt). We say that the program has reached a
terminating state (also known as “all finished”). Therefore, one goal of programming is to create a program
that finishes it’s work normally so that the operating system can deallocate the resources and regain control
of our computer.
In order to finish, what had to be true? Clearly, the program had to run and do what we wanted.
Running. The program is running, doing the job we designed it to do. Perhaps it is controlling a device or
computing something. The program is undergoing a number of internal state changes as it moves from its
initial or start-up state to its terminating state. Often it reaches terminating state because we clicked the
Quit menu item. Another goal of programming, then, is to have the program behave correctly when it is
running.
In order to run properly and do what we wanted, what had to be true? The program had to start running.
Starting. The operating system loads the program into memory from files on a disk. The operating system
may load additional standard modules that the program requires. The operating system also creates a
schedule for our program. Most operating systems interleave several activities, and our program is only one
of many programs sharing the time and memory of the computer. Once everything is in place we see it start
running. Another goal of programming is to have a program that cooperates with the operating system to
start in a simple way and follow all the rules for allocating resources.
When we reverse this sequence, it leads us to our goal. This goal-focused design is very important.
This sequence of activities is just one point of view. It isn’t the only viewpoint, we’ll look at several others.
Sometimes we call this the processing view of our program because it reflects processing steps that lead to
changes in state.
We’ll revisit this in depth in Where Exactly Did We Expect To Be? and show some techniques for reviewing
the state changes of our programs.
In What is a Program? we noted the difference between a binary executable and a script. We defined a
binary program as using codes that are specific to our processor chip and operating system. A script, on
the other hand, is written in an easy-to-read language like the Python language. It turns out that they are
intimately intertwined because the scripts depend on a binary executable.
The Python program, python or python.exe, is described as an interpreter or a virtual machine. The
Python program’s job is to read statements in the Python language and execute those statements. For
historical reasons, this process is called “interpreting” the program. You might think that an interpreter
should be translating the program into another language; after all, that’s what human interpreters do.
Software people have bent the meaning of this term, and the process of executing a script is called interpreting.
Ultimately, everything that happens in a computer is the result of the processor executing it’s internal binary
instructions. In the case of Python , the python program contains a set of binary instructions that will
read the Python-language statements we provide and execute those statements.
Looking Under the Hood. This is the real story behind the two kinds of executable programs we run on
our computers.
• A binary executable program uses the processor’s instruction and controls the computer directly.
• A script uses some language to control a binary executable program; the binary executable program
controls the computer. The script’s control over the computer is indirect.
At this point our TV playing a TV show metaphor (from About Computers) is starting to look a little shabby.
Originally, we said there is a parallel between a computer running a program and a TV playing a particular
TV show. With computers, however, we have three layers of meaning.
• The computer system running programs – in a broad and general sense – is like a TV set playing a
TV show.
• The computer system running the Operating System program can be viewed as a single device. The
computer hardware combined with the operating system software makes a new, abstract device. The
composite (hardware-plus-software) device runs our application software.
• The computer system plus the Operating System plus the Python program can also be viewed as a
single device. This complex, multi-layered device is what runs the application scripts that we write.
This isn’t very much like TV at all: we never tune to one channel (the operating system) that enables
us to watch another channel ( Python) that finally lets us watch the video we made with our own
video camera.
Software builds up in stacks and layers, based on the principle of abstraction. TV simply switches channels.
It looks like computers are so strange that metaphors will only cause more confusion. There aren’t many
things that are like computer systems where the behavior we see is built up from independent pieces. We
can’t really talk about them metaphorically, which makes computers a unique intellectual challenge.
Here’s a picture that shows the abstract Computer-Plus-Operating system. This hardware plus software
combination creates a “virtual” machine. The real machine is controlled by a binary executable. The virtual
machine (hardware plus operating system plus Python) is controlled by our Python-language program.
Bottom Line. When we write Python-language statements, those statements will control the Python
program; the Python program controls the OS kernel; the OS kernel controls our computer. These are the
most obvious and influential layers of abstraction. It turns out that there are other parts of this technology
stack, but we can safely ignore them. The OS makes hardware differences largely invisible; and Python
makes many OS differences invisible.
The cost of these layers of indirection is programs that are somewhat slower than those which use the
computer’s internal codes. The benefit is a huge simplification in how we write and use software: we’re freed
from having to understand the electro-techno-mumbo-jumbo of our processor chip and can describe our data
and processing clearly and succinctly.
Running our Python-language Programs. Remember that the Python program’s job is to read state-
ments in the Python language and execute those statements. Our job as a programmer is to write the
statements that tell the Python program what to do.
From the operating system’s point of view, all of our various Python programs and tools are really just
the python program. When you double click the file you created (usually a file with a name that ends
in .py) this is what happens under the hood. Let’s pretend you’re running a program you wrote named
roulette.py.
1. The OS looks up the binary executable associated with the roulette.py file. This is the Python
program, python or python.exe.
2. The OS loads the binary executable Python program, allocates resources and starts it running. It
uses the kernel to share these resources politely with all other programs.
3. The OS provides the file name you double-clicked (roulette.py) to the Python program.
4. The Python program reads the roulette.py file and executes the Python language statements it finds.
5. When the statements are finished the Python program has nothing more to do, so it terminates.
6. The OS releases the resources allocated to the Python program.
Note: Additional Factoids
The Python program was written in the C language and then compiled into a binary executable that is
specific for your hardware chip and operating system. That’s why the various distribution files for Python
have names that include “i386” for Intel 80386-compatible chips and “fc9” for Fedora Core 9 GNU/Linux.
While a bit beyond our scope, we’ll talk about this a little in So How Do They Create Binary Executables?.
While the coffee-shop answer is “programming is how we create programs” , that doesn’t help very much.
We can identify a number of skills that are part of the broadly-defined craft of programming. We’ll stick
to two that are foundational: designing Python statements and debugging problems with those statements.
Design comes in a number of levels of detail, and we’ll work from the smallest level up to larger and more
inclusive levels
We take much of our guidance on this from Software Project Management [Royce98]. Royce identifies four
stages of software development, with distinct kinds of activities and skills.
• Inception. We have to start by defining the problem. The central skills you use here are observing
and writing. You need to observe the problem and write a clear, simple description of what is wrong
and how software can be used to fix it. If we clearly state our problem, then all of the rest of the
programming activities are directed at a single goal.
If we aren’t clear on what we’re trying to accomplish, we’re very likely to go astray at this point. It’s
more important to clearly define the problem than it is to try and design software. We’ll get to the
software design in stages. We need the problem defined or we’ll never get anywhere.
We’ll return to this in Inception – Getting the Characters Right.
• Elaboration. We elaborate our solution into solid description of how software will sove the problem.
We move from there to identifying what we will need to buy, what we will build and what we will
download from the open source community. We use design and architecture skills to create a solution
to our problem. We need to be sure that our elaborated solution really will solve our problem. We
also need to be sure that the cost is appropriate for the value we will create.
This is rarely shows up as a single good idea for a Python program. Instead, this is often a series of
experiments where we imagine something that would solve the problem, and then try to design a more
complete solution. It takes a lot of practice to imagine something that can be written as a Python
program. We’ll guide you through that imagination process a number of times.
We’ll return to this in Elaboration – Overcoming Obstacles.
• Construction. This is where we create our Python language statements and put them into module
files and script files. Here we are building the solution that we designed during the elaboration stage.
We can decompose construction into several things: the Python language skills, testing our programs
to make sure they work, and debugging our programs to find out why they don’t work.
This is the programming part, and the part on which most of this book focuses.
• Transition. Our programs have to make the transitions from engineering effort to useful tool. That
means they have to be installed on a computer where they can be used. Here is where the problem we
started with in inception is actually solved by using the software.
We know that we’ve done this phase well when we have a nice file that we can double-click, or run
from the Terminal window that does the job we imagined and solves the original problem.
We’ll return to this in Transition – Installing the Final Product.
We’re going to focus on two skills in this book: creating Python language statements, and debugging problems
when we make mistakes. Testing is a rich subject; it would double the size of this book to talk about
appropriate testing techniques. The analytical skills for inception and elaboration don’t require knowledge
of Python, just common sense and clear thinking.
You get to the control panels with Start Settings Control Panel. One of your control panels
is the :application:‘ Add/Remove Programs‘ control panel. When you double-click this, it shows
many of the application programs that you’ve installed on your computer.
• MacOS. In your Applications folder, you have a Utilities folder. One of these utilities is
the System Profiler. Double-click this icon to see a complete description of your Macintosh,
including the list of application programs.
• GNU/Linux. There are a number of standard places where GNU/Linux application programs
are kept. You can use the ls command to look at directories like /bin, /usr/bin, /usr/local/bin.
Notice the common theme to the directory names: bin is short for binary, as in binary executable.
This is a useless digression. It may help you understand how the team that wrote the Python program did
it. It can help you demystify programming. It may not help you learn the Python language, so feel free to
skip it.
Binary executable files are created by a program called a compiler. A compiler translates statements from
some starting language into the processor’s native instruction codes. This leads to blazing speed. This
approach is typified by the C language. One consequence of this is that we must recompile our C language
programs for each different chip set and operating system.
The C language isn’t terribly easy to read. The language was designed to be relatively easy for the compiler
to read and translate. It reflects an older generation of smaller, slower computers.
The GNU Tools. For the most part, the GNU C Compiler and C language libraries are used to write binary
executables like Python. The C language has been around for decades, and has evolved a widely-used style
that makes it appropriate for a variety of operating systems and processors. The GNU C compiler has been
designed so that it can be tailored for all processors currently used to build computers. Many companies
make processors, include Intel, National Semiconductor, IBM, Sun Microsystems, Hewlett-Packard, and
AMD. The GNU C Compiler can produce appropriate binary codes for all of these various processor chips.
In addition to the processor (or “chip architecture” ), binary executables must also be specific to an operating
system. Different operating systems provide different kernel services and use different formats for their binary
executable files. Again, the GNU C Compiler can be made to work with a wide variety of operating systems,
producing binary executable files with all the unique features for that operating system.
The ubiquity of the GNU C compiler leads to the ubiquity of Python. By depending on the GNU C compiler,
the authors of Python assured that the python program can be compiled for any processor chip and any
operating system.
What is a programming language? This is actually a complex question that exposes the very heart of
computing. The essence of a computer is the processor chip. This chip is a very complex electronic
circuit built up from a number of simpler circuit elements that we’ll call “flip-flops” . A flip-flop is
either on or off and can be flipped on or off electrically. There are a number of kinds of flip-flops
with different electronic connections to flip (or flop) and detecting if the circuit is presently flipped or
flopped. In addition to flip-flops are logic gates to do things like determine if two flip-flops are on at
the same time ( “and” ) or if one of two flip-flops is on ( “or” ), or if a flip-flop is off ( “not” ).
The designers of computers will often group the flip-flops into bunches and call them registers. These
register specific values or conditions within the processor. For example, one register may contain the
memory address of the next instruction to fetch. Another register might have a numeric value on which
we are calculating. Another register might be a clock that counts up automatically from zero when
the processor is turned on.
A computer’s memory, it turns out, is just a collection of billions of flip-flops.
The processor chip does two things: it fetches instructions from memory, and executes those instruc-
tions. The fetching part is a relatively simple process of reading data from the memory chips and
changing registers to reflect that instruction. The execution part is more complex, and involves chang-
ing the state of other flip-flops based on the instruction itself, data in memory and the state of the
various processor registers.
The instructions in memory form a kind of “language” for controlling the processor. At this level, the
language is very primitive. Since it is narrowly focused on the ways the processor works, it is almost
incomprehensible. The language can only express a few simple imperative commands in a very precise
– essentially numeric – form.
The idea that computers are controlled with a kind of language is an example of an abstraction that
has immense and far-reaching consequences.
• It lets us translate from more expressive languages into the machine’s native language. We call
this kind of translator a compiler.
• It lets us design more expressive languages that better describe the problems we are trying to
solve.
• It changes our view of computing. We are no longer controlling an electronic chip thingy; we are
capturing knowledge about data and processing.
Why can’t programming be done in English? There are a number of reasons why we don’t try to do
programming in English.
• English is vague. More precisely, English has many subtle shades of meaning. Try to explain the
difference between “huge” and “immense” . Further, English has words borrowed from a number
of languages, making it more difficult to assign precise meanings to words.
• English is wordy. Data processing can be very simple; however, English is a general-purpose lan-
guage. Because we’re only talking about data processing, it helps to have a number of simplifying
assumptions and definitions.
Over the years there have been a number of attempts at “natural language” processing, with varying
degrees of success. It takes quite a bit of computing horsepower to parse and understand general
English-language writing. All of this horsepower would then make the Python program large and slow;
a net loss in value.
In order to keep to short, focused statements, we would do well to use only a limited number of words.
We would also find it handy to allow only a few of the available English sentence forms. We should
also limit ourselves to just one verb tense. By the time we’ve focused ourselves to a small subset of
English, we’ve created an artificial language with only a small resemblance to English. We might as
well do another round of simplification and wind up with a language that looks like Python.
What if I’m no good with languages? First, we aren’t learning a complete natural language like
Swedish. We’re learning a small, artificial language with only about twenty kinds of statements.
Second, we aren’t trying to do complex interpersonal exchanges like asking someone which bus will get
us to Slottberg in Gamla Stan. Interpersonal interactions are a real struggle because we don’t have
all day to look up the right words in our phrase book. Python is all done as written exchanges: we
have hours to look things up in our various reference books, think about the response from the Python
program, and do further research on the Internet.
Also, the Python language lacks subtle shades of meaning. It is a mathematical exercise; the meanings
are cut and dried. The meanings may be novel, but the real power of software is that it captures
knowledge in a rigorous formal structure.
Why is the terminology so confusing? One of the biggest sources of confusion is the overuse of the
word “system” . Almost everything related to computers seems to be a system. We have computer
systems, software systems, operating systems, systems programmers, system architects and network
systems. Most of this is just casual misuse of the words. We’ll limit “system” to describing the
computer hardware system.
Another big source of confusion is overuse of “architecture” and the wandering meaning of “platform” .
We’ll try to avoid these words because they aren’t really going to help us too much in learning Python.
However, we have software architectures and hardware architectures. The hardware architecture and
the platform are both, in essence, the processor chip and supporting electronics.
Generally, however, the biggest issue is that computers and computing involve a number of very new
concepts. These new concepts are often described by using existing words in a new sense. For example,
when we talk about computer systems being “clients” or “servers” , we aren’t talking about a lawyer’s
customers or a restaurant’s wait staff.
Before we can use Python, we may have to download it and install it on our computer. This chapter will
cover a number of installation scenarios.
We’ll need to have access to a reasonably modern computer. This can be either a Macintosh with MacOS X,
a Windows machine with Windows 98 or higher, or any of the wide variety of GNU/Linux or UNIX machines.
The computer doesn’t need to be spectacular or huge, just a machine that works reliably. Python does run
on really small systems like the Palm OS, but this is an inconvenient platform for software development.
You’ll also need a few basic computer skills; if you’re new to computing, you might need a couple of “For
Dummy’s” books to fill in your background. Since we’re going to download and install software, you’ll
need access to the Internet, plus authority to install software on your computer. In an office or academic
environment, you might not have permission to install new software; in this case, you’ll need to work through
the organization that provides your computer to do the installation for you.
This chapter has a number of sections, but you’ll only really need to read a little bit of this chapter, depending
on your operating system.
• Windows. You need to work through Windows Installation, where we describe downloading Python
2.5 (or newer) and installing it.
• Mac OS. In Mac OS 10.5 (“Leopard”), Python 2.5 is included. In Mac OS 10.4 (“Tiger”) Python
2.3 was included. In still older Mac OS’s, you will have to add Python. Additionally, you may want
to upgrade your Python to the latest and greatest. We’ll look at a Mac OS upgrade in Macintosh
Installation.
• GNU/Linux. In Red Hat or Fedora GNU/Linux, Python is included. Often, the upgrades are
automatically done. We’ll look at the common variations on the GNU/Linux installation in GNU/Linux
and UNIX Overview. If you have YUM, see YUM Installation. Additionally, we’ll look at the non-RPM
installation procedure in Non-RPM GNU/Linux Installation: Building Python From Scratch.
We’ll provide some FAQ’s in Installation FAQ’s.
Once we have Python installed, we can move on to interact with the Python program in the next chapter.
There’s a distinction between download and install that sometimes escapes newbies.
When you go to http://www.python.org and download some software, you wind up with a file on your
computer. But this file isn’t in a location where the operating system can find it or use it.
Generally, software posted on the internet is compressed into a small file. On your computer, it generally
exists as a number of files, often in an expanded form that is easier to process, but larger. When you install
a piece of software, the installer both uncompresses the files and distributes them to their proper locations.
The installer can take a number of forms, depending in your operating system.
• Windows installers can be .zip, .exe or .msi files. In rare cases, you may have an .exe or .zip
file which unpacks an .msi file which you then have to run separately. An .exe file is (hopefully) a
“stand-alone .zip executable”, not a virus. A .zip file (whether named .zip or .exe) is a compressed
archive, which will expand itself into the proper location. An .msi file is more sophisticated; it is a
Microsoft Installer, and can do a variety of installation tasks. It will generally display a series of steps,
leading you through the installation process.
• Mac OS X installers are often .dmg files, which contain disk images. When you double-click a .dmg file,
a new “disk” appears on your desktop. This can contain files that you simply drag (usually to your
Applications folder), or it may contain a .pkg file. If there’s a .pkg file, this is a Mac OS Installation
package. When you double click the .pkg file, the installer will step through the installation process,
telling you what you’re installing, where you’re installing it, what the licensing terms and conditions
are, etc.
• There are a variety of Linux installers. Details vary with each Linux variant. One very easy-to-use
installer is Yum, which handles just about everything for you: download and installation. Another
popular installer is RPM, which can handle download and installation together.
In some circumstances, installing software in Windows may require administrator privilege. The details are
beyond the scope of this book. If you can install software on your PC, then you have administrator privileges.
In a corporate or academic environment, someone else may be the administrator for your PC.
The Windows installation of Python has three broad steps.
1. Pre-installation: make backups and download the installation kit.
2. Installation: install Python.
3. Post-installation: check to be sure everything worked.
We’ll go through each of these in detail.
Windows Pre-Installation
Backup. Before installing software, back up your computer. I strongly recommend that you get a tool
like Norton’s Ghost. This product will create a CD that you can use to reconstruct the operating system
on your PC in case something goes wrong. It is difficult to undo an installation in Windows, and get your
computer back the way it was before you started.
I’ve never had a single problem installing Python. I’ve worked with a number of people, however, who
either have bad luck or don’t read carefully and have managed to corrupt their Windows installation by
downloading and installing software. While Python is safe, stable, reliable, virus-free, and well-respected,
you may be someone with bad luck who has a problem. Often the problem already existed on your PC and
installing Python was the straw that broke the camel’s back. A backup is cheap insurance.
You should also have a folder for saving your downloads. You can create a folder in My Documents called
downloads. I suggest that you keep all of your various downloaded tools and utilities in this folder for two
reasons. If you need to reinstall your software, you know exactly what you downloaded. When you get a
new computer (or an additional computer), you know what needs to be installed on that computer.
Download. After making a backup, go to the http://www.python.org web site and look for the Download
area. In here, you’re looking for the pre-built Windows installer. This book will emphasize Python 2.5.4.
In that case, the kit is python-2.5.4.msi. When you click on the filename, your browser should start
downloading the file. Save it in your downloads folder.
A newer Python (e.g. 2.6) is also a candidate for a download. Python 3, however, has some differences;
don’t download this until the next edition of this book comes out.
Backup. Now is a good time to make a second backup. Seriously. This backup will have your untouched
Windows system, plus the Python installation kit. It is still cheap insurance.
If you have anti-virus software [you do, don’t you?] you may need to disable this until you are done installing
Python.
At this point, you have everything you need to install Python:
• A backup
Windows Installation
You’ll need two things to install Python. If you don’t have both, see the previous section on pre-installation.
• A backup
• The Python installer
Double-click the Python installer (python-2.5.4.msi).
You should get a “Security Warning” asking if you want to run this file. The answer is to click Run.
First, you’ll be asked if you want to install for all users or just yourself. You require administrator privileges
to install for all users. If you’re using a corporate PC, for example, you might not have administrator
privileges. If you have the privileges, then install for all users. Otherwise, install for yourself. Click Next
to continue.
The next step is to select a destination directory. The default destination should be C:\Python25. Note
that Python does not expect to live in the C:\My Programs folder. There’s a subtle problem with the My
Programs folder: it has a space in the middle of the name, something that is atypical for all operating
systems other than Windows. This space is sometimes unexpected by Python programs, and can cause no
end of obscure problems. Consequently, Python folks prefer to put Python into C:\Python25 on Windows
machines. Click Next to continue.
The next step is to customize list of components to install. You have a list of five components. You have no
reason to change these.
• Register Extensions. You want this.
• Tcl/Tk (Tkinter, IDLE, pydoc). You want this, so that you can use IDLE to build programs.
• Documentation (Python HTML Help file). This is some reference material that you’ll probably want
to have.
• Utility scripts (Tools/). We won’t be making any use of this; it’s simplest if you install it.
• Python test suite (Lib/test/). We won’t make any use of this, either. It won’t hurt anything if you
install it.
Click Next to continue.
The installer puts files in the selected places. This takes less than a minute.
Click Finish; you have just installed Python on your computer.
Tip: Debugging Windows Installation
The only problem you are likely to encounter doing a Windows installation is a lack of administrative
privileges on your computer. In this case, you will need help from your support department to either do the
installation for you, or give you administrative privileges.
Windows Post-Installation
In your Start... menu, under All Programs, you will now have a Python 2.5 group that lists five things:
• IDLE (Python GUI)
• Module Docs
• Python (command line)
• Python Manuals
• Uninstall Python
GUI is the Graphic User Interface . We’ll turn to IDLE in IDLE Time : Using Tools To Be More Productive.
Important: Testing
If you select the Python (command line) menu item, you’ll see the Python (command line) window.
This will contain something like the following.
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
If you hit Ctrl-Z and then Enter, Python will exit. The basic Python program works. You can skip to the
next chapter to start using Python.
If you select the Python Manuals menu item, this will open a Microsoft Help reader that will show the
complete Python documentation library.
Python is part of the MacOS environment. For uses of Leopard (MacOS 10.5) you already have Python
2.5.1.
This from-the-factory installation includes a copy of IDLE, it isn’t always obvious where it is located on
your Macintosh. You can skip down to Adding IDLE Without An Install on Mac OS X for information on
making use of IDLE without doing an install.
It’s probably simpler to upgrade your copy of Python to 2.5.4. This will make IDLE available as a first-class
icon in your Applications folder.
In order to install software in the Macintosh OS, you must know the administrator, or “owner” password. If
you are the person who installed or initially setup the computer, you had to pick an owner password during
the installation. If someone else did the installation, you’ll need to get the password from them.
The Mac OS installation of Python has three broad steps.
1. Pre-installation: make backups and download the installation kit.
2. Installation: install Python.
3. Post-installation: check to be sure everything worked.
We’ll go through each of these in detail.
Macintosh Pre-Installation
Before installing software, back up your computer. While you can’t easily burn a DVD of everything on
your computer, you can usually burn a DVD of everything in your Mac OS X Home directory.
I’ve never had a single problem installing Python. I’ve worked with a number of people, however, who either
have bad luck or don’t read carefully and have managed to corrupt their Mac OS installation by downloading
and installing software. While Python is safe, stable, reliable, virus-free, and well-respected, you may be
someone with bad luck who has a problem. A backup is cheap insurance.
You should also have a folder for saving your downloads. You can create a folder in hour Documents called
downloads. I suggest that you keep all of your various downloaded tools and utilities in this folder for two
reasons. If you need to reinstall your software, you know exactly what you downloaded. When you get a
new computer (or an additional computer), you know what needs to be installed on that computer.
Download. After making a backup, go to the http://www.python.org web site and look for the Download
area. In here, you’re looking for the pre-built Mac OS X installer. This book will emphasize Python 2.5.4.
In that case, the kit is python-2.5.4-macosx.dmg. When you click on the filename, your browser should
start downloading the file. Save it in your downloads folder.
A newer Python (e.g. 2.6) is also a candidate for a download. Python 3, however, has some differences;
don’t download this until the next edition of this book comes out.
Backup. Now is a good time to make a second backup. Seriously. It is still cheap insurance.
At this point, you have everything you need to install Python:
• A backup
• The Python installer
Macintosh Installation
When you double-click the python-2.5.4-macosx.dmg file, it will create a disk image named Universal
MacPython 2.5.4. This disk image has your license, a ReadMe file, a Build file and the MacPython.mpkg.
When you double-click the MacPython.mpkg fie, it will take all the necessary steps to install Python on your
computer. The installer will take you through seven steps. Generally, you’ll read the messages and
Introduction. Read the message and click Continue.
Read Me. This is the contents of the ReadMe file on the installer disk image. Read the message and click
Continue.
License. You can read the history of Python, and the terms and conditions for using it. To install Python,
you must agree with the license. When you click Continue, you will get a pop-up window that asks if you
agree. Click Agree to install Python.
Select Destination. Generally, your primary disk drive, usually named Macintosh HD will be highlighted
with a green arrow. Click Continue.
Installation Type. If you’ve done this before, you’ll see that this will be an upgrade. If this is the first
time, you’ll be doing an install. Click the Install or Upgrade button.
You’ll be asked for your password. If, for some reason, you aren’t the administrator for this computer, you
won’t be able to install software. Otherwise, provide your password so that you can install software.
Finish Up. The message is usually “The software was successfully installed”. Click Close to finish.
Macintosh Post-Installation
In your Applications folder, you’ll find a MacPython 2.5 folder, which contains a number of applications.
• BuildApplet
• Extras
• IDLE
• PythonLauncher
• Update Shell Profile.command
Once you’ve finished installation, you should check to be sure that everything is working correctly.
Important: Testing
Now you can go to your Applications folder, and double click the IDLE application. This will open two
windows, the Python Shell window is what we need, but it is buried under a Console window.
Here’s what you’ll see in the Python Shell window.
At the top of the window, you’ll see a menu named IDLE with the menu item Quit IDLE. Use this to
finish using IDLE for now, and skip to the next chapter.
You may notice a Help menu. This has the Python Docs menu item, which you can access through the
menu or by hitting F1. This will launch Safari to show you the Python documents that you also downloaded
and installed.
If you did an install of Python 2.5.4, you should have IDLE available in your Mac Python 2.5 folder in the
Applications folder.
If you have Leopard with Python 2.5.1, and you did not install an upgrade, you will want to add IDLE to
your environment. There are four approaches.
• One choice is to move the icon that starts IDLE into your Applications folder.
• A second choice is put the Python binaries on your PATH. This allows you to easily run IDLE from
the Terminal tool.
• You can also build an AppleScript icon which will run IDLE for you.
The following directory has the IDLE program:
/System/Library/Frameworks/Python.framework/Versions/Current/bin/idle2.5
You can do any one of the following alternatives to make IDLE available without a complete installation.
Don’t do all of them.
1. Move the idle icons.
This is probably the simplest aproach.
First, create a Mac Python 2.5 folder in your Applications folder.
To move the existing idle and idle2.5 icons, you’ll have to start from your Macintosh HD, you can
locate the bin directory which contains the files named idle and idle2.5.
Second, drag these two folders into your new Mac Python 2.5 folder.
Now the IDLE icon is easy to find. You’re ready to move to the next chapter.
PATH="/System/Library/Frameworks/Python.framework/Versions/Current/bin:${PATH}"
PATH="${PATH}:/usr/local/bin"
export PATH
It’s beyond the scope of this book to address the various tools that can edit files like your
~/.bash_profile.
Now you can type ‘idle &’ at the Terminal prompt and run IDLE. You’re ready to move to the next
chapter.
3. Create a new AppleScript icon.
First, create a Mac Python 2.5 folder in your Applications folder.
Use the ApplkeScript Script Editor to create a file with the following script.
Now the IDLE icon is easy to find. You’re ready to move to the next chapter.
In order to install software in GNU/Linux, you must know the administrator, or “root” password. If you are
the person who installed the GNU/Linux, you had to pick an administrator password during the installation.
If someone else did the installation, you’ll need to get the password from them.
Normally, we never log in to GNU/Linux as root except when we are installing software. In this case,
because we are going to be installing software, we need to log in as root, using the administrative password.
If you are a GNU/Linux newbie and are in the habit of logging in as root, you’re going to have to get a
good GNU/Linux book, create another username for yourself, and start using a proper username, not root.
When you work as root, you run a terrible risk of damaging or corrupting something. When you are logged
on as anyone other than root, you will find that you can’t delete or alter important files.
Do You Already Have Python? Many GNU/Linux and Unix systems have Python installed. On some
older Linuxes [Linuxi? Lini? Linen?] there may be an older version of Python that needs to be upgraded.
Here’s what you do to find out whether or not you already have Python.
You’ll need to run the Terminal tool. The GNOME desktop that comes with Red Hat and Fedora has
a Start Here icon which displays the applications that are configured into you GNOME environment.
The System Tools icon includes the Terminal application. Double click Terminal icon, or pick it off the
menu, and you’ll get a window which prompts you by showing something like [slott@linux01 slott]$. In
response to this prompt, enter ‘env python’, and see what happens.
Here’s what happens when Python is not installed.
Here’s what you see when there is a properly installed, but out-of-date Python on your GNU/Linux box.
In this case, the version number is 2.3.5, which is good, but we need to install an upgrade.
Note that we typed Ctrl-D to finish using Python.
Unix is not Linux. For non-Linux commercial Unix installations (Solaris, AIX, HP/UX, etc.), check
with your vendor (Sun, IBM, HP, etc.) It is very likely that they have an extensive collection of open source
projects like Python pre-built for your UNIX variant. Getting a pre-built kit from your operating system
vendor is the best way to install Python.
Some Linux distributions use tools like Yum. For example, if you are a Fedora user, you will have Yum.
Other Linux distributions have similar tools.
If you have an out-of-date Python, you can enter the following commands in the Terminal window to do an
upgrade.
The first command will upgrade Python to the latest and greatest version.
The second command will assure that the extension package named tkinter is part of your Fedora instal-
lation. It is not, typically, provided automatically. You’ll need this to make use of the IDLE program used
extensively in later chapters.
This is, perhaps, the lowest common denominator of installation: building Python from scratch. There are
many GNU/Linux variants, and we can’t even begin to cover them. Here’s an overview of how to install
using a largely manual sequence of steps.
1. Pre-Installation. Make backups and download the installation kit. You’re looking for the a file
named python-2.5.4.tgz.
2. Installation. The installation involves a fairly common set of commands. If you are an experienced
system administrator, but a novice programmer, you may recognize these.
Change to the /opt/python directory with the following command.
cd /opt/python
Do the following four commands to configure the installation scripts, make the Python package and
then install Python on your computer.
cd Python-2.5.4
./configure
make
make install
If you hit Ctrl-D (the GNU/Linux end-of-file character), Python will exit. The basic Python program works.
Tip: Debugging Other Unix Installation
The most likely problem you’ll encounter in doing a generic installation is not having the appropriate GNU
GCC compiler. In this case, you will see error messages from configure which identifies the list of missing
packages. Installing the GNU GCC can get complex.
Why are there so many operating systems? This is often asked as “Why not just use Windows?” or,
in many Information Technology organizations at big companies, it is paraphrased as “We only use
Windows.”
There are two parts to the answer. The first part of the answer is that one size does not fit all. Even
Microsoft, in their ongoing quest to write a good operating system, release a number of products that
use the brand name Windows, but are very different on the inside. As for the rest of the world, one
person’s GNU/Linux has too many features, too few features, or is simply the wrong color for another
person. Since we can customize it (and hopefully improve on it), why not?
The second part of the answer is that the people who make the computer systems (Apple, Dell, HP,
IBM, Sun, etc.) have to provide software to make their computer systems of any value to anyone. A
computer without software is like a stereo without CD’s, and a TV without TV shows. A computer
without software is just a good idea waiting to happen.
In the early days of computing, there was relatively little software, and it was provided by the hardware
vendor. IBM grew to be the software giant it is today by bundling a processor and some software to
solve business problems. As the industry matured, independent companies produced software. As the
marketplace matured, the software become one valuable commodity and the computer to run that
software a different commodity.
One lesson that the innovative companies learned was that new hardware had a hidden cost. A new,
faster, sleeker processor couldn’t run the old software. The software had to be converted to the newest
processor’s binary instruction codes. This drove up the cost of producing software, and ate away at
profit margins from making new processors. To reduce these costs, operating systems, languages and
compilers evolved so that, within limits, software could be more easily moved to the latest, coolest
processor.
This cycle of innovation never stops. Each new good idea can lead to new processors that aren’t
compatible enough with old processors or new operating systems that aren’t enough like old operating
systems.
Python, to an extent, gets us out of this arms race of hardware and operating system improvements.
We write our software in Python, which is identical on all processors and all operating systems. We
can have large libraries of Python software that are the same everywhere. All we need to install is the
base Python program itself. This program acts as a framework that insulates us from the operating
system and the underlying processor.
Why is GNU/Linux so complex? Complexity is in the eye of the beholder. An operating system like
Microsoft Windows is well known only to a few engineers in Microsoft. For the rest of us, it is
tightly-sealed mystery. The GNU/Linux operating systems, however, are completely exposed to the
scrutiny of software developers the world over. While this makes it perfectly transparent, it also means
that everybody (and their brother) wants to make customizations, amendments and exceptions to the
operating system.
Microsoft (and Apple) have pre-configured the operating system with things they think we need. In
GNU/Linux, this is not as common. Even vendors like Red Hat provide alternative packages which
are more finely tuned to different needs.
It isn’t so much that one OS is more complex than the other. It’s more of the nature of what you
can adjust and how easily you can adjust it. With GNU/Linux, every knob is exposed, and everyone
wants to adjust those knobs. This exposes more of the software installation process to you, the user.
For Windows and Mac OS, the knobs are there, but they’re tucked away where we can’t see them.
There are a couple of problems that we’ll use throughout this book to show how (and why) you use Python.
Both problems are related to casino games. We don’t embrace gambling; indeed, as you work through these
sample problems, you’ll see precisely how the casino games are designed to take your money.
We like using casino games because they are (a) moderately complex and (b) not very geeky. Really complex
problems require whole books just to discuss the problem and its solution. Simple problems can be solved
with a spreadsheet. In the middle are moderately complex problems that require Python.
There are numerous geeky problems. Most computer-science textbooks are packed with geeky problems
that are relevant to professional programmers, but hard to explain to newbies. Rather than dig into geeky
problems like stacks, queues, state machines, or parsers, we’ll stick with games.
While it’s pretty safe to assume that you know a little about casino gambling, we’ll provide a few definitions
in About Gambling just to be sure. From there, we’ll define the Roulette problem in The Roulette Problem.
We’ll look at the Craps problem in The Craps Problem. We’ll stake out our overall strategy in Directions.
We’ll answer some questions in Problem FAQ’s.
The casino table games of Craps and Roulette (and a number of similar games) allow the bettor to place a
bet (or wager) on an outcome or set of outcomes. Some random device (cards, dice, a wheel, a spinner) is
used to make a selection. This selection usually resolves the bets as winners, losers, or a “push” where your
money is returned.
In Roulette, each random event defines a complete set of outcomes, and all bets are resolved. You see this
in the play at the Roulette table: people place bets, the wheel is spun, all of the bets are resolved. Once the
bets are resolved as winners or losers, players are permitted to bet again.
In Craps, each random event does not define a complete set of outcomes. Some bets are not resolved when
the dice are thrown; instead, the bets remain. Craps is played as a series dice throws that are part of a
2.4. Two Minimally-Geeky Problems : Examples of Things Best Done by Customized Software 39
Programming for Non-Programmers, Release 2.5.1
round or turn. The turn can be as short as a single throw of the dice, or it can be indefinitely long. It is
unlikely (about a 1% chance) for a turn to take more than seven throws of the dice, but not impossible.
Generally, the person throwing the dice, the “shooter”, holds the dice as long as they win their round. When
they lose, the dice move to a new shooter. These nuances of casino play has no impact on the actual game,
so we’ll ignore details like these.
Odds. If the outcome you bet on is likely, your payout is rather small. If the outcome you bet on is rare,
your payout may be huge. They call this the odds of winning. When the odds are small, the event is pretty
likely. For example, almost half the Roulette wheel has numbers colored red. Betting on red, then, is pretty
safe. Since it’s about half the numbers, the payout is 1:1. If you bet $10, you could win an additional $10.
Contrast red (or black) with the number zero, which is just one of the thirty eight bins on the wheel. Since
zero is so rare, it pays off at 35:1. If you bet $10 on zero, and it comes up, you could win $350. They call
these long odds or a long shot.
Here’s the short form of the question: “How well does the Martingale betting system work for Roulette?”.
After we define any unknown jargon in this question, we’ll see that it is not terribly complex and it will lead
us to some related questions. All of these questions can be answered with simple Python programs.
Roulette. In Roulette players make bets and wheel is spun to determine which bets win and which bets
lose. The Roulette table has a number of positions on which you can place bets by stacking up chips. The
Roulette wheel is a collection of numbered bins. When the wheel is spun, a small ball is dropped into it,
and the ball will eventually come to rest in one of the bins. The bin selected by the ball determines which
of the betting positions are winners and which are losers. Each position has a payout ratio that determines
how much you win based on how much you bet.
There are over a hundred possible bets on the Roulette table, and a wide variety of payout ratios. We’ll
define a few of them, and focus on just six of the available bets.
• The 38 individual numbers. The numbers go from one to thirty-six, colored red and black. Addi-
tionally, there are zero and double-zero, colored green. The numbers all pay off at 35:1.
• Groups of numbers. You can place bets between pairs of numbers, groups of three, four or six
numbers. You can also place a bet on zero, double zero, one, two and three as a combination of five
numbers. If any of the numbers wins, your bet is a winner. The more numbers in your combination,
the lower the payoff odds.
• The Columns. The numbers form three columns of 12 values. If any of the numbers in the columns
wins, the column as a whole pays off at 2:1. Zero and double zero are not part of any column, if they
are spun, all column bets lose.
• The Ranges. Like the columns, the table is also blocked off into three ranges: one to twelve, thirteen
to twenty four and twenty five to thirty six. If any number in the range wins, the range pays off at 2:1.
Zero and double zero are not part of any range, if they are spun, all range bets lose.
• Red, Black, Even, Odd, High and Low. All of the numbers except zero and double zero are
colored red or black, are even or odd, or are low (between one and eighteen) or high (between nineteen
and thirty six). These bets all include a large range of values and pay off at 1:1. We’ll focus on these
bets because they are so simple and so commonly used.
Martingale Betting. The Martingale betting system suggests that you organize your casino play as follows:
1. Establish a budget with a minimum bet. Since tables vary in the size of bets required, we’ll just call
this amount b, the basic betting unit. At a $10 table, it would often be $10.
2. Bet the minimum amount, b, on one of the 1:1 bets (red, block, even, odd, high or low).
3. If the bet wins, you’re way ahead. Reset your bet back to the minimum amount, b. If the bet loses,
you double your bet. In the even of several losses, you’ll be betting 2 × b, 4 × b or even 8 × b.
Now, let’s look at our question again. How well does this Martingale system work? We can see that the
green zero and double zero complicate the analysis. There are ways to work out the details, but rather than
learn a lot of math, we’ll learn a little Python and simulate the whole thing. We can collect some statistics
showing the results of our simulated Roulette game.
We can ask a whole family of related questions by replacing the Martingale betting system with more complex
systems. We can ask questions based on extending the Martingale system to include additional bets. This
is the beauty of writing our own simulation: we can modify our program to try out different variations on
our betting procedure.
Here’s the short form of the question: “How well does the Field bet pay in Craps?”. We’ll define the gambling
jargon and then look at this question again, in a little more detail.
In Craps, players make bets and a pair of dice are thrown to determine the state of the game. Some dice
throws are significant events and will resolve some or all of the bests as winners or losers. Some dice throws
are less significant and resolve some bets. Some dice throws don’t change the state of the game at all.
The Craps table has a number of positions on which you can place bets by stacking up chips, as well as a
token that shows the state of the game. A shooter will throw two dice; the number on the dice will do several
things. First, the number will pay off any proposition bets based on just this throw of the dice. Second, the
number will pay off any of the various number bets that can be placed. Third, the number may change the
state of the game, which can also resolve certain kinds of bets.
The Craps game has two states: point “off” and point “on”. The casino will place a large black and white
disk on the table to show the state of the game.
Point Off or the Come Out Roll. The first time the shooter throws the dice, the point is off. If the
shooter throws 7 or 11, this turn is an immediate winner, and bets are resolved. If the shooter throws 2,
3 or 12, this turn is an immediate loser and bets are resolved. In this case, the point is still off, the game
didn’t change state, it’s still just beginning.
When the point is off, and the shooter throws 4, 5, 6, 8, 9 or 10, the game changes state, and now the point
is on. The casino will flip over the large disk to show the “on” side, and put it on the betting space that
shows the point number.
Point On. When the point is on, a number of additional bets are allowed. Additionally, the disk sits in a
number’s space to prevent certain other bets. We’ll avoid the complexity of these conditionally permitted
bets. In a casino, however, you would see a flurry of activity when a point is established.
When the point is on, and the shooter throws this point number, the round is a winner, and most of the
bets are resolved. There are some bets that will persist, however. When the shooters throws a seven, the
round is a loser, and all bets are resolved.
Throwing a seven means the shooter lost, and most bets are losers. There are, however, some “don’t” bets
that will be winners when the shooter doesn’t win. These are sometimes called “wrong bets”, and involve a
more sophisticated odds calculation. In general, you can put up a lot to win a little when you make wrong
bets.
When the shooter throws 2, 3, 11 or 12, nothing much can happen. Certain one-roll proposition bets are
resolved, but these four numbers are neither points nor are they 7, which ends the game.
Other Bets. There are a number of bets which don’t depend on the state of the game. These are one roll
“proposition” bets. The field is one of these bets. You place your bet in the box marked “Field” before the
dice are thrown. The number on the dice determines the field bet result immediately.
2.4. Two Minimally-Geeky Problems : Examples of Things Best Done by Customized Software 41
Programming for Non-Programmers, Release 2.5.1
The field bet wins on any of 2,3,4,9,10,11, or 12. The 3,4,9,10, and 11 pay 1:1 (“even money”) and the 2 and
12 pay off at 2:1.
Analysis. There are a number of questions about the field bet. We can create a simple simulator to see the
basic outcome. We can use a more sophisticated simulation of doing Martingale betting (see The Roulette
Problem) to see how that changes the performance of this bet. Some people use an even more complex
betting system for the field by increasing their bet with each win and decreasing it with each loss. We’ll
stick with a simple simulation as a way to learn Python
2.4.4 Directions
We aren’t going to describe the solutions to any of these casino game problems here – that would rob you of
the intellectual fun of working out your own solutions to these problems. Instead, we want to provide some
hints and nudges that will parallel the course this book will take.
This may already be obvious, but we’re going to address these problems by writing new software in the
Python language. The reason why it is important to restate the (potentially) obvious is that in Using
Python we’re going to spend time on learning to control the python program in a simple, manual way.
Then, when we write programs, we’ll control python with our programs to do more sophisticated work.
Any solution to these kinds of problems will involve some simple math. Almost all computing involves some
kind of math. Business programming tends to involve the simplest math. Engineering and science can
involve some really complex math. Statistics is often in the middle ground, which is why we will look at it
closely in Arithmetic and Expressions.
By the way, in addition to math-oriented computing, there is also computing that could be termed “symbolic”
in nature. It might involves words or XML documents or things that aren’t obviously mathematical; we’ll
set this aside as atypical for newbies.
Sequential Thinking. A program in Python is often a sequence of operations. In the casino game
definitions, we saw that each game was a sequence of individual steps. We can often summarize programs by
looking at their inputs, their processing steps and their outputs. This input-process-output model reflects
the sequential order of processing: first, read the inputs; second, do the processing; third, print the outputs.
More sophisticated programs (like games or web servers) will interleave these operations. We’ll look at this
in Programming Essentials.
The sequence of operations is rarely fixed and immutable. With casino games, we have some bets which
are winners and some bets which are losers. We have conditional operations of collecting losing bets and
paying winning bets. Additionally, we’ll have some operations which have to be repeated for a number of
simulations, or until some condition is satisfied. We’ll look at this in Some Self-Control.
Our exploration of Python starts with arithmetic expressions and moves on to statements, then to sequences
of statements. We’ll add conditional and iterative statements. The next step will be a simple organizing
principle called a function definition. We’ll introduce this in Organizing Programs with Function Definitions
and use it to package parts of our program until a useful, discrete components that can help us control the
overall complexity of our program.
Other Side Of the Coin. Beginning with Getting Our Bearings we’ll turn to a different tack. The first
parts of our exploration were focused on the processing, and the procedural nature of our problems. The
second part of our exploration will look at the data and collections of data.
If we are going to simulate a number of sessions at the Roulette wheel, following our Martingale strategy,
we’ll need to collect the results and do statistical analysis on the collection. We’ll look at collections of data
items in Basic Sequential Collections of Data.
We’ll address some programming techniques in Additional Processing Control Patterns that make our Python
programs more reliable and also a bit simpler. Simplification is a touchy subject: simplifications aren’t always
appreciated until you see the more complex alternative. Further, since we’re approaching Python by moving
from the elementary to the advanced, some things we’ll look at will be complex but elementary. As we learn
more, we can replace them with something simple but advanced.
In More Data Collections we’ll look at some additional data structures that can help us develop truly useful
solutions to our problems. These additional data structures will give us foundational knowledge of the
Python language and the built-in data types that we can use.
Successful Collaboration. When we look at our problems, we see that there is considerable interaction
among a number of objects. For example, in Roulette, we have the following kinds of things:
• the wheel, which returns a random bin,
• the table, which holds bets,
• the player, which uses the Martingale strategy to place bets
This interaction between player, table and wheel forms a larger thing, called the game, which lasts until the
player wins big, loses big, or has spent too much time at the table. Each game produces a final result of
zero dollars, big bucks or some number of dollars that was available when time ran out. These, in turn are
collected for statistical analysis. An even bigger assembly of objects does the simulation and analysis. We’ll
learn how to define these collaborating objects in Data + Processing = Objects.
A lot of the basic components that make a program robust and reliable are already packaged as Python
modules, and we’ll cover these in Modules : The unit of software packaging and assembly. We’ll also use the
built-in modules as templates for designing our own modules; this allows us to organize our program neatly
into discrete, easy-to-manage pieces.
Our final section, Fit and Finish: Complete Programs, will cover some final issues. These are the things that
separate a fragile mess that almost works most of the time from a useful program that can be trusted.
Why Casino Gambling? We think we’ve got two compelling reasons for using casino gambling for pro-
gramming problems in this book.
• Casino games have an almost ideal level of complexity. If they were too simple, the house edge
would be too obvious and people would not play them. If they were too complex, people would
not enjoy them as simple recreation. Years (centuries?) of experience in the gaming industry has
fine-tuned the table games to fit nicely with the limits of our human intellect.
• The results are sophisticated but easy to interpret. Probability theory has been applied by others
to develop precise expectations for each game. These simulations should produce results consistent
with the known probabilities. This book will skim over the probability theory in order to focus on
the programming. For a few exercises, the theoretical results will be provided to serve as checks
on the correctness of the student’s work.
This book does not endorse casino gaming. Indeed, one of the messages of this book is that all casino
games are biased against the player. Even the most casual study of the results of the exercises will
allow the student to see the magnitude of the :firstterm:‘ house edge ‘ in each of the games presented.
Why not Something Simpler? While many problems are simpler than casino gambling, they don’t re-
quire customized software written with a powerful language like Python to solve them. It’s hard to
locate things that are both simpler than casino gambling and still interesting enough to provide more
than one trivial exercise.
Why not Your Subject Here ? As an author, I’m not as knowledgeable in Your Subject Here as you are,
and can’t do it justice. Also, I had to pick something, and I chose something that I knew a little bit
about.
2.4. Two Minimally-Geeky Problems : Examples of Things Best Done by Customized Software 43
Programming for Non-Programmers, Release 2.5.1
More importantly, however, the point of this book is to equip you to go out and tackle Your Subject
Here using your new-found programming skills.
We’ll ramble on a bit about Python and the reasons why it is so cool. This won’t really help you learn the
language. It’s mostly op-ed material to provide some justification for why someone would invest time in
learning Python. In Core Coolness we’ll cover some fundamental reasons why Python is cool. The FAQ in
Coolness FAQ’s touches on a few more questions that sometimes get asked.
Python reflects a number of growing trends in how people develop new computer programs. It is a very
simple language, supported by an interpreter and surrounded by a vast library of add-on modules. It is
an open source project, supported by dozens of individuals; this encourages you to build complete solutions
from smaller components and partial solutions. We’ll look at each of these facets separately.
Planet Python. Python is really four separate elements in a single, tidy package. I like to think of it as
an wonderfully efficient planet that we can visit. To get things done on that planet you have to learn the
language. Once you’ve learned the language, however, you find that the whole planet is organized to do
everything you ask precisely and very quickly. Like any well-run organization, it has a number of services
that make life convenient and safe, and assure the common good of all the inhabitants. Finally, it offers a
kind of public forum for making your requests and seeing the results of those requests.
This mythical Planet Python is the Python program itself, we’ll call it python in this book. Windows
users may see it as python.exe. The Python program, python, runs on your computer, and carries out
statements written in the Python language. The program has just one purpose – execute Python language
statements – so it is small and efficient. Because it is so tightly focused, it is wonderfully reliable.
The planet’s services are the Python libraries. These libraries include programs you can extend, and pieces
of programs that you might use to create a more complete program. Some parts of the libraries are both:
things you extend to add new features, and then use in your final program. I think of these as essential
services like police departments, public libraries, laundromats, and telephone sanitizers. You build your
complete organization or enterprise using these pre-built organization units.
The public forum is the integrated development environment (IDE). This is the environment where you
develop your Python program. It’s integrated because all the tools you might want are right there in a single
program. In this case, the program’s name is IDLE. You use IDLE to write Python statements, execute
sequences of Python statements and read any resulting messages.
Simplicity. Python is a relatively simple programming language that allows you to express data processing
in clear, precise terms. The Python language has an easy-to-use syntax, focused on the programmer who
must type, read and understand a program. The language is designed to look a bit like a natural language,
with simple punctuation and indentation. Computer languages are more rigid than human languages: when
you misspell something in English, people can often determine what you meant, and make sense of what you
wrote. The Python program, python , is only a simple piece of software: spelling and punctuation really
matter. While Python is easier than most other programming languages, you must still be precise.
On Simplicity
The simplicity of Python is so important that we’re going to emphasize it heavily. In other languages,
desirable features were often added as new statements in the language. The language then evolved
into a complicated mixture of optional extensions and operating-system features muddled up with the
original core statements of the language. A poorly designed language rarely works the same on different
computers or operating systems, or it requires many compromises to achieve portability. This kind of
badly designed language is always hard to learn.
One hint that a language has too many features is that a language subset is available. The most
outstanding example of this is COBOL. There are a number of subsets with different kinds of compat-
ibilities with different tools and operating systems. While originally easy-to-read, COBOL has evolved
into a monstrously complex problem for many businesses.
The Python language has only twenty statements, the language is easy to learn, and there is no need
to create a simplified language subset.
Interpreted. The computer science folks characterize the Python program, python , as an interpreter
: it interprets and executes the Python language statements, doing your data processing. Because it is
interpreting our statements, it can provide useful diagnostic information when something goes wrong. It
can also handle all of the tedious housekeeping that is part of how programs make use of the computer’s
resources. As users, we don’t see this housekeeping going on, and as newbie programmers we shouldn’t have
to cope with it, either.
The computer-science types make a distinction between interpreters (like Python) and compilers (used for
the C language). The C compiler (controlled by a program named cc ) translates C language statements
into a program that uses the hardware-specific internal codes used by your computer. The operating system
can then directly execute that resulting program. After you see the results of execution you might make
changes, recompile and re-execute. This compilation step makes everything you do somewhat indirect. The
compiler translates your C statements into another language which is then executed. This indirection makes
compiled languages harder to learn; it also makes diagnosing a problem very hard.
Here’s a diagram that may help clarify how Python differs from a language like C. For a C programmer,
they will use a complex IDE which includes the C Compiler to translate their C statements into a binary
executable program from their statements. For a Python programmer, a simpler IDE uses the python
program to execute the Python statements.
The binary executables have relatively direct control over the operating system and computer. A Python-
language program controls Python.
Technical Digression
The Python interpreter, which runs Python-language programs, is implemented in the C programming
language and relies on the extensive, well understood, portable C libraries. Using the C-language under
the hood means that it fits seamlessly with Unix, GNU/Linux and POSIX environments. Since these
standard C libraries are widely available for the various MS-Windows variants, Python runs similarly in
just about all computers and operating systems. Because of the abstraction created by the C libraries,
you’ll find it impossible to find meaningful differences between Windows-2000, Windows-XP, Red Hat
GNU/Linux and MacOS.
Why does anyone use a compiled language like C? C is more complex than Python and writing C
requires the programmer to keep careful track of a number of housekeeping details. The program that
results from the C compiler is hardware-specific and consequently very fast. This is the key to why
Python helps us out so much. The Python program, having been written in C, and compiled to be
specific to our computer’s hardware, is very efficient. However, since we can express our data processing
needs in the (easy to learn) Python language we can use all this speed without having to learn C or
how to compile C-language statements into a program.
When we need blazing speed, we have to write in C. When we need simplicity, we find it easier to write
in Python. We can have the best of both worlds. Most programs only need amazing performance in
small sections of the program. We can, with some care, write just those small sections in C, and then
make that component available to Python. This gives us the speed of C where we need it and the
simplicity of Python everywhere else.
It turns out that Python often does a secret compilation pass on your Python statements in order to
speed things up a hair. It doesn’t change the fundamental benefit that accrues because Python is a
kind of interpreter. It only blurs the distinction between compiled and interpreted languages.
Libraries. Python, the project, includes a rich set of supporting libraries. These libraries contain the basic
gears, sprockets, flywheels and drive-shafts that you can use to make a program. By separating the library
tool-boxes from the core language, the designers of Python could keep the language simple, which means
the interpreter can be very efficient and reliable. Yet, they can provide an extensive feature set as separate
extensions. Every new idea can be added as another extension.
There are other consequences to having extensive and separate libraries. Principally, good ideas can be
preserved and extended, and bad ideas can be ignored. This basic evolution saves programmers from having
to design everything perfectly the first time. As you get more experience with the Python programming
community, you will see ideas come and go. Some extensions will blossom and become widely used, where
others will be quietly ignored because something better has come along.
Another consequence of having separate libraries is that any programming project should begin with a survey
of available libraries. This can replace unproductive programming with more productive research and reuse.
Development Environment. Finally, we see that Python also comes with a development environment,
or workbench, that you can use to write and execute your Python statements. The integrated development
environment ( IDE ) includes an editor for writing Python files, and the Python interpreter, plus some other
tools for searching the Python libraries.
Interestingly, the Python development environment is just another Python program. When you double-click
on the IDLE icon, you are starting a Python program that helps you write Python programs. At first, this
seems like a real mind-wrenching problem. You might think of it as similar to asking “which came first, the
chicken or the egg?” . It isn’t all that bad a problem however. In this case, someone else wrote IDLE to
help you write your program. Your program, and IDLE (and a large number of other programs) all share
the Python program as the driving engine.
Timeline. The Python programming language was created in 1991 by Guido van Rossum based on lessons
learned doing language and operating system support. Python is built from concepts in the ABC lan-
guage and Modula-3. For information ABC, see The ABC Programmer’s Handbook [Geurts91], as well
If Python uses C, why not cut out the middleman and just learn C? We have a number of rea-
sons for avoiding C. First, programming in C is a more difficult proposition because of the number
of tools involved: C uses a compiler to build programs: you don’t interact directly with C; you build
a program, then interact with the operating system to run that program. Second, the C language is
designed to make the C compiler work efficiently, it wasn’t designed to be easy to write or easy to
read. Third, C exposes a number of house-keeping chores that professionals can exploit for efficiency;
they won’t help newbies get their first program written.
If Python is so cool, why doesn’t everyone use it? That’s like asking why everyone doesn’t like the
Boston Red Sox, Philly cheese steaks, and the Red Hot Chili Peppers. Some people prefer Mom, Apple
Pie and the Beatles. There’s really no accounting for taste.
Some languages like Visual Basic and C# have the powerful and sophisticated marketing arm of Mi-
crosoft backing them. Other languages, like Java, have Sun backing them, and a large, well-established
open-source community.
Some languages, like COBOL, are entrenched in the way data is processed at large organizations.
While Python may be superior, it appears cheaper (in the short run) to leave the COBOL programs in
place rather than convert them to something less complex and less expensive to operate and maintain.
The most important reason, however, is that languages are often specialized around particular tasks or
data structures. Some languages, like SQL, express some operations more precisely and with a useful
level of abstraction.
THREE
USING PYTHON
Now that you have Python installed, we can start using it. We’ll look at a number of ways that we can
interact with the Python application. We’ll use these interactions to learn the language.
In later sections, after we’ve got a more complete grip on the language and start to write programs, we’ll
move on to more advanced ways to use the Python program. Our goal is to use Python in an automated
fashion to do data processing. Here in phase one, we’ll be using Python manually to learn the language.
We’ll describe the direct use of the python to process Python-language statements in Instant Gratification
: The Simplest Possible Conversation. This will help us get started; it provides immediate gratification, but
isn’t the easiest way to work.
We’ll dig into IDLE in IDLE Time : Using Tools To Be More Productive. We’ll emphasize this as a good
way to learn the language as well as build programs.
There are two ways to exercise the Python program: interactively and with a script. In interactive mode,
Python responds to each statement that we type in. In script mode, we give the Python program a file with
a script of statements and turn it loose to interpret all of the statements in that script. Both modes produce
identical results. Our goal is to write finished programs that will be run as a script. It’s a long journey to
scripting, which begins with some first small steps. We have to start with experimenting and exploring, so
we’ll use Python interactively. This gives us the instant gratification of a dialog with the Python program.
To be sure that we’ve got the basics installed and working, we’ll use Python directly for our interactions. In
the next chapter, we’ll add the IDLE tool to the mix.
We’ll look at starting Python in several sections: The Windows Command Prompt, The Mac OS Terminal
Tool, and The GNU/Linux Terminal Tool. We’ll look at ending out conversation in How Do We Stop?.
The real work starts in Your First Conversation in Python: miles per gallon. We’ll look at numbers in
Decimal-Points and Accuracy and look at more arithmetic in More Conversations on Arithmetic.
We’ll examine some core features of the language in Parenthesis and Precedence, Long-Winded Statements,
and More About Punctuation. We’ll answer a few questions in Direct Python Interaction FAQ.
The Command or Terminal tool use of Python is the simplest and most ubiquitous way to use Python.
This doesn’t have flashy, interactive, colorful screens; it’s just plain text. When we get to Fit and Finish:
Complete Programs, we’ll see that this way of using Python has an elegant simplicity that the experts use
heavily.
49
Programming for Non-Programmers, Release 2.5.1
The command prompt is sometimes hard to find in Windows. In Windows 2000, you have to look in the
Start menu under Programs, and then under Accessories to find the Command Prompt.
You can also use the Run... menu item in the Start menu. This will give you a small dialog box where you
can type the name of a program. The name of the command prompt is just cmd. You can type ‘cmd’, and
click Okay.
When you run the command tool, it will present a black window with a prompt from the operating system
that looks something like C:\Documents and Settings\SLott>. Here, you can type the word ‘python’, hit
return, and you’re off and running.
Tip: Debugging Windows Command Prompt
In the unlikely event that you can’t use Python from the Command Prompt, you have an issue with your
Windows “path”. Your path tells the Command Prompt where to find the various commands. The word
python becomes a command when the python.exe file is on the system’s path.
Generally, you should reinstall Python to give the Python installer a chance to set the path correctly for
you. If, for some reason, that doesn’t work, here’s how you can set the system path in Windows.
Click on the value and use the right arrow key to scroll through the value you find. At the end, add
the following ‘;C:\python25’. Don’t forget the ‘;’ to separate this search location from other search
locations on the path.
Click OK to save this change. It is now a permanent part of your Windows setup on this computer.
You’ll never have to change this again.
7. Finish Changing Your System Properties
The current dialog box has a title of Environment Variables. Click OK to save your changes.
The current dialog box has a title of System Properties. Click OK to save your changes.
In the Applications folder, you’ll find a Utilities folder. In the Utilities folder, you’ll find a program
named Terminal. Double click Terminal and you’ll get a window with a prompt from the operating system
that looks something like [DVDi-Mac-1:~] slott%. Here, you can type ‘env python’, and you’re off and
running.
You might want to drag the Terminal icon onto your dock to make it easier to find.
The Fedora Linux desktop, for example, has a Start Here icon which displays the applications that are config-
ured into you GNOME environment. The System Tools icon includes the Terminal application. Double
click Terminal and you’ll get a window which prompts you by showing something like [slott@linux01
slott]$. In response to this prompt, you can type ‘env python’, and you’re off and running.
For non-Gnome Linux and Unix variants, you must find your Terminal tool, into which can type ‘python’.
Once the Python program has started, it looks something like the following. It doesn’t matter whether
Python starts up from the command prompt or terminal window, the basic operation is the same. The
window title and background color may be different, but our interaction with Python will be the same.
When we get the >>> prompt, the Python interpreter is listening to us. We can type any Python statements
we want. Each complete statement is executed when it is entered.
To finish using Python, we enter the end-of-file character. We do this when we’re completely done with all
of our work. We don’t absolutely have to do this, because we can always just exit the Command Prompt
or Terminal. When we stop the Terminal, the running Python program will be killed, also.
MacOS and GNU/Linux. The polite way to tell Python that we’re done is Ctrl-D.
Windows. The polite way to finish a conversation with Python is Ctrl-Z, followed by Enter.
The Python program’s job is very simple: it prompts you for a statement, executes the statement you
entered, and then responds back to you with the result of executing the statement. This little three-step
loop is all that Python does. Of course, as we will see, the real power comes from the wide variety of
statements we provide in the Python language.
Important: Don’t Forget to Run Python
While this may seem like a silly reminder, it’s important to start the Python program. We emphasize it
because it isn’t always obvious what piece of software processes our Python language statements.
In The Python Program and What It Does we described our four-tiered device built from the Computer
System, Operating System, Terminal (or Command Prompt) and Python. First, we start the computer
system with the power button. The Operating System starts more-or-less automatically. Second, we have
to locate the Terminal (or Command Prompt), called a “shell”. Third, we run Python.
Each tier of software has it’s own unique prompt. The basic operating system presents a slick GUI desktop
metaphor with colorful icons and menus. The shell provides a technical-looking prompt like C:\Documents
and Settings\SLott>, or [DVD-iMac-2:~] slott%. Python provides the >>> prompt that tells us we can
enter a Python statement.
Bottom Line. We’re always interacting with some program on our computer. We can’t “simply type things”;
we have to run a program which will respond appropriately when we give that program statements in a
language it can process. If you don’t see the >>> prompt, you’re not interacting with Python.
Since we are all newbies to programming, we’ll start with some very simple Python interactions, just to see
what kinds of things Python can do. We’ll start the Python program and then type Python statements
that evaluate a simple formula. For these first few examples, we’ll include the reminder to start running
Python.
This first example will show the mathematical operation of ÷. If you look at your computer keyboard, you
won’t find the ÷key. Python uses ‘/’ (and ‘//’) for division.
1. The shell prompted me with MacBook-5:~ slott$. I typed ‘python’ to start the python program
running.
2. Python provided some information on itself.
3. Python prompted me with >>>. I typed ‘351 / 18’ to compute miles per gallon I got driving to Newark
and back home. This is a complete Python statement, and Python will evaluate that statement.
4. Python responded with 19: a rotten 19 miles per gallon. I’ve got to get a new car that uses less
gasoline.
This shows Python doing simple integer arithmetic. There were no fractions or decimal places involved.
When I entered ‘355 / 18’ and then hit Return, the Python interpreter evaluated this statement. Since the
statement was an expression, Python printed the results.
The usual assumption for numbers is that they are integers, sometimes called whole numbers.
Note that Python does not like ‘,’ in numbers. Outside Python, we write large numbers with ‘,’ to break
the numbers up for easy reading. (The exception is the calendar year, where we omit the ‘,’: we write 2007,
not 2,007.) Python can’t cope with ‘,’ in the middle of numbers. The mileage on my odometer reads 19,241.
But, in Python we write this as ‘19241’.
Bottom Line. For now, be comfortable that Python is perfectly happy with whole numbers. Remember to
avoid commas. We sometimes call these numbers ints, short for integers. Later, we’ll see that Python has a
pretty expansive set of numbers available to work with.
That calculation was nice, but you’ll notice that whole numbers aren’t really very accurate. If you pull out
a calculator, you’ll see that Python got a different answer than your calculator shows.
If you include a period in your numbers, you get “floating decimal point” numbers. We call these floating-
point or floats. The number of digits on either side of the decimal point can “float”. Floating point numbers
are handy for many kinds of calculations.
Our previous conversation used whole numbers. Let’s try again, using floating-point numbers.
1. I typed ‘351. / 18.’ to compute miles per gallon I got driving to Newark and back home.
2. Python responded with 19.5: the more accurate 19.5 miles per gallon.
Floating-point isn’t adequate for everything, so there’s another kind of number that we’ll get to later. When
we do financial calculations on US dollars, the decimal point is fixed; we have two digits to the right of the
decimal point and no more. These fixed-decimal point numbers aren’t a built-in feature of Python, but there
are ways to extend Python with a library that gives us this capability.
Bottom Line. For now, be comfortable that Python is perfectly happy with floating-point numbers that
have about 17 total digits of accuracy, but a range that is huge. Remember to include a decimal point to tell
Python that you want to see decimal places in the calculation. Also, remember to avoid commas, they’re
just confusing.
So far, we’ve given arithmetic expressions to Python and Python’s response is to evaluate those expressions.
When we look at our keyboard, we can see that we have √ ‘/’ (for division), ‘+’ for addition and ‘-’ for
subtraction. What about multiplication (×)? Square roots ( )? Raising to a power? These aren’t keys on
a standard keyboard.
Here are the arithmetic operations that Python recognizes in forms very similar to the way mathematics is
written:
• Addition (+) is the ‘+’ character. You say ‘123+456’ to add two numbers.
• Subtraction (-) is the ‘-’ character. You say ‘9116-8765’ to find the difference between two numbers.
• Multiplication ( ×) is the ‘*’ character. You say ‘19*18’ to find the product of two numbers.
• Division ( ÷) is the ‘/’ character and the ‘//’ sequence of characters. You say ‘351/18’ to find the
quotient of two numbers.
• Raising to a power (ap ) is the ‘**’ sequence of characters. You can say ‘5**2’ to raise 5 to the 2nd
power, 52 .
Additionally, Python (and many other programming languages) provide two handy operators that mathe-
maticians don’t normally write down in this form. Mathematicians may talk about “modular” arithmetic,
with something like a mod m. This is written in Python using the ‘%’ character. For non-mathematicians,
this is the remainder after division.
Here’s what this shows us: 113 goes into 355 with 16 left over. Mathematically, 355 = 3 × 113 + 16.
We’ll look at all of these operators closely in Simple Arithmetic : Numbers and Operators.
The usual mathematical rules of operator precedence apply to Python expressions: multiplies and divides
will be done before adds and subtracts. Plus, we get to use ‘()’ are used to group terms against precedence
rules. Unlike mathematics, we can’t use ‘[]’ and ‘{}’ in arithmetic expressions. Mathematicians can use
these, but in Python, we have to limit ourselves to just ‘()’.
For example, converting 65 °Fahrenheit to Celsius is done as follows.
We have to put the ‘65-32’ in parenthesis so that it is done before the multiply and divide. Also, you’ll note
that when one number is floating point (‘9.’) it forces the calculation to be done as floating-point.
What would happen if we said ‘65-32*5/9’? Try it first, to see what happens.
If we don’t include the ‘()’ for grouping, then Python would do what every mathematician would do:
compute ‘32*5/9’ first and then the difference between that and 65. Python did what we said, but not what
we meant. We know the answer is wrong because 65 °Fahrenheit can’t be the impossibly hot 48 °Celsius.
In the second example, we put in extra ‘()’ that don’t change the resulting answer.
Python prompts us with the basic “I’m listening” prompt of >>> When we type an expression statement,
Python prints the result for us, and then another prompt.
Python has a second prompt that you will see from time to time. It indicates that your statement isn’t
complete, and more is required. It’s the “I’m still listening” prompt of .... Here’s how it works.
For this section only, we’ll emphasize the usually invisible Return key by showing it as ←-. When we
start using compound statements in Processing Only When Necessary : The if Statement, we’ll add some
additional syntax rules. For now, however, we have to emphasize that statements can’t be indented; they
must begin without any leading spaces or tabs. Here’s a simple case: converting 65 °Fahrenheit to Celsius.
>>> ( 65 - 32 ) * 5 / ←-
File "<stdin>", line 1
(65-32)*5 /
^
SyntaxError: invalid syntax
>>>
This leads us to the first of many syntax rules. We’ll present them in order of relevance to what we’re doing.
That means that we’re going to skip over some syntax rules that don’t apply to our situation.
Important: Syntax Rule One
Statements must be complete on a single line. If the statement is incomplete, you’ll get a SyntaxError
response.
Just to be complete, we’ll present syntax rule two, but it doesn’t really have much impact on what we’re
going to be doing.
Important: Syntax Rule Two
The invisible end-of-line character is slightly different on different platforms. On Windows it is actually two
non-printing characters, where on GNU/Linux and MacOS it is a single non-printing character. You may
notice this when moving files back and forth between operating systems.
There is an escape clause that applies to rule one (“one statement one line.”) When the parenthesis are
incomplete, Python will allow the statement to run on to multiple lines.
>>> ( 65 - 32 ←-
... ) * 5 / 9 ←-
18
>>>
>>> 5 + 6 * \ ←-
... 7 ←-
47
>>>
This is called an escape and it allows you to break up an extremely long statement. It creates an escape
from the usual meaning of the standard meaning of the end-of-line character; the end-of-line is demoted to
just another whitespace character, and loses it’s meaning of “end-of-statement, commence execution now”.
We’ve been ignoring spaces in our expressions. There are some spaces in the examples, but we haven’t been
dwelling on precisely how many spaces and where the spaces are allowed. It turns out that spaces other than
indentation are very flexible. Indentation is not flexible.
Important: Syntax Rule Nine
You can use spaces and tabs freely to separate tokens, or language elements.
We have found some kinds of mistakes that we can make with unclosed ‘()’‘s and an extra ‘\’ at the end of
the line. This leads us to an important debugging tip.
Tip: Debugging Typing a Python Statement
When you see the ... prompt from Python, it means that your statement is incomplete. Are you missing
a ‘)’ to make the ‘()’ pairings complete? Did you accidentally use the ‘\’? Hit Return twice and you’ll get
a nice syntax error and you’ll be back at the >>> where you can try again.
Also, you’ll get unexpected errors if you try to use ‘[]’, and ‘{}’ the way mathematicians do. Python only
uses ‘()’ to group expressions. If you try to use ‘[]’, you’ll get a TypeError: unsupported operand
type(s) for [] : 'list' and 'int'. If you try to use ‘{}’, you get a SyntaxError: invalid syntax.
>>> help
Type help() for interactive help, or help(object) for help about object.
>>> help()
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://www.python.org/doc/tut/.
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".
help>
You can see that the prompt is now help>. To go back to ordinary Python programming mode, enter ‘quit’.
help> quit
You are now leaving help and returning to the Python interpreter.
If you want to ask for help on a particular object directly from the
interpreter, you can type "help(object)". Executing "help('string')"
has the same effect as typing a particular string at the help> prompt.
>>>
>>> help("EXPRESSIONS")
You’ll get a page of output, ending with a special prompt from the program that’s helping to display the
help messages. The prompt varies: Mac OS and GNU/Linux will show one prompt, Windows will show
another.
Mac OS and GNU/Linux. In standard OS’s, you’re interacting with a program named less; it will
prompt you with : for all but the last page of your document. For the last page it will prompt you with
(END).
This program is very sophisticated. The four most important commands you need to know are the following.
q Quit the less help viewer.
h Get help on all the commands which are available.
␣Enter a space to see the next page.
b Go back one page.
Windows. In Windows, you’re interacting with a program named more; it will prompt you with -- More
--. The four important commands you’ll need to know are the following.
q Quit the more help viewer.
h Get help on all the commands which are available.
␣Enter a space to see the next page.
Why are numbers 32 bits? The coffee-shop answer is “that’s the way computers are built”.
The real answer is that the use of 32 bits has a long engineering history. One very important consider-
ation is parallelism. The processor chip designers want to have many things happen at the same time.
In the case of retrieving data from memory, getting data in 4-byte chunks will take 1/4 the time of
getting data in 1-byte chunks. Modern processors often fetch a very large number of bits from memory
and keep it in a special cache buffer on the processor chip.
The number of bits used to represent data has varied somewhat. A comfortable group of bits is called
a byte. Some older computers used 9-bits in each byte, and put four of these together to make 36-bit
numbers. Early modems used a signal protocol optimized to send 7-bits in each byte.
The 7-bit byte allows for 128 values in a single byte. If we take the US Latin alphabet (26 lower case
letters, 26 upper case letters, 10 digits, 40-odd punctuation marks) have about 96 characters. Adding
some additional codes for housekeeping, we have 128 character codes, which only needs a 7-bit number
to encode each character.
We can then use an eighth bit to carry a primitive error-detection code. We can insist that each valid
character code have an even number of bits switched on. If we receive a character with an odd number
of bits, we know that a bit got garbled. This is one of the many historical precedents that made 8-bit
bytes appealing.
Also, of course, there is an elegant symmetry to using 8-bit bytes when we are using binary number
coding. The powers of two that we use for binary number positions are 1, 2, 4, 8, 16, 32, 64 and 128.
This sequence of numbers has almost mystic significance. Of course we would prefer 8-bit bytes over
9-bit bytes. 32-bit numbers fit this sequence of numbers better than 36-bit numbers.
From Bytes to Words. Once we’ve settled on 8-bit bytes, the next question is how many bytes make
up a respectable “word”. Early computers had 64 kilobytes of memory, a number that requires only
16 bits (2 bytes) to represent. We can use a two-byte register to identify any of the bytes in memory.
Many early microprocessors made use of this. The legendary Apple ][ PC had a 6502 processor chip
that worked this way. Growing this to 640K only adds 4 more bits to the address information, a kind
of half-byte compromise that Microsoft made use of to create DOS for the Intel 8088 processor chip.
In the metric measurement system, a kilometer is 1,000 meters. In the world of computers, there is an
elegant power-of-two number that we use instead: 1024. A kilobyte, then is 1024 bytes; a megabyte is
1024*1024 = 1,048,576 bytes; a gigabyte is 1,073,741,824 bytes.
As the amount of memory grew, the size of numbers had to grow so that each location in memory
could have a unique numeric address. Currently, 32-bit numbers are oriented around computers with
2 gigabytes of memory. Newer, larger computers use 64-bit numbers so that they can comfortably
handle more than 2 Gb of memory.
Is the 8-bit byte still relevant? When we look at the world’s alphabets, we discover that our 26-letter
US Latin alphabet isn’t really very useful. For most European languages that use the Latin alphabet
we’ll need to add a number of accented characters. For mathematics, we’ll need to add a huge number
of special characters. Once we open the door, we might as well provide for non-Latin alphabets like
Greek, Arabic, Cyrillic, Hebrew and others. We’re going to need a lot more than 128 character codes.
And then there’s the Chinese problem: there are thousands of individual characters. This is solved by
having Multi-byte Character Sets (MBCS). Currently the Unicode standard uses as many as four bytes
to represent the world’s alphabets.
Since a byte is no longer an individual character, it is not relevant for that purpose. However, it is the
unit in which memory and data are measured, and will be for the foreseeable future.
What Are The Missing Syntax Rules? Yes, we did skip over rules three, four, seven and eight. These
are more advanced topics.
We’ll look at rules three and four in Turning Python Loose with More Sophisticated Scripts. These
rules have to do with lines Python ignores, called “comments” and character encoding for Python files.
We’ll look at rules seven and eight in Processing Only When Necessary : The if Statement. These rules
have to do with indenting and completing compound statements.
We’ll look at how we can use the IDLE program to make our lives easier. IDLE puts an Integrated
Development Environment ( IDE ) around the Python program. Rather than work with Python directly,
using the text-only interface, we’ll add some nice features that help us spot errors, save files, and generally
see that’s going on.
We’ll look at this what this environment helps us do in The Development Environment. We’ll look at how
to start and stop IDLE in Starting and Stopping IDLE. We’ll touch on the basic features of IDLE in
Using IDLE’s “Python Shell” Window. We’ll do the real work of entering simple Python statements in A
Conversation Using IDLE.
In IDLE Interaction FAQ we’ll answer some common questions.
Python programming is often done using an Integrated Development Environment ( IDE ) named IDLE .
The IDLE program does a number of things that make programming easier.
• IDLE runs the Python interpreter in interactive mode for us. You’ll see this in a window named
“Python Shell”. You can type Python statements and have them executed immediately. We’ll make
heavy use of this mode to continue to get instant gratification.
• IDLE has an easy-to-use text file editor. When you create a new window, IDLE opens a very nice
editor. This editor knows the Python language and can highlight syntax in color, making the program
easier to read.
• When we start writing scripts, we’ll find that IDLE can run our scripts for us, saving the output from
the script for us.
IDLE isn’t your only choice for an IDE . It is, however, free and so easy to use that we’ll focus on it in this
book. There are some alternatives that might want to explore.
• ActiveState’s Komodo is a very sophisticated editor that knows Python.
• MacOS programmers sometimes use BBEdit or TextMate.
• Windows programmers sometimes use Textpad or notepad++
• Linux programmers can work directly from the command line, using vi or emacs or any of the other
text file editors available in GNU/Linux.
• The LEO editor can be used to create complex programs. It is a literate programming editor with
outlines. LEO isn’t as easy for newbies to use because it is focused on experts. LEO is written in
Python, also.
After we get past the operating-specific details, we’ll see that the Python Shell window of IDLE is the
same on all of out various operating systems.
Windows
You can use the Start menu, Programs submenu, Python 2.5 submenu to locate the IDLE (Python
GUI) menu item. This will open two windows, the Python Shell window is what we need, but it is often
hidden behind a Console window.
MacOS
You can go to your Applications folder, find the Python 2.5 folder, and double click the IDLE application.
This will open two windows, the Python Shell window is what we need, but it is buried under a Console
window.
I recommend dragging the IDLE icon onto your dock to make it easier to find.
GNU/Linux
You have two choices for starting IDLE under GNU/Linux: from the Terminal or using the GUI. Configuring
GNOME or KDE to include an icon for starting IDLE is beyond the scope of this book. It isn’t hard, but
it makes the book too big. So we’ll skip straight to using the Terminal to start IDLE.
Ideally. If your Linux is setup correctly, you may find that the system’s PATH includes
/usr/lib/python2.5/idlelib/. If this is the case, then entering the following command will start IDLE.
idle.py
Less Ideal. From the Terminal prompt, you can type the following command to start IDLE .
Yes, this is long. There are some ways to shorten this up. We’ll cover some of them because they tell us a
lot about how GNU/Linux really works. You only have to do one of these. Pick the one method that seems
simplest to you and ignore the others.
• Write a script. This is a short file that becomes a new Linux command.
• Update your PATH setting. This is a change to your environment that makes the idle.py file usable
by your shell.
• Create an alias. This is a change to your environment that creates a new Linux command.
• Create a link. This adjusts the file system so that idle appears to be in your home directory. This is a
bit risky because your file system may not be organized the same as mine, meaning my example may
not work for you.
Write a Script. To create a script, you’ll put a command in a file, and mark that file as executable. Once
you’ve done these two steps, you’ve effectively added a new command to your GNU/Linux environment.
1. Use an editor (I like gedit) to create a file named idle. Put this above into that file as the only line.
Save the file into your home directory.
2. Execute the command ‘chmod +x idle’ to mark your new file as executable.
Now you can type ‘./idle’ to start IDLE . We recommend this because when you do it this way, you’ve
written your first program! Okay, it’s only one line, but it’s a program.
Tip: Debugging A Script
If your idle script file doesn’t work, there are some common things to confirm:
• Your file is in the same directory that the Terminal starts in. If you are unsure, you can use the pwd
to print the working directory. In my case it is /home/slott. That’s where I put my idle startup file.
• Your file is plain text. A word processor won’t save files as plain text automatically, so you should use
something like gedit to assure that you’re creating a plain text file.
Update your PATH. To update your path, you must make sure that the shell sets the environment you
want.
Most shells, it turns out, read a hidden file named .profile every time you log in to GNU/Linux. The
bash shell reads .bash_profile . There’s a two step process to creating an alias. Once you’ve done these
two steps, you’ve configured your shell environment.
1. Use an editor (I like gedit) to update your .profile or .bash_profile file.
You won’t see this file in ordinary directory listings; the ‘.’ in the name means that it’s hidden; use ‘ls
-a’ to see all files. Insert the following line at the very end. Note that the apostrophes are essential to
making this work.
export PATH=$PATH:/usr/lib/python2.5/idlelib
2. Log out. That way, when you log in again, your .profile is executed.
Now you can type ‘idle.py’ to run the IDLE program.
Create an Alias. To create an alias, you have to make sure that the alias command is executed every time
you log in.
Most shells, it turns out, read a hidden file named .profile every time you log in to GNU/Linux. The
bash shell reads .bash_profile . There’s a two step process to creating an alias. Once you’ve done these
two steps, you’ve configured your shell environment.
1. Use an editor (I like gedit) to update your .profile or .bash_profile file.
You won’t see this file in ordinary directory listings; the ‘.’ in the name means that it’s hidden; use ‘ls
-a’ to see all files. Insert the following line at the very end. Note that the apostrophes are essential to
making this work.
2. Log out. That way, when you log in again, your .profile is executed.
Now you can type ‘idle’ to run the IDLE program. This is a handy technique, but we don’t want to go
overboard creating too many aliases.
Tip: Debugging An Alias
If your alias doesn’t work, there are some common things to confirm:
• Your .profile works correctly. You can type ‘sh -v .profile’ or ‘bash -v .bash_profile’ to test
it. If you see error messages, likely you missed an apostrophe or messed up the spaces.
Create a Link. To create a link, you’ll execute one command. This will make the idle.py file exist in
your home directory as well as the Python library directory.
After we get past the operating-specific details, we see that the Python Shell window of IDLE is the same
on all of the various operating systems. The Python Shell window will have the following greeting.
****************************************************************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer's internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
****************************************************************
IDLE 1.2.4
>>>
If you have personal firewall software and it does warn you about IDLE, you can ignore your personal
firewall’s messages. Your firewall is detecting ordinary activity called “interprocess communication” among
the various components of IDLE. Rather than a personal firewall, I buy routers that do this for all the
computers in my home.
You can use the File menu, item Exit to exit from IDLE. You can also close the window by clicking on the
close icon.
When IDLE is running, the Python Shell shows the Python >>> prompt. This is the same “I’m Listening”
prompt we saw in Your First Conversation in Python: miles per gallon. Interacting with Python through
IDLE is the same as interacting with Python directly.
Interesting. When the Stockholm weather says -20 Celsius, that is -4 Fahrenheit. That’s cold.
Drat! We used numbers without any decimal points. That means we used integer division, which won’t be
very accurate. We’d like to try that statement again without having to retype the entire thing from scratch.
IDLE has a couple of features to make it possible to work more efficiently.
First, we have ordinary copy and paste capabilities. If you look on the Edit menu, you’ll see the usual
culprits: Cut , Copy and Paste . If you are new to this sort of thing, here’s the play-by-play.
1. Click and drag to highlight the ‘-20 * 9/5 + 32’.
2. Use Edit menu, Copy menu item to copy this. Or, you can use Ctrl-C to copy this.
Why are the multiple ways to use Python? Python can be used a variety of ways, depending what
problem you are solving.
We can interact directly with Python at the “command-line”. This was what we saw in Instant
Gratification : The Simplest Possible Conversation. This is available because Python is must usable
when it is a shell program.
A tool like IDLE makes it easier to enter Python statements and execute them. IDLE shows us a
Python Shell window, which is effectively the command-line interaction with Python, plus offers a
handy text editor as a bonus. IDLE is both written in Python and uses Python as a shell program.
A tool like BBEdit or TextPad is a handy text editor that can execute the Python command-line
tool for us. This interaction is made possible because “under the hood”, Python is a command-line
program with the ultra simple character-oriented command-line interface.
Why all the colors? Can I turn that off? Some newbies find syntax coloring distracting. Most experi-
enced programmers find it very handy because the colors provide immediate feedback that the syntax
of the statement is sensible.
If you want to change or disable the syntax coloring, use the Options Configure IDLE... to provide
different syntax coloring.
FOUR
The heart of Python is a rich variety of numeric types and arithmetic operators. We can use these various
numeric types to do basic mathematical operations on whole numbers, real numbers and complex numbers.
We’ll look at the basics in Simple Arithmetic : Numbers and Operators.
In addition to the basic arithmetic capabilities, many kinds of problems need additional mathematical and
financial functions. We’ll look at some of the built-in functions and some functions in add-on modules in
Better Arithmetic Through Functions and Extra Functions: math and random.
For more specialized problems, Python has a variety of additional operators. We’ll look more deeply at these
additional operators in Special Ops : Binary Data and Operators.
We’ll cover some optional topics in Peeking Under the Hood, including different approaches to execution of
Python statements, some notes on Python writing style.
Python provides four slightly different flavors of numbers: plain integers, long integers, floating-point numbers
and complex numbers. Each of these have their various strengths and weaknesses. The mathematical
abstraction of a number doesn’t really exist inside the computer. Instead, we have different representations
of numbers, each reflecting a slightly different tradeoff in the amount of computer memory required and the
speed of performing operations.
In Plain Integers, Also Known As Whole Numbers we’ll look at basic numbers. In Floating-Point Numbers,
Also Known As Scientific Notation we’ll look at numbers with a wider range of values. We’ll look at Python’s
ability to handle very large numbers in Long Integers – Whole Numbers on Steroids. We’ll review the rules
for mixing different species of numbers in Mixing Numbers, Some More Rules.
For the mathematicians and engineers, we’ll look at complex numbers in Complex Numbers – For The
Mathematically Inclined; this is optional material unless you’re really curious.
We’ll look at strings of characters in Strings – Anything Not A Number.
For the most part, Python uses conventional decimal numbers, in base 10. However, for specialized computer-
related tasks, Python can also work in base 8 or base 16. There is a hidden shoal here, so we’ll look at alternate
bases in Octal and Hexadecimal – Counting by 8’s or 16’s.
65
Programming for Non-Programmers, Release 2.5.1
Plain integers in Python are written as strings of digits without commas, periods, or dollar signs. A negative
number begins with a single ‘-’. Plain integers have range ± 2 billion, or about 9 decimal digits.
Internally, an integer is compact, using just four bytes of memory. It’s also blazingly fast for most math-
ematical operations. However, this small size and high speed also mean that it has a limited range of
values.
Here are some examples of integers. Note the absence of ‘,’, ‘.’, ‘$’ or other punctuation. We can only use
‘-’ to mean a negative number.
• ‘0’
• ‘2005’
• ‘8675309’
• ‘-42’
Here are the basic arithmetic operations that Python recognizes:
• Addition (+) is the ‘+’ character.
• Subtraction (-) is the ‘-’ character.
• Multiplication ( ×) is the ‘*’ character.
• Division ( ÷) is the ‘/’ character for standard division, and ‘//’ for integer-like division.
• Raising to a power (ap ) is the ‘**’ sequence of characters.
• Modulus (remainder in division) is the ‘%’ character.
• Grouping is done with the ‘(’ and ‘)’ characters.
Here are some examples.
>>> 32 - 42
-10
>>> 42 * 19 + 21 / 6
801
>>> 2**10
1024
>>> 241 % 16
1
>>> (18-32)*5/9
-8
Pay close attention to ‘42 * 19 + 21 / 6’. In particular, remember that your desktop calculator may
say that 21 ÷ 6 = 3.5. However, since these are all integer values, Python uses integer division, discarding
fractions and remainders. ‘21/6’ is precisely 3.
Does Python Round? Try this to see if Python rounds. If Python does not round, the answers will all
be 2. If Python does round, the answers will be 2, 2, 3 and 3.
8 / 4
9 / 4
10 / 4
11 / 4
What happened? It shouldn’t be any surprise that integer arithmetic is done very simply. For more so-
phistication, we’ll have to use floating-point numbers and complex numbers, which we’ll look at in later
sections.
New Syntax: Functions. More sophisticated math is separated into the math module, which we will look
at in The math Module – Trig and Logs. Before we get to those advanced functions, we’ll look at a few
less-sophisticated functions.
The absolute value (sometimes called the magnitude or absolute magnitude) operation is done using a
slightly different syntax than the conventional mathematical operators like ‘+’ and ‘-’ that we saw above.
A mathematician would write |n|, but this can be cumbersome for computers. Instead of copying the
mathematical notation, Python uses a kind of syntax that we call prefix notation. In this case, the operation
is a prefix to the operands.
Here are some examples using the abs() function.
>>> abs(-18)
18
>>> abs(6*7)
42
>>> abs(10-28/2)
4
The expression inside the parenthesis is evaluated first. In the last example, the evaluation of ‘10-28/2’ is
-4. Then the abs() function is applied to -4. The evaluation of ‘abs(-4)’ is 4.
Here’s the formal Python definition for the absolute value function.
abs(number)
Returns the absolute value of number.
For non-numeric arguments, raises a TypeError.
This tells us that abs() has one parameter that must be a numeric value and it returns a numeric value. It
won’t work with strings or sequences or any of the other Python data types we’ll cover in Basic Sequential
Collections of Data.
Floating decimal point numbers are written as strings of digits with one period to show the decimal point.
They can’t have commas or dollar signs. A negative number begins with a single ‘-’. We call them floats or
floating point numbers for short.
These numbers are different from the “fixed-point” decimal numbers that we use for financial calculations.
With fixed-point numbers, the number of positions to the right of the decimal place is fixed. Doing fixed-
point processing in Python is done with an add-on library; we’ll cover this in One Way To Tackle Fixed
Point Math.
A floating-point number takes at least eight bytes, making it twice the size of a plain integer. The extra
complexity of scientific notation makes them much slower than plain integers. They have about 17 digits of
useful precision, but they can represent values with an astronomical range.
Here are some examples:
• ‘0.’
• ‘3.1415926’
• ‘867.5309’
• ‘-42.0’
We can, if we want, write our numbers in scientific notation. A scientist might write 6.022 × 1023 . In Python,
they use the letter ‘E’ or ‘e’ instead of ×10. Here are some examples.
• ‘6.022e23’
• ‘1.6726e-27’
• ‘8.675309e3’
• ‘2.998e8’
All of the arithmetic operators we saw in Plain Integers, Also Known As Whole Numbers also apply to
floating-point numbers. Here are a couple of examples.
You Call That Accurate? What is going on with that last example? What is that “0000003” hanging off
the end of the answer?
That tiny, tiny error amount is the difference between the decimal (base 10) display and the binary (base
2) internal representation of the numbers. That tiny, annoying error can be made invisible when we look
at formatting our output in Sequences of Characters : str and Unicode. For now, however, we’ll leave this
alone until we have a few more Python skills under our belt.
One consequence is that some fractions are spot-on, while others involve an approximation. Anything that
involves halves, quarters, eighths, etc., will be represented precisely. 3.1 has to be approximated, where 3.25
is something that Python handles exactly.
Important: Mixing Numbers
When you mix numbers, as in ‘2 + 3.14159’, Python coerces the integer value to a floating-point value. This
assures that you never loose any information. It also means that you don’t have to meticulously check every
number in a statement to be sure that they are all floating-point. As long as some numbers are floating-point,
the others will likely get promoted properly.
The coercion rules are done for each individual operation. ‘2+3/4.0’ and ‘2.0+3/4’ will do different things.
We’ll return to this below.
Scientific Notation. Floating point numbers are stored internally using a fraction and an exponent, in a
style some textbooks call “scientific notation”. Usual scientific notation uses a power of 10. In the Python
language, we write the numbers as if we were using a power of 10. We think of a number like 123000 as
1.23e5. Generally, it means the following, where g is 1.23 and c is 5.
n = g × 10c
While the Python language allows us to enter our numbers in good-old decimal, our computer doesn’t use
base 10, it uses base 2. Really, our floating point numbers are converted to the following form.
n = b × 2b
It’s that conversion between the value of g (as entered in base 10) to b (in base 2) back to base 10 that gives
us the tiny approximation errors.
One important consequence of this is the need to do some algebra before simply translating a formula into
Python. Specifically, if we subtract two nearly-equal floating point numbers, we’re going to magnify the
importance of the stray error bits that are artifacts of conversion.
Now that we’ve seen integers and floating-point numbers, we can look more closely at division.
Here’s the example of ‘/’ division: integer values give an integer answer, floating-point values give a floating
point answer, mixed values lead to coercion, and a float-point answer.
>>> 355/113
3
>>> 355./113.
3.1415929203539825
>>> 355./113
3.1415929203539825
This will change in Python 3. We’ll look at this in depth in The Two Specialized Division Operators: / and
// .
As part of that change, there’s a second division operator, ‘//’. This division operator gives us the rounded-
down “no fractions, no decimal places” result of division.
At first, this seems seems a little silly, since ‘355/113’ is 3. So is ‘355//113’. Why have a separate operator
that gives the same result?
Consider ‘355.//113.’. Above, we said that using the decimal points made this a floating decimal point
calculation. Yet, the answer doesn’t seem to reflect this.
>>> 355.//113.
3.0
>>> 355./113.
3.1415929203539825
Aha! When we use ‘//’ for ÷, the floating-point numbers are treated like they were whole numbers, and
integer-like division is done. When we use ‘/’ for ÷, we get the “natural” division appropriate to the two
numbers: with floating-point numbers, we get precise answers; with integers, we get an integer answer.
Bottom Line. In Python 3, the ‘/’ operator will provide “exact” division. It will no longer depend on the
numeric values. We’ll look at this in depth in The Two Specialized Division Operators: / and // .
Python allows us to use very long integers. Unlike ordinary integers with a limited range, long integers have
arbitrary length; they can have as many digits as necessary to represent an exact answer.
There’s a trade-off with long integers. An ordinary integer uses relatively little memory and the operations
are blazing fast. A long integer will use a lot of memory and the operations are quite slow.
We write long integers as a string of digits (no periods) that end in ‘L’ or ‘l’. Upper case ‘L’ is preferred,
since the lower-case ‘l’ looks too much like the digit 1. Additionally, Python is graceful about converting to
long integers when it is necessary.
Here are some examples of long integers. Note the absence of ‘,’, ‘.’, ‘$’ or other punctuation. We can only
use ‘-’ to mean a negative number.
• ‘0L’
• ‘2005L’
• ‘4294967296L’
• ‘-42L’
How many different combinations of 32 bits are there? The answer is there are 232 (we write this ‘2**32’ in
Python). The answer is too large for ordinary integers, and we get an answer in long integers.
>>> 2**32
4294967296L
There are about 4 billion ways to arrange 32 bits. How many bits in 1K of memory? 1024 × 8 bits. How
many combinations of bits are possible in 1K of memory?
2**(1024*8)
I won’t attempt to reproduce the output from Python. It has 2,467 digits. There are a lot of different
combinations of bits in only 1K of memory. The computer I’m using has 256 × 1024 K of memory; there are
a lot of combinations of bits available in that memory.
Important: Mixing Numbers
When you mix numbers, as in ‘2 + 3L’, Python coerces the integer value to a long value. This assures that
you never loose any information. If you mix long and floating-point numbers, as in ‘3.14 + 123L’, the long
number is converted to floating-point.
Warning: Python 3
In Python 3, the trailing ‘L’ will no longer be required. There will be almost no distinction between
integers and long integers.
We’ve noted in a couple of places that when you have mixed kinds of numbers Python will coerce the numbers
to be all one kind. The rules aren’t that complex, but they’re important for understanding the semantics of
a mathematical formula.
When you mix integers and longs, the integers are coerced to be longs. The idea here is that a long will
preserve all the information of an integer, even though the long works more slowly. It’s a fair tradeoff. ‘2+3L’
is ‘5L’ because the ‘2’ was coerced to ‘2L’.
When you mix integers or long integers with floating-point, the integers are coerced to floating-point. Again,
the idea is to preserve as much information as possible. However, the floating-point version of a number
might not preserve everything.
A floating-point number can represent a vast range of values, but it only has about 17 digits of precision. A
long integer can have any number of digits. If your long integer is over 17 digits, some of the precision has
to be sacrificed, and it will be the right-most digits of the long integer.
Remember that a floating-point number’s right-most digits aren’t all perfectly accurate; we’re reminded of
that every time we see a dangling “0000003”. Consequently, making a floating-point value into a long integer
doesn’t work out well. Some of the digits on the right-hand end of such a number are more error than
precision.
How Coercion Happens. Coercion is something Python does as it evaluates each operator. Here’s
something you can try to see the effect of these rules.
>>> 2+3/4.0
2.75
>>> 2.0+3/4
2.0
In the first example, the first expression to be evaluated (‘3/4.0’) involves coercing ‘3’ to ‘3.0’, with a result
of ‘0.75’. Then the ‘2’ is coerced to ‘2.0’ and the two values added to get ‘2.75’.
In the second example, the first expression to be evaluated (‘3/4’) is done as integer values, with a result of
‘0’. Then this is coerced to ‘0.0’ and added to ‘2.0’ to get ‘2.0’.
As we’ll see in Functions are Factories (really!) we can force specific conversions if Python’s automatic
conversions aren’t appropriate for our problem.
Besides plain integers, long integers and floating-point numbers, Python also provides for imaginary and
complex numbers. These use the European convention of ending with ‘J’ or ‘j’. People who don’t use
complex numbers should skip this section.
√
3.14J is an imaginary number = 3.14 −1.
A complex number is created by adding a real and an imaginary number: 2 + 14 j. Note that Python always
prints these in ‘()’‘s; for example (2+14j).
The usual rules of complex math work perfectly with these numbers.
>>> (2+3j)*(4+5j)
(-7+22j)
Python even includes the complex conjugate operation on a complex number. Syntactically, the operation
conjugate() follows the complex number, separated by a dot (‘.’). This makes it a post-fix operator. For
example:
>>> 3+2j.conjugate()
(3-2j)
A complex number is a pretty complicated object: it has a real part, an imaginary part, and a number of
really unusual operations. Complicated objects force us to use a more sophisticated notation. This is part
of a larger, more general syntax pattern that we’ll return to this additional syntax in Defining New Objects.
A string is a sequence of characters without a specific meaning. We surround strings with quotes to separate
them from surrounding numbers and operators. Unlike a number, which supports arithmetic operations, a
string supports different kinds of operations including concatenation and repetition.
You can use either apostrophes (‘'’) or quotes (‘"’) to surround string values. This gives you plenty of
flexibility in what characters are in your strings. You can put an apostrophe into a quoted string, and you
can put quotes into an apostrophe’d string. The full set of quoting rules and alternatives, however, will have
to wait for Sequences of Characters : str and Unicode.
Here are some examples of strings. We use apostrophes for the strings that have quotes. We use quotes for
the strings that have apostrophes.
• ‘"Hello world"’
• ‘'"The time has come," the walrus said'’
• ‘"Alice's Adventures in Wonderland"’
What if we need both quotes and apostrophes in a single string value? We have to use a technique called
an escape. In a quoted string, we may need to escape from the usual meaning of the quote as the end of the
string. We use the character ‘\’ in front of the quote as an escape. In a quoted string, we use ‘\"’ to include
a quote inside the string. In an apostrophe string, we use ‘\'’ to embed an apostrophe.
• ‘"Larry said, \"Don't do that.\""’
• ‘'Natalie said, "I won\'t."'’
The first example shows a quoted string with a quotation inside it. If we tried ‘"Larry said, "Don't do
that.""’, we would have a syntax error. We’d have a quoted string (‘"Larry said, "’), some random
letters (‘Don't do that.’), and another quoted string (‘""’). We have to escape the meaning of the two
internal quotes, so we use ‘\"’ for them.
The second example shows an apostrophe’d string with an apostrophe inside it. To escape the meaning of
the apostrophe, we use ‘\'’.
String Operators. Strings have two basic operators:
• Concatenation is the ‘+’ operator; it puts two strings together to make a new string.
• Repetition is the ‘*’ operator; it repeats a strings several times to make a new string.
Here are some examples. Note that we had to include spaces in our strings so that the concatenation would
look good.
We’ll use strings more heavily in Seeing Results : The print Statement. It turns out that strings are actually
very sophisticated objects, so we’ll defer exploring them in depth until Sequences of Characters : str and
Unicode.
Note: Adjacent String Literals
As a special case, Python will automatically concatenate adjacent string literals. This only works for quoted
strings, but sometimes you’ll see programs that look like this.
Remember from Syntax Rule 5 that the \ extends the statement to the next line. This statement is three
adjacent string literals. Python will concatenate these three strings to make one long message.
For historical and technical reasons, Python supports programming in octal (base 8) and hexadecimal (base
16). I like to think that the early days of computing were dominated by people with 8 or 16 fingers.
You might say to yourself, “Why am I reading this section? I’m not a computer heavyweight!” It turns out
that there is a hidden shoal lurking just under the surface of the numbers we’ve seen so far. The debugging
tip, below, is the reason we have to mention this topic.
For much, much more information on bits, bytes, octal and hexadecimal, see Special Ops : Binary Data and
Operators.
Base 8 – “Octal”. A number with a leading 0 (zero) is octal and uses the digits 0 to 7. Here are some
examples:
• ‘0’
• ‘0123’
• ‘-077’
• ‘012’
When you enter one of these numbers, Python evaluates it as an expression, and responds in base 10.
>>> 0123
83
>>> 0777
511
An attempt to use digits 8 and 9 in an octal number is illegal and gets you a strange looking error message.
In base 8, we only have the digits 0 to 7, the value 8 is 010 (1 in the 8’s place, 0 in the 1’s place).
>>> 09
File "<stdin>", line 1
09
^
SyntaxError: invalid token
In the obscure parlance of language parsing, any symbol, including a number is a token. In this case, the
token could not be parsed because it began with a zero, and didn’t continue with digits between 0 and 7. It
isn’t a proper numeric token.
Tip: Debugging Octal Numbers (Leading Zero Alert)
A number that begins with a zero is supposed to be in base 8. If you are copying numbers from another
source, and that other uses leading zeros, you may be surprised by what Python does. If the number has
digits of 8 or 9, it’s illegal. Otherwise, the number isn’t decimal.
I spent a few hours debugging a program where I had done exactly this. I was converting a very ancient
piece of software, and some of the numbers had zeroed slapped on the front to make them all line up nicely.
I typed them into Python without thinking that the leading zero meant it was really base 8 not base 10.
Base 16 – “Hexadecimal”. A number with a leading 0x or 0X is hexadecimal, base 16. In order to count
in base 16, we’ll need 16 distinct digits. Sadly, our alphabet only provides us with ten digits: 0 through 9.
The computer folks have solved this by using the letters a-f (or A-F) as the missing 6 digits. This gives us
the following way to count in base 16: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, 10, 11, 12, 13, 14, etc. Here
are some examples of hexadecimal numbers:
• ‘0x0’
• ‘0x123’
• ‘-0xcbb2’
• ‘0xbead’
When you enter one of these numbers, Python evaluates it as an expression, and responds in base 10.
>>> 0x53
83
>>> 0x1ff
511
>>> 0xffcc33
16763955
Hex or octal notation can be used for long numbers. 0x234C678D098BAL, for example is 620976988526778L.
Use any of these forms to compute the mortgage payment, m, due with a principal, p, of $110,000,
an interest rate, r, of 7.25% annually, and payments, n, of 30 years. Note that banks actually process
things monthly. So you’ll have to divide the interest rate by 12 and multiply the number of payments
by 12.
5. Surface Air Consumption Rate.
Surface Air Consumption Rate (SACR) is used by SCUBA divers to predict air used at a partic-
ular depth.
For each dive, we convert our air consumption at that dive’s depth to a normalized air consump-
tion at the surface. Given depth (in feet), d, starting tank pressure (psi), s, final tank pressure
(psi), f, and time (in minutes) of t, the SACR, c, is given by the following formula.
33(s − f )
c=
t(d + 33)
Typical values for pressure are a starting pressure of 3000, final pressure of 500.
A medium dive might have a depth of 60 feet, time of 60 minutes.
A deeper dive might be to 100 feet for 15 minutes.
A shallower dive might be 30 feet for 60 minutes, but the ending pressure might be 1500. A
typical c (consumption) value might be 12 to 18 for most people.
Write expressions for each of the three dive profiles given above: medium, deep and shallow.
Given the SACR, c, and a tank starting pressure, s, and final pressure, f, we can plan a dive to
depth (in feet), d, for time (in minutes), t, using the following formula. Usually the 33(s − f )/c
is a constant, based on your SACR and tanks.
33(s − f )
= t(d + 33)
c
For example, tanks you own might have a starting pressure of 2500 and ending pressure of 500,
you might have a c (SACR) of 15.2. You can then find possible combinations of time and depth
which you can comfortably dive.
Write two expressions that show how long one can dive at 60 feet and 70 feet.
1. Wind Chill. Used by meteorologists to describe the effect of cold and wind combined.
Given the wind speed in miles per hour, V, and the temperature in °F, T, the Wind Chill, w, is given
by the formula below.
Wind Chill, new model
Wind speeds are for 0 to 40 mph, above 40, the difference in wind speed doesn’t have much practical
impact on how cold you feel.
You can do square root of a given wind speed, V, using an expression like ‘V ** 0.5’. For example, a
20 mph wind would use ‘20 ** 0.5’ in the formula.
Write an expression to compute the wind chill felt when it is -2 °F and the wind is blowing 15 miles
per hour.
2. Force on a Sail.
How much force is on a sail?
A sail moves a boat by transferring force to its mountings. The sail in the front (the jib) of a typical
fore-and-aft rigged sailboat hangs from a stay. The sail in the back (the main) hangs from the mast.
The forces on the stay (or mast) and sheets move the boat. The sheets are attached to the clew of the
sail.
The force on a sail, f, is based on sail area, a (in square feet) and wind speed, w (in miles per hour).
f = w2 × 0.004 × a
For a small racing dinghy, the smaller sail in the front might have 61 square feet of surface. The larger,
mail sail, might have 114 square feet.
Write an expression to figure the force generated by a 61 square foot sail in 15 miles an hour of wind.
3. Craps Odds. What are the odds of winning on the first throw of the dice?
There are 36 possible rolls on 2 dice that add up to values from 2 to 12. There is just 1 way to roll a
2, 6 ways to roll a 7, and 1 way to roll a 12. We’ll take this as given until a later exercise where we
have enough Python to generate this information.
Without spending a lot of time on probability theory, there are two basic rules we’ll use time and
again. If any one of multiple alternate conditions needs to be true, usually expressed as “or”, we add
the probabilities. When there are several conditions that must all be true, usually expressed as “and”,
we multiply the probabilities.
Rolling a 3, for instance, is rolling a 1-2 or rolling a 2-1. We add the probabilities: 1/36 + 1/36 =
2/36 = 1/18.
On a come out roll, we win immediately if 7 or 11 is rolled. There are two ways to roll 11 (2/36) or 6
ways to roll 7 (6/36).
Write an expression to print the odds of winning on the come out roll. This means rolling 7 or rolling
11. Express this as a fraction, not as a decimal number; that means adding up the numerator of each
number and leaving the denominator as 36.
4. Roulette Odds.
How close are payouts and the odds?
An American (double zero) Roulette wheel has numbers 1-36, 0 and 00. 18 of the 36 numbers are red,
18 are black and the zeros are green. The odds of spinning red, then are 18/38. The odds of zero or
double zero are 2/36.
Red pays 2 to 1, the real odds are 38/18.
Write an expression that shows the difference between the pay out and the real odds.
You can place a bet on 0, 00, 1, 2 and 3. This bet pays 6 to 1. The real odds are 5/36.
Write an expression that shows the difference between the pay out and the real odds.
We’ve seen one function, abs(), that is also a standard mathematical function. The usual mathematical
notation is |x|. Some mathematical functions are difficult to represent with simple lines of text, so the folks
who invented Python elected to use “prefix” notation, putting the name of the function first.
This function syntax is pervasive in Python, and we’ll see many operations that are packaged in the form
of functions. We’ll look at many additional function definitions throughout this book. In this chapter, we’ll
focus on built-in functions.
We’ll look at a few basic functions in Say It With Functions; we’ll show how formal definitions look in pow()
and round() Definitions. We’ll show how you can evaluate complex expressions in Multiple Steps. We’ll
touch in the accuracy issue in Accuracy?. We’ll look at how Python gives you flexibility through optional
features in Another Round, Please.
There are a number of conversion or factory functions that we’ll describe in Functions are Factories (really!).
In Going the Other Way we’ll see how we can use conversion functions to make strings from numbers. Finally,
in Most and Least, we’ll look at functions to find the maximum or minimum of a number of values.
Many of the Python processing operations that we might need are provided in the form of functions. Func-
tions are one of the ways that Python lets us specify how to process some data. A function, in a mathematical
sense, is a transformation from some input to an output. The mathematicians sometimes call this a mapping,
because the function is a kind of map from the input value to the output value.
We looked at the abs() function in the previous section. It maps negative and positive numbers to their
absolute magnitude, measured as a positive number. The abs() function maps -4 to 4, and 3.25 to 3.25.
We’ll start out looking at two new mathematical functions, pow() and round(). Here are some examples of
abs(), pow() and round().
>>> abs(-18)
18
>>> pow(16,3)
4096
>>> round(9.424)
9.0
>>> round(12.57)
13.0
A function is an expression, with the same syntactic role as any other expression, for example ‘2+3’. You
can freely combine functions with other expressions to make more complex expressions. Additionally, the
arguments to a function can also be expressions. Therefore, we can combine functions into more complex
expressions pretty freely. This takes some getting used to, so we’ll look at some examples.
>>> 3*abs(-18)
54
>>> pow(8*2,3)*1.5
6144.0
>>> round(66.2/7)
9.0
>>> 8*round(abs(50.25)/4.0,2)
100.48
1. In the first example, Python has to compute a product. To do this, it must first compute the absolute
value of -18. Then it can multiply the absolute value by 3.
2. In the second example, Python has to compute a product of a pow() function and 1.5. To do this,
it must first compute the product of 8 times 2 so that it can raise it to the 3rd power. This is then
multiplied by 1.5. You can see that first Python evaluates any expressions that are arguments to
the function, then it evaluates the function. Finally, it evaluates the overall expression in which the
function occurs.
3. In the third example, Python computes the quotient of 66.2 and 7, and then rounds this to the nearest
whole number.
4. Finally, the fourth example does a whopping calculation that involves several steps. Python has to find
the absolute value of 50.25, divide this by 4, round that answer off to two positions and then multiply
the result by 8. Whew!
The function names provide a hint as to what they do. Here are the formal definitions, the kind of thing
you’ll see in the Python reference manuals.
pow(x, y, [z])
Raises x to the y power.
If z is present, this is done modulo z: xy mod z.
round(number, [ndigits])
Rounds number to ndigits to the right of the decimal point.
The [ and ]‘s are how we show that some parts of the syntax are optional. We’ll summarize this in Function
Syntax Rules.
Important: Function Syntax Rules
We’ll show optional parameters to functions by surrounding them with [ and ]. We don’t actually enter the
[ and ]‘s; they’re just hints as to what the alternative forms of the function are.
round(number, [ndigits])
Rounds number to ndigits to the right of the decimal point.
In the case of the round() function, the syntax summary shows us there are two different ways to use this
function:
• We can use round() with the one required parameter, number. Example: ‘round( 3.14159 )’
• We can use round() with two parameters, number and ndigits. Example: ‘round( 3.14159, 2 )’
Note that there is some ambiguity between using ‘[’ and ‘]’ in our Python programming and using [ and ]
as markup for the grammar rules. Usually the context makes it clear.
We can use the pow() function for the same purpose as the ‘**’ operator. Here’s an example of using pow()
instead of x ** y.
>>> 2L**32
4294967296L
>>> pow(2L,32)
4294967296L
Note that ‘pow(x,0.5)’ is the square root of x. Also, the function math.sqrt() is the square root of x. The
pow() function is one of the built-in functions, while the square root function is only available in the math
library. We’ll look at the math library in The math Module – Trig and Logs.
In the next example we’ll get the square root of a number, and then square that value. It’ll be a two-step
calculation, so we can see each intermediate step.
The first question you should have is “what does that ‘_’ mean?”
The _ is a Python short-cut. During interactive use, Python uses the name _ to mean the result it just
printed. This saves us retyping things over and over. In the case above, the “previous result” was the value
of ‘pow( 2, 0.5 )’. By definition, we can replace a _ with the entire previous expression to see what is
really happening.
Until we start writing scripts, this is a handy thing. When we start writing scripts, we won’t be able to use
the _, instead we’ll use something that’s a much more clear and precise.
4.2.4 Accuracy?
Let’s go back to the previous example: we’ll get the square root of a number, and then square that value.
>>> round(2.45
...
...
... )
2.0
The ... is Python’s hint that the statement is incomplete. You’ll need to finish the ‘()’‘s so that the
statement is complete.
Above, we noted that the round() function had an optional argument. When something’s optional, we can
look at it as if there are two forms of the round() function: a one-argument version and a two-argument
version.
• The one-argument round() function rounds a number to the nearest whole number.
• If you provide the optional second parameter, this is the number of decimal places to round to. If the
number of decimal places is a positive number, this is decimal places to the right of the decimal point.
If the number of decimal places is a negative number, this is the number of places to the left of the
decimal point.
>>> round(678.456)
678.0
>>> round(678.456,2)
678.46000000000004
>>> round(678.456,-1)
680.0
So, rounding off to -1 decimal places means the nearest 10. Rounding off to -2 decimal places is the nearest
100. Pretty handy for doing business reports where we have to round off to the nearest million.
How do we get Python to do specific conversions among our various numeric data types? When we mix whole
numbers and floating-point scientific notation, Python automatically converts everything to floating-point.
What if we want the floating-point number truncated down to a whole number instead?
Here’s another example: what if we want the floating-point number transformed into a long integer instead
of the built-in assumption that we want long integers turned into floating-point numbers? How do we control
this coercion among numbers?
We’ll look at a number of factory functions that do number conversion. Each function is a factory that
creates a new number from an existing number. Eventually, we’ll identify numerous varieties of factory
functions.
These factory functions will also create numbers from string values. When we write programs that read
their input from files, we’ll see that files mostly have strings. Factory functions will be an important part of
reading strings from files and creating numbers from those strings so that we can process them.
float(x)
Creates a floating-point number equal to the string or number x. If a string is given, it must be a valid
floating-point number: digits, decimal point, and an exponent expression. You can use this function
when doing division to prevent getting the simple integer quotient.
For example:
>>> float(22)/7
3.1428571428571428
>>> 22/7
3
>>> float("6.02E24")
6.0200000000000004e+24
int(x)
Creates an integer equal to the string or number x. This will chop off all of the digits to the right of
the decimal point in a floating-point number. If a string is given, it must be a valid decimal integer
string.
>>> int('1234')
1234
>>> int(3.14159)
3
long(x)
Creates a long integer equal to the string or number x. If a string is given, it must be a valid decimal
integer. The expression ‘long(2)’ has the same value as the literal 2L. Examples: ‘long(6.02E23)’,
‘long(2)’.
>>> long(2)**64
18446744073709551616L
>>> long(22.0/7.0)
3L
The first example shows the range of values possible with 64-bit integers, available on larger computers. This
is a lot more than the paltry two billion available on a 32-bit computer.
Complex Numbers - Math wizards only. Complex is not as simple as the others. A complex number
has two parts, real and imaginary. Conversion to complex typically involves two parameters.
complex(real, [imag])
Creates a complex number with the real part of real; if the second parameter, imag, is given, this is
the imaginary part of the complex number, otherwise the imaginary part is zero.
If this syntax synopsis with the [ and ] is confusing, you’ll need to see Function Syntax Rules.
Examples:
>>> complex(3,2)
(3+2j)
>>> complex(4)
(4+0j)
Note that the second parameter, with the imaginary part of the number, is optional. This leads to two
different ways to evaluate this function. In the example above, we used both variations.
Conversion from a complex number (effectively two-dimensional) to a one-dimensional integer or float is not
directly possible. Typically, you’ll use abs() to get the absolute value of the complex number. This is the
geometric distance from the origin to the point in the complex number plane. The math is straight-forward,
but beyond the scope of this introduction to Python.
>>> abs(3+4j)
5.0
If the int() function turns a string of digits into a proper number, can we do the opposite thing and turn
an ordinary number into a string of digits?
The str() and repr() functions convert any Python object to a string. The str() string is typically more
readable, where the repr() result can help us see what Python is doing under the hood. For most garden-
variety numeric values, there is no difference. For the more complex data types, however, the results of
repr() and str() can be different.
Here are some examples of converting floating-point expressions into strings of digits.
Note that the results are surrounded by ‘'’ marks. These apostrophes tell us that these aren’t actually
numbers; they’re strings of digits.
What’s the difference? Try this and see.
11+12
11+'12'
A string of digits may look numeric to you, but Python won’t look inside a string to see if it “looks” like a
number. If it is a string (with ‘"’ or ‘'’), it is not a number, and Pyhton won’t attempt to do any math.
Here are the formal definitions of these two functions. These aren’t very useful now, but we’ll return to them
time and again as we learn more about how Python works.
str(object)
Creates a string representation of object.
repr(object)
Creates a string representation of object, usually in Python syntax.
The max() and min() functions accept any number of values and return the largest or smallest of the values.
These functions work with any type of data. Be careful when working with strings, because these functions
use alphabetical order, which has some surprising consequences.
The last example (‘max( '10', '11', '2' )’) shows the “alphabetical order of digits” problem. Superficially,
this looks like three numbers (10, 11 and 2). But, they are quoted strings, and might as well be words. What
would be result of ‘max( 'ba', 'bb', 'c' )’ be? Anything surprising about that? The alphabetic order
rules apply when we compare string values. If we want the numeric order rules, we have to supply numbers
instead of strings.
Here are the formal definitions for these functions.
max(sequence)
Returns the object with the largest value in sequence.
min(sequence)
Returns the object with the smallest value in sequence .
1. Numeric Expressions.
Write an expression to convert the mixed fraction 3 5/8 to a floating-point number.
2. Truncation.
Evaluate ‘(22.0/7.0)-int(22.0/7.0)’. What is this value? Compare it with ‘22.0/7.0’. What
general principal does this illustrate?
3. Illegal Conversions.
Try illegal conversions like ‘int('A')’, ‘int(3+4j )’, ‘int( 2L**64 )’. Why are exceptions raised?
Why can’t a simple default value like zero be used instead?
In Meaningful Chunks and Modules, we’ll digress to look at the extension libraries. This is because the bulk
of the math functions are in a separate module or library, called math. We’ll look at parts of it in The math
Module – Trig and Logs. We’ll also look at the random number generators in The random Module – Rolling
the Dice.
For those who will be using Python for financial and other fixed-point calculations, we’ll look at fixed-point
math, also. However, we’ll defer this until Fixed-Point Numbers : Doing High Finance with decimal because
it is a bit more advanced than using the built-in types of numbers.
Python’s use of modules is a way to break the solution to a problem down into meaningful chunks. We
hinted around about this in Core Coolness. There are dozens of standard Python modules that solve dozens
of problems for us. We’re not ready to look at modules in any depth, that comes later in Modules : The
unit of software packaging and assembly. This section has just a couple of steps to start using modules so
that you can make use of two very simple modules: math and random.
A Python module extends the Python language by adding new classes of objects, new functions and helpful
constants. The import statement tells Python to fetch a module, adding that module to our working
environment. For now, we’ll use the simplest form: import.
import m
This statement will tell Python to locate the module named m and provide us with the definitions in that
module. Only the name of the module, m, is added to the local names that we can use. Every name inside
module m must be qualified by the module name. We do this by connecting the module name and the
function name with a ‘.’. When we import module math, we get a cosine function that we refer to with
“module name dot function name” notation: math.cos().
This module qualification has a cost and a benefit. The cost is that you have to type the module name over
and over again. The benefit is that your Python statements are explicit and harbor no assumptions. There
are some alternatives to this. We’ll cover it when we explore modules in depth.
Another important thing to remember is that you only need to import a module once to tell Python you will
be using it. By once, we mean once each time you run the Python program. Each time you exit from the
Python program (or turn your computer off, which exits all your programs), everything is forgotten. Next
time you run the Python program, you’ll need to provide the import statements to add the modules to
Python for your current session.
An Interesting Example. For fun, try this:
import this
The this module is atypical: it doesn’t introduce new object classes or function definitions. Instead, well,
you see that it does something instead of extending Python by adding new definitions.
Even though the this module is atypical, you can still see what happens when you use an extra import.
What happens when you try to import this a second time?
The math module defines the common trigonometry and logarithmic functions. It has a few other functions
that are handy, like square root. The math module is made available to your programs with:
import math
Since this statement only adds math to the names Python can recognize, you’ll need to use the ‘math.’ prefix
to identify the functions which are inside the math module.
Here are a couple of examples of some trigonometry. We’re calculating the cosine of 45, 60 and 90 degrees.
You can check these on your calculator. Or, if you’re my age, you can use a slide rule to confirm that these
are correct answers.
6.123233995736766e-17
>>> round( math.cos( 90*math.pi/180 ), 3 )
0.0
asin(x)
Returns the arc sine of x.
atan(x)
Returns the arc tangent of x.
atan2(y, x)
Returns the arc tangent of y / x. arctan y/x
cos(x)
Returns the cosine of x radians.
sin(x)
Returns the sine of x radians.
tan(x)
Returns the tangent of x radians.
Additionally, the following constants are also provided.
pi The value of π, 3.1415926535897931
e The value of e, 2.7182818284590451, used for the exp() and log() functions.
Here’s an example of using some of these more advanced math functions. Here is a trig identity for the
cosine of 39 degrees. We use ‘39*math.pi/180’ to convert from degrees to radians. We also use the square
root function (sqrt()).
Here are some more of these common trigonometric functions, including logarithms, anti-logarithms and
square root.
The following batch of functions supplement the basic round() function with more sophisticated computa-
tions on floating-point numbers. You can probably guess from the names what ceiling and floor mean.
>>> math.ceil(2.1)
3.0
>>> math.floor(2.999)
2.0
The math module contains the following other functions for dealing with floating-point numbers.
Other Floating-Point Function Definitions.
ceil(x)
Returns the next larger whole number. ‘math.ceil(5.1) == 6’, ‘math.ceil(-5.1) == -5.0’.
fabs(x)
Returns the absolute value of the x as a floating-point number.
floor(x)
Returns the next smaller whole number. ‘math.floor(5.9) == 5’, ‘math.floor(-5.9) == -6.0’.
Some of the math functions only work for a limited domain of values. Specifically, square root is only defined
for non-negative numbers and logarithms are only defined for positive numbers. What does Python do when
math.sqrt(-1)
math.log(-1)
math.log(0)
You’ll see one of two kinds of results. The details vary among the operating systems.
• You’ll see a result of nan. This is a special code that means Not a Number.
• You’ll see an exception, like ValueError or OverflowError. An exception will display a bunch of
debugging information that ends with the exception name and a short explanation.
Both results amount to the same thing: the result cannot be computed.
The random module defines functions that simulate random events. This includes coin tosses, die rolls and
the spins of a Roulette wheel. The random module is made available to your program with:
import random
Since this statement only adds random to the names Python can recognize, you’ll need to use the ‘random.’
prefix on each of the functions in this section.
The randrange() is a particularly flexible way to generate a random number in a given range. Here’s an
example of some of the alternatives. Since the answers are random, your answers may be different from
these example answers. This shows a few of many techniques available to generate random data samples in
particular ranges.
1. We’re asking for a random number, n, such that 0 ≤ n < 6. The number will be between 0 and 5,
inclusive.
2. We’re asking for a random number, n, such that 1 ≤ n < 7. The number will be between 1 and 6,
inclusive.
3. We’re asking for a random even number, n, such that 2 ≤ n < 37. The range function is defined by
start, stop and step values. When the step is 2, then the values used are 2, 4, 6, . . . , 36.
4. We’re asking for a random odd number, n, such that 1 ≤ n < 36. The number will be between 1 and
35, inclusive. Here, we start from 1 with a step of 2; the values used are 1, 3, 5, . . . , 35.
The random module contains the following functions for working with simple distributions of random num-
bers. There are several more sophisticated distributions available for more complex kinds of simulations.
Casino games only require these functions.
choice(sequence)
Chooses a random value from the sequence sequence. Example: ‘random.choice( ['red', 'black',
'green'] )’.
random()
Creates a random floating-point number, r , such that 0 ≤ r < 1.0. Note that random() doesn’t
require any arguments, but does require the empty ‘()’‘s to alert Python that it is really the name of
a function. We use it like this: ‘random.random()’.
randrange([start], stop, [step])
Chooses a random element from ‘range( start, stop , step )’. We’ll revisit this in Built-in
Functions for Lists. For now, we’ll stick with the following examples:
‘randrange(6)’ returns a number, n, such that 0 ≤ n < 6.
‘randrange(1,7)’ returns a number, n, such that 1 ≤ n < 7.
‘randrange(10,100,5)’ returns a number, n, between 10 and 95 incremented by 5’s, 10 ≤ 5k < 100.
uniform(a, b)
Creates a random floating-point number, r , such that a ≤ r < b.
Why do functions have an usual syntax? Python functions all consistently look a little like the math-
ematical ‘sin(x)’. Mathematicians have evolved a number of other forms for functions. Python’s
syntax is, at least, consistent. Rather than ask why Python looks the way it does, we prefer to ask
why the mathematicians have so many different forms for functions.
Why is math (or random or decimal) a separate module? There are two reasons for keeping math (or
random or decimal) in separate modules.
• Not everyone needs math so why include it needlessly?
• There will always be new implementations of basic numeric algorithms with different trade-offs
for range, precision, speed and amount of storage. Rather than pick one, Python leaves it to you
to select among the various alternatives and pick that one that best meets your needs.
Everything I do involves math (or random or decimal), why do I have to import it in every single script?
There is one very important reason for importing the module in every single script. It keeps you (and
Python) honest: nothing is assumed. You said you needed math, making it clear to everyone else who
reads your script. While you know that all your programs are mathematical, almost no one else knows
this. The import statement sets the assumptions on a script-by-script basis, making each a successful,
stand-alone program, without requiring any insider information or background to understand it.
This chapter is optional. If you expect to be working with individual bits, these operators are very helpful.
Otherwise, if you don’t expect to be working with anything other than plain-old decimal numbers, you can
skip this chapter.
While we write numbers using decimal digits, in base 10, computers don’t really work that way internally.
We touched on the computer’s view in Octal and Hexadecimal – Counting by 8’s or 16’s. Internally, the
computer works in binary, base 2, which makes the circuitry very simple and very fast. One of the benefits
of using Python is that we don’t need to spend much time on the internals, so this chapter is optional.
We’ll take a close look at data in Bits and Bytes, this will provide some justification for having base 8 and
base 16 numbers. We’ll add some functions to see base 8 and base 16 in Different Bases and Representations.
Then we’ll look at the operators for working with individual bits in Operators for Bit Manipulation.
The special operators that we’re going to cover in this chapter work on individual bits. First, we’ll have to
look at what this really means. Then we can look at what the operators do to those things called bits.
A bit is a “binary digit” . The concept of bit closely parallels the concept of decimal digit with one important
difference. There are only two binary digits (0 and 1), but there are 10 decimal digits (0 through 9).
Decimal Numbers. Our decimal numbers are a sequence of digits using base 10. Each decimal digit’s
place value is a power of 10. We have the 1,000’s place, the 100’s place, the 10’s place and the 1’s place. A
number like 2185 is 2 × 1000 + 1 × 100 + 8 × 10 + 5.
Binary Numbers. Binary numbers are a sequence of binary digits using base 2. Each bit’s place value in
the number is a power of 2. We have the 256’s place, the 128’s place, the 64’s place, the 32’s place, the 16’s
place, the 8’s, 4’s, 2’s and the 1’s place. We can’t directly write binary numbers in Python. We’ll show them
as a series of bits, like this ‘1-0-0-0-1-0-0-0-1-0-0-1’. This starts with a 1 in the 2048’s place, a 1 in the
128’s place, plus a 1 in the 8’s place, plus a 1, which is 2185.
Octal Numbers. Octal numbers use base 8. In Python, we begin octal numbers with a leading zero. Each
octal digit’s place value is a power of 8. We have the 512’s place, the 64’s place, the 8’s place and the 1’s
place. A number like 04211 is 4 × 512 + 2 × 64 + 1 × 8 + 1. This has a value of 2185.
Each group of three bits forms an octal digit. This saves us from writing out all those bits in detail. Instead,
we can summarize them.
Hexadecimal Numbers. Hexadecimal numbers use base 16. In Python, we begin hexadecimal numbers
with a leading ‘0x’. Since we only have 10 digits, and we need 16 digits, we’ll borrow the letters ‘a’, ‘b’, ‘c’,
‘d’, ‘e’ and ‘f’ to be the extra digits. Each hexadecimal digit’s place value is a power of 16. We have the
4096’s place, the 256’s place, the 16’s place and the 1’s place. A number like 0x8a9 is 8 × 256 + 10 × 16 + 9,
which has a value of 2217.
Each group of four bits forms a hexadecimal digit. This saves us from writing out all those bits in detail.
Instead, we can summarize them.
Bytes. A byte is 8 bits. That means that a byte contains bits with place values of 128, 64, 32, 16, 8, 4, 2,
1. If we set all of these bits to 1, we get a value of 255. A byte has 256 distinct values. Computer memory
is addressed at the individual byte level, that’s why you buy memory in units measured in megabytes or
gigabytes.
In addition to small numbers, a single byte can store a single character encoded in ASCII. It takes as many
as four bytes to store characters encoded with Unicode.
An integer has 4 bytes, which is 32 bits. In looking at the special operators, we’ll look at them using integer
values. Python can work with individual bytes, but it does this by unpacking a byte’s value and saving it in
a full-sized integer.
In Octal and Hexadecimal – Counting by 8’s or 16’s we saw that Python will accept base 8 or base 16
(octal or hexadecimal) numbers. We begin octal numbers with ‘0’, and use digits ‘0’ though ‘7’. We begin a
hexadecimal number with ‘0x’ and use digits ‘0’ through ‘9’ and ‘a’ through ‘f’.
Python normally answers us in decimal. How can we ask Python to answer in octal or hexadecimal instead?
The hex() function converts its argument to a hexadecimal (base 16) string. A string is used because
additional digits are needed beyond 0 through 9; a-f are pressed into service. A leading ‘0x’ is placed on the
string as a reminder that this is hexadecimal. Here are some examples:
>>> hex(684)
'0x2ac'
>>> hex(1023)
'0x3ff'
>>> 0xffcc33
16763955
>>> hex(_)
'0xffcc33'
Note that the result of the hex() function is technically a string, An ordinary number would be presented
as a decimal value, and couldn’t contain the extra hexadecimal digits. That’s why there are apostrophes in
our output.
The oct() function converts its argument to an octal (base 8) string. A leading ‘0’ is placed on the string
as a reminder that this is octal not decimal. Here are some examples:
>>> oct(512)
'01000'
>>> oct(509)
'0775'
>>> int('010101',2)
21
>>> int('321',4)
57
>>> int('2ac',16)
684
In base 2, the place values are 32, 16, 8, 4, 2, 1. The string ‘10101’ is evaluated as 1 × 16 + 1times4 + 1 = 21.
In base 4, the place values are 16, 4 and 1. The string ‘321’ is evaluated as 3 × 16 + 2 × 4 + 1 = 57.
Recall from Octal and Hexadecimal – Counting by 8’s or 16’s that we have to press additional symbols into
service to represent base 16 numbers. We use the letters a-f for the digits after 9. The place values are 256,
16, 1; the string ‘2ac’ is evaluated as 2 × 256 + 10 × 16 + 12 = 684.
While it seems so small, it’s really important that numbers in another base are written using strings.
To Python, ‘123’ is a decimal number. ‘'123'’ is a string, and could mean anything. When you say
‘int('123',4)’, you’re telling Python that the string ‘'123'’ should be interpreted as base 4 number, which
maps to 27 in base 10 notation. On the other hand, when you say ‘int('123')’, you’re telling Python that
the string ‘'123'’ should be interpreted as a base 10 number, which is 123.
int(object, [base])
Generates an integer from the value object. If object is a string, and base is supplied, object must be
proper number in the given base. If base is omitted, and object is a string, it must be decimal.
We’ve already seen the usual math operators: ‘+’, ‘-’, ‘*’, ‘/’, ‘%’, ‘**’; as well as a large collection of
mathematical functions. While these do a lot, there are still more operators available to us. In this section,
we’ll look at operators that directly manipulate the binary representation of numbers. The inhabitants of
Binome (see Binary Codes are more comfortable with these operators than we are.
We won’t wait for the FAQ’s to explain why we even have these operators. These operators exist to provide
us with a view of the real underlying processor. Consequently, they are used for some rather specialized
purposes. We present them because they can help newbies get a better grip on what a computer really is.
In this section, we’ll see a lot of hexadecimal and octal numbers. This is because base 16 and base 8 are also
nifty short-hand notation for lengthy base 2 numbers. We’ll look at hexadecimal and octal numbers first.
Then we’ll look at the bit-manipulation operators.
There are some other operators available, but, strictly speaking, they’re not arithmetic operators, they’re
logic operations. We’ll return to them in Processing Only When Necessary : The if Statement.
Precedence. We know one basic precedence rule that applies to multiplication and addition: Python does
multiplication first, and addition later. The second rule is that ‘()’ ‘s group things, which can change the
precedence rules. ‘2*3+4’ is 10, but ‘2*(3+4)’ is 14.
Where do these special operators fit? Are they more important than multiplication? Less important than
addition? There isn’t a simple rule. Consequently, you’ll often need to use ‘()’‘s to make sure things work
out the way you want.
The ~ operator
The unary ‘~’ operator flops all the bits in a plain or long integer. 1’s become 0’s and 0’s become 1’s. Note
that this will have unexpected consequences when the bits are interpreted as a decimal number.
>>> ~0x12345678
-305419897
>>> hex(~0x12345678)
'-0x12345679'
What makes this murky is the way Python interprets the number has having a sign. The computer hardware
uses a very clever trick to handle signed numbers. First, let’s visualize the unsigned, binary number line,
it has 4 billion positions. At the left we have all bits set to zero. In the middle we have a value where the
2-billionth place is 1 and all other values are zero. At the right we have all bits set to one.
Now, let’s redraw the number line with positive and negative signs. Above the line, we put the signed values
that Python will show us. Below the line, we put the internal codes used. The positive numbers are what
we expected: 0x00000000 is the full 32-bit value for zero, 1 is 0x00000001; no surprise there. Below the
2 billion, we put 0x7fffffff. That’s the full 32-bit value for positive 2 billion (try it in Python and see.)
Below the -2 billion, we put 0x80000000, the full 32-bit value for -2 billion. Below the -1, we put 0xffffffff.
This works very nicely. Let’s start with -2 (0xfffffffe). We add 1 to this and get -1 (0xffffffff), just
what we want. We add 1 to that and get 0x00000000, and we have to carry the 1 into the next place value.
However, there is no next place value, the 1 is discarded, and we have a good-old zero.
This technique is called 2’s complement . Consequently, the ‘~’ operation is mathematically equivalent to
adding 1 and switching the number’s sign between positive and negative.
This operator has the same very high precedence as the ordinary negation operation, ‘-’ . Try the following
to see what happens. First, what’s the value of ‘-5+4’ ? Now, add the two possible ‘()’ ‘s and see which
result is the same: ‘(-5)+4’ and ‘-(5+4)’ . The one the produces the same result as ‘-5+4’ reveals which
way Python performs the operations.
Here are some examples of special ops mixed with ordinary operations.
>>> -5+4
-1
>>> -(5+4)
-9
>>> (-5)+4
-1
The binary ‘&’ operator returns 1-bits everywhere that the two input bits are both 1. Each result bit depends
on one input bit and the other input bit both being 1. The following example shows all four combinations
of bits that work with the ‘&’ operator.
Here’s the same kind of example, combining sequences of bits. This takes a bit of conversion to base 2 to
understand what’s going on.
>>> 3 & 5
1
The number 3, in base 2, is 0011 . The number 5 is 0101 . Let’s match up the bits from left to right:
0 0 1 1
& 0 1 0 1
-------
0 0 0 1
This is a very low-priority operator, and almost always needs parentheses when used in an expression with
other operators. Here are some examples that show you how ‘&’ and ‘+’ combine.
>>> 3&2+3
1
>>> 3&(2+3)
1
>>> (3&2)+3
5
The ^ operator
The binary ‘^’ operator returns a 1-bit if one of the two inputs are 1 but not both. This is sometimes called
the exclusive or operation to distinguish it from the inclusive or . Some people write “and/or” to emphasize
the inclusive sense of or. They write “either-or” to emphasize the exclusive sense of or.
>>> 3^5
6
0 0 1 1
^ 0 1 0 1
-------
0 1 1 0
The | operator
The binary | operator returns a 1-bit if either of the two inputs is 1. This is sometimes called the inclusive
or to distinguish it from the exclusive or‘ operator.
>>> 3|5
7
0 0 1 1
| 0 1 0 1
-------
0 1 1 1
Let’s look at this in a little bit of detail. Our first expression has two or operations, they’re the lowest
priority operators. The first or operation has ‘3&0x1f’ or ‘0x80’ . So, Python does the following steps to
evaluate this expression.
1. Calculate the and of ‘3’ and ‘0x1f’ . This is 3 (try it and see.) You can work it out by hand if you
know that 3 is ‘0-0-0-1-1’ in binary and 0x1f is ‘1-1-1-1-1’.
The ‘<<’ is the left-shift operator. The left argument is the bit pattern to be shifted, the right argument is
the number of bits. This is mathematically equivalent to multiplying by a power of two, but much, much
faster. Shifting left 3 positions, for example, multiplies the number by 8.
This operator is higher priority than ‘&’ , ‘^’ and ‘|’ . Be sure to use parenthesis appropriately.
0xA is hexadecimal; the bits are ‘1-0-1-0’. This is 10 in decimal. When we shift this two bits to the left,
it’s like multiplying by 4. We get bits of ‘1-0-1-0-0-0’. This is 40 in decimal.
The ‘>>’ is the right-shift operator. The left argument is the bit pattern to be shifted, the right argument
is the number of bits. Python always behaves as though it is running on a 2’s complement computer. The
left-most bit is always the sign bit, so sign bits are shifted in. This is mathematically equivalent to dividing
by a power of two, but much, much faster. Shifting right 4 positions, for example, divides the number by 16.
This operator is higher priority than ‘&’, ‘^’ and ‘|’ . Be sure to use parenthesis appropriately.
>>> 80 >> 3
10
The number 80, with bits of ‘1-0-1-0-0-0-0’, shifted right 3 bits, yields bits of ‘1-0-1-0’, which is 10 in
decimal.
Tip: Debugging Special Operators
The most common problems with the bit-fiddling operators is confusion about the relative priority of the
operations. For conventional arithmetic operators, ‘**’ is the highest priority, ‘*’ and ‘/’ are lower priority
and ‘+’ and ‘-’ are the lowest priority. However, among ‘&’, ‘^’ and ‘|’, ‘<<’ and ‘>>’ it isn’t obvious what
the priorities are or should be.
When in doubt, add parenthesis to force the order you want.
1. Bit Masking.
One common color-coding scheme uses three distinct values for the level of red, green and blue that
make up each picture element (pixel) in an image. If we allow 256 different levels of red, green and
blue, we can mash a single pixel in 24 bits. We can then cram 4 pixels into 3 plain-integer values. How
do we unwind this packed data?
We’ll have to use our bit-fiddling operators to unwind this compressed data into a form we can process.
First, we’ll look at getting the red, green and blue values out of a single plain integer.
We can code 256 levels in 8 bits, which is two hexadecimal digits. This gives us a red, green and blue
levels from ‘0x00’ to ‘0xFF’ (0 to 255 decimal). We can string the red, green and blue together to make
a larger composite number like ‘0x0c00a2’ for a very bluish purple.
What is ‘0x0c00a2 & 0xff’? Is this the blue value of ‘0xa2’? Does it help to do ‘hex( 0x0c00a2 &
0xff)’?
What is ‘(0x0c00a2 & 0xff00) >> 8’? ‘hex( (0x0c00a2 & 0xff00) >> 8 )’?
What is ‘(0x0c00a2 & 0xff0000) >> 16’? ‘hex( (0x0c00a2 & 0xff0000) >> 16 )’?
2. Division.
How can we break a number down into different digits?
What is ‘1956 / 1000’? ‘1956 % 1000’?
What is ‘956 / 100’? ‘956 % 100’?
What is ‘56 / 10’? ‘56 % 10’?
What happens if we do this procedure with ‘1956.’, ‘956.’ and ‘56.’ instead of ‘1956’ , ‘956’ and
‘56’? Can we use the ‘//’ operator to make this work out correctly?
Why is there bit-fiddling? Some processing requires manipulating individual bits. In particular, sound
and image data is often coded up in a way that is best processed using these bit-fiddling operations.
Additionally, the various compression schemes like MP3 and JPEG use considerable manipulation of
individual bits of data.
Why are there two division operators? Sometimes we expect division to create precise answers, usually
the floating-point equivalents of fractions. Other times, we want a rounded-down integer result. One
way to work around this problem is to add lots of ‘int’ functions to force integer operations. Another
way is to provide two division operators with different meanings.
This is some additional background in Python and programming. We’ll talk a little about what it means
to execute the statements in a program and evaluate expressions in Execution – Two Points of View. We’ll
provide some style notes in Expression Style Notes.
Currency amounts fall into the cracks between integers (no decimal places) and floating-point numbers
(variable number of decimal places.) Currency requires a fixed digits after the decimal point. We’ll talk
about one way to handle fixed point math in One Way To Tackle Fixed Point Math.
On a minimally-related topic, we’ll look more closely at the two division operators in The Two Specialized
Division Operators: / and // .
What does it mean when a computer “does” a specific task? This is the essential, inner mystery of pro-
gramming. There are two overall approaches to specifying what should happen inside the computer. Most
modern languages are a mixture of both approaches. These two approaches are sometimes called functional
and procedural, or applicative and imperative. Since the programming language business is very competitive,
any term we chose is loaded with meaning and many hairs get split in these conversations. We’ll look at both
the applicative and imperative views of Python, because Python uses each approach where it is appropriate.
Applicative Approach. Functional or applicative programming is characterized by a style that looks a lot
like conventional mathematics. Functions are applied to argument values using an evaluate-apply cycle.
We can see the applicative approach when we look, for example, at f = 32 + 9c 5 . We start wth “evaluate
c” to get its current value (for example, 18); apply a multiply operation using 9 and the current value of c;
apply a divide operation with the previous result (9c) and 5; apply an addition operation with 32 and the
previous result ( 9c
5 ). The result is 64.4.
We call this process “expression evaluation”. We expect our programming language to apply math-like
operations and functions using math-like rules: apply the parenthesized operations first, apply the high
priority operations (like multiply and divide) in preference to low priority operations (like add and subtract).
Python has some sophisticated expression operators. Some of them transcend the simple add-subtract-
multiple-divide category, and include operators that apply a function to a list to create a new list, apply a
function to filter a list and apply a function to reduce a list to a single value.
When we evaluate a function like ‘abs(-4)’, we name the -4 an argument to the function abs(). When looking
at ‘3+4’, we could consider 3 and 4 to be argument values to the +() function. We could – hypothetically –
imagine rewriting 3+4 to be +(3,4) just to show what it really means.
Imperative Approach. On the other hand, the imperative style is characterized by using a sequential list
of individual statements. Donald Knuth, in his Art of Computer Programming [Knuth73], shows a language
he calls Mix. It is a purely imperative language, and is similar to the hardware languages used by many
computer processor chips.
The imperative style lists a series of commands that the machine will execute. Each command changes the
value of a register in the central processor, or changes the value of a memory location. In the following
example, each line contains the abbreviation for a command and a reference to a memory location or a
literal value. Memory locations are given names to make them easy to read. Literal values are surrounded
by ‘=’. The following fragment uses a memory locations named ‘C’ and ‘F’, as well as a processor register.
LDA C
MUL =9=
DIV =5=
ADD =32=
STA F
This first command loads the processor’s ‘A’ register with the value at memory location ‘C’. The second
command multiplies the register by 9. The third command divides the register by 5. The next command
adds 32 to the register. The final command stores the contents of the ‘A’ register into the memory location
of the variable ‘F’.
Python. Python, like many popular languages, has elements drawn from both applicative and imperative
realms. We’ll focus initially on expressions and expression evaluation, minimizing the imperative statements.
We’ll then add various procedural statements to build up to the complete language.
The basic rule is that each statement is executed by first evaluating all of the expressions in that statement,
then performing the statement’s task. The evaluation of each expression is done by evaluating the parameters
and applying the functions to the parameters.
This evaluate-apply rule is so important, we’ll repeat here so that you can photocopy this page and make a
counted cross-stitch sampler to hang over your computer. Yes, it’s that important.
Important: The Evalute-Apply Rule
Each statement is executed by (1) evaluating all of the expressions in that statement, then (2) performing
the statement’s task.
The evaluation of an expression is done by (1a) evaluating all parameters and (1b) applying the function to
the parameters.
Example: ‘(2+3)*4’, evaluates two parameters: ‘2+3’ and ‘4’, and applies the function ‘*’. In order to
evaluate ‘2+3’, there are two more parameters: ‘2’ and ‘3’, and a function of ‘+’.
While it may seem excessive to belabor this point, many programming questions arise from a failure to fully
grasp this concept. We’ll return to it several times, calling it the evaluate-apply cycle. For each feature of
the language, we need to know what happens when Python does its evaluation. This is what we mean by
the semantics of a function, statement or object.
Another Imperative Example. Here’s another example of the imperative style of programming. This
style is characterized by using a sequential list of individual statements. This imperative language is used
internally by Python.
In the following example, each line contains an offset, the abbreviation for a command and a reference to a
variable name or a literal value. Variable names are resolved by Python’s namespace rules. The following
fragment uses a variable named c.
2 0 LOAD_FAST 0 (c)
3 LOAD_CONST 1 (9)
6 BINARY_MULTIPLY
7 LOAD_CONST 2 (5)
10 BINARY_DIVIDE
11 LOAD_CONST 3 (32)
14 BINARY_ADD
This first command (at offset 0) pushes the object associated with variable named c on the top of the
arithmetic processing stack. The second command (at offset 3) loads the constant 9 on the top of the stack.
The third command (at offset 6) multiplies the top two values on the stack. This leaves a new value on the
top of the stack.
The fourth command (at offset 7) pushes a constant 5 onto the stack. The fifth command (at offset 10)
performs a divsion operation between the top two values on the stack.
The sixth command (at offset 11) pushes a constant 32 onto the stack. Finally, the sixth command perfor-
mances an add operation between the top two values on the stack.
There is considerable flexibility in the language; two people can arrive at different presentations of Python
source. Throughout this book we will present the guidelines for formatting, taken from the Python Enhance-
ment Proposal (PEP) 8, posted on http://www.python.org/dev/peps/pep-0008/.
Python programs are meant to be readable. The language borrows a lot from common mathematical notation
and from other programming languages. Many languages (C++ and Java) for instance, don’t require any
particular formatting; line breaks and indentation become merely conventions; bad-looking, hard-to-read
programs are possible. Python makes the line breaks and indentations part of the language, forcing you to
create programs that are easier on the eyes.
Spaces are used sparingly in expressions. Spaces are never used between a function name and the ()’s that
surround the arguments. It is considered poor form to write:
int (22.0/7)
Instead, we prefer:
int(22.0/7.0)
A long expression may be broken up with spaces to enhance readability. For example, the following separates
the multiplication part of the expression from the addition part with a few wisely-chosen spaces.
b**2 - 4*a*c
In Floating-Point Numbers, Also Known As Scientific Notation, we saw that floating-point numbers are for
scientific and engineering use and don’t work well for financial purposes. US dollar calculations, for example,
are often done in dollars and cents, with two digits after the decimal point.
If we try to use floating-point numbers for dollar values, we have problems. Specifically, the slight discrep-
ancy between binary-coded floating-point numbers and decimal-oriented dollars and cents become a serious
problem. Try this simple experiment.
>>> 2.35
2.3500000000000001
There’s a classic trick that can be used to solve this problem: use scaled numbers. When doing dollars and
cents math, you can scale everything by 100, and do the math in pennies. When you print the final results,
you can scale the final result into dollars with pennies to the right of the decimal point. This section will
provide you some pointers on doing this kind of numeric programming.
Later, in Fixed-Point Numbers : Doing High Finance with decimal we’ll look at the decimal module, which
does this in a more sophisticated and flexible way.
Scaled Numbers. When we use scaled numbers, it means that the proper value is represented as the
scaled value and a precision factor. For example, if we are doing our work in pennies, the value of $12.99 is
represented as a scaled value of 1299 with a precision of 2 digits. The precision factor can be thought of as
a power of 10. In our case of 12.99, our precision is 2. We can multiply by 10 -precision to convert our scaled
number into a floating-point approximation.
We have three cases to think about when doing fixed-point math using scaled integers: addition (and sub-
traction), multiplication and division. Addition and subtraction don’t change the precision. Multiplication
increases the precision of the result and division reduces the precision. So, we’ll need to look at each case
carefully.
Addition and Subtraction. If our two numbers have the same precision, we can simply add or subtract
normally. This is why we suggest doing everything in pennies: the precisions are always 2, which always
match. If our two numbers have different precisions, we need to shift the smaller precision number. We do
this by multiplying by an appropriate power of 10.
What is $12.00 + $5.99? Assume we have 12 (the precision is dollars) and 599 (the precision is pennies).
We add them like this: ‘12*100 + 599’. We applied the penny precision factor of 100 to transform dollars
into pennies.
Multiplication. When we multiply two numbers, the result has the sum of the two precisions. If we multiply
two amounts in pennies (2 digits to the right of the decimal point), the result has 4 digits of precision. We
have to be careful when doing this kind of math to determine the rounding rules, and correctly scale the
result.
What is 7.5% of $135.99? Assume we have 13599 (the precision is pennies, 2 digits after the decimal point)
and 75 (the precision is 10th of a percent, three digits to the right of the decimal point). When we multiply,
our result will have precision of 5 digits to the right of the decimal point. The result (1019925) represents
$10.19925. We need to both round and shift this back to have a precision of 2 digits to the right of the
decimal point.
We can both round and scale with an expression like the following. The ‘*.001’ resets the scale from 5 digits
of precision to 2 digits of precision.
>>> int(round(13599L*75,-3)*.001)
1020
>>> int(round(45276L*100000/41615,-1)*.1)
10880
This meas that the labor rate was $108.80 per hour.
The Bigger Picture. Whew! It looks like the special cases of adding (and subtracting), multiplying and
dividing are really complex. Actually, they aren’t too bad, they’re just new to you.
There’s a trick to this, and the trick is to begin with the goal in mind and work forward to what data we
need to satisfy our goal. For adding and subtracting, our goal precision can’t be different from our input
precision. When multiplying and dividing, we work backwards: we write down our goal precision, we write
down the precision from our calculation, and we work out rounding and scaling operations to get from our
calculation to our goal.
It turns out that this trick is essential to programming. We’ll return to it time and again.
Python 2 harbors an assumption that – it turns out – is a bad idea. Python 3 will fix this by removing the
assumption.
While most features of Python correspond with common expectations from mathematics and other program-
ming languages, the division operator, ‘/’, has certain complexities. This is due to the lack of a common
expectation for what division should mean. In a mathematics text book, the author will provide additional
explanations to clarify the precise meaning of an operator. In a Python program, also, we need to clarify
the precise meaning of the ‘/’ operator.
A basic tenet of Python is that the data determine the result of an operation. For example, when we say
‘2+3’, both numbers are plain integers, and the result is expected to be a plain integer. When we say ‘2+3.14’,
Python will coerce the ‘2’ to be the mathematically equivalent ‘2.0’; now both numbers are floating-point,
and the answer can be a floating-point number.
This rule meets most of our expectations for ordinary math. However, this doesn’t work out well for division
because there are two different, conflicting expectations:
• Sometimes we expect division to create precise answers, usually the floating-point equivalents of frac-
tions.
• Other times, we want a rounded-down integer result.
There’s no best answer and no real compromise. Sometimes we mean one and other times we mean the
other. We need both kinds of division operations.
In Python 2, the going-in assumption is “data determines the answer,” which just doesn’t work for division.
In Python 3, this assumption will be removed. You can then specify which sense of division you meant.
To see the effect of this assumption, try the following to see what Python does.
355/113
355.0/113
355/113.0
55.0/113.0
The Unexpected Integer. Here are two examples of the classical definition of division. We’ve used the
formula for converting 18 °Celsius to Fahrenheit. The first version uses integers, and gets an integer result.
The second uses floating-point numbers, which means the result is floating-point.
>>> 18*9/5+32
64
>>> 18.0*9.0/5.0 + 32.0
64.400000000000006
In the first example, we got an inaccurate answer from a formula that we are sure is correct. We expected
a correct answer of 64.4, but got 64.
In Python 2, when a formula has a ‘/’ operator, the inaccuracy will stem from the use of integers where
floating-point numbers were more appropriate. (This can also occur using integers where complex numbers
were implicitly expected.)
If we use floating-point numbers, we get a value of 64.4, which was correct. Try this and see.
18.0*9.0/5.0 + 32.0
The Problem. The problem we have is reconciling the basic rule of Python (data determines the result)
and the two conflicting meanings for division. We have a couple of choices for the solution.
We can solve this by using explicit conversions like float() or int(). However, we’d like Python be a simple
and sparse language, without a dense clutter of conversions to cover the rare case of an unexpected type of
data. So this isn’t ideal.
Instead, Python offers us two division operators.
• For precise fractional results, the ‘/’ will work nicely.
• When we want division to simply compute the quotient, Python has a second division operator, ‘//’.
This produces rounded-down integer answers, even if both numbers happen to be floating-point.
Old vs. New Division. While usiung Python 2, we need to specify which meaning of ‘/’ should apply. Do
we mean the original Python 2 definition (data type determines results)? Or do we mean the newer Python
3 meaning of ‘/’ (exact results)?
Python 2 gives us two tools to specify the meaning of the ‘/’ operator: a statement that can be placed in a
program, as well as a command-line option that can be used when starting the Python program.
Program Statements to Control /. To ease the transition from older to newer language features, the
statement ‘from __future__ import division’ will changes the definition of the ‘/’ operator from Python
2 (depends on the arguments) to Python 3 (always produces floating-point).
Note that ‘__future__’ has two underscores before and after ‘future’. Also, note that this must be the first
statement in a script.
Here’s the classic division:
>>> 18*9/5+32
64
>>> 355/113
3
>>> 355./113.
3.1415929203539825
>>> 355.//113.
3.0
1. Here is the python command with the -Qold option. This will set Python to do classical interpretation
of the ‘/’ operator.
2. When we do old-style ‘/’ division with integers, we get an integer result.
3. When we do old-style ‘/’ division with floating-point numbers, we get the precise floating-point result.
4. When we do ‘//’ division with floating-point numbers, we get the rounded-down result.
Here’s how it looks when we start Python with the -Qnew option.
1. Here is the python command with the -Qnew option. This will set Python to do the new interpretation
of the ‘/’ operator.
2. When we do new-style ‘/’ division with integers, we get the precise floating-point result.
3. When we do new-style ‘/’ division with floating-point numbers, we get the precise floating-point result.
4. When we do ‘//’ division with floating-point numbers, we get the rounded-down result.
Why All The Options?. There are two cases to consider here.
If you have an old program, you may need use -Qold to force an old module or program to work the way it
used to.
If you want to be sure you’re ready for Python 3, you can use the -Qnew to be sure that you always have
the “exact quotient” version of ‘/’ instead of the classical version.
Important: Debugging The -Q Option
If you misspell the -Q option you’ll see errors like the following. If so, check your spelling carefully.
If you get a message that includes Unknown option: -q, you used a lower-case ‘q’ instead of an upper-case
‘Q’.
FIVE
PROGRAMMING ESSENTIALS
We often define programs using the pattern “input-process-output” . We’ll work through this sequence
backwards. In order to see output from a script, we’ll need to use the print statement. We’ll look at this in
Seeing Results : The print Statement.
Once we are comfortable with the print statement, we can introduce processing in Turning Python Loose
With a Script. When we start making more finished and polished programs, we’re going to want to make
them easy to use. There are a lot of options and shortcuts available to us, and we’ll touch on a few of them
here. Later, we’ll add even more ease-of-use features.
We In order to do processing, we’ll introduce variables and the assignment statement in Expressions, Con-
stants and Variables. This will allow us to do the basic steps of processing. We’ll describe some additional
features in Assignment Bonus Features
When we add input in Can We Get Your Input?, we’ll have all three parts to the input-process-output
pattern.
We write programs so they can produce useful results. We’ll start with statements that immediately satisfy
our goal: seeing the results. We’ll cover the basic print statement in The print Statement. We’ll add some
useful features in Dressing Up Our Output.
Yes, this chapter is really short; the print statement is delightfully simple.
Important: Python 3
In Python 3, the print statement will be replaced with a slightly simpler print() function. Consequently,
we’ll skip some of the nitty-gritty details of print, since those details are going to be simplified.
The print statement takes a list of values and, well, prints them. It converts numbers and other objects to
strings and puts the characters out on a file called standard output. Generally, this standard output file is
directed to the Python Shell window in IDLE. If you run Python directly, it is directed to the Terminal
(or Command Prompt) window where Python was started.
While outside the scope of this book, it is important to note that each shell has ways to redirect the standard
output file. Python has considerable flexibility, and so does the shell that runs Python. Too many choices
105
Programming for Non-Programmers, Release 2.5.1
is either confusing or empowering. We’ll limit ourselves to looking at the choices Python gives. You can,
however, look at your GNU/Linux shell documentation or Windows Command Prompt documentation to
see what additional choices you have.
When we are interacting with Python and we give Python an expression, the result is printed automatically.
This is the way Python responds when interacting with a person. When we run script, however, we won’t
be typing each individual statement, and Python won’t automatically print the result of each expression.
Instead, we have to tell Python to show us results by writing an explicit print statement that shows the
response we want.
The basic print statement looks like this: ‘,’
The print statement converts the expressions to strings and writes them to standard output.
Important: Statement Syntax Rules
We’ll show optional clauses in statements by surrounding them with ⟨ and ⟩‘s. We don’t actually enter the
⟨ ⟩ ‘s, they surround optional clauses to show us what alternative forms of the statement are.
We use a trailing ellipsis (...) to indicate something that can be repeated. There’s no real upper limit on
the number of times something can be repeated.
Also notice that we put a ‘,’ before the expression. This is your hint that expressions are separated with ‘,’
characters when you have more than one.
In the case of print, the syntax summary shows us there are many different ways to use this statement:
• We can say ‘print expression’ with one expression.
• We can say ‘print expression, expression’ with two expressions, separated by ‘,’.
• And so on, for any number of expressions, separated by ‘,’‘s.
While our summary doesn’t show this, there are several other forms for the print statement. We’ll return
to some of these.
Here are some examples of a basic print statement.
We can make our printed output easier to read by including quoted strings. See Strings – Anything Not A
Number to review how we write strings.
For example, the following trivial program prints a string and a number. Since our string had an apostrophe
in it, we elected to surround the string with quotes (‘"’).
import math
print 'Value of "pi"', 6.0/5.0*( (math.sqrt(5)+1) / 2 )**2
The print list of expressions can end with a comma, to allow piecing together a long line of output from
multiple statements. The following program will produce one line of output from two print statements. If we
have very complex expressions, this can make our program easier to read by breaking into understandable
chunks.
print "335/113=",
print 335.0/113.0
How can I get more control over the output? The print statement offers relatively little control over
the printed output. It always puts a space between items, which may not always be desirable.
The string formatting operator provides complete control over the formatting of data. We’ll cover
this in depth in Sequences of Characters : str and Unicode. First, we want to introduce a number of
programming statements. Once we’ve got more of the language under our belt, we’ll tackle the “fit
and finish” issues of nicely formatted output.
How can I direct output to stderr? We’ll talk about this in detail in External Data and Files. However,
if you can’t wait until then, we’ll provide some hints as to what will come in the future.
import sys
print >>sys.stderr, "an error"
How do I produce binary output? MP3’s, MOV’s, JPEG’s, etc. We’ll talk about this in detail in
External Data and Files. There’s no quick-and-dirty shortcut for that kind of operation; it requires
interacting with the file system. Also, these more sophisticated data formats require more sophisticated
programming.
One of our goals is to have the Python interpreter execute our scripts. Program scripts can vary from a few
simple expressions to complex sequences of Python commands. There are two parts to this: creating the
script and then running the script. We’ll cover the basics of creating the script in Making A Script File. We
show a simple technique for running a script in IDLE in Running Scripts in IDLE.
In the long run, however, we’ll want to use more direct methods to run our scripts. After all, we don’t want
to have to start IDLE every time we want to run our program. After we get some more experience with
programming, we’ll look at making our programs a perfectly seamless part of our work environment.
We’ll provide some answers to common questions in Scripting FAQ.
The first step in Python programming is to create the program script. For the following examples, we’ll
create a simple, two-line script, called example1.py.
example1.py
Within IDLE, you create a file by using the File menu, the New Window item. This will create a new
window into which you can enter your two-line Python program. Check your spelling and spacing carefully.
When you use the File menu, Save item, be sure to read where the file is going to be saved. You’ll notice
that IDLE may be starting in C:\Python25, your Macintosh HD, or /home/slott or some other unexpected
directory.
For now, be sure to save this file in your home directory. This could be C:\Documents and Settings\SLott,
or /home/slott.
You can’t easily use a word processor for this, since word processors include a lot of formatting markup that
Python can’t read. If you want to try and use an office product to create this kind of file, you have to be
absolutely sure that you save the file as pure text.
There are several ways we can run the Python interpreter and have it evaluate our script file. Since IDLE
is virtually identical on all platforms, we’ll cover this next.
Important: Writing and Saving A Script
One of the biggest benefits of using IDLE is that your Python script has various syntax elements highlighted.
In mine, the keywords show up in orange, strings in green, and my expressions are black. If I misspell print,
it doesn’t show up in orange, but shows up in black.
The most common problem we see is people saving their file to unexpected locations on their disk. It’s
important to save the file to a directory where you can find it again.
One interesting confusion we’ve seen arises when people forgetting to save the file in the first place. IDLE
will ask you if you want to save the file when you attempt to run it. Sometimes this message is unexpected
and that can be confusing. Our advice is to save early and save often.
Alternatives to IDLE. If you don’t want to use IDLE to create text files, you do have several choices for
nice program editors. These will require you down download and install additional software.
• Windows. You have the built-in notepad, or you can purchase any of a large number of programmer’s
text editors, including TextPad. There are free editors like jEdit, also.
• MacOS. You have the built-in textedit application. Be sure to use the Format menu, Make Plain
Text menu item to strip the file down to just text. Or you can purchase any of a large number of
programmer’s text editors, including BBEdit. There are free editors like jEdit, also.
• GNU/Linux. If you are using GNOME, you have gedit. If you want, you can also use vim or
emacs, two very fine sophisticated editors that have been used for decades to write software.
After you create your file outside IDLE, you can open the file with IDLE in order to run it. You use the
File menu, Open... item to open a file you created outside IDLE It’s important to take note of where you
save files so that you can find them and open them again.
The window for your script file will have a Run menu. (The ordinary Python Shell window doesn’t have
this menu.) On the Run menu, you’ll find the Run Module menu item, which will execute your script file.
This will show the results in the Python Shell window.
Why is it called Run Module? Most Python files are called “modules”, which are files of definitions. Even
though the official name is “module”, we’ll insist on calling them “scripts”, because that is a much more
descriptive name.
If you have trouble finding the Run menu, be sure you are looking at the correct window. The initial window
in IDLE is the Python Shell. It has the Shell menu and shows the >>> prompt. When you create a new
window to edit a script (or you open a script file), this widow will have the Run menu. When you open a
script or save a script, the window name reflects the name of the script file.
When we select Run Module menu item from the Run menu, we see the following in the Python Shell
window.
This shows us that the Python shell was restarted using our script as input. It also shows us the output
from our two print statements. We ran our first program.
Important: Debugging Aids in IDLE
If you have syntax errors, you’ll see a pop-up dialog box named Syntax error with a message like There's
an error in your program: invalid syntax. You’ll also notice that some part of your script will be
highlighted in red. This is near the error.
Since IDLE highlights various syntax elements, you can use the color as a hint. In mine, the keywords
show up in orange, strings in green, and my expressions are black. If I misspell print, it doesn’t show up in
orange, but shows up in black.
If you have semantic errors, you’ll see these in the shell window in red. For example, I got the following by
messing up my program.
You can see my erroneous print statement: it has ‘"F"/2’. And you can also see Python’s complaint. While
the syntax is acceptable, it doesn’t mean anything to divide the letter "F" by 2.
We can fix our script file, save it, and re-run it. You’ll notice that the Run Module menu item has a
short-cut key, usually F5. This edit-save-run cycle is how software gets built.
1. Simple Script.
Create a Python file with the following three commands, each one on a separate line: ‘copyright’,
‘license’, ‘credits’.
2. Print Script.
Create and run Python file with commands like the following examples: ‘print 12345 + 23456’;
‘print 98765 - 12345’; ‘print 128 * 256’; ‘print 22 / 7’.
3. Another Simple Print Script.
Create and run a Python file with commands like the following examples: ‘print "one red",
18.0/38.0’; ‘print "two reds in a row",(18.0/38.0)**2’.
4. Numeric Types.
Compare the results of ‘22/7’ and ‘22.0/7’. Explain the differences in the output.
What are the various ways to use Python? Python can be used a variety of ways, depending what
problem you are solving.
• Interactively. We can interact directly with Python at the “command-line”. This was what we
saw in Instant Gratification : The Simplest Possible Conversation. A tool like IDLE makes it
easier to enter Python statements and execute them. We looked at this in IDLE Time : Using
Tools To Be More Productive.
• Scripted. Tis makes the processing completely automatic. We’ll look at this in Turning Python
Loose with More Sophisticated Scripts In the long run, this automation is our goal. However, to
learn the language, we find the direct interaction is very helpful. Manual interaction via IDLE
is our “training wheels” for learning the language.
• Through The Web. While beyond the scope of this book, Python can be part of the Internet,
with your application running on a web server.
Why are there so many ways to use Python? Or, why can’t we just use IDLE? The huge number
of choices is a natural consequence of creating a simple, flexible program. Many people use Python
through IDLE and are happy and successful in what they do.
More sophisticated problems, however, often require more complex use of Python. Since the Python
program (python, or python.exe) can be used a variety of ways, we can use Python to build a number
of different kinds of solutions to our data processing problems.
In a book like this, we hate to present Python from a single point of view. We prefer to present a
number of choices so that different readers can locate one that looks like it will solve their problem.
Do I have to write a script? You don’t have to write scripts, you can do everything through interaction
with IDLE. Scripting is not required, but it is generally the goal of programming. An automated
solution should be something that can be double-clicked, or something that is invoked by a web server.
Generalizing a Calculation
Our programs up until this point have been somewhat limited. We’ve been able to write programs that do
exactly one calculation and nothing more than that. How many times do we want to convert 65 degrees F
to degrees C?
We can change the original program each morning when we check the weather, but this is second-rate. If
we make a mistake, we might break the program completely. We want something more general, something
that can convert any temperature from degrees F to C.
To generalize our calculations, we need to replace a literal value with a variable that can take on any value.
Our programs can then work by assigning a specific value to a variable and using that variable in a generic
calculation. This simple generalization technique gives us a bunch of new capabilities to examine. We’ll look
at creating variables in Putting Name Tags on Results.
When we assign a value to a variable, it acts as a kind of placeholder; it’s a way of saying “we’ve gotten
this far in our work.” We’ll introduce the assignment statement that creates and updates variables in The
Assignment Statement. Since setting a variable is so important, there are a number of variations on the
assignment statement. We’ll look at these in Assignment Combo Package.
Since our programs are getting more sophisticated, we need ways to test and debug them. We’ll look at one
of these techniques in Where Exactly Did We Expect To Be?.
A Python variable is a name that refers to an object. It’s easy to think of a variable as a name tag, pinned
to the object. An object can be any of the numeric types that we looked at in Arithmetic and Expressions.
It turns out that many more things than just numbers are objects that can have names pinned to them.
A Python variable name must be at least one letter, and can have a string of numbers, letters and ‘_’ to any
length. Spaces and punctuation marks other than ‘_’ are not allowed in a variable name.
Here are some examples of variable names:
• ‘x’
• ‘pi’
• ‘data’
• ‘aLongName’
• ‘multiple_word_name’
• ‘__str__’
• ‘_hidden’
Important: Python Name Rules
Names that start with ‘_’ or ‘__’ have special significance:
• Names that begin with ‘_’ are typically private to a module or class. We’ll return to this notion of
privacy in Defining New Objects and Module Definitions – Adding New Concepts.
• Names that begin with ‘__’ are part of the way the Python interpreter is built. We should never attempt
to create variables with names that begin with ‘__’ because it can be lead to confusion between our
programs and Python’s internals.
The Semantics of Naming. How does a variable name get stuck to an object? Generally, the assignment
statement does this labeling. We’ll look at the syntax of assignment in the next section. First, we need to
talk about what assignment means, then we’ll look at how to write it.
1. An assignment statement evaluates the expression.
2. An assignment statement then assigns the result to a variable. In effect, it pins the variable name
onto the result. There are two variations on this.
• If the variable name already existed, the name tag is moved from the old value to this new value.
• If the variable name did not already exist, it is created and pinned on this new value.
We generally don’t worry about creating new variables; there’s no cost, they’re just names. Create as many
as you need to make your program’s purpose crystal-clear.
A Python variable has a scope of visibility. The scope is the set of statements that can reference this variable.
For our first programs, all of our variables will have a global scope: we can use any variable anywhere we
want. When we look at organizing our programs into separate sections – beginning in Organizing Programs
with Function Definitions – we’ll see how Python’s separation between local scopes and a global scope can
simplify our programming by localizing a name.
Important: A Script Is A Journey
If we think of a script as a journey from the first statement to the last, we’ll often mark our progress along
that journey by setting variables. The values that are assigned to our variables amount to a big “You Are
Here” arrow showing us where we are.
When a variable is created or changed, the overall position along our journey has changed. The variables
start with initial values; the values change as inputs are accepted and our program executes the various
statements. Eventually the state of the variables indicates that we have reached our goal, and our program
can exit.
We emphasize this because some of the more common program design errors have to do with failure to use
variables correctly. We may see a program that doesn’t set a variable to indicate when progress has been
made. The mistake is either a missing assignment statement or assignment to the wrong variable. We’ll look
at ways to debug these kinds of problems in Where Exactly Did We Expect To Be?.
Our variables are more than just labels slapped on objects. They have a profound significance; they reflect
the “meaning” of our program.
Pragmatically, a variable is a label slapped on an object.
We create and change variables with the assignment statement. Here’s the syntax summary:
variable = expression
First, evaluate expression, creating some result object. Then, assign the given variable name to that result
object. If the variable was in use, any previous value is lost.
Here’s a short script that contains some examples of assignment statements.
example3.py
1. We create the variable shares, set to the plain integer object 150.
2. We create the variable price, set to the object created by the expression 3 + 5.0/8.0.
3. We create the variable value, set to some object created by the expression shares * price. Setting this
variable advances our program nearly to completion. Once we print the value of this variable, we are
finished processing.
Tip: Debugging the Assignment Statement
There are two common mistakes in the assignment statement. The first is to choose an illegal variable name.
If you get a SyntaxError: can't assign to literal or SyntaxError: invalid syntax, the most likely
cause is an illegal variable name.
The other mistake is to have an invalid expression on the right side of the =. If the result of an assignment
statement doesn’t look right, remember that you can always enter the various expressions directly into
IDLE‘s Python Shell window to examine the processing one step at a time.
One very common pattern is to update a variable by performing an operation on that variable. Look at the
following example where we update the sum variable using the ‘+’ operation.
sum= 0
sum= sum + 25
sum= sum + 42
sum= sum + 37
print "average", sum/3.0
This assignment statement pattern is so common that the pattern had to be added to the language as the
augmented assignment statement. These augment the basic assignment with an additional operation. There
are several variations on this combo-pack assignment statement.
The most common application of this pattern is to accumulate a sum. This augmented assignment makes it
obvious what we are doing. For example, look at this common augmented assignment statement.
sum += v
This statement is a handy shorthand that means the same thing as the following:
sum = sum + v
We can use this to replace our first example above with something slightly simpler.
sum= 0
sum+= 25
sum+= 42
sum+= 37
print "average", sum/3.0
Here’s a larger example that does more substantial calculation at each step. This shows the strength of this
statement.
Create the following file name portfolio.py. In IDLE, you can run this using the Run Module item on
the Run menu.
portfolio.py
The other basic math operations can be used similarly, although the purpose gets obscure for some of the
possible operations. These include ‘-=’, ‘*=’, ‘/=’, ‘%=’, ‘&=’, ‘^=’, ‘|=’, ‘<<=’ and ‘>>=’.
Here’s an interesting use of ‘/=’. This computes the various digits in a base-10 number from right to left.
>>> y=1956
>>> y%10
6
>>> y/=10
>>> y%10
5
>>> y/=10
>>> y%10
9
>>> y/=10
>>> y%10
1
Try the same basic sequence of operations using 16 instead of 10. You’ll get a sequence of three numbers
before y is equal to zero. Compare that sequence of numbers to ‘hex(1956)’.
Tip: Debugging the Augmented Assignment Statement
There are two common mistakes in the augmented assignment statement. The first is to choose an illegal
variable name. If you get a SyntaxError: can't assign to literal or SyntaxError: invalid syntax
the most likely cause is an illegal variable name.
The other mistake is to have an invalid expression on the right side of the assignment operator. If the result
of an assignment statement doesn’t look right, remember that you can always enter the various expressions
directly into IDLE‘s Python shell to examine the processing one step at a time.
As our program moves along its journey toward completion, it will create variables and change the value of
variables. There are two questions we can ask at the end of each statement:
craps.py
# Results
print "first roll win", win
print "first roll lose", lose
print "first roll establishes a point", point
There’s a 22.2% chance of winning, and a 11.1% chance of losing. What’s the chance of establishing a point?
One way is to figure that it’s what’s left after winning or loosing. The total of all probabilities always add
to 1. Subtract the odds of winning and the odds of losing and what’s left is the odds of setting a point.
More Probability
Here’s another way to figure the odds of rolling 4, 5, 6, 8, 9 or 10.
point = 0
point += 2*3/36.0 # ways to roll 4 or 10
point += 2*4/36.0 # ways to roll 5 or 9
point += 2*5/36.0 # ways to roll 6 or 8
print point
By the way, you can add the statement ‘print win + lose + point’ to confirm that these odds all add to
1. This means that we have defined all possible outcomes for the “come out” roll in Craps.
How To Make A Trace. When we make an execution trace, we start with a clean piece of paper. As we
look at our Python source statements, we write down the variables and their values on the paper. From this,
we can see the state of our calculation evolve.
When we encounter an assignment statement, we look on our paper for the variable. If we find the variable,
we put a line through the old value and write down the new value. If we don’t find the variable, we add it
to our page with the initial value.
Here’s our example from craps.py script through the first part of the script. The win variable was created
and set to ‘0’, then the value was replaced with ‘0.16’, and then replaced with ‘0.22’. The lose variable
was then created and set to ‘0’. This is what our trace looks like so far.
win: 0.0 0.16 0.22
lose: 0
Here’s our example when craps.py script is finished. We changed the variable lose several times. We also
added and changed the variable point.
win: 0.0 0.16 0.22
lose: 0.0 0.027 0.083 0.111
point: 1.0 0.77 0.66
We can use this trace technique to understand what a program means and how it proceeds from its initial
state to its final state.
# Convert 8 C to F
C=8
F=32+C*float(9/5)
print "celsius",C,"fahrenheit",F
You’ll want to rewrite these exercises using variables to get ready to add input functions.
2. State Change.
Is it true that all programs simply establish a state?
It can argued that a controller for a device (like a toaster or a cruise control) simply maintains a steady
state. The notion of state change as a program moves toward completion doesn’t apply because the
software is always on. Is this the case, or does the software controlling a device have internal state
changes?
For example, consider a toaster with a thermostat, a “brownness” sensor and a single heating element.
What are the inputs? What are the outputs? Are there internal states while the toaster is making
toast?
We’ll cover two additional features of the assignment statement. In Combining Assignment Statements
we’ll cover “multiple assignment”, a handy short-hand. We’ll look at the interplay between assignment
statements and our interactive exploration of simple expressions in More About Python Conversations.
The assignment statement can be expanded to assign multiple variables at one time. Python will evaluate
all of the expressions and then assign the set of variables all at once. All we have to do is assure that the
number of variables on left side of the ‘=’ is the same as the number of expressions on the right side.
The first important part is the obvious match-up between the number of expressions and the number of
variables. We generally don’t assign more than two or three things at once, so this is an easy rule to observe.
Another important part of this is the “all at once”. We use the multiple assignment statement when we’re
doing two things at the same time and want to lock those two things together. Separate assignment state-
ments imply that there’s a sequence to things; that the steps are in this order because one step depends on
another. In a some cases, however, a pair of steps may depend on previous steps, but the pair of steps don’t
depend on each other.
Multiple-Assignment Syntax. A multiple-assignment statement looks like a standard assignment state-
ment. We separate the left-side variables with ‘,’ and the right-side expressions with ‘,’, also. Here’s the
syntax for multiple assignment:
The ‘...’ means that the variable or expression can be repeated any number of times. The , means that we
separate multiple variables and multiple expressions with ,‘s.
We must have the same number of variables on the left as expressions on the right.
Examples. In all of the examples, we’ll try to show a pattern where two variables are tightly coupled. We
use this when we don’t want the assignments to get separated in our program. We want the two assignments
in the same statement to emphasize how tightly coupled the two variables are.
The following script has some more examples of multiple assignment. In this case, we’re doing some algebra
to compute two values at the same time. The slope, m, and the intercept, b, both depend on the two points,
and can be computed at the same time.
Here’s a short example that you can save, named line.py. In IDLE, you can run this using the Run
Module item on the Run menu.
line.py
print "y=",m,"*x+",b
This program sets variables x1, y1, x2 and y2. Then we computed m and b from those four variables. Then
we printed the m and b.
The All-At-Once Rule. The basic rule is that Python evaluates the entire right-hand side of the assign-
ment statement. Then it matches values with destinations on the left-hand side. If the lists are different
lengths, an exception is raised and the program stops.
Because of the complete evaluation of the right-hand side, the following construct works nicely to swap to
the values of two variables. This is often quite a bit more complicated in other languages.
a,b = 1,4
b,a = a,b
print a,b
In Doubles, Triples, Quadruples : The tuple we’ll see even more uses for this feature.
Tip: Debugging Multiple Assignment Statements
There are three common mistakes in the augmented assignment statement. The first is to choose an illegal
variable name. If you get a SyntaxError: can't assign to literal or SyntaxError: invalid syntax
the most likely cause is an illegal variable name.
One other mistake is to have an invalid expression on the right side of the assignment operator. If the result
of an assignment statement doesn’t look right, remember that you can always enter the various expressions
directly into IDLE‘s Python shell to examine the processing one step at a time.
The third mistake is to have a mismatch between the number of variables on the left side of the = and the
number of expressions on the right side.
When we first looked at interactive Python in Instant Gratification : The Simplest Possible Conversation
we noted that Python automatically prints the results of an expression. However, if we enter a complete
assignment statement, Python executes the statement silently. Sometimes this silence can be inconvenient.
Consider the following example.
>>> pi=335/113.0
>>> area=pi*2.2**2
>>> area
14.348672566371683
The first two inputs are complete statements, so Python provides no response. Our final calculation of area
didn’t produce a response, so we had to provide a simple expression, ‘area’, to see our answer.
It turns out that there’s a subtle bug in this. It was hidden from us because of the silent execution of
statements.
The solution is based on a built-in feature of Python. When you simply enter an expression, Python always
assigns the result to the implicit result variable, named _. It’s as though you typed the following around
each expression.
_ = expression
print _
A Longer Conversation. Here’s how we use the implicit results variable. We type expressions, and – if
the result is helpful – we save the result (_) in a new variable.
>>> 335/113.0
2.9646017699115044
>>> 355/113.0
3.1415929203539825
>>> pi=_
>>> pi*2.2**2
15.205309734513278
>>> area=_
Our first expression had an error. We fixed that error and saved the correct implicit result into pi by saying
‘pi=_’. When we finished, we saved the last implicit result into area with ‘area=_’.
Th comes in handy when you exploring something rather complex.
Debugging Only. It’s important to note that the _ trick only works when we’re using Python interactively.
We can’t (and shouldn’t) write this in our script files. Our scripts will simply assign expressions to variables
directly.
Spaces are used sparingly in Python. It is common to put spaces around the assignment operator. The
recommended style is
c = (f-32)*5/9
Do not take great pains to line up assignment operators vertically. The following has too much space, and
is hard to read, even though it is fussily aligned. The following is considered as a poor way to write Python.
a = 12
b = a*math.log(a)
aVeryLongVariable = 26
d = 13
This is considered poor form because Python takes a lot of its look from natural languages and mathematics.
This kind of horizontal whitespace is hard to follow: it can get difficult to be sure which expression lines
up with which variable. Python programs are meant to be reasonably compact, more like reading a short
narrative paragraph or short mathematical formula than reading a page-sized UML diagram.
Variable names are typically lower_case_with_underscores() or mixedCase(). Variable names typically
begin with lower-case letters.
In addition, the following special forms using leading or trailing underscores are important to recognize:
• single_trailing_underscore_: used to avoid conflicts with Python keywords. For example: ‘print_
= 42’
• __double_leading_and_trailing_underscore__: used for special objects or attributes, e.g.
__init__, __dict__ or __file__. These names are reserved; do not use names like these in your
programs unless you specifically mean a particular built-in feature of Python.
In Getting Raw Input we’ll introduce a primitive interactive input function. We’ll look at another function
for input in Another Kind Of Input. This will finish up the statements we need to fill out the “input-process-
output” pattern for simple programs. We’ll provide some additional notes in Additional Notes and Caveats
and the formal definitions for these functions in Input Function Definitions.
To make complete use of this, we’ll need to digress on the standard input, output and error files in The
Standard Files.
The material on the del statement in The del Statement is here for completeness. Logically, there’s a nice
symmetry between creating variables with the assignment statement, setting values with input functions
and removing variables with the del statement. As a practical matter, however, we rarely need to remove a
variable.
We’ll answer some additional questions in Input FAQ.
Python provides simplistic built-in functions to accept input and set the value of variables. These are not
really suitable for a professional-quality application, but they will help us learn the language. The more
robust and reliable input functions are generally embedded in a web-based application, or a sophisticated
GUI, both of which are way beyond what we can cover in this book.
These input functions will gather data from a file called standard input. Generally, this standard input file
is your keyboard, and the results will show on the Python Shell window in IDLE. If you run Python
directly, the Terminal (or Command Prompt) where Python was started will manage reading characters
from your keyboard.
Raw Input. By “raw”, we mean unprocessed, unevaluated or uninterpreted. The input is what the person
typed; it isn’t every keystroke, it’s the finished product of typing and backspacing. But it’s always a string
without further interpretation as a number or date.
We can draw a useful parallel with the Japanese delicacy called Sashimi. Sashimi has been cut and prepared
by a chef; it’s not like they throw a big old salty, bleeding salmon down on your table. Similarly, the user’s
input to the raw_input() function has been sliced up into individual lines of input by the operating system,
and backspaces have been handled graceefully, but little beyond this has been done.
The OS will handle the enter key for you. Plus it also makes sure that the backspace operates as we expect.
We have to talk about the raw_input() from two distinct points of view.
• What you see. You will see a prompt on standard output – usually the console – and you can respond
to that prompt by typing on standard input. This console will usually be the Python Shell window of
IDLE, or the terminal window, depending on how you are running Python.
• What you say in Python. The Python script evaluates a function; the value of that function will
be a string that contains the characters someone typed. We’ll take a very close look at strings in
Sequences of Characters : str and Unicode. For now, we do a few simple things with strings.
An Example Script. Here’s a very small script that uses raw_input() that produces a prompt, reads and
prints the result. This will give you a sense of the two worlds in which this function lives: the world of user
interaction as well as the world of Python function evaluation.
Create the following file, named rawdemo.py. Save it and then run it in IDLE using the Run Module item
in the Run menu.
rawdemo.py
This program begins by evaluating the raw_input() function. When raw_input() is applied to the param-
eter of "continue?", it writes the prompt on standard output, and waits for a line of input.
We entered why not?. When we hit enter, we told the operating system that our input line was complete.
The OS hands the completed input line to Python. Python then returns this string as the value of the
raw_input() function.
Our program saved the value from raw_input() int the variable answer. The second statement printed that
variable.
Important: Python 3
In Python 3, this function will be named input().
Making Raw Input Useful. If we want numeric input, we must convert the resulting string to a number.
In the following example, we’ll use the int() and float() functions to convert the strings we got from the
raw_input() function into numbers that we can use for calculation.
We’ll use the raw_input() and int() functions to get a number of shares. The resulting number is assigned
the name shares. Then the program uses the raw_input() and float() functions to get the price.
Create the following file, named stock.py. Save it and then run it in IDLE using the Run Module item
in the Run menu.
stock.py
shares: 150
dollars: 24.18
value 3627.0
Exceptional Input. Exceptions, in Python, mean exceptionally bad. The raw_input() mechanism has
some limitations. If the string returned by raw_input() is not suitable for use by int(), an exception is
raised and the program stops running.
Here’s what it looks like when we ran stock.py and provided inappropriate input values.
In addition to the raw_input() function, which returns the exact string of input characters, we also have
the input() function. This function takes one more step beyond what raw_input() does. After reading
the input, the input() function then applies the Python eval() function to evaluate the input string and
create a proper Python object.
The point is to automatically convert a string of digits to a proper numeric value. The following two sequences
of statements are identical.
Important: Python 3
This version of the input() function will be removed from Python 3. In Python 3, the input() function
will behave like Python 2’s raw_input() and that will be the only input function.
The reason why Python 2 has this function is because we sometimes like to decode a string of digits as an
integer. Further, we expect that digits plus a period will become floating-point number.
We’ll avoid input(), since it’s going away in Python 3.
If you try to run these examples from TextPad, you’ll see that TextPad doesn’t have any place for you to
type your input. You’ll get an immediate end-of-file error. Why does this happen? It happens because
TextPad doesn’t have a proper file for standard input. Since the file doesn’t exist, we get an immediate error
when we try to use it.
For MacOS users using tools like BBEdit, you’ll can use the Run In Terminal item in the #! menu
to create a Terminal window for your interaction. This new window appears when your run your script,
showing your standard input and giving you a place for standard input.
Tip: Debugging the raw_input() Function
There are two kinds of mistakes that occur. The first kind of mistake are basic syntax errors in the
raw_input() function call itself.
The other mistake, which is more difficult to prevent, is to provide invalid input to the script when it
runs. Currently, we don’t quite have all of the language facilities necessary to recover from improper input
values. When we cover the try statement and exception processing in The Unexpected : The try and except
statements we’ll see how we can handle invalid input.
In the long run, we’ll see that the raw_input() function is not the most reliable tool. For simple programs,
problems with raw_input() are easily solved. If you give your software to someone else, the vagaries of what
is legal and how Python responds to things that are not legal can be frustrating for them to learn.
Professional quality software doesn’t make much use of these functions. Typically, interactive programs use
a complete graphic user interface (GUI), often written with the Tkinter module or the pyGTK module. Both
of these are beyond the scope of this book: they aren’t newbie-friendly modules.
We need to take a quick digression to look at how your keyboard really works. Generally, we take our
keyboard for granted: we start an application, we type and the letters appear. After a while, you get used
to letters only showing up in the front-most window. Our operating system tells us which window is active
by providing a number of visual cues like bringing the window to the font, showing a blinking cursor and a
fancier frame around the window.
Under the hood, your operating system is watching your keyboard device for activity. Most of the buttons
on your keyboard generate an “event‘. Some of the buttons are “modifiers”: the shift, alt, command, and
control keys modify the basic key event. The operating system routes these key events to the front-most
window. The application program that displays the front-most window is responsible for making sense of
the events.
Why “events”? Why not just “characters”? The reason is that some programs don’t have characters.
A game, for example, doesn’t want characters, it wants events that will make the pinball flippers flip, or the
person walk.
For many programs, most of these events will be interpreted as characters. There are two really common
events that are not characters: the backspace event and the enter event are not letters; instead, they change
the sequence of characters being accumulated. The front-most window has to do something with events like
backspace. What most of us expect is that backspace removes the previously accumulated character. The
enter key alerts the program that you are finished typing and are ready for the program to see the input
letters.
Plus, when you look at your keyboard, you’ve got a dozen (or more) F-keys, plus keys with names like Insert,
Delete, Home, End, etc. These are not characters in the same sense as the other keys. These extra keys
are used by IDLE to control your interactive Python session. When you run Python from the Command
Prompt or Terminal tool, you’ll see that these extra F-keys do little or nothing. In the Windows Command
Prompt, you can use a program named doskey to define actions for these non-letter keys. In the MacOS,
there are a number of programs that use these additional F-keys for a variety of purposes; for instance, F12
brings up my dashboard.
Redirection. Each shell also has ways to change the origin of the characters available on standard input.
When you redirect standard input, it means that your program will wind up reading from a disk file instead
of the keyboard. In The print Statement, we mentioned the file called standard output. Standard output is
like standard input: it was opened for you, and it can be redirected outside your program.
This shell redirection technology allows a single program to read from a disk file or read from the keyboard
without any changes to the program; there is just a small change to the shell command that starts the
program. Similarly, it also allows a program to write the terminal window, or write to a disk file depending
on settings provided to the shell. While the details of controlling the shell are outside the scope of this book,
the idea is that one program can do any of the preceding, with no change to the program. This gives us a
lot of flexibility for no real cost or complexity in our programming.
Refer back to the exercises in Expression Exercises for formulas and other details. Each of these can be
rewritten to use variables and an input conversion. For example, if you want to tackle the Fahrenheit to
Celsius problem, you might write something like this:
C = input('Celsius: ')
F = 32+C*float(9/5)
print "celsius",C,"fahrenheit",F
1. Stock Value.
Input the number of shares, dollar price and number of 8th’s. From these three inputs, compute the
total dollar value of the block of stock.
2. Convert from °C to °F.
Write a short program that will input °C and output °F. A second program will input °F and output
°C.
3. Periodic Payment.
Input the principal, annual percentage rate and number of payments. Compute the monthly payment.
Be sure to divide rate by 12 and multiple payments by 12.
4. Surface Air Consumption Rate.
Write a short program will input the starting pressure, final pressure, time and maximum depth.
Compute and print the SACR.
A second program will input a SACR, starting pressure, final pressure and depth. It will print the
time at that depth, and the time at 10 feet more depth.
5. Wind Chill.
Input a temperature and a wind speed. Output the wind chill.
6. Force from a Sail.
Input the height of the sail and the length. The surface area is 21 × h × l. For a wind speed of 25 MPH,
compute the force on the sail. Small boat sails are 25-35 feet high and 6-10 feet long.
An assignment statement creates a variable, or assigns a new object to an existing variable. This change in
state is how our program advances from beginning to termination. Python also provides a mechanism for
removing variables, the del statement. This version of the statement is used rarely; we describe it here to
close the circle of the life for a variable.
The most common use for the del statement is to remove individual elements from a list object. We’ll revist
this statement when we look at lists in Flexible Sequences : the list. There, we’ll find a more practical use
for this statement.
The del statement looks like this: ,
A target is a name of a Python object: a variable, function, module or other object. The variable is removed.
Generally, this also means the target object is removed from memory.
The del statement works by unbinding the name, removing it from the set of names known to the Python
interpreter. If this variable was the only reference to an object, the object will be removed from memory
also. If, on the other hand, other variables still refer to this object, the object won’t be deleted.
If there is no use for the del statement, why cover it? The del statement isn’t completely useless
for newbies. We cover it for a number of reasons. First, we’ll return to it in the chapter on lists and
use it to remove an item from a list. Second, when you see it in someone else’s program, you’ll be able
to interpret it. And third, we can say that we covered all the language, identifying the parts that meet
more advanced needs.
If input() and raw_input() are so poor, what’s better? We’ll take a quick survey of four overall ar-
chitectures where you will be interacting with your computer. What we want to emphasize is the
tremendous differences between these architectures. Since there is so little in common, Python doesn’t
have a newbie-friendly, reliable, flexible, and richly interactive input mechanism.
• A command-line utility. These are programs like the GNU/Linux grep program, where all of
the interaction is centered around running the program from the command line or as part of a
processing pipeline. These programs read from standard input and write to standard output.
They typically use file-oriented read() and write() methods, not the input() or raw_input()
functions.
• A GUI program. These are programs like those in MS-Office or Open Office; this group also
includes all games. These programs generally rely on a “framework” that provides basic graphics
capabilities. Python programmers use Tkinter or pyGTK for this kind of program. The framework
handles keyboard and mouse events and provides specialized functions for interacting with the
GUI objects.
• A Web program. These are programs like eBay or Yahoo!. In this case, the program exists on a web
server and does its processing in response to web requests. These programs rely on the HTTP
protocol and HTML web pages for their interaction. There are a number of Python-oriented
frameworks for running Python programs from a web server.
• An embedded program. These are programs like those in your microwave oven, thermostat or
coffee-maker. You interact with these programs through specially-engineered devices like mem-
brane keyboards, buttons and LED’s. These programs often rely on specialized mini-operating
system to handle the devices.
With these styles of programming having so little in common, there’s very little built-in to the Python
language to support a user interface. For all but the first case (command-line utilities), you’ll have to
master some kind of add-on package appropriate to the kind of programs you want to write.
SIX
SOME SELF-CONTROL
This section represents a significant milestone. Up until this part, we have presented Python as a souped-up
desk calculator. This part shows the essential elements of building automated data processing.
We’ll start with truth and logic in Truth and Logic : Boolean Data and Operators. This is an extension
to the expressions and numeric types we started out with. We’ll add another data type, boolean , and a
number of operators, including comparisons and basic logic of and, or and not. With this foundation in
logic, we can introduce comparisons in Making Decisions : The Comparison Operators.
The basic tools of logic and comparison are the essential ingredient to looking at conditional processing
in Processing Only When Necessary : The if Statement. Conditional processing is controlled by the if
statement, and reflects processing that only makes sense when a condition is true.
The other side of this is iterative processing, which we’ll cover in While We Have More To Do : The for
and while Statements. Iterative processing also depends on a condition, but it iterates (or repeats) while the
condition is true. Python provides two statements for this, the for statement and the while statement.
We’ll cover a number of additional topics Becoming More Controlling. This includes the break , continue
and assert statements to provide a finer level of control over the processing. Additionally, we’ll look at
many of the traps and pitfalls associated with iterative processing.
In Turning Python Loose with More Sophisticated Scripts we’ll return to scripting to make our scripts fit
more smoothly with our operating system. We’ll look at a complete family tree of processing alternatives
using the command line as well as the GUI. There are a number of operating-system specific variations on
this theme, and we can’t easily cover every alternative.
In Arithmetic and Expressions we looked at various types of numeric data, including whole numbers and
floating-point numbers. We showed all of the arithmetic operations that we could apply to those various
kinds of numbers. In Truth, we’ll introduce another type of data to represent truth. In Logic we’ll manipulate
those truth values with logic operators.
Mathematically, this is the essential foundation of all computing. Pragmatically, however, this is not as
interesting, so we’ve pushed it back to here.
127
Programming for Non-Programmers, Release 2.5.1
6.1.1 Truth
The domain of arithmetic involves a large number of values: there are billions of integer values and an
almost unlimited range of long integer values. There are also a wide variety of operations, including addition,
subtraction, multiplication, division, remainder and others, too numerous to mention. The domain of logic
involves two values: False and True, and a few operations like ‘and’, ‘or’ and ‘not’.
This world of logic bridges language, philosophy and mathematics. Because we deal with logic informally all
the time, it can seem needless to define a formal algebra of logic. Computers, however, are formally defined
by the laws of logic, so we can’t really escape these definitions. If you don’t have any experience with formal
logic, there’s no call for panic: with only two values (true and false), how complex can the subject be?
Mostly, we have to be careful to follow these formal definitions, and set aside the murky English-language
idioms that masquerade as logic.
We also have to be careful to avoid confusing logic and rhetoric. A good public speaker often uses rhetorical
techniques to make their point. In some cases, the rhetoric will involve logic, but other times, it will
specifically avoid logic. One example is to attack the speaker personally, rather than attack the logic behind
the point they’re trying to make. Political debates include many examples of rhetorical techniques that have
a certain kind of logic, but aren’t grounded in the kind of formal mathematical logic that we’re going to
present here.
Truth. Python has a number of representations for truth and falsity. While we’re mostly interested in the
basic Python literal of False and True, there are several alternatives.
• False.
Also 0, the complex number ‘0+0j’, the special value None, zero-length strings "", zero-length lists
[], zero-length tuples (), and empty mappings {} are all treated as False. We’ll return to these list,
tuple and map data structures in later chapters. For now, we only need to know that a structure that
is empty of meaningful content is effectively False.
• True.
Anything else that is not equivalent to False. This means that any non-zero number, or any string
with a length of one or more characters are equivalent to True.
What about “maybe’s” and “unknown’s”? You’ll need a good book on more advanced logic systems if you
want to write programs that cope with shades of meaning other than simple true and false. This kind of
fuzzy logic isn’t built in to Python. You could write your own extension module to do this.
The bool Function. Python provides a factory function to provide the truth value of any of these objects.
In effect, this collapses any of the various forms of truth down to one of the two explicit objects: True or
False.
bool(object)
Returns True when the argument object is equivalent to true, False otherwise.
We can see how this works with the following examples.
>>> bool(1)
True
>>> bool(0)
False
>>> bool( "a string" )
True
Historical Note
Historically, Python didn’t have the boolean literals True and False. You may find older open-source
programs that define variables to have values that mean True and False. You might see a cryptic
dance that looks something like the following:
try:
True, False
except NameError:
True, False = (1==1), (1==0)
This little trick is no longer necessary. We present it here so that you won’t be surprised by seeing it
in an open source package you’re reading.
6.1.2 Logic
Python provides three basic logic operators that work on the domain of True and False values: ‘not’, ‘and’
and ‘or’. This domain and the applicable operators forms a complete algebraic system, sometimes called a
Boolean algebra, after the mathematician George Boole.
In Python parlance, the data values of True and False, plus the operators ‘not’, ‘and’ and ‘or’ define a data
type. In Simple Arithmetic : Numbers and Operators we saw a number of numeric data types, and we’ll look
at yet more data types as we learn more about Python.
Truth Tables. The boolean data type has only two values, which means that we can define the boolean
operators by enumerating all of the possible results in a table. Each row of the table has a unique combination
of True and False values, plus the result of applying the logic operator to those values. There are only four
combinations, so this is a pretty tidy way to define the operators.
We wouldn’t want to try this for integer multiplication, since we have almost four billion integer values
(including both negative and positive values), which would lead to a table that enumerates all 18 quintillion
combinations.
Here’s an example of a truth table for some hypothetical operator we’ll call ‘cake’. Rather than show ‘and’,
‘or’ or ‘not’ specifically, we’ll use a made-up operator so we can show how a truth table is built.
This table shows all possible results for x ‘cake’ y. It shows all four combinations of inputs and the result
of applying our logic operation to those values.
x y x cake y
True True True cake True = False
True False True cake False = True
False True False cake True = True
False False False cake False = False
The not Operator. The following little program creates a truth table that shows the value of ‘not’ x for
both vales of x. It may seem silly to take such care over the obvious definition that ‘not True’ is ‘False’.
However, we can use this technique to help us visualize more complex logical operations.
x ‘not’ x
True False
False True
The and Operator. This next little program creates a truth table that shows the value of x ‘and’ y for all
four combination of True and False. You can see from this table that x ‘and’ y is only True if both of the
terms are ‘True’. This corresponds precisely to the English meaning of “and”.
x y x ‘and’ y
True True True
True False False
False True False
False False False
The or Operator. The following table shows the evaluation of x ‘or’ y for all four combination of True
and False. You can see from this table that x ‘or’ y is True if one or both of the terms are ‘True’. In
English, we often emphasize the inclusiveness of this by writing “and/or” . We do this to distinguish it from
the English-language “exclusive or”, (sometimes written “either/or”) which means “one or the other but not
both”. Python’s x ‘or’ y is the inclusive sense of “or”.
x y x ‘or’ y
True True True
True False True
False True True
False False False
An important note is that ‘and’ is a higher priority operator than ‘or’, analogous to the way multiplication
is higher priority than addition. This means that when Python evaluates expressions like ‘a or b and c’,
the ‘and’ operation is evaluated first, followed by the ‘or’ operation. This is equivalent to ‘a or (b and c)’.
Tip: Debugging Logic Operators
The most common problem people have with the logic operators is to mistake the priority rules. The lowest
priority operator is ‘or’; ‘and’ is higher priority and ‘not’ is the highest priority. If there is any confusion,
extra parentheses will help.
Other Operators. There are – theoretically – more logic operators. However, we can define all of other the
other logic operations using just ‘not’, ‘and’ and ‘or’. Other logic operations include things like “if-then”,
“if-and-only-if”. For example, “if a then b” can be understand as ‘(a and b or not a)’.
One of the more important additional logic operations is “or in an exclusive sense”, sometimes called one-
or-the-other-but-not-both or exclusive or, abbreviated xor. We can understand “a xor b” as ‘((a or b) and
not (a and b))’. The parenthesis are required to create the correct answer.
How can we prove this? Write a short program like the following:
a, b = True, True
print a, b, ((a or b) and not (a and b))
a, b = True, False
print a, b, ((a or b) and not (a and b))
You’ll have to repeat this for ‘False, True’ and ‘False, False’ combinations, also.
The claim that we can define all logic operations using only ‘not’, ‘and’ and ‘or’ is a fairly subtle piece of
mathematics. We’ll just lift up a single observation as a hint to how this is possibly true. We note that given
two values and an operation, there are only four combinations of values in the truth table. There are only
16 possible distinct tables built from four boolean values. The logic puzzle of creating each of the 16 results
using only ‘not’, ‘and’ and ‘or’ isn’t terribly hard. For real fun, you can try constructing all 16 results using
only the not-and operator, sometimes called “nand”.
5. Implies.
The word implies has a formal logic definition. We say “a implies b” as a short form of “if a, then b”.
We might say “rain implies a wet lawn”, or “if it rains, then the lawn gets wet”. In Python, we might
write ‘a implies b’ if Python had a logic operator named ‘implies’. When we look at the formal
meaning of our hypothetical x implies y, we want it to be true when x and y are true. When x is false,
the truth or falsity of y doesn’t really matter. We can say that implication is true when both x and y
are true or x is false.
Does ‘(x and y) or (not x)’ create the correct truth table for “implies”?
Why are there alternatives to True and False? There are two schools of thought on this subject:
• Boolean data is a first class data type, unique and distinct.
• Boolean operations work just fine on 1 and 0, don’t clutter the language with a specialized type
that only has two values.
Boolean data is a unique type of data: it has a unique domain of values and unique operators. The
domain is really tiny (True and False), but it is a proper mathematical domain with as many interesting
properties as whole numbers, rational numbers or irrational numbers. For this reason, it deserves its
own data type.
Claiming that the values of True and False are really just aliases for 1 and 0 misses two important
points. First, from a historical perspective, the computer engineers borrowed Boole’s algebra of logic
and used it to build computer circuits. The proper historical context shows us that the engineers figured
out how to use the ideas of True and False to build electronic circuits that could be interpreted as
meaning 1 and 0.
Second, and more important, the standard approach to avoiding a boolean type is to use the special
operators (Operators for Bit Manipulation. This doesn’t eliminate the boolean type, it just eliminates
plain boolean literals. We have a domain of values (1 and 0) and a suite of operators (‘&’, ‘|’, ‘^’,
and ‘~’) on that domain of values. This creates an ambiguity over the meaning of 1: does it mean the
number one or True?
This logic stuff seems to be “Over The Top” for something that is common sense.
When talking to another intelligent human being, this many appear as needless fussiness over something
that is common sense. However, we’re not talking with people, we’re writing a program in the formal
language of Python which will control a mindless collection of transistors. We need to be as precise
and inflexible as the circuitry in our computer.
There are two boolean values, 256 unique byte values, 4 billion unique integers. How many unique floating-
The “almost unlimited” at the beginning of the chapter was unsatisfyingly vague.
The domain of values for floating-point numbers is technically finite. The domain depends, to a
small extent, on your computer. We’ll assume 64-bit floating point numbers. These have 264 distinct
values, which is 18.4 quintillion. These values, however, are spread over a range that includes 2−1023
(approximately 10−308 ) as the number closest to zero, and 21024 (approximately 10308 ) as the number
furthest from zero.
Some computers have 80-bit floating-point numbers. The ranges in this case would obviously be
somewhat larger.
Comparisons are the heart of decision-making. Decision-making is the heart of controlling what our programs
do. We’ll start off looking at the basic comparison operators in Greater Than? Less Than?. We’ll look at
some more advanced comparison techniques in More Sophisticated Comparisons.
We’ll take second look at how the logic operators of ‘and’ and ‘or’ work in Taking Other Short-Cuts.
We’ll answer some additional questions in Comparison FAQ.
Ordinary arithmetic operators are functions that map some numbers to another number. For example,
addition maps two numbers to the number which is their sum: 3+5 maps to 8. Similarly, multiplication
maps two numbers to their product, 3 × 5 7→ 15.
A comparison maps two numbers to a boolean value that reflects the relationship between the numbers. For
example, 3 < 5 7→ True because 3 is less than 5; 3 ≥ 5 7→ False for the same reason.
We compare values with the comparison operators. Here are the comparisons that Python recognizes:
• Less than (<) is ‘<’.
• Greater than (>) is ‘>’.
• Less than or equal to (≤) is ‘<=’.
• Greater than or equal to (≥) is ‘>=’.
• Equal to (=) is ‘==’.
• Not equal to (̸=) is ‘!=’.
Important: Python 3
In Python 2, you can also use ‘<>’ for (̸=). This will be removed in Python 3, since it’s almost never used.
Why is ‘==’ used to test for equality? The problem is that mathematicians use the symbol = pretty freely,
but we have to provide more formal definitions. We elected to use ‘=’ for the assignment statement (The
Assignment Statement). To distinguish between assignment and comparison, we have to use ‘==’ to mean
comparison.
Here are some examples. You can see that a comparison produces a boolean result of either True or False.
>>> 10 > 2
True
>>> 10 >= 9+1
True
>>> 10 >= 9+2
False
>>> 1 == 2
False
>>> 1 != 2
True
The = and == Problem. Here’s a common mistake. We’ve used a single ‘=’ (assignment), when we
meant to use ‘==’ (comparison). We get a syntax error because we have a literal 99 on the left side of the
‘=’ statement.
>>> 99 = 2
File "<stdin>", line 1
SyntaxError: can't assign to literal
An Unexpected Coercion. Here’s a strange thing that can happen because of the way Python converts
between numeric type data and boolean type data. First, look at the example, then try to figure out what
happened.
Because of the ‘()’, the ‘10 >= 9’ is evaluated first. What is the result of that comparison?
How can it make sense to compute a sum of a boolean value (True or False) and a number? It doesn’t,
really, but Python tries anyway. It must have converted the boolean result of ‘10 >= 9’ to a number. Try
the following to see what has happened.
Comparisons can be combined in Python, unlike most other programming languages. For example, we can
ask: ‘0 <= a < 6’ which has the usual mathematical meaning. We’re not forced to write out the longer
form: ‘0 <= a and a < 6’.
Here’s an example of checking for the “middle twelve” in Roulette. Since the number is random, your results
may vary.
>>> spin
12
Writing ‘13 <= somethingComplex <= 24’ instead of ‘13 <= somethingComplex and somethingComplex
<= 24’ is particularly useful when somethingComplex is actually some complex expression that we’d rather
not repeat.
Proper Floating-Point Comparison. Exact equality between floating-point numbers is a dangerous
concept. After a lengthy computation, round-off errors and conversion errors in floating-point numbers may
have infinitesimally small differences. In Better Arithmetic Through Functions, we saw answers that were off
in the 15th decimal place. These answers are close enough to be equal for all practical purposes, but one or
more of the 64 bits may not be identical.
The following technique is the appropriate way to do the comparison between floating-point numbers a and
b.
abs(a-b)/a<0.0001
Rather than ask if the two floating-point values are the same, we ask if they’re close enough to be considered
the same. For example, run the following tiny program.
floatequal.py
$ python floatequal.py
0.333333333333 0.333333333333 Fale
The two values appear the same when printed. Yet, on most platforms, the == test returns False. They
are not precisely the same. This is a consequence of representing real numbers with only a finite amount of
binary precision. Certain repeating decimals get truncated, and these truncation errors accumulate in our
calculations.
There are ways to avoid this problem; one part of this avoidance is to do the algebra necessary to postpone
doing division operations. Division introduces the largest number erroneous bits onto the trailing edge of
our numbers. The most important part of avoiding the problem is never to compare floating-point numbers
for exact equality.
Python makes an important (but subtle) distinction between the following two questions:
• Do two objects have the same value?
• Are two objects references to the same thing?
Consider the following
a = 123456789
b = a
The variable a refers to 123456789. The variable b also refers to the same object.
When we evaluate the following, the results aren’t surprising.
>>> a=123456789
>>> b=a
>>> a is b
True
>>> a == b
True
The ‘is’ operator tells us that variable a and variable b are the same underlying object.
The ‘==’ operator tells us that variable a and variable b refer to objects which have the same numeric value.
In this case, since ‘a is b’ is True, it’s not surprising that ‘a == b’.
Not the Same Thing. In most cases, however, we’ll have situations like the following. We’ll create two
distinct objects that have the same numeric value.
>>> a=123456789
>>> c=a*1
>>> c is a
False
>>> c == a
True
>>> c is not a
True
In this example. we’ve evaluated a simple operator (‘*’), which created a new object. We know it’s a new
object because ‘c is a’ is False (also, ‘c is not a’ is True). However, this new object has the same
numeric value as a.
Common Use. The most common use for is and is not is when comparing specific objects, not generic
numeric values. We do this mostly with the object None.
2. Field Win.
Assume d1 and d2 have the numbers on 2 dice. The field pays on 2, 3, 4, 9, 10, 11 or 12. Actually
there are two conditions: 2 and 12 pay at one set of odds (2:1) and the other 5 numbers pay at even
money. Write two conditions under which the field pays.
Why do the logical operators short-circuit? Isn’t that an egregious violation of the eval-apply cycle?
In Execution – Two Points of View we emphasized the evaluate-apply cycle like it was a natural law
or divine writ, direct from the almighty. Yet, here we’re saying that the ‘and’ and ‘or’ operators
violate this law.
First, we’re only bending the law. The essential principle is still followed, we’re just extending the rule
a little: all of the logically necessary parts of an expression are evaluated first.
The alternatives to the short-circuit sense of ‘and’ and ‘or’ are either much more complex logic oper-
ators (‘and’, ‘or’, ‘cand’ and ‘cor’) or decomposing relatively simple logic into a complex sequence of
statements, using a if statement instead of a short-circuit logic operator.
The objective of software is to capture knowledge of processing in a clear and formal language. Fussy
consistency in this case doesn’t help achieve clarity.
There are two advanced logic operators we need to look at. In The Conditional Expesssion we’ll look at the
conditional expression. In Taking Other Short-Cuts we’ll look at the “short-cut” nature of and and or.
These operators are rule-benders: they behave in a slightly different way than all other Python operators.
Python has a really fancy logic operator, called the “conditional expression” that looks like this.
This is a three-part operator that has a condition (in the middle) and two values. If the condition is True,
then the value of the entire expression is the trueValue. If the condition is False, then the value of the entire
expression is the falseValue.
Note: Terminology
Sometimes you’ll hear this called “the ternary operator”. This is a confusing name, and shouldn’t be used.
It’s a ternary operator: there are three arguments. All other operators are unary (‘-a’) or binary (‘a+b’).
This happens to be the only ternary operator. There’s no reason for calling it the ternary operator because
others could be fashioned.
Here’s an example. Let’s say we’re monitoring the temperature of a walk-in cooler.
If the temperator is between -5 and 0, the status is “in range”. If the temperature is outside the range, the
label will be “problem”.
This is strictly a two-way true-false comparison. If you need more than two simple choices, you’ll need
something more sophisticated like the complete if statement, Processing Only When Necessary : The if
Statement.
Rule-Bender. This violates the basic rule we defined in The Evalute-Apply Rule. The general rule applies
almost everywhere else: every expression is fully evaluated. This conditional expression bends this rule,
however, to limit evaluation to the logically necessary sub-expressions rather than every single sub-expression.
Python always evaluates the condition. It then evaluates one of the two other expressions. The remaining
expression is not evaluated.
Here’s another example.
average = float(sum)/count if count != 0 else then the value of the expression is the value of :samp:`float(sum)/co
An important feature of the ‘and’ and ‘or’ operators is that they do not evaluate all of its parameters before
they are applied.
In the case of ‘and’, if the left-hand side is equivalent to False, the right-hand side is not evaluated, and the
left-hand value is returned.
For now, you can try things like the following.
This will show you that when the left-side value is equivalent to False, that is what Python returns for and.
The other value isn’t even evaluated.
Try this.
What happens?
The ‘and’ operator doesn’t evaluate the right-hand parameter if the value on the left-hand side is False.
The ‘or’ operator, similarly, does not evaluate the right-hand parameter if the left-hand side is equivalent
to True.
Rule-Bender. This violates the basic rule we defined in The Evalute-Apply Rule. The general rule applies
almost everywhere else: every expression is fully evaluated. The ‘and’ and ‘or’ operators bend this rule,
however, to limit evaluation to the logically necessary sub-expressions rather than every single sub-expression.
This short-circuit can be useful. This is an example of the “practicality beats purity” principle that makes
Python so cool.
Simplifications. Let’s look at the informal logic of English for a moment. When sailing, we might say “if
the wind is over 15 knots, we reef the main sail.” Reefing, for non-sailors, is a technique for reducing the
area of the sail; we do this for a variety of reasons, for example, so that the boat doesn’t lean over (“heel”)
too far in a high wind.
One important consequence of the short-cut rule is that the Python logic operators are very handy for
creating a simple, clear statement of some sophisticated processing. One of the most notable examples of
this are expressions like the following which summarize our sailing rule very nicely.
Comparison operators are higher priority than logic operators, so Python evaluates ‘windSpeed > 15’ first,
and develops a truth value. Also, ‘and’ is higher priority than ‘or’, so the ‘and reefed’ is evaluated before
the ‘or full’. After the comparison, there are two possible sequences of evaluation.
• If the ‘windSpeed > 15’ comparison is True, Python evaluates the right side of the ‘and’ operator, the
result of the ‘and’ operation is reefed. Since the value of reefed is equivalent to True, Python does
not need to evaluate the right side of the ‘or’ operator at all. The result is reefed (72).
• If the ‘windSpeed > 15’ comparison is False, Python does not evaluate right side of the ‘and’ operator;
the result of the entire ‘and’ operation is False. Python is forced to evaluate the right side of the ‘or’
operator. The result is full (65).
One More Condition. What if we are motoring, not sailing? In English, we can say something like “when
sailing and the wind is over 15 knots, we reef the main sail.” The implication is that when we are motoring,
the wind-speed comparison is irrelevant. Aftewr all, it is a bit silly to also check the wind speed when we
don’t even have the sails up.
If we don’t think carefully, we would wind up with the following set of conditions.
Engine Conditions Configuration
Sailing Wind Speed <= 15 kn full
Wind Speed > 15 kn reefed
Motoring Wind Speed <= 15 kn full
Wind Speed > 15 kn reefed
The table above is silly because motoring makes the wind speed and sail positions irrelevant. Why are we
checking them needlessly?
Clarification. This table has what we really meant. This clearly states that when we’re motoring, we don’t
need to check the wind-speed.
Engine Conditions Configuration
Sailing Wind Speed <= 15 kn full
Wind Speed > 15 kn reefed
Motoring Doesn’t matter None
This English-language sense of “and-only-when-it’s-relevant” is a handy simplification. This is common in
English, and the reason why the Python operators include this same short-cut sense.
We might express this with something like the following in a Python program:
sailArea= (reefed if windSpeed > 15 else full) if engine == "Sailing" else None
This reflects the “decision tree” in our table. The overall condition is the ‘if engine == "Sailing"’ check.
If we’re sailing, then there’s a second check based on the wind speed.
We can also do this with the short-circuit ‘and’ and ‘or’.
sailArea= engine == "Sailing" and (reefed if windSpeed > 15 else full) or None
When sailing in light air (10 knots), we should have the full sail, all 72 square feet deployed.
When motoring in a stiff breeze (25 knots), we should have no sail.
1. Develop an “or-guard”.
This is the “and-guard” pattern. It guards the division operation, by comparing the divisor with zero.
If count really is zero, this returns False rather than attempting an illegal division.
Develop a similar technique using or instead of and. This will require some reversals of the logic in
the above example. We can interpret it as doing a comparison or a calculation. If the first clause (the
comparison) is false, we want to continue on to the next clause (the calculation).
2. Hardways.
Assume d1 and d2 have the numbers on 2 dice. A hardways proposition is 4, 6, 8, or 10 with both dice
having the same value. It’s the hard way to get the number. A hard 4, for instance is ‘d1+d2 == 4
and d1 == d2’. An easy 4 is ‘d1+d2 == 4 and d1 != d2’.
You win a hardways bet if you get the number the hard way. You lose if you get the number the easy
way or you get a seven. Write the winning and losing condition for one of the four hard ways bets.
We’ll address the meaning of conditional processing in Conditional Processing. We’ll present the basic
Python if statement in The if Statement. We’ll look at some examples in Example if Statements.
We’ll add a number of conditional processing features in The elif Condition for Alternatives, The else
Condition as a Catch-All and The pass Statement: a Do-Nothing.
The programs we’ve seen so far have performed a sequence of steps, unconditionally. We’re going to introduce
some real sophistication by making some of those steps conditional. We’ll start by looking at what it takes
to design a sequence of steps that does what we want.
Back in Where Exactly Did We Expect To Be? we talked about the significance of putting a variable name on
an object. The values we assign to our variables define the program’s state of being. Changing a variable’s
value changes the program’s state. When we’ve planned our program well, each state change moves our
program from a nebulous starting state toward the well-defined finished state.
Let’s look at converting Celsius temperatures to Fahrenheit temperatures. We’ll work backwards from the
ending.
• Goal: we need to have both C and F variables defined, and the values must satisfy an equation that
maps between the two temperatures. How do we get to this well-defined final state?
• Final Step: Compute the value for F. To do this, we’ll need the value for C. Then we can use a formula
from the exercises in Expression Exercises to set the desired value for F.
• Precondition: Get the value for C. When can get the value for C by using the input() function. What’s
the precondition for getting C?
• Initial Condition. Any initial values of F and C are valid for the start of this program.
When we reverse this list of goals, we have the algorithm for computing the Fahrenheit temperature from
the Celsius temperature.
This example shows sequential execution, where each step is unconditional. Sometimes the processing in a
given step depends on a condition being met. When we are planning our programs, we may have to choose
one of several statements depending on the data values or the processing goal. We call this conditional
processing, which is the subject of this chapter.
The next state may depend on a condition being true for all of a set of data or finding a condition true for
some of a set of data. We call this iterative processing, and that’s the subject of the While We Have More
To Do : The for and while Statements chapter.
Many times a program’s exact processing or state change depends on a condition. Conditional processing
is done by setting statements apart in groups called suites that have conditions attached to the suites. The
Python syntax for this is an if statement. The if embodies this semantics of “if a condition is true, execute
the suite of statements” .
The basic syntax of an if statement looks like this:
if expression :
suite
The word if and the : are essential syntax. The suite is an indented block of one or more statements. Any
statement is allowed in the block, including indented if statements. You can use either tabs or spaces for
indentation. The usual style is four spaces, and we often set BBEdit or TextPad to treat the tab key on our
keyboard as four spaces.
This is the first compound statement we’ve seen. A compound statement statement makes use of the essential
syntax rules we looked at in Long-Winded Statements. It also uses two additional syntax rules, that we’ll
look at next.
Semantics. The if statement evaluates the condition expression first. When the result is True, the suite of
statements is executed. Otherwise the suite is skipped. Let’s look at some examples.
Syntax Help from IDLE. The suite of statements inside the if statement is set apart from other statements
by its indentation. This means you have to indent the statements in the suite consistently. Any change to
the indentation is, in effect, another suite or the end of this suite.
The good news is the IDLE knows this rule and helps us by automatically indenting when we end a line
with a ‘:’. It will automatically indent until we enter a blank line. Here’s how it looks in IDLE. In order to
show you precisely what’s going on, we’re going to replace normally invisible spaces with ␣characters.
>>>␣if␣1+2␣==␣3:
...␣␣␣␣print␣"good"
...
good
1. You start to enter the if statement. When you type the letter f, the color of ‘if’ changes to orange,
as a hint that IDLE recognizes a Python statement. You hit enter at the end of the first line of the
if statement.
2. IDLE indents for you. You type the first statement of the suite of statements.
3. IDLE indents for you again. You don’t have any more statements, so you hit enter. The statement
is complete, so IDLE executes the statement.
4. This is the output. Since 1+2 does exactly equal 3, the suite of statements is executed.
Important: Syntax Rule Eight
Compound statements, including if, while, for, have an indented suite of statements. You have a number
of choices for indentation; you can use tab characters or spaces. While there is a lot of flexibility, the most
important thing is to be consistent.
We’ll show an example with spaces shown via ␣.
a=0
if␣a==0:
␣␣␣␣print␣"a␣is␣zero"
else:
␣␣␣␣print␣"a␣is␣not␣zero"
Here’s an example with spaces shown via ␣and tabs shown with ⊢:
if␣a%2==0:
$\vdash$print␣"a␣is␣even"
else:
$\vdash$print␣"a␣is␣odd"
Important: Syntax Rule Seven
When using Python interactively, an entirely blank line ends a multi-line compound statement.
Note that if you’re using another editor (BBEdit, TextPad, etc.) you won’t get the same level of automatic
help that you get from IDLE. Other tools can provide syntax coloring and remember your indentation, but
they don’t all automatically indent when you end a line with a : the way IDLE does.
We’ll look at some examples of if statements to see some additional examples of how they work. We’ll take
a couple of examples from the rules for Craps.
Is This Craps?. During the game of Craps, once a point is established, a roll of 7 is “craps”, a loser. The
following example combines arithmetic expressions, comparison and the if statement.
The variables d1 and d2 are set randomly, so each time you run this it may behave differently.
if d1+d2 == 7:
print "craps"
Here we have a typically complex expression. Here’s how the if statement works.
1. The expression ‘d1+d2 == 7 or d1+d2 == 11’ is evaluated.
The ‘or’ operator evaluates the left side of the ‘or’ operation first; if this is False, it will then evaluate
the right side. If the left side is True, the result is True.
2. The expression ‘d1+d2 == 7’ is evaluated.
3. If this value is True, ( d1 + d2 really is 7), the entire ‘or’ expression is True and evaluation of the
expression is complete.
4. If the left side is False, then the right side is evaluated. The value of the right side ( ‘d1+d2 == 11’)
is the value for the entire ‘or’ operation. This could be True or False.
5. If the value of the expression is True, the suite is executed, which means that a message is printed.
If the expression is True, the suite is skipped.
Often there are several alternatives conditions that need to be handled. We encounter this when we have a
series of rules that apply to a situation.
A good example is from Roulette, when we have a spin that could be even, odd or zero. We have a situation
like the following.
• If the number 0 or 00, bets on even or odd are losers.
• Else, if the number is even (the remainder when divided by 2 is equal to 0), bets on even are winners.
• Else, if the number is odd (the remainder when divided by 2 is equal to 1), bets on odd are winners.
This is done by adding elif clauses. This is short for “else-if”. We can add an unlimited number of elif
clauses. The syntax for the elif clause is almost identical to the initial if clause:
elif expression :
suite
Semantics. Python treats the if and elif sequence of statements as a single, big statement. Python
evaluates the if expression first; if it is True, Python executes the if suite and the statement is done; the
elif suites are all ignored. If the initial if expression is False, Python looks at each elif statement in order.
If an elif expression is True, Python executes the associated suite, and the statement is done; the remaining
elif suites are ignored. If none of the elif suites are true, then nothing else happens
Complete Come Out Roll. Here is a somewhat more complete rule for the come out roll in a game of
Craps:
result= None
if d1+d2 == 7 or d1+d2 == 11:
result= "winner"
elif d1+d2 == 2 or d1+d2 == 3 or d1+d2 == 12:
result= "loser"
print result
spin= random.randint(-1,36)
result= None
if spin == 0 or spin == -1:
result= "neither"
elif spin % 2 == 0:
result= "even"
elif spin % 2 == 1:
result= "odd"
print spin, result
3. If the first elif condition is false, then Python moves on to the second elif condition. If that condition is
true, Python executes the second suite (set result to ‘"odd"’), and the entire if statement is complete.
If none of these conditions is true, the if statement has no effect. The script prints the result, which will be
None.
Finally, there is the capability to put a “catch-all” suite at the end of an if statement, which handles all
other conditions. This is done by adding an else clause. The syntax for the else clause it somewhat simpler.
else:
suite
This clause is always last and, effectively, always True. When the if expression and all of the elif expressions
are false, Python will execute any else suite that we provide.
Come Out Roll Script. Here’s the complete come-out roll rule. In this final example, we’ve added the
necessary import and assignment statements to make a complete little script.
comeoutroll.py
import random
d1,d2= random.randrange(1,7), random.randrange(1,7)
point= None
result= None
if d1+d2 == 7 or d1+d2 == 11:
result= "winner"
elif d1+d2 == 2 or d1+d2 == 3 or d1+d2 == 12:
result= "loser"
else:
point= d1+d2
result= "point is", point
print result
Here, we used the else: suite to handle all of the other possible rolls. There are six different values (4, 5,
6, 8, 9, or 10), a tedious typing exercise if you write it our using or. We summarize this complex condition
with the else: clause.
Tip: Debugging the if statement.
If you are typing an if statement, and you get a SyntaxError: invalid syntax, you omitted the ‘:’.
A common problem with if statements is an improper condition. You can put any expression in the if or elif
statement. If the expression doesn’t have a boolean value, Python will use the bool() function to determine
if the expression amounts to True or False. It’s far better to have a clear boolean expression rather than
trust the rules used by the bool() function.
One of the more subtle problems with the if statement is being absolutely sure of the implicit condition that
controls the else clause. By relying on an implicit condition, it is easy to overlook gaps in your logic.
Consider the following complete if statement that checks for a winner on a field bet. A field bet wins on 2,
3, 4, 9, 10, 11 or 12. The payout odds are different on 2 and 12.
outcome= 0
if d1+d2 == 2 or d1+d2 == 12:
outcome= 2
print "field pays 2:1"
elif d1+d2==4 or d1+d2==9 or d1+d2==10 or d1+d2==11:
outcome= 1
print "field pays even money"
else:
outcome= -1
print "field loses"
Here’s the subtle bug in this example. We test for 2 and 12 in the first clause; we test for 4, 9, 10 and 11
in the second. It’s not obvious that a roll of 3 is missing from the “field pays even money” condition. This
fragment incorrectly treats 3, 5, 6, 7 and 8 alike in the else:.
While the else: clause is used commonly as a catch-all, a more proper use for else: is to raise an exception
because a condition was found that did not match by any of the if or elif clauses.
Once in a while you may have a situation where the logic is kind of tangled, and you want to say something
like the following:
if a > 12:
do nothing
elif a == 0:
print "zero"
else:
print "a between 1 and 12"
Unfortunately, the Python languages doesn’t allow a suite of statements to be empty. We don’t want to have
to rearrange our program’s logic to suit a limitation of the language. We want to express our processing
clearly and precisely. Enter the pass statement.
The syntax is trivial.
pass
The pass statement does nothing. It is essentially a syntax place-holder that allows us to have a “do nothing”
suite embedded in an if statement.
Here’s how it looks.
if a > 12:
pass
elif a == 0:
print "zero"
else:
print a, "between 1 and 12"
If the value of a is greater than 12, the if statement’s expression is true, and Python executes the first suite
of statements. That suite is simply pass, so nothing happens.
If the value of a is zero, the first elif statement’s expression is true, and Python executes the second suite
of statements. That suite is a print statement, and we see a “zero” printed.
If none of the previous expressions are true, Python falls back to the else statement, in which case, we would
see a message about a being between 1 and 12.
We’ll address the general need for iterative processing in Iterative Processing. There are a few specific kinds
of iterations that we can identify, and we’ll describe these in Patterns of Iteration. The most commonly-used
Python iterative statement is presented in The for Statement. We’ll look at some examples in Multi-
Dimensional Loop-the-Loop and Simulating All 100 Rolls of the Dice.
6.5. While We Have More To Do : The for and while Statements 147
Programming for Non-Programmers, Release 2.5.1
In The while Statement we’ll look at the other iterative statement. We’ll put together a big example in
Counting Sevens.
We’ll answer some questions in Iteration FAQ.
Later, in Becoming More Controlling we’ll add some additional control to these statements. We have to set
this more advanced material aside until we’ve learned more Python.
A program may have a goal that is best described using the words “for all”, where we have to do some
calculation for all values in a set of values.
Let’s look at creating a table of Celsius temperatures and their matching Fahrenheit temperatures. We only
need useful temperatures between -20 °C and 40 °C. We’ll work backwards from the ending.
• Goal: we need to print all C and F values; the values must satisfy an equation that maps between the
two temperatures; the values for C are between -20 and 40.
How do we get to this well-defined final state?
• Loop Condition: The value for C is between -20 and 44, and we have not computed and printed the
value for F yet. When this condition is true, we have more work to do. When this is false, we have
satisfied our for all condition.
What work do we have to do that satisfies the rest of our goal? What precondition is required to make
this true initially?
– Iterative Step 3: Add 2 to the value of C. This satisfies part of our for all goal by creating a value
of C for which we haven’t computed an F.
What else do we have to do?
– Iterative Step 2: Print the values for C and F. This satisfies part of our for all goal by printing
values of C and F.
What’s the precondition for printing C and F?
– Iterative Step 1: Compute the value for F. To do this, we’ll need the value for C. Then we can use
a formula from the exercises in Expression Exercises to set the desired value for F.
• Precondition: Set the value for C to -20. This sets our Loop Condition to be true.
What’s the precondition for setting C?
• Initial Condition. Any initial values of F and C are valid for the start of this program.
When we reverse this list of goals, we have the algorithm for computing a mapping between the Fahrenheit
temperature and the Celsius temperature.
We often call iterative or repetitive processing a “loop” because the program statements are executed in a
kind of loop. Both the for and while statements provide a condition that controls how many times the loop
is executed. The condition in the for statement is trivial, but the pattern is so common that it has a large
number of uses. The condition in the while statement is completely open-ended, therefore it requires a little
more care when designing the statement.
Iterative processing relies on all the elements of sequential and conditional processing that we’ve already seen.
Iterative programming is the backbone of computing. First we’ll look at three common kinds of iteration.
Then we’ll see how to write those kinds of iteration in Python.
There are three basic species of iterations: mapping, reducing and filtering. As with much of computer
science, other words have been borrowed for these rather abstract ideas. Don’t think of road maps, weight
loss or clothes dryers. Think of mapping in the sense of mapping one value to another, reducing a set of
values to a single value, and filtering unwanted values out of a set.
Mapping All Values In A Set. Perhaps the simplest kind of iterations is called a mapping. Our iteration
maps all values in a set from some domain to some range. We see this kinds of mapping when we look
at a Fahrenheit to Celsius conversion table, or a deciliters to cups table. Even an chart that maps the
combination of air temperature and wind speed to a wind-chill temperature is a kind of mapping. We’ll look
at these kinds of iterations extensively in this chapter.
The for statement is ideal for performing a mapping that has to be done for all values in a set. The typical
pattern for a mapping uses a Python for statement and one or more “compute mapped value” statements.
It’s a Python statement with a suite of statements, and has a general outline like the following:
Here’s the result of a small program that produces a mapping from Swedish Krona (SEK) to US Dollars
(USD); it’s a currency exchange table. A Krona is worth about $0.125 right now. We used a Python “for
all” loop to iterate through all values from 5 to 50 in steps of 5.
5 0.625
10 1.25
15 1.875
20 2.5
25 3.125
30 3.75
35 4.375
40 5.0
45 5.625
50 6.25
The result of a mapping is an output set of values; the size of the output set matches the size of the input
set. In our example above, we have has many Krona values as Dollar values.
Reducing All Values To One Value. Another common kind of iteration is a reduction where all the
values in a set are reduced to a single resulting value. When we add up or average a column of numbers,
we’re doing a reduction. As we look at our two representative problems (see Two Minimally-Geeky Problems
: Examples of Things Best Done by Customized Software), we see that we will be simulating casino games
and computing averages of the results of a number of simulation runs.
The for statement is ideal for performing reductions. The typical pattern for a reduction uses a “initializa-
tions”, a “for all”, and one or more statements to “update the reduction”.
The result of a reduction is a single number created from the input set of values. Common examples are
the sum, average, minimum or maximum. It could also be a more sophisticated reduction like the statistical
median or mode.
6.5. While We Have More To Do : The for and while Statements 149
Programming for Non-Programmers, Release 2.5.1
Filtering All Values To Find a Subset. The third common kind of iteration is a filter where the iteration
picks a subset of the values from all values in a set. For instance, we may want a filter that keeps only even
numbers, or only red numbers in Roulette.
In this case, we’re introducing a condition, which makes a filter more complex than the map or reduce. A
filter combines iteration and conditional processing.
There are two senses of filtering:
• Find all values that match the condition.
• Find some value that matches the condition. This is a slightly more complex case, and we’ll return to
it several times.
These are sometimes lumped under the category of “search”. Search is so important, that several computer
science books are on focused on just this subject.
When we look closely at the rules for Craps we see that a game is a kind of filter. Once the game has
established a point, the rest of the game is a kind of filter applied to a sequence of dice roles that ignores
dice roles except for 7 and the point number. We can imagine adding filter conditions; for example, we could
add a filter to keep the dice rolls that win a hardways bet.
The while statement can be used for filtering. Additionally, the break and continue statements can
simplify very complex filters. The typical pattern for a filter uses an “initialize”, a “while not finished”,
“filter condition” and an “update the results”.
The result of a filter is a subset of the input values. It may be the original set of values, in the rare case that
every value passes the filtering test. It may be a single value if we are searching for just one occurrence of a
value that passes the filter.
The most common way to do a “for-all” mapping, reduction or filtering is with the for statement.
The for statement looks like this:
The words for and in and the : are essential syntax. The suite is an indented block of statements. Any
statement is allowed in the block, including indented for statements.
There are a number of ways of creating the necessary sequence of values. The most common way to create a
sequence is to use the range() function. First we’ll look at the for statement, then we’ll provide a definition
for the range() function.
Printing All The Values. This first example uses the range() function to create a sequence of six values
from 0 to just before 6. The for statement iterates for all values of the sequence, assigning each value to the
local variable i. For each of six values of i, the suite of statements inside the for statement is executed.
The suite of statements is just a print statement, which has an expression that adds one to i and prints the
resulting value.
for i in range(6):
print i+1
We can summarize this as “for all i in the range of ‘0 to one before 6’, print i +1”.
Using A Literal Sequence Display. We can also create the sequence manually, using a literal sequence
display. A sequence display looks like this: [ expression , ... ]. It’s a list of expressions; for now they should
be numbers separated by commas. The square brackets are essential