The following content is
provided under a Creative
Commons license.
Your support will help MIT
OpenCourseWare continue to
offer high quality educational
resources for free.
To make a donation or view
additional materials from
hundreds of MIT courses, visit
MIT OpenCourseWare at
ocw.mit.edu.
PROFESSOR: Good morning.
AUDIENCE: Good morning.
PROFESSOR: Thank you.
OK.
So we're about to launch into
learning some basic elements
of Python today.
The elements I'm going to talk
about are common to every
programming language that I
know, at least in concept, and
of course slightly different
in detail.
But as I said last time,
everything you're going to
learn about Python should
be readily transferable.
I'll be using, for all of the
examples I present, something
called an integrated development
environment, and
in particular, one that's built
for Python called IDLE.
Usually we talk about these
things as IDEs.
I'm told, I don't know if it's
true, that the IDE for Python
is called IDLE after Eric Idle
of Monty Python, which was
also, I'm told, the inspiration
for the name of
the programming language.
So what is an integrated
programming environment?
In this case, it includes a
specialized text editor that
provides highlighting,
auto-completion, smart indent,
and you'll see shortly why all
that's very important, and a
few other amenities that make it
easier to use this to type
Python than typing it into
a generic text editor.
It includes something called
a shell, which is the
environment that actually
interprets the Python code.
And the nice thing about it
is it includes syntax
highlighting.
So the shell gives you some
information about the syntax,
as does the text editor
of course.
And finally, it includes
an integrated debugger.
This could be useful in the
unlikely event that your
programs have errors when
you write them.
Though truth be told, I've been
programming in Python for
years and I don't know that I've
ever used the debugger.
It's not that I don't make
mistakes, it's just that I'm
kind of a Luddite, and I
typically use print statements
for debugging.
And in fact, almost every
programmer that I know, when
push comes to shove, ends up
using print statements.
But the debugger is there,
should you care to take a try.
All right.
So you'll see on the screen
here an IDLE shell.
In the shell, we can
type things.
What are we going to type?
Well the first thing to
understand is that at the core
of Python, and probably the
most important thing to
understand, are something
called objects.
Everything in Python
is an object.
So every kind of entity that you
can create in Python is an
object, and in fact, Python
code itself is an object.
You'll remember, we talked about
stored program computers
last time, and the concept that
a program is data, just
like a number is data.
Each object has a type that
tells us the kind of object it
is, and in particular, what
we can do with it.
And then there's a built-in
function, called type, that
can be used to find out
the type of an object.
As we'll see, there are two
fundamental kinds of types.
Scalar and non-scalar.
We'll start with talking
about scalar types.
And the key thing to think about
there is that they are
indivisible.
Think of them as the atoms of
the programming language.
Now, I know that some of you
have studied physics and know
that atoms are in principle
divisible, but of course, only
at great expense and with
serious consequences.
And we've seen the
same thing here.
You can, if you're desperate,
chop up these scalar types,
but it almost always leads
to something bad.
All right.
Well let's look at some.
Well, the first one you'll see
is used to represent integers,
and that's called int.
For every type, or every
built-in type, there's the
notion of a literal, which
is how we type it.
So for example, we can type 3,
and that will now tell us it
is the value 3.
You'll note it's typed
it in blue.
And I can ask what
the type of 3 is.
So you'll notice as I type
things into the shell, it's
using colors to give
me a hint.
So it's this fuchsia color for
the word type, telling me
that's a built-in function.
And now if I ask it, it will
tell me that the type of the
literal 3 is "int".
So it's an integer.
And I can use other
sorts of things.
All right.
There's also a type float.
So those correspond to
the real numbers.
So I can do something
like that.
And we'll talk about this in a
second, but you'll notice if I
do type of 3.2, it tells
me it's a float.
And for that matter, I can do
type of 3.0, and it will tell
me it's a float.
So there's a difference
between 3 and 3.0.
One is an int, and
one is a float.
Now you'll notice something
kind of weird here.
When the interpreter printed
back the value of the literal
3.2, it gave me 3.2 and a bunch
of zeroes, and then this
funny 2 standing at the end.
In a few lectures, I'll explain
why it does this, but
for now, you should just take
this as a warning that floats
are not the same thing
as real numbers.
You learned about reals,
presumably in middle school or
high school.
Floats are a computer
scientist's approximation to
reals, but they're not
quite the same.
The good news is almost all the
time, you can pretend that
a floating point number is a
real, but as we'll see in a
few lectures, every once in a
while it can really sit up and
bite you, if you believe that.
But for now, we'll just pretend
that they're reals.
There's Booleans, a nice scalar
type of which there are
only two values.
One of them is true, and what
do you think the other
Boolean value is?
AUDIENCE: False?
PROFESSOR: Thank you.
So somebody said false.
I have no idea who, but
whoever it is, there's
probably some candy to be had.
Oh, I managed to find the one
place in the room where there
was an empty.
I'm hoping that people will now
scramble and fight for it,
like a foul ball at
a baseball game.
No, people are too
polite thus far.
All right.
So we have true and false
as the type Booleans.
And then we can do operations
on them.
So for example, true and false
is false, as you might guess.
Finally, there's this funny
value, none, which doesn't
print anything when I type it.
And if I look at the type
of none, we'll see
it's the none type.
Not very interesting.
Fundamentally, as we'll see,
that gets used when you want
to put in something temporary.
When you don't yet know what its
value is going to be, you
know it's going to eventually
have one, so maybe you start
out calling it none.
And then you can check,
and we'll see
how we might do that.
So those are the fundamental
scalar types,
the indivisible ones.
Interestingly enough, Python
does not have what is a common
scalar type in every other
language called char, short
for character.
Instead, what it has is strings
that can be used to
represent strings
of characters.
So for example, I can write the
string "a", and if I ask
for the type of it, it
tells me it's an
str, short for string.
Happens to be a string of
length 1, which we might
usually think of as
a character, but
there is no type char.
So it's not a problem.
We just have to remember it.
Literals of type string can be
written with single quotes or
with double quotes.
There's no difference.
Just convenient that you can do
it either way, and we can
build strings of things.
It's worth noting that the type
of, say, the string 123
is str, whereas the type of 123
without the quotes is int.
So we have to be a little bit
careful sometimes as to
whether we're dealing with
strings or ints when we look
at these literals.
You can only get so far with
literals, things you can type.
So of course, Python has in
it something called an
expression.
Again, this shouldn't
surprise anybody.
And an expression
is a sequence of
operands and operators.
The operands are objects.
So for example, we can write
the expression 3 plus 2.
And when we type an expression
into IDLE, it automatically
evaluates it and prints the
value of the expression.
In this case, of
course it's 5.
One thing to be a little careful
about is if I type the
expression 3/2, slash is the
divide operator, I get 1.
Whereas if I type the expression
3.0 divided
by 2.0, I get 1.5.
So dividing two integers
in Python 2.x gives you
essentially a floor operator.
In 3.0, by the way, integer
division is not allowed.
It always converts it to floats
and does a floating
point division.
But for many of you this will
be something that will trip
you up as a bug.
If you want to get real
division, write
floating point numbers.
Otherwise, unpleasant
things may happen.
Some other interesting things
I can type, just as I could
type 3 plus 2, I can
type a plus b.
What do you think
I'll get there?
It does concatenation.
So what we see here is that
the operator plus is
overloaded.
So overloaded operators have a
meaning that depends upon the
type of the operands.
And of course, we've already
seen that with the slash
operator, which means one thing
for ints and another
things for floats.
And of course, we see the
same thing with plus.
What do you think will
happen here?
3 blank 3?
Any guesses?
I get a syntax error.
Remember, we talked about
that on Tuesday.
It's not a valid Python
expression,
so we get an error.
How about this one?
That is syntactically valid.
It's got operand, operator,
operand.
What do you think it will do
when I hit Return here?
Somebody?
AUDIENCE: A static
semantics error?
PROFESSOR: Pardon?
AUDIENCE: A static
semantics error?
PROFESSOR: A static
semantics error.
And because of these--
Wait, I can't see
who said that.
Raise your hand?
Oh, come on.
All the way back there?
All right.
I have the most chance of
carrying with one of these.
I'm going to lie.
Those of you who are watching
OpenCourseWare, it was a
perfect throw.
OK.
So indeed, we get a static
semantic error of a particular
kind, called the type error,
saying you cannot concatenate
an str and an int.
Type errors are actually
good things.
The language does type checking
in order to reduce
the probability that a
programmer will write a
program with a meaning that
will surprise its author.
So it looks at it and says,
somebody might have a weird
guess what this means, but just
to be safe, we're going
to disallow it rather than--
it could, of course, make
up some funny meaning
if it wanted to.
But it doesn't.
And I think you'll find type
checking saves you from a lot
of careless programming
errors as you go on.
All right, let's continue.
Let's look at some
other things.
I can write this.
Because that's just two
strings, and it just
concatenates them, the string
a and the string 3.
Or interestingly,
I can do this.
So now what we're seeing is
that you can take any type
name, use it as a conversion
function to attempt to convert
one type to another.
So this has now converted the
int 3 to the str "3".
Similarly, I can do something
like this.
And here, it's converted the
str "3" to the int 3.
On the other hand,
I could do this.
And it will tell me it's a
static semantic error.
It can't convert 0.0
into an int.
Similarly, it can't
convert 2.1.
Or can it?
So now I've given it the float
2.1, and I've tried to
convert it to int.
Not the string 2.1,
but the float.
And it succeeds.
And it succeeded by essentially
truncating it.
Is this a good thing
or a bad thing?
To me, it's kind
of a bad thing.
If I've typed something like
that or I've evaluated some
expression that happened to
work that way, more likely
than not, I'm confused.
And I would probably have
preferred to get a type error,
rather than it deciding
how to do it.
It's one of the things I don't
like about Python.
It's too generous.
It lets me get away with
stuff it shouldn't
let me get away with.
Other languages, for example
Java, are much stricter.
This is a design decision and
it is the way it is, and we
have to live with it.
AUDIENCE: Professor?
Yes?
AUDIENCE: Is that the same
reason that 3 divided by 2
turned into 1 up top?
PROFESSOR: Yeah.
Exactly.
If it's the same reason that
that happens, this will never
go that far.
[UNINTELLIGIBLE].
Yeah, exactly.
It's the same reason.
The question was, is it the same
reason that 3 divided by
2 doesn't give you the
answer you would get
with floating point.
And it's because Python
has tried to help you.
Again, Python 3.0 is a little
stricter about these things.
We'll talk much more about
this during the term.
This is close to the last time
you'll see me typing things
directly into IDLE.
For the most part, as you write
programs, you'll use the
text editor to produce them
and then go to the
shell to run them.
But you want to--
obviously, if I had a 100 line
program, I wouldn't want to
sit here and retype it every
time I needed to change it.
So instead, I use the editor
in IDLE to produce the
programs, and then
I can run them.
And that's what I wanted
to start doing.
I should probably mention that
what most people call a
program, some Python programmers
call a script.
Think of those two things
as synonyms.
But you will see people
use both of them.
I will typically call
them a program.
All right.
Let's look at an example.
So the first thing to say is
that things look a little bit
different when they're executed
from a script than
when you execute them directly
in the interpreter.
So I happen to have
a script here.
If a line in a script starts
with a sharp sign or a number
sign, that makes it a comment.
So it's not executed.
So I've started here just by
commenting out everything.
But now--
whoops--
what happens if I just put
the number 3 here?
We saw when I typed it into
IDLE, it echoed it in some
sense and gave me what it was.
Or just to be clear, I'm
going to put in the
expression type of 3.
I'll save it, and then I'll
hit F5 to run it.
And it does nothing.
Right?
You saw it move.
It didn't print anything.
So when you type an expression
into the shell,
it prints the value.
But when it executes a script
with an expression, it
evaluates the expression
but does not
display it on the screen.
Well, so what do we
do about that?
There is something called
a print command.
So I can do this, Print type of
3, and now if I run it, it
will actually appear.
So whenever you want to get
something to appear, you have
to use the Print command.
Not a very complicated
concept.
A program, or a script, is
a sequence of commands.
Each one tells the interpreter
to do something.
So a command is Print,
for example.
OK.
So that's there.
That's kind of boring.
I'll get rid of that.
The next command is a really
interesting one.
It's an assignment statement.
A key concept in almost every
programming language is that
of a variable.
Different languages have
different notions of what a
variable means.
In Python, a variable is simply
a name for an object.
And what an assignment statement
does in Python, is
it binds the name
to an object.
So the assignment stetement you
see here binds the name x
to the object 3.
The next statement rebinds the
name x to the value of the
expression x times x.
So it takes the old value of x,
evaluates the expression,
and then binds the name
x to the new value.
So at the end of the
second statement, x
will be bound to 9.
By the way, these are really
stupid comments
I've written here.
I put them in just to
show you what these
statements are doing.
For goodness sake, when you
write comments in your
programs, assume that the reader
can read Python, and
you don't have to explain
the programming
language in your comments.
That's not to say you shouldn't
write any comments.
The purpose of a comment
is to make the
program easier to read.
And so typically, comments are
there to explain things.
Not to explain the language or
its semantics, but to explain
your thinking when you
wrote the program.
What is the algorithm
you've used?
And we'll see some useful
examples of comments, probably
not today, but later.
All right.
So let's execute this script.
Sure enough, it printed 9.
Just what we would have hoped.
All right.
Now let's try some
other things.
Print lets us output things.
Raw input lets us
input things.
Get things from the keyboard,
essentially.
So this statement here is making
a request to whoever is
using the program to
enter a number.
There are two kinds of input
statements in Python 2.x.
There's raw input, which is the
only one you will see me
use, and input.
Raw input, by the way, is the
only one that exists in 3.0.
So please, just use raw input.
The difference is, raw input
always expects, interprets
what the user types
as a string.
So it will see here, it says,
y equals float of raw input.
Enter a number.
So let's run it.
So it's taken the argument to
raw input, the string enter a
number asked me to
enter a number.
I'll enter a number.
And then it's converted
it to a float.
Suppose I get rid of that.
Suppose I do this.
That should work.
So now something has happened.
It's printed both
of them as 3.0.
It looks like they're
the same, but in
fact, they're not.
And this is something
to beware of.
What we've seen here is when
it prints a string, it does
not print the quotation marks.
So even though, if I were to put
this in here, I'll put in
two print types of y.
And I'll comment this out
because I'm getting kind of
tired of seeing 9.
You'll note that one
is a string and
the other is a float.
Again, I point this out because
this is something that
can confuse people when they're
debugging programs.
Because you think it's
a float, when
in fact it's a string.
OK.
Nothing deep, but these are the
things that sort of get
people in trouble.
Now the kinds of programs we've
been looking at so far
are what are called straight
line programs.
What distinguishes a straight
line program is it's a
sequence of commands you execute
one after another.
You execute every command
without making any deviations,
without going back with any
loops to execute a command
more than once.
So in a straight line program,
every command gets executed
exactly once.
There is a very elegant, and
even useful theory that talks
about different layers of,
levels of complexity of
programs and says, for
example, what kind of
functions can you compute with
straight line programs.
We'll talk more about that
field, which is called
complexity theory, later
in this semester.
But for now, the thing to
realize is that straight line
programs are just dead boring.
You can't compute anything
interesting with one.
Last time we talked about
a recipe as an
analogy for a program.
Imagine a recipe
with no tests.
So every recipe, or almost
every recipe I
know, has some decisions.
Taste it and add salt
if you need it.
Or poke at the meat and
see if it's done.
Or cook it until the
thermometer says
some degree on it.
Those are the kinds of
tests we need to
make interesting programs.
The most primitive kind of test
we see is what's called a
conditional statement.
And those are written using the
word if, and optionally as
we'll see, the words else or
elif, standing for else, if.
So let's look at an
example here.
Where'd my mouse,
oh there it is.
Yes?
Somebody has a question?
Shout it out.
AUDIENCE: Sorry.
I was wondering, when the user's
prompted to put in the
raw input, instead of putting
in a float, puts in string,
could you define it as
a floating integer?
How would you interpret
that input?
PROFESSOR: I didn't
get the question.
So this is an argument to
raw input, or their
response to raw input.
AUDIENCE: So yeah, for the
raw input where you
define it as a quote--
PROFESSOR: Yeah.
AUDIENCE: It usually
puts in a string.
How does Python interpret
that?
PROFESSOR: It will interpret
it as a string containing
quotation marks.
AUDIENCE: OK.
PROFESSOR: So typically you
don't type a string, because
it interprets everything you
type as if it were a string.
So don't bother typing
strings.
Good question.
Thank you.
All right.
So let's look at this.
So here I'm going to get an
int, or at least a string.
I'll convert it to an int.
Then I'll say, if x remainder
two, that's what the percent
sign is, it's a remainder
or a mod operator,
is equal equal zero.
That's important.
You'll notice that we used an
equal sign to do assignments.
If we want to do a comparison,
whether two objects have the
same value, we don't write
a single equal.
We write a double equal.
So whenever you're testing for
equality of objects, you use
double equal.
So it says, if the object x mod
2 has the same value as
the object zero, print even.
Else, print odd.
And then, just for fun, I'm
going to see whether or not
it's divisible by three.
Why did I do that?
Just to show you that I can
nest conditionals inside
conditionals.
So in one of the branches of
the conditionals, I'm now
doing a test.
So what this does, is if comes
down, it does the test.
If the value of the test is
true, it executes the block of
code following the if, in
this case, just print.
And then it skips the else.
It does not execute the else.
So it executes one
or the other.
If the test is false, it skips
the block of code following
the if and executes the block
of code following the else.
So it does a or b,
but not both.
The indentation is important.
Python is very unusual in that
the way you indent things
actually affects the
meaning of them.
And you can tell that, if I
were to type this in the
editor, you'll note here it's
on that line, but if I hit
Return, it automatically
indents it.
That's the auto indent feature
I mentioned earlier in the
editor of IDLE.
And this tells me how these
things line up.
So the fact that this is here
tells me I execute it only as
part of the else clause.
The program would mean something
quite different if I
wrote this.
Then it would mean, if x mod
2 is zero, print even.
Otherwise, print odd.
And whether or not it was
even or odd, do this
test in the if statement.
So the indentation actually
affects the
meaning of the program.
Now a lot of other languages,
almost all other languages,
don't do that.
They have some punctuation.
For example, c uses set braces
to designate what's called a
block of code.
If you look, however, at a
well-written piece of C code,
or Java code, or any other
language that I know,
programmers are trained to use
indentation to show the
structure of the program.
Even though you don't need, it
you could line up everything
right at the left edge and
just use the punctuation.
People don't do that.
And the reason they don't do
that is programs are intended
to be read, not just executed.
Why are they intended
to be read?
Because the only reason, the
only way you can debug a
program is reading
the code in it.
Typically, you want to write
your program so that if you
look at it from a distance, the
visual structure of the
program reflects the semantics
of the program.
And that's why people use
indentation when they don't
need to, so that you can see the
structure of the program
by looking at it on your screen
and not having to parse
each symbol.
The authors of Python made what
I think is a very good
design decision.
They said, well, if that's the
way you ought to write your
programs, let's force people to
write their programs that
way and guarantee that the
visual structure of the
program actually matches
the semantic structure.
The problem with languages like
C and Java is that you
can indent things and fool the
reader of the program by
making it look like something is
under something else, when
in fact it really isn't, because
of the punctuation.
So here we have a guarantee
that the visual structure
matches the semantic structure,
and I think that
was one of the really good
design decisions in Python.
OK, people see that?
So we could execute
this program.
Let me get back to what
it was before.
Control z is the go back.
And now we can enter an integer,
say 14, and it will
tell us it's even.
I can run it again, and now I'll
put 15 in, and it will
tell me it's odd.
We'll try it once more.
We'll put in 17.
It was odd and it's not
divisible by three.
These kinds of programs are
called branching programs.
And that's because the structure
of them, as you go
down you execute some
statements, and then there's a
branch which says execute these
statements or execute
those statements.
And then typically it comes back
together and continues.
Of course, branches can
have sub-branches.
We could do this and then
join further down,
as we've seen here.
Now branching programs are much
more interesting than
straight line programs.
We can do a lot of things with
them, but fundamentally
nothing really interesting.
And we can think about that by
thinking about how long it
takes a branching
program to run.
So let's first ask the question,
how long does it
take a straight line
program to run?
14 seconds?
No, that's not the way
to think about it.
How would we think about how
long it takes it to run?
What governs the length
of time a straight
line program can take?
AUDIENCE: [INAUDIBLE].
PROFESSOR: Exactly.
The number of statements or
commands in the program.
Since it executes every command
exactly once, if you
have 100 command, it will
have 100 steps in it.
Now there's some variation on
how long each step will be.
Some commands might take longer
than others, but the
length of time it can take
to run has nothing
to do with its input.
It has to do only with the
number of lines of code.
And that tells us it's not very
useful because, well, we
can only type so many lines
in our lifetime.
Well branching programs
have the same problem.
In a branching program,
each command is
executed at most once.
So again, the length of time
it takes to execute the
program is governed strictly
by the size of the program.
Why isn't that good enough?
Well, think about a program,
say, to compute the GPA of all
the students at MIT.
Well how long is that
going to take?
Think instead about a program to
compute the GPA of all the
students at the University of
Michigan, which is probably 10
times bigger than MIT.
Well you would expect that
to take longer, right?
Because you have to look
at more students.
And in fact, it's true.
Most programs that are
interesting, the amount of
time they take to run should
depend not on the length of
the program, but on the size of
the data that you want to
evaluate using the program.
So you would argue that the
amount of time taken to
compute the GPA of the students
at MIT should be
proportional to the number of
students, not proportional to
the length of the program
used to do it.
We'll talk a lot more about that
later in the term in a
much more thorough way.
But it's important to get that
as something you think about.
So the fact that branching
programs are not proportional
in time to the input means that
they're limited in what
they can do.
So that gets us to the final
concept we need to write every
program that could ever be
written, or at least to
compute every function that
could ever be computed.
And that's some sort of
a looping construct.
Once we add loops, we get to a
class of programming languages
or programming constructs that's
called Turing Complete.
And I mentioned this
last time.
Any program that can be written,
or any function that
can be computed, rather, can
be computed in a Turing
Complete language.
So let's look at an
example here.
This concept, by the way,
is called iteration.
And if we look at languages with
iteration, what we'll see
is a more complicated
flow of control.
You execute some statements,
maybe you do some
branching if you want.
But then you're allowed to go
back and execute statements
you've already executed.
Typically what you have
is another branch.
One branch goes back
and one continues.
So now we see we can execute
a statement more than once.
Suddenly we have enormous
power at our disposal.
So let's look at an
example of that.
By the way, I'm skipping some
of the code in your handout,
but that's probably fine because
it's there for you to
be able to read.
And what I would recommend by
the way, is that we will post
the handouts on the web, but
at the end of every lecture
within a few hours or a few days
at least, go through the
handouts and make sure you
understand everything in.
Because if you don't, you're
probably missing something
you'll need to understand
to do the problem sets.
So here's a little program that
finds the cube root of a
perfect cube.
This, by the way, is a useful
comment here, right?
Tells you what the program
is intended to do.
So we get an integer.
We set the variable
ans to zero.
And then while ans times ans
times ans is less than the
absolute value of x,
we're going to set
ans to ans plus 1.
We could print where we are.
I put those sort of things in
as debugging statements.
If ans times ans times ans is
not equal to the absolute
value of x when I finish the
loop, then I'll print x is not
a perfect cube.
Otherwise I have to do something
to deal with
positive and negative values.
Now I know that this was fast
and that most of you probably
don't fully assimilate
this program.
Do not worry.
It will be discussed in
recitations tomorrow.
So tomorrow, the recitations
will review the Python
concepts we've discussed today,
but we'll start by
emphasizing how these
loops work.
OK.
Thanks for coming.
Enjoy recitation tomorrow.
