Lecture 1: Introduction to CS and Programming Using Python
By MIT OpenCourseWare
Summary
## Key takeaways - **Programming is a Skill, Not Just Observation**: Programming is a skill akin to math or reading; it requires consistent practice rather than passive observation to become second nature. [02:12] - **Imperative vs. Declarative Knowledge**: Computer science operates on imperative knowledge, which is a recipe or a 'how-to' guide, unlike declarative knowledge which is merely a statement of fact. [05:11] - **Computers Execute Algorithms, They Don't Decide**: Computers are machines that execute algorithms precisely as instructed; they are not inherently smart and do not make decisions independently. [09:16] - **Object Types Dictate Operations**: The type of an object in Python determines the operations that can be performed on it; for instance, you can add numbers but not divide strings. [22:11] - **Assignment is Not Equality**: In computer science, the equals sign represents an assignment statement, binding a name to a value, rather than an equality or a solve-for-x situation as in mathematics. [44:34] - **Line-by-Line Execution**: Programs are executed sequentially, line by line, from top to bottom, without inherent repetition or decision-making until specific control flow structures are introduced. [54:33]
Topics Covered
- Programming is a skill that demands practice.
- Programming is imperative: Computers need a recipe.
- Computers are dumb: They only follow instructions.
- Object types define what you can do.
- Variable assignment is not mathematical equality.
Full Transcript
[SQUEAKING] [RUSTLING] [CLICKING]
ANA BELL: All right, so welcome to the first lecture of 6.100L.
That's our new number.
My name is Ana Bell.
That's two separate names, first name Ana,
last name Bell-- super confusing.
But I've been a lecturer here in the EECS Department
for probably almost 10 years now.
And I've been doing the intro course for a while.
I'm really happy to be teaching this full semester version
of 6.100A.
So today what we're going to do is go over
a little bit of course administrative information,
and then we'll dive right into some thoughts
about computers, high level how they work.
And then we'll start going into some Python basics.
So we're going to get coding right away.
So I highly encourage you, since you're in this class,
to download the lecture slides beforehand,
to take notes, and run code when I do.
Some of the lectures are interactive.
And we'll have breaks, so there'll
be a place where you can take a break
to actually do some coding.
And that's important--
I call them "you try it" breaks.
That's important to make sure that you're actually
practicing what we are learning right at this time.
The main idea for lectures is, yes, I will do some teaching,
but there will also be opportunities
for questions and for you guys to try some programming
right on the spot.
Even if you don't finish writing a program
that we start talking about, I will finish it,
and we can all talk about it together.
And I'll show you some pitfalls and things like that.
There will be lots of opportunities
to practice in this class at various degrees of granularity.
And then there's also lots of opportunities
that I have in the handouts to do extra practice
at home and through a bunch of different resources as well.
The reason why I stress participation and practice is
because part of the reason you're here is you
want to learn how to program.
You don't know how to program yet.
And programming is actually a skill.
it's like math or reading.
It's something that you have to practice.
You can't just watch me type in a bunch of lines of code
And then when it comes time to do the quiz,
you automatically know how to do it.
You need to do it often, more and more so that it
becomes sort of second nature.
So the three big things you'll get out of this class are
knowledge of concepts, obviously--
we're going to learn some computer science ideas--
programming skill, and problem solving--
problem solving skills.
Lectures and exams basically help you
with your knowledge of-- test your knowledge of concepts
and help you get knowledge of concepts.
Finger exercises give you the programming skills.
And the problem sets help you with problem solving.
Basically, if you're given an English version of-- a problem
in English, how do you go from that
to thinking about what computer science concepts can I apply?
And then after that, how do I take those computer science
concepts and actually do the programming?
So what are some topics we'll be covering?
We will be, at the core of it, learning
computational thinking.
So in the future, when you encounter a problem,
your first thought shouldn't be, How do I mathematically
solve this? or, How do I brute force
or manually solve this problem?
How can I apply computation to help me solve this problem?
And throughout these lectures, you're
going to see some examples of us applying computation
to a problem you might have already seen and maybe
solved mathematically, which is pretty cool.
Obviously, to get that, we're going
to learn the Python programming language.
Once we get the basics, we're going
to see how we can start to structure our code
to look a little bit better so we don't just
have a bunch of code dumped in a file.
We're going to start to organize our code
and see how we can make it neat, readable, and modular.
And then towards the--
not in this lecture but in a couple of lectures
and as a theme throughout this class,
we're going to look at some algorithms.
They're not super complicated, but they're
kind of the base algorithms for a bunch of algorithms
you might see in the future if you
decide to take more CS classes.
Lastly, towards the end of the class,
we're going to see algorithmic complexity, which basically
means we're going to start asking or trying to answer
the question, how do we know the programs
we write are efficient?
We can write programs, but how do we know that they're fast,
and how do we know that they don't take up
all the memory in the computer?
So things like that, comparing different algorithms
that do the same thing against each other.
So if there's no questions--
again, as I said, a bunch of this information
is already in the handout plus more--
we can begin.
OK, so let's start by talking about knowledge.
Declarative knowledge is a statement of fact,
and a lot of us probably in math and in the past
have worked with declarative knowledge.
But this is not how computer science, this is not
how this class works.
In computer science what we do is we
work with imperative knowledge, which is basically a recipe,
how to do something.
And when we're programming, all we're doing
is writing a recipe for the computer to do something.
That's it.
So here's a numerical example.
The first statement is a declarative statement.
The square root of a number x is y such that y times y
is equal to x.
There are many possible values for x and y
that this statement can be true, right?
But if we gave that statement to a computer,
it wouldn't know what to do with it.
What we need to do is tell the computer
how to find the square root of a number
and then tell us what the square root of that number is.
And so the computer then needs a recipe.
So the recipe, a really simple one
for finding the square root of a number,
is steps one, two, three.
So what we do is-- let's say we want
to find the square root of 16.
We obviously know it's four, but the computer doesn't.
And so we give it an initial guess.
Let's say the guess is three.
How do we go from there?
So the steps we follow--
step one, if 3 times 3, 9, is close enough to 16,
we can stop.
It's not really close enough for me.
So let's keep going.
Step two-- otherwise, we're going
to make a new guess by averaging g,
which is our original guess, 3, and x
over g, which is 16 over 3.
16 was the square root we wanted to find.
So our next guess is 4.17.
OK, using the new guess, repeat the process
until we are close enough.
So we go back to step one.
That's the first part of the process.
We find guess squared.
4.17 squared is 17.36.
So now we say, is that close enough?
Not really.
It's not.
It's 17.
It's not really even close to 16.
So let's do it again.
We make a new guess by averaging 4.17 and 16 divided by 4.17.
That gives us our new guess, 4.0035.
OK, next step, using the new guess, we repeat the process.
So 4.0035 squared is 16.277--
.0277.
Is that close enough to x?
Yeah, I could be happy with this.
I could stop there because we're within sort of plus/minus 1.
So I'm OK with that.
But if we want it to be within plus or minus 1 times 10
to the negative 6 or 7 or something like that,
then we would continue the process.
So really what we had there is an algorithm.
It's a sequence of steps--
step one, step two, step three.
There's some sort of flow of control.
We had a place where we said if the guess is close enough,
then we can stop.
Otherwise, we do something else.
We had another flow of control where
we said repeat this thing.
So we're kind of not going linearly,
but we're changing the flow.
And then lastly is a way to stop.
We don't want the algorithm to go on forever.
We would like to stop at some point.
And this stopping point, I was kind of vague about it.
But it could be when we were within plus or minus 1
of the actual answer.
And so recipes are basically algorithms, right?
My grandmother was basically teaching algorithms
when she would teach me to bake a cake.
She didn't call it that, but she was really.
And so even recipes have that same structure.
There's a sequence of steps.
There's a flow of control.
Like, if you don't have egg, use egg substitute.
Or repeat sticking a toothpick to see
if it comes out clean every minute or something like that.
And then there's a way to stop.
When the toothpick comes out clean,
you take it out of the oven, and you eat it.
And so computers are machines that execute these algorithms.
They're actually dumb.
Computers are not very smart.
They don't make decisions on their own.
They just follow these sequences of steps
that we told them to do.
Computers are good at storing lots and lots of data.
We can't really do that, but computers
can store gigabytes of storage, terabytes even.
And computers can do operations really,
really quickly, which is something we can't do.
They're good at those two things,
but they're not very smart.
They can't make decisions unless they're
told to make the decisions.
So really, the computer only does what you tell it to do.
And that's one of the big ideas that I want you to come away
from this lecture with.
Computer only does what you tell it to do.
The sequences of steps that you tell it to do,
that's the only thing it follows.
So a little brief history just to make you appreciate
programming, Python programming language before we actually get
started with it is--
so before the 1940s, we had these things
called fixed program computers.
A pocket calculator as an example of that.
Every button was an operation.
In the little screen, you could use parentheses
to put a bunch of different operations together,
but there was no way to store all these operations together
to later put in different inputs for that same sequence
of operations.
You had to input it every single-- input those sequences
of operations every single time.
After the 1940s, stored programs computers came into play.
And they were able to store instructions to do things
as data.
And there was a special program called an interpreter that
executed these instructions.
It knew how to follow simple sequences of steps.
When the program told it to go to a different location,
it did.
So it was basically executing these instructions.
And the instructions that it did were arithmetic and logical,
so addition, subtraction, things like that;
simple tests like checking for equality between two values;
and moving data, so taking this value
and putting it at a different memory location.
So I just wanted to give you a really brief overview,
and this is not super accurate, but it gives you
a sense of how exactly things happen
low level in the computer.
So the computer basically has memory,
where things are stored.
It has an arithmetic logic unit that does operations.
It knows how to add things, subtract things, multiply
things, compare things.
And then it has the control unit, where
this program counter is set.
And this is where you put a program in.
So let's see if this works.
This is a program.
And up here is our memory.
So we have a bunch of memory locations, 3456, 3457.
And at each of these memory locations,
we have some values stored, prefilled.
So when we first run this program, what ends up happening
is that the interpreter sees the first instruction,
Add, the values at 3456 and 3457 together.
So it goes to these memory locations here,
grabs the 3 and the 4, and sends them
to the Arithmetic Logic Unit.
The ALU knows how to do the addition.
So it adds 3 plus 4, 7, and sends the result back here.
Now, we never told it to store that result anywhere.
But the next instruction says Store
the value you just got back from the ALU
at this memory location, 3458.
So the next step basically takes that 7
and stores it at memory location 3458.
Super tedious-- all we did was add 3 plus 4.
We do that again.
We add the values at 7889 and 7890.
So it goes in the memory.
It grabs the 5 and the 2, sends it to the ALU.
The ALU calculates it as 7, brings it back,
and then we store that in location 7891.
And then after that, all we've done is two additions.
And then the next instruction says Compare the values
at memory locations 3458 and 7891.
So we're going to compare the 7 with the 7.
The ALU again does this comparison and says,
all right, well, 7 and 7 are equivalent.
So this is true or whatever it wants to give back
to the interpreter.
And then the last instruction here we
have is Print the result of that comparison.
So we print True because they were equal.
Again, super high level, but it kind of
gives you an appreciation for programming languages
these days.
This is very tedious to write if we had to write programs
in this manner.
Alan Turing a long time ago showed
that you can compute anything with actually
an even more basic set of primitives,
not addition, subtraction.
But instead, with a tape, you would actually
have six primitives-- move the tape left, move the tape right,
read the value at the tape, put a value on the tape,
erase the value from the tape, and no operation.
And so since he showed this what the result of it actually was
is down here.
Anything computable in one language
is computable in any other programming language.
So if we had some program written in Java,
that basically boils down to something super
long but something that is made up of these six primitives.
That means that if we boil down this program to these six
primitives, we can build back up the same program
in a completely different language.
And that's really powerful.
That's a really cool statement.
Now, we're not going to be working with those primitives.
We're going to be using the Python primitives, which
are more convenient, and they allow
us to do a lot more things in much less time.
I'm going to do a little comparison
as we talk about the primitives of Python with English.
So in English, some of the primitives might be words
or even we can do letters or characters.
But we can say it's words.
With characters, we can build up words.
With words, we can build up sentences.
With sentences, we can build up stories.
With stories, we can build up books and things like that.
In programming languages, the primitives
are numbers, sequences of characters, operators
like addition, multiplication, division,
checking for equality, checking that something is greater
than, things like that.
So once we have these primitives in a language,
we can start to build up the syntax of the language.
So in English, having something like noun and noun and noun
doesn't make any sense.
Cat dog boy doesn't make much sense.
It's not syntactically valid.
But noun verb noun is syntactically valid.
Similarly, in programming languages,
we can have two objects kind of side by side.
So here, this is a sequence of characters h and i.
And this is the number 5 right beside that sequence
of characters.
But that doesn't make any sense, right?
What does it mean to have this sequence of characters
and that number right beside it?
It has no meaning in Python.
Instead, what we have to do is we
have to add an operator in between these two objects.
So here we add a little star operator
in between the sequence of characters "hi"
and the number 5.
And in Python, the meaning to this
is I want to repeat the sequence of characters "hi,"
h-i, five times.
So this would basically give me hi, hi, hi, hi, hi.
So once we have sentences in English
and expressions that are syntactically valid,
we can now talk about the static semantics of the language.
So in English, saying something like "I are hungry"
is syntactically correct, but it's not static--
it's not-- sorry, it doesn't have good static semantics.
There's no meaning-- there is no meaning to that because the
"are" is for you or plural.
Similarly, in programming languages,
and this will differ depending on what programming language
you use--
here, in the previous slide, we saw
that you can use the star operator between the sequence
of characters and the number.
And that meant repeat that sequence many times.
But if we use a plus operator in between the sequence
of characters and a number, that doesn't
have any meaning in Python.
So it has a static semantic error,
even though it's syntactically valid, right?
We have operator-- sorry, object operator object.
So, so far, we've been able to find really nice parallels
with English, the English language and the programming
languages.
But this is kind of where things break down,
when we talk about the semantics of a language.
So in English, you can have many different meanings.
The chicken is ready to eat means let's eat this chicken.
Or the chicken is ready to eat means the chicken wants
to eat something.
Programming languages, there is no multiple meanings
to a program that you write.
Because the computer, the machine,
the language follows the set of instructions to a T,
there is no ambiguity about what it needs to do.
It just follows the instructions and does
what it needs to do to the end, till it reaches the--
it terminates the program.
And so programs only have one meaning,
but the problem is it might not be the meaning
that you intended it to have.
And that's when things start to go wrong.
We can have syntactic errors in our program, spelling errors
and indentation errors, things like that.
And those are easy to catch.
Static semantic errors are 90% probably easy to catch.
But the problem comes in with the semantics.
The meaning that you intended this program to have
might not be what it's actually doing.
And that's where most of my errors happen.
And that's where I get super frustrated when I program.
And that's probably where you guys will get super frustrated
too because you write a program that you think
is doing one thing, but instead, either it crashes right away,
or it runs forever and doesn't really stop, or it terminates,
but it gives you an incorrect answer.
It's not what you were expecting.
And we'll talk about this in a few lectures.
So when we write programs, we're basically
writing sequences of definitions and commands.
And we're going to write these either in a file editor
or in a shell.
The first, today at least, we're writing in the shell directly.
And half of tomorrow, we'll write in the shell
because we're not really writing any--
we're not really writing many lines of code.
We're just going to be--
I'm just going to be showing you some really quick things
that we can do with the Python programming language.
So hopefully you all have installed the programming
environment.
This is the Code Editor.
So tomorrow, we'll start working in here.
But for today, we're really just going to work in the shell.
And even in the future, you can still
type commands in the shell.
I find the shell very useful if there's just something really
quick that I want to check, that I
don't want to write a program for and then run.
It's just like a simple command that I
want to check to make sure it's doing
what I think it's doing before I insert it in my code editor.
So here we have this.
So mine is--
I guess I'm using the white theme just because I find
it easier for you guys to see.
This is the file editor.
And this is just a bunch of expressions or--
yeah, a bunch of code that we're going to type in today.
And we're going to type it in the shell today, so the thing
on the right-hand side.
OK, so what exactly do we do when we write a program?
At the base of it, we are going to create
objects inside our programs, and we're going to manipulate them.
That's it.
That's what programming is mostly about at its core.
Now, when we create objects, it's
important-- this is kind of something
we're going to come back to again
and again in a more high-level setting.
But right now what I want you to understand
is that when we create an object, an object has a type.
And the type that an object has tells Python
the things you're allowed to do with that object.
So here are two examples.
The number 30, it's a number.
The type we'll talk about it in a bit.
The type is an integer.
It's a whole number.
But basically, what are the things
we can do with this integer, with this number?
We can add it to another number.
We can subtract it to another number.
We can take it to another power.
We can take some other number to this power of 30.
A bunch of mathematical operations,
as you would expect.
So that's pretty straightforward.
What about this one here, this quotation capital
A, lowercase a--
lowercase n, lowercase a quotation?
So this is something we'll talk about next lecture.
It's called a string.
And it's a sequence of characters.
The quotations tell Python it's a sequence of characters.
And the characters part of it are capital A, lowercase n,
and lowercase a.
The kinds of things I can do with this string
are not the same kinds of things I'm allowed
to do with the number, right?
If I tried to take Ana and divide it
by the sequence of characters Bob,
Python would complain very much because you
can't divide a string by another string,
a sequence of characters.
It doesn't make sense to divide it
by another sequence of characters.
Similarly, I can't take Ana to some power.
I can't multiply--
I can't multiply by itself, things like that.
But the kinds of things that I am allowed
to do on a sequence of characters
is different than the kinds of things
I'm allowed to do on a number.
So the things I can do with a sequence of characters
is I can say, well, what's the character
at the first position?
What's the middle character?
How long is the sequence of characters?
How many characters do I have?
And so now you can see that the type of the object
is actually really important.
Python uses it to know the kinds of operations
you're allowed to do with it.
And so there's actually scalar objects,
and these are Python's primitives, numbers
and truth values.
And there are nonscalar objects.
We're not talking about these yet.
We'll talk about these in a few lectures.
But these have some sort of structure.
So for example, a list of numbers
has a structure because there's a number at the beginning
of the list, there's a number at the end of the list,
things like that.
But a number itself doesn't have a structure.
It's just the number.
So what are the types of the scalar objects?
What are the types of the primitives in Python?
Integers, so number 5, 0, negative 100, 1 million.
Float is another type.
It represents all the real numbers, so 3.27.
2.0 is a float because it has a decimal number even
though to us that just means 2.
But to Python, if you put in 2.0,
it says that's a type float.
Negative 3.14159, things like that.
Bool is a Boolean.
It represents truth values.
And there's only two possible values that a Boolean type has,
True and False.
And it has to be capital T True and capital F False.
And the last one is this NoneType type.
It's literally called NoneType.
And it has only one special value, None.
We're not going to talk about it for a bit,
but we will sometime in the future.
So to figure out the type of an object
when you create that object, you use the type command.
So we can say something like type parentheses.
And this is a command.
And inside the parentheses, you say, what do you
want to find the type of?
So if we do type of 7, it tells me it's an int.
And if you want to do the same command again,
I hit the up arrow, and it automatically
puts in what I wrote previously.
And then if I want to do type of 0.0,
it's a float because there's a decimal point.
So this is basically what I said.
So we type this in the shell.
And the shell tells us what the output is.
So just to reiterate, int, float, bool,
and NoneType are types of objects.
And there can be many different objects
you can create of that type.
So if you think about it, ints and floats,
we basically have an infinite number
of objects we can create of those types
because we can have 0, 1, 2, 3, 100, 200, 300, 1 million,
and all the negatives.
There's almost an infinite number of values or objects
that we can create of type int and float.
But bool, there's only two, the truth values True or False.
And the NoneType, there's only one, this None.
So that's the type, and these are the possible values,
possible objects we can create.
You try it.
So you can just yell out the answers.
There's nothing to type unless you want to check yourself so
what is the type of 1234?
AUDIENCE: Int.
ANA BELL: Int.
Type of 8.99?
Float.
Type of 9.0?
Float.
Type of True?
Bool.
And type of False?
Bool.
Perfect.
If you ever wonder what the type of something is,
you type it in here.
You guys are doing well.
Type is bool.
Type of lowercase t true is an error,
just wanted to point that out just to reiterate the fact
that capitalization matters in Python.
This is our first error, by the way, guys.
Very exciting.
The error is a NameError, and this is
the message associated with it.
You also know that it's something special in Python
when you have color-coded stuff.
So you see capital T True, capital F False are
this dark blue here, whereas anything
that's not special in Python is just black.
So type is a special command.
This is a float, so you see they're color coded.
OK.
So once we create objects, one thing
we can do with these objects is to cast them
to a different type.
Now, this is a little bit maybe confusing
because we're not actually changing the object once we've
created it.
So once we create the integer 3, it's there in memory.
If we cast that integer to a float version of it,
we're creating a new object in memory.
We're not changing the 3.
The 3 already exists.
We're just getting the float version of it
and storing it as a new object in memory.
So when we do float 3, this is a command
that gets for me the float version of the integer 3.
So that will give me 3.0.
So for example, this is what I had, float 3.
The output is 3.0.
If I do int of 5.2, it truncates it,
and it gives me the integer portion of this float.
If I do int of 5.9, it still truncates it
and gives me the integer version of this float.
It doesn't round.
I'm just asking for the integer version of this float.
Some operations like round is an operation
we can do has an implicit cast in it.
So if I round 5.9, it's actually going to round it to 6.0
and then cast it to an integer.
So notice it doesn't give me as an output 6.0.
It then rounds it to just six.
So that's basically what I said in the example.
So let's have you try this.
What are the types of the following?
I don't need the values but the types.
So if I get type of float of 123, what is the type of that?
Float yeah exactly.
Yep.
What if I round 7.9?
What's the type of the result?
Int yep.
What if I create a float of the round of 7.2?
AUDIENCE: Float.
ANA BELL: Yes, good.
Float would be 7.0.
And the int of 7.2?
AUDIENCE: 7.
Int.
ANA BELL: Int, yes, exactly.
I want the type not the value.
And the int of 7.9 is an int, exactly.
Awesome good.
OK, so we've created a bunch of objects.
We know that we can create a bunch of objects
in our programs.
What do we do with them?
Well, we can combine them into expressions.
So let's say we have 3 plus 2.
I've got object, operator, object.
Cool, syntactically valid in Python
and has no static semantic error.
So if I do that in Python, it's going to be OK.
3 plus 2, 5.
And the type of 3 plus 2 is an integer.
So basically what I've done here,
I've put an expression within this type command.
And that's OK.
That's, in fact, encouraged in Python.
You don't just want to calculate and then stick in.
That would be very, very tedious.
So you can insert expressions in many, many different places.
So here we have 3 plus 2, 5 divided by 3.
Again, we've got 5 divided by 3 has this decimal value.
And the result has a float--
is of type float.
So the important thing to remember
when we're doing expressions is Python reads the expression,
but it does not store the expression in memory.
What it does is it reads the expression,
evaluates it to one single value,
and then it stores the result value in memory.
So it never stores the expression.
It evaluates the expression and then stores the value.
And so this is the syntax for an expression-- object, operator,
object, as we just saw.
And that's really-- and the idea I said before,
where Python stores values of expressions,
not the expressions themselves, is really, really important.
So this is my first big idea slide.
I decided to insert these because I
think they stress the importance of several concepts.
So I hope this is one.
So we're taking expressions.
They can be as complex as you'd like.
We can use parentheses, a bunch of-- it
doesn't just have to be object, operator, object.
It can be more complex than that.
But basically, however complex that expression
is, we evaluate it, and we replace it with one value.
And the expression can be something like this.
It doesn't just have to be something that's mathematical.
This was a mathematical expression,
but this is also an expression.
And it evaluates.
So this entire thing evaluates to this word, this word which
represents the type integer.
So here are some more examples.
3 plus 2, again.
We've got these examples with the parentheses,
4 plus 2 times 6 minus 1 obviously
gives us the number, 35.
And then we can insert expressions wherever we'd like.
So here I'm inserting that specific expression
in the type command.
And this is also an expression, like I just said.
And its result is int.
And similarly, we can also insert that expression here.
And then we can wrap that around cast.
And it gives us a float.
Yes?
AUDIENCE: So when you're inserting expressions
[INAUDIBLE] include the operators--
[INAUDIBLE] operators in?
ANA BELL: When you're inserting-- sorry,
when you're inserting what?
AUDIENCE: Well, since you said they're expressions,
and you said that you need like object, operator, object,
expression type.
What would be the operators in this case?
ANA BELL: Oh, I see.
AUDIENCE: How are they defined?
ANA BELL: Yeah, that's a good-- that's a good question.
So in this particular case, the type and the float are not--
there is no operator I guess in this particular case.
It's more like a command that gives us an output.
But there is still some--
there is still an output that it gives us.
So we can then take the result of this
and save it somewhere else.
Sorry, yeah, I guess the example I gave on the previous slide
was just an example of an expression
where we could do object, operator, object.
Yeah.
Yeah, so when we have these--
I guess it works for mathematical expressions.
Mathematical expressions work left to right, just
like in math.
Parentheses can override certain precedents.
If we have commands that have computations,
then we have this command with the parentheses.
And we evaluate what's inside the parentheses first.
So we work our way in to out in that particular case.
So here are some examples.
Let's have you try these.
So we can type these in our console.
What are the values of the following expressions?
So 13 minus 4 divided by 12 times 12.
So we can try that.
I don't know off the top of my head,
so we'll have to type it in.
0.0625 OK.
So the value of that expression is a float, right?
0.0625.
What's the value of the expression type 4 times 3?
AUDIENCE: Int.
ANA BELL: Int, yeah.
What about the type of the expression 4.0 times 3?
AUDIENCE: Float.
ANA BELL: Yes, exactly.
That's very good.
So type of 4 times 3 is int.
But 4.0 times 3 is a float.
Good.
And then what about int of a half or of 1 over 2?
AUDIENCE: So it's 0.
ANA BELL: Yeah, exactly, it's 0.
Yep, because it's 0.5, and we truncate to 0.
The reason I had this here is because it leads nicely
into this slide.
You don't have to memorize these rules.
You can always check it out in the console.
But there are some rules for the resulting
types when we do operations.
So when we do operations with numbers,
addition, subtraction, and multiplication always
yield an integer if both of the operators are integers.
If one is a float or both are floats,
then it gives me a float.
Division is different.
No matter what types you divide, you will always get a float.
Now what about this // and this percent?
These are actually useful operations.
They kind of go hand in hand with division.
So when I do 5 divided by 3, it's this 1.667.
// is basically a floor or getting the integer portion
of the division.
So 5//3 gives me one.
It truncates the fraction.
The percent gives me the remainder.
So 5%3 gives me the remainder when I divide 5 by 3.
So it's going to give me-- give it to me in a whole number.
So that's going to be 2 because there's 2 left over when
I divide 5 by 3.
So these are pretty useful operations,
the // and the percent, when we do mathematical programs.
The last thing is the ** is how we
denote power, exponentiation, kind of different
than you might be used to in math.
So 2 to the power of 3, 8.
2 to the power of 3.0, 8.0.
And the rules for integer division, percent,
and exponentiation are just like addition, subtraction,
multiplication.
If one is a float, then the result will be a float as well.
Yeah.
OK, and we talked about the type of output.
So I think I briefly mentioned this.
The operator precedence is exponentiation and then
multiplication, division, percent or remainder
at the next level, and then addition,
subtraction at the bottom.
But you can always override these using parentheses.
OK, questions so far before we move on?
Yes.
AUDIENCE: So why does division-- why does it always
result in float if you have 9 by 3
and that's [INAUDIBLE] why does it [INAUDIBLE]??
ANA BELL: Yeah, so the question is, why does it always
result in a float?
If it didn't, I think it would the operation itself would have
to do extra work to figure out whether it's a whole number
or not.
So I think it's just easier that it gives us always a float,
I guess.
Previous versions of Python, the / was actually,
I think, integer division, which is super counterintuitive
because you would use that in your program.
And then you would basically integer divide,
and things would go wrong.
But again, just a design choice on behalf of the programmers.
Other questions so far?
OK, so we have a lot of objects.
Objects have different types, again, floats, integers,
Booleans.
What can we do with them?
So far, they're kind of just sitting in there,
and we can get properties about them.
But what we'd like to do is write programs,
basically trying to automate some things
about these objects, manipulate them
to help us achieve a more complicated and interesting
program.
So what we can do to get to that end
is to start assigning names to some of these objects.
If I create an object for pi in my program to 20 decimal places
somehow, and I have that number in my program,
that float in my program--
if I want to use that number in many different places
in my program, I'd have to copy and paste
it a whole bunch of times so far, which is very tedious,
lots of errors will happen.
I don't want to do that.
So instead what I can do is I can give a name
to this ridiculously long value of pi called pi.
And then I can just use this name anywhere
I want to grab that ridiculously long value for pi
in my program.
It's a lot easier to read.
It's a lot easier for me to write this program.
And it leads to a really nice and neat program.
So what we can do is we can start
saying that the float 0.001 will be referenced by the name
"small" or the 100.4 will be referenced by the name "temp."
So what we want to do is create these things called variables.
And a variable is different in computer science
from a mathematical variable or variables
that you've known so far in math.
So math variables come back to the idea
of declarative knowledge, a declarative statement.
You can have something like a plus b is equal to b minus 1
in math, or x is equal to-- or x times x is equal to y,
and that's perfectly OK.
In math, we basically say that variable x represents
all the square roots of y.
That's not going to fly in computer science.
In computer science, we don't have--
we don't do declarative knowledge.
We do imperative knowledge.
And so what we're working with in computer science
is a bunch of assignment statements.
So what we can do in computer science
is we're going to basically bind a value to a variable.
So we're going to say this variable name is
bound to this value.
Every time I want to grab this value,
I'm going to invoke this variable name.
So here are some examples.
I've got a is equal to b plus 1.
The thing on the right-hand side will evaluate to some value
as long as I have something that b has a value for.
I've got here m is equal to 10.
So m is a variable.
Its value is 10.
I've got F is equal to m times 9.98.
So again, I have an expression on the right-hand side,
and that's OK.
I'm going to use the value of 10, so F's value will be 99.8.
Yeah.
AUDIENCE: Can you put it so that for F--
is it like this one value of m?
Or can you have it so it's going to be
whatever m assigned recently?
ANA BELL: Yeah.
The question is, can you have m whatever it recently is?
So in this particular case, I just have these two lines.
And m will be whatever 10 is.
But we'll see in a couple lectures that we can write
a loop where you change m.
And then every time you change m, you immediately calculate F.
And then it'll calculate F based on the new value of m.
But if we just have these two lines, that's all there is.
It just uses 10.
Was there another question?
So in computer science, you have only one variable
to the left of this equal sign, called the assignment operator.
And you have a value to the right-hand side
of the equal sign, the assignment operator.
So one variable basically maps to or binds to one value.
So the equal sign is an assignment statement.
It's not equality.
It's not a solve for x type of situation.
It's just an assignment.
It binds this name to this value.
So the way that we figure out the name with the value
is, well, if we have this assignment statement here,
we first look at the right-hand side.
So we always start with the right-hand side.
And we evaluate it.
Remember, we have an expression on the right.
We have to evaluate it to one value.
So this will be 3.14, whatever it is, 1.159.
And then we take that value and bind it to the name pi.
So anytime I type in p-i, "pi," in my program from now on,
Python will automatically grab 3.14159 from memory.
So it's bound to that value now.
OK, there are some rules.
Did I have them on the previous one?
Yes, there are some rules to variable names,
but we'll talk about that in a bit.
For now, I want you to tell me if any of the following
are allowed.
If I do x is equal to 6, is that allowed in Python?
AUDIENCE: Yes.
ANA BELL: Yes, it is.
Good.
Because I have one variable name bound to one value, 6.
What about 6 equals x?
It's just backward.
AUDIENCE: No.
ANA BELL: OK, good.
6 equals x is bad, syntax error.
How about x times y equals 3 plus 4?
AUDIENCE: No.
ANA BELL: No, exactly, because the thing on the left
has an operator in it.
And operators are special.
So it can't have-- you can't have a variable with that *
as a name.
How about xy equals 3 plus 4?
AUDIENCE: Yes.
ANA BELL: Allowed, yes, exactly.
I was hoping to get you guys with that, but I didn't.
Xy equals 3 plus 4 is OK.
There was no error.
And then I can invoke the name of the variable I just
created simply by typing it in.
So if I type in xy, it gives me 7.
And then I can do operations with it, xy plus 1 is 8.
Yeah.
AUDIENCE: Before you were putting the strings
with apostrophes.
So wouldn't you need that?
ANA BELL: So those are strings, right, sequences of characters.
Here, these are variables.
So these are names that I am giving as a variable.
Yeah, that's a great question.
So this is going to be a string.
And you notice it changed color.
It has some meaning in Python.
But xy is a variable that I create.
OK, so why do we want to give names to variables?
Because as I showed you with the pi example,
it's a lot easier to write readable code
if you have variable names within your programs.
So when you grab--
when you write programs, it's important to choose
variable names wisely.
You don't want to use just single letters.
You don't want to name it something
that doesn't have something to do with the program you're
writing, because you're going to want
to reread these programs sometime in the future.
Or others might want to read your programs sometime
in the future.
So here's an example of a nice program.
It's just basically four assignment statements
that do some calculations.
The first line of the program is not really a line.
It's called a comment.
You can have as many of these as you like.
They start with a hash.
It's a line that starts with a hash.
And it's basically a text that you
write that helps you or others figure out what
the code is supposed to do.
And usually we comment large chunks of code at a time,
not line by line.
Then we have these four assignment statements.
So here I'm defining variable named pi bound to the value
here, so not the division but 3.14159.
Variable named radius bound to this float 2.2.
And then I have a variable named area
which is bound to the result of this expression.
So when Python sees my pi and my radius,
it grabs them from memory, replaces them with the values,
evaluates the expression, grabs that one
value that we evaluated to 15-point-something, whatever
this is, and binds the 15-point-something to the name
area.
Same with circumference.
Code style is something that we're actually
going to look at in your problem sets.
So I just wanted to quickly talk about that.
Here is a program that has really bad style.
Actually, that shouldn't be meh.
It should be terrible or something like that.
But in case you haven't noticed, it's
the same program as on the previous slide.
But if I gave you this program straight off the bat,
you probably wouldn't know what it's doing.
It's reusing 355 over 113 twice here.
It's using just a and c as variable names.
Its description is "do calculations."
So pretty bad.
This is a little bit better.
I've recognized that 355 over 113 is being used twice.
So I'm saving it as a variable.
But my variables are still single characters.
And my comments are pretty bad.
I'm basically saying what the code is doing.
Please don't do that.
We can see that a equals p times r times r.
I see that I'm multiplying p with r squared.
I don't need to read that in English.
What I would like to see is a comment like this.
Here I'm commenting a chunk of code.
And someone who doesn't want to read this chunk of code
just reads the comment, and I already
know that I'm calculating the area and circumference using
an approximation for pi.
That's a pretty nice comment there and good descriptive
names and all that.
So we can actually-- once we create an object,
a variable-- sorry, once we create an object and bind it
to a variable, we can change the bindings.
So we can take that variable name
and bind it to a completely different value.
This might not be useful right now,
but it will be useful when we introduce
control flow in our programs.
So to rebind a variable what that means is
we're going to take the name, we're
going to lose the binding to the previous value,
and we're going to rebind it to a new value.
So I'm going to show you how this looks like in memory.
I'm going to use this sort of cloud picture
to represent what happens behind the scenes
whenever we write programs.
And it's like a little animation to help you understand line
by line what's going on.
So here we have pi equals 3.14.
So the green 3.14 is my value in memory.
Cloud is memory.
That's my value in memory.
And it's bound to this name pi.
So this is my variable name.
The next line, radius equals 2.2, same thing.
I've got 2.2 as my value in memory, my object.
And radius is the name for that object.
Area equals pi times radius squared.
So what happens behind the scenes
is it calculates this value.
It doesn't store the expression.
It stores the value resulting from the calculation,
and then it saves it--
or binds it to the name area.
OK, everything OK so far?
We've seen this code before.
Cool.
So now what happens when we do this,
radius equals radius plus 1?
In math, that would say 0 equals 1.
But we're not in math here.
We're in computer science, and this is perfectly valid.
We're following the rule when we have an assignment that
says look at the right-hand side first and evaluate it
and then bind it to the left-hand side.
So if we look at the right-hand side first, we see radius.
Well, what's the value?
2.2.
We see add 1 to it, 3.2.
Save that in memory.
And then we see the assignment.
Now save it with the name radius.
OK, so we can only have one variable assigned
to one value at a time.
This is not math.
This is computer science.
So you can only have radius point to one thing at a time.
With this line of code, radius equals radius plus 1.
We've lost the binding to 2.2, this object in memory,
and we've rebound it to the value 3.2.
And that's perfectly fine.
2.2 is now just sitting in memory.
We can't get back to it unless we say maybe radius equals 2.2.
It just sits in memory and then might
be collected later on by-- or reclaimed
by garbage collection or something like that.
But for now, we can't get back to it.
Now, what's the value for area at the end of these lines?
Well, according to this, it's 15.1976.
So it's using the old 2.2 value for radius.
And that's OK because the program never told--
never had a line that said recalculate area
after we changed the radius.
It's just following, dumb, line by line.
It doesn't know that, hey, if I change the radius,
the user might want the area changed.
It doesn't make those connections.
It's just following instructions.
And that's OK.
If we want it to change the area,
we would have to copy this line and paste it
after we've changed the radius.
And then the area would change as well.
Does that make sense?
That's kind of an important part of this lecture.
OK cool.
So big idea here is our lines are evaluated one
after the other.
We're not skipping.
We're not repeating things.
That's something we're going to learn about later.
But for now, line by line.
So here's a little you try it.
These three lines are executed in order.
What are the values for meters and feet
variables at each line?
So how about at the first line, what's the value for meters
after we execute the first line?
100.
What about feet?
So at the end of the first line, there is no value for feet yet.
How about after the second line?
328.08.
Right?
How about the value for meters?
AUDIENCE: 100.
ANA BELL: 100 still.
And what about after the third line?
I'm changing meters to 200.
Exactly yeah.
Meters is 200, but feet is still 328.08.
And this is something I want to show you guys today.
And we're going to use this Python
Tutor a lot more in the future.
Python Tutor is a nice website that allows
you to step in your code--
step through your code step by step.
So at each line that you execute,
you get to see the values of all the variables in the code.
It's a very useful debugging tool.
I hope you'll try it out today and on Monday, maybe,
for the finger exercises if you're having trouble.
And you can use it for quizzes to help you debug.
But I can just show you.
It's pretty simple here because it's just a step by step.
So we step through.
So the red says the line I'm going to execute.
Green is the line I just executed.
So I just executed meters 100.
So here I have my meters variable with the value 100.
Step through next.
So I just executed feet equals this.
So I now have a variable named feet with a value 328.08.
Meters still 100.
And then meters 200, feet remained 328.08.
So obviously, this is a pretty simple program
to run the Python Tutor on, but you
can imagine using it in more complex settings.
How about one more?
And this is my last example.
I want you to try to write a program that
swaps the values of x and y.
So originally-- and I'll draw this,
the memory diagram real quick.
So we have-- this is our memory.
We have x is bound to 1.
Y is bound to 2.
And what I want to do without saying x equals 2,
y equals 1, what I want to do is swap the values.
I want x to be associated with 2 and y to be associated with 1
but only using commands like this.
And so the code here is buggy.
That means it's wrong.
It has an error in it.
Well, let's step through-- let's step
through a little bit at a time.
Y equals x.
What do I do when y equals x here?
Yeah, exactly, y is going to move from 2 to 1.
Now, what happens when I do x equals y?
Yes, x stays the same.
My first line, y equals x, lost the binding to 2.
And now it's all messed up because I can't get it back.
So instead-- so if you didn't understand this,
you can click Python Tutor and just step through step
by step on your own.
But how can we fix this?
AUDIENCE: Create a third variable.
ANA BELL: Create a third variable?
Yeah, that's a great idea.
Yeah, we can create a third variable.
So x is 1, y is 1--
y is 2.
So we can create a third variable.
What do you want to make the variable equal to?
X or y?
Yeah, either one.
I made it y, so let's do y.
So here I've got a temporary variable called "temp,"
and I made it equal to 2.
And now what can I do?
Which one can I reassign now?
X equals y, or y equals x?
Exactly, y equals-- if I do x equals y,
I lose my binding to 1, and it messed up again.
So y equals x is OK to do.
So I'm going to lose the binding from y from 2
and bind it up to 1.
And now what do I do?
Yeah, now I can safely reassign x to temp.
So I can say x is equal to temp because temp points to 2.
And I want to make x point to 2 as well.
So in terms of code, that's sort of the diagram.
But we can write the code.
So you don't-- let's see.
We don't write it in here, but on your own,
you can write it in here if you'd like.
Or we can do it together.
So x is equal--
oops.
X equals 1, y equals 2.
And then we had temp.
We wanted to assign it to whatever y was.
So we say temp is equal to y.
And if you want to check the values of the variables,
you can just invoke the names.
So x is 1, y is 2, and temp should be whatever y is, 2.
OK, good so far.
So now I'm at the step here, I think, right?
I've just created this.
And then the last thing I need to do
is lose the binding from x to whatever temp is.
So I want to do this operation here,
which means I want to assign x to be equal to temp.
So now x is 2, y is 1.
What did I do?
Yeah, so this happens sometimes.
We can just start all over.
So y equals temp.
Sorry.
Temp equals y.
Y equals x.
Y is one.
X is 1.
And then x equals temp.
Y is one, x is 2.
So it's OK if things go wrong.
They will go wrong.
We can just start all over in this particular case
by redefining our variables and just
trying it out all over again.
So that's kind of what the shell is for.
That's what I use it for.
That's what we're going to use it for in the future,
just to do quick things like this and also things
like checking the types and other commands we've
done earlier.
OK, so any questions before we do the summary?
Was this all right pace or was it too fast?
Or it was OK?
OK good.
Thumbs up is good.
So let's do a quick summary.
We saw that we can create programs
by manipulating objects.
We created objects in Python.
And we saw that objects have a particular type.
The type that the object has tells Python the things
that you can do with that object.
We can combine objects in expressions.
And these expressions evaluate or boil down
to one particular value.
Objects or values can be stored in variables.
And these variables allow us to access these values
with nicer names later on in our program.
And then we're able to write neater, more legible programs
as well.
So the equal sign--
I showed you a couple of differences between math
and computer science.
The equal sign was one notable difference.
The equal sign in math is declarative,
and the equal sign in computer science is an assignment.
You're basically saying this is associated with this.
And we're not doing any sort of equality in computer science.
And yes, computers do what you tell them to do.
That's kind of the big thing here.
Line by line, it executes starting from the top,
goes line by line.
So far, we haven't seen any places where
the computer makes a decision.
But next lecture, we will see how
we can insert decision points in our programs
for the computer to either execute one set of code
or another set of code.
All right, so that's the end of today's lecture.
Thank you all for joining.
I will see you on Monday.
Loading video analysis...