Placeholder Image

Subtitles section Play video

  • 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: Hello, and welcome to 6.01.

  • I'm Denny Freeman.

  • I'm the lecturer.

  • One thing you should know about today is that there's a

  • single hand-out.

  • You should have picked it up on your way in.

  • It's available at either of the two doors.

  • What I want to do today in this first lecture is mostly

  • focus on content.

  • But before I do that, since 6.01 is a little bit of an

  • unusual course, I want to give you a little bit of an

  • overview and tell you a little bit about the administration

  • of the course.

  • 6.01 is mostly about modes of reasoning.

  • What we would like you to get out of this course is ways to

  • think about engineering.

  • We want to talk about how do you design, how do you build,

  • how do you construct, how do you debug complicated systems?

  • That's what engineers do, and we're very good at it.

  • And we want to make you very good at it.

  • We're very good at it.

  • And you know that from your common, everyday experience.

  • Laptops are incredible.

  • As we go through the course, you're going to see that

  • laptops incorporate things from the tiniest, tiniest

  • level, things so small that you can't see them.

  • They're microscopic.

  • The individual transistors are not things that you can see.

  • We develop special tools for you even to be able to

  • visualize them.

  • And yet, we conglomerate billions of them into a system

  • that works relatively reliably.

  • Now, I realize I'm going out on a limb because when you say

  • things like that, then things always fail.

  • But I'll go out on a limb and say, for the most part, the

  • systems we construct are very reliable.

  • We'd like you to know how you think about making such a

  • complicated system and making it reliable.

  • We want to tell you about how you would model things.

  • How do you gain insight?

  • How do you get predictability?

  • How do you figure out how something will work before

  • you've built it?

  • If you're limited to trying out how things work by

  • actually constructing it, you spend a lot of time

  • constructing things that never make it.

  • We want to avoid that by -- where we can --

  • making a model, analyzing the model, making a prediction

  • from the model, and using that prediction to build a better

  • system on the first try.

  • We want to tell you about how to augment the physical

  • behavior of a system by putting computation in it.

  • That's a very powerful technique that is increasingly

  • common in anything from a microwave to a refrigerator.

  • We'd like you to know the principles

  • by which to do that.

  • And we'd like you to be able to build systems that are

  • robust to failure.

  • That's a newer idea.

  • It's something that people are very good at.

  • If we try to do something, and we make a mistake, we

  • know how to fix it.

  • And often, the fix works.

  • We're less good at doing that in constructing artificial

  • systems, in engineering systems.

  • And we'd like to talk about principles by

  • which we can do that.

  • So the goal of 6.01 is, then, really to convey a distinct

  • perspective about how we engineer systems.

  • Now, having said that, this is not a philosophy course.

  • We are not going to make lists of things to do if you want it

  • to be robust.

  • We're going to learn to do things by

  • actually making systems.

  • This is an introductory engineering course.

  • And so you're going to build things.

  • The idea is going to be that in constructing those things,

  • we've written the exercises so that some of those important

  • themes become transparent.

  • So the idea is -- this is introductory engineering.

  • You'll all make things.

  • You'll all get things to work, and in the process of doing

  • that, learn something about the bigger view of how quality

  • engineering happens.

  • So despite the fact that we're really about modes of

  • reasoning, that will be grounded in content.

  • We selected the content very broadly from across EECS.

  • EECS is an enormous endeavor.

  • We can't possibly introduce everything

  • about EECS in one subject.

  • That's ridiculous.

  • However, we wanted to give you a variety.

  • We wanted to give you a sense of the variety of tasks that

  • you can use, that you can apply the same techniques to.

  • So we want to introduce modes of reasoning, and then show

  • you explicitly how you can use those modes of reasoning in a

  • variety of contexts.

  • So we've chosen four, and we've organized the course

  • around four modules.

  • First module is software engineering, then signals and

  • systems, then circuits, then probability and planning.

  • Even so, even having chosen just four out of the vast

  • number of things we could have chosen, there's no way we can

  • tell you adequately--

  • we can't give you an adequate introduction to any of those

  • things either.

  • What we've chosen to do instead is focus on key

  • concepts represented by the asterisks.

  • The idea is going to be we choose one or two things and

  • really focus on those deeply so you get a thorough

  • understanding not only of how that fits within, for example,

  • the context of software engineering, but also how that

  • concept ramifies into other areas.

  • Notice that I tried to choose the stars so they

  • hit multiple circles.

  • That's what we're trying to do.

  • We're trying to not only introduce an idea to you, but

  • also show you how it connects to other ideas.

  • So the idea, then, is to focus on a few, we hope, very

  • well-chosen applications that will demonstrate a variety of

  • powerful techniques.

  • Our mantra, the way we intend to go about teaching this

  • stuff, is practice, theory, practice.

  • There's an enormous educational

  • literature that says--

  • whether you like it or not--

  • people learn better when they're doing things.

  • You have a lot of experience with that.

  • You have a lot of experience on the other side, too.

  • I'll try to forget the other side, or at least try to wipe

  • it from your brain momentarily to focus on your more

  • fundamental modes of learning.

  • When you were a kid and you were learning your first

  • language, you didn't learn all the rules of grammar first.

  • You didn't learn all the letters of the alphabet first.

  • You didn't learn about conjugating verbs first.

  • You learned a little bit about language.

  • You started to use it.

  • You ran into problems.

  • You learned a little more about language.

  • You learned to go from words like "feed me" to higher level

  • concepts, like "Hey, what's for dinner?"

  • So the idea is that you learned it in an iterative

  • process where you learned some stuff, tried it out, learned

  • some more stuff, tried it out.

  • And it built up.

  • There's an enormous literature in education that says that's

  • exactly how we always learn everything.

  • And so that's the way this course is focused.

  • What we will do is, for example, for today, we'll

  • learn a little bit about software engineering.

  • Then, we'll do two lab sessions where you actually

  • try to use the things we talk about.

  • Then, we'll come back to lecture and we'll have some

  • more theory about how you would do programming.

  • And then, you go back to the lab and do some more stuff.

  • And the hope is that by this tangible context, you'll have

  • a deeper appreciation of the ideas that

  • we're trying to convey.

  • So let me tell you a little bit about the four modules

  • that we've chosen.

  • The course is going to be organized on four modules.

  • Each module will take about one fourth of the course.

  • First thing we'll look at is software engineering.

  • As I said, we don't have time to focus on, or even survey,

  • all of the big ideas in software engineering.

  • It's far too big.

  • So we're going to focus narrowly on one or two things.

  • We'd like you to know about abstraction and modularity

  • because that's such an important idea in the

  • construction of big systems.

  • So that's going to be our focus.

  • In today's lecture, we'll begin talking about modularity

  • and abstraction at the small scale.

  • How does it affect the things you type as

  • instructions to a computer?

  • But by next week, we're going to be talking about a whole

  • bigger scale.

  • By next week, we're going to talk about constructing

  • software modules at a much higher level.

  • In particular, we'll talk about something that we'll

  • call a state machine.

  • A state machine is a thing that works in steps.

  • On every step, the state machine gets a new input.

  • Then, based on that input and its memory of what's come

  • before, the state machine decides to do something.

  • It generates an output.

  • And then, the process repeats.

  • We will see that that kind of an abstraction --

  • state machines --

  • there's a way to think about state machines that is

  • compositional that you can think of as a hierarchy, just

  • as you can think of low-level hierarchies within a language.

  • I'll say a lot more about that today.

  • So the idea will be that once you've composed a state

  • machine, you'll be able to join two state machines and

  • have its behavior look just like one state machine.

  • That's a way to get a more complicated behavior by

  • constructing two simpler behaviors.

  • That's what we want.

  • We want to learn tools that let us compose complex

  • behaviors out of simple behaviors.

  • And the tangible model of that will be the robot.

  • We will see how to write a program that controls a robot

  • as a state machine.

  • That's certainly not the only way you could control a robot.

  • And it's probably not the way you would first think of it if

  • you took one course in programming and somebody said

  • to you, go program the robot to do something.

  • What we will see is that it's a very powerful way to think

  • about it for exactly this reason of modularity.

  • The bigger point that we will make in thinking about this

  • first module is the idea of, how do you

  • make systems modular?

  • How do you use abstraction to simplify the design task?

  • And in particular, we will focus on something

  • that we'll call PCAP.

  • When you think about a system, we will always think about it

  • in terms of, what are the primitives?

  • How do you combine them?

  • How do you abstract a bigger behavior from

  • those smaller behaviors?

  • And what are the patterns that are important to capture?

  • So the bigger point is this idea of PCAP, which we will

  • then revisit in every subsequent module.

  • OK, second module is on signals and systems.

  • That's also an enormous area.

  • So we only have time to do one thing.

  • The thing that we will do is we will think about discrete

  • time feedback.

  • How do you make a system that's cognizant of what it's

  • done so that it, in the future, can do things with

  • awareness of how it got there?

  • A good example is robotic steering.

  • So the idea is going to be, OK, think about what you do

  • when you're driving a car.

  • And think about how you would tell a robot to

  • do that same thing.

  • Here's a naive driving algorithm.

  • I don't recommend it, but it's widely used in Boston,

  • apparently.

  • [LAUGHTER]

  • I find myself to the right of where I would like to be.

  • So what should I do?

  • Turn left.

  • I'm still to the right of where I'd like to be.

  • What should I do?

  • Turn left.

  • Oh!

  • I'm exactly where I should be.

  • What should I do?

  • Go straight ahead.

  • Oh, that's a bad idea.

  • And what we'll see is that perfectly innocent looking

  • algorithms can have horrendous performance.

  • What we'll do is try to make an abstraction of that.

  • We'll try to make a model.

  • We'll try to capture that in math so that we don't need to

  • build it to see the bad behavior.

  • We'll make a model.

  • We'll use the model to predict that that algorithm stinks.

  • But more importantly, we'll use the model to figure out an

  • algorithm that'll work better.

  • In fact, we'll even be able to come up with bounds on how

  • well such a controller could possibly work.

  • So the focus in this module is going to be, how do you make a

  • model to predict behavior?

  • How do you analyze the model so that you can design a

  • better system?

  • And then, how do you use the model and the analysis to make

  • a well-behaved system?

  • The third module is on circuits.

  • Again, circuits is huge.

  • We don't have time to talk about all of circuits.

  • We'll do very simple things.

  • We'll focus our attention on how you would add a sensory

  • capability to an already complicated system.

  • The idea is going to be to start with a robot--

  • I guess this is brighter--

  • start with our robots and design a head for the robot.

  • The robot comes from the factory with sonar sensors.

  • The sonar sensors are these things.

  • There's eight of them.

  • They tell you how far away something that reflects the

  • ultrasonic wave is.

  • As they come from the factory, the robots can't sense light.

  • What you'll do is add light sensors.

  • The goal is to make a system to modify the robot so that

  • the robot tracks light.

  • That's a very simple goal.

  • And the way we'll that is to augment the robot with a

  • simple sensor here, showed a little more magnified here.

  • The idea is that this is a LEGO motor.

  • The LEGO motor will turn this relative to the attachment.

  • That's the robot head's neck.

  • So the robot will be able to do this.

  • And the robot will have eyes.

  • These are photosensors, photoresistors, actually.

  • So the idea is going to be that there's information

  • available in those sensors for figuring out where light is so

  • that you can track it.

  • Your job will be to build a circuit--

  • that that's this thing--

  • that connects via cables--

  • these red cables and yellow cables--

  • connects via cables over to this head.

  • We'll give you the head.

  • Your job will be to make the circuit that converts the

  • signal from the photoresistor--

  • which is in proportion to light--

  • and figures out how to turn the motor to get the head to

  • face the light and then ship that information down to the

  • robot to let the robot turn its wheels to get the body.

  • So it's kind of like the light comes on bright over here.

  • The robot looks at it and says, oh, yeah, that's where I

  • want to be.

  • So that's the idea in the third module is to incorporate

  • new sensing capabilities into the robot.

  • The final module is on probability and planning.

  • And the idea there is to learn about how you make systems

  • that are robust to uncertainty and that can implement

  • complicated plans, that they, too, are robust to

  • uncertainty.

  • So there's a number of things that we will do, including

  • creating maps of spaces that the robot doesn't understand,

  • telling the robot how to localize itself, how if it

  • woke up suddenly in an environment, it could figure

  • out where it is, how to make a plan.

  • And as an example, I'll show you the kind of system that we

  • will construct.

  • Here, the idea is that we have a robot.

  • The robot knows where it is.

  • Imagine there's a GPS in it.

  • There isn't, but imagine there is.

  • So the robot knows where it is, and it knows where it

  • wants to go.

  • That's the star.

  • But it has no idea what kind of obstacles are in the way.

  • So if you were a robotic driver in Boston, you know

  • that you started out at home and you want to end up in MIT.

  • But there's these annoying obstacles, they're called

  • people, that you should, in principle at least, miss.

  • So that's kind of the idea.

  • So I know where I am.

  • I'm the robot.

  • I know where I am.

  • I know where I want to be.

  • And I'm going to summarize that information here.

  • Where I am is purple.

  • Where I want to be is gold.

  • And I have a plan.

  • That's blue.

  • My plan's very simple.

  • I don't know anything about anything other than I'm in

  • Waltham and I want to go to Cambridge.

  • So blast east.

  • So I imagine that the best way to do there

  • is a straight line.

  • OK, so now what I'm going to do is turn on the robot.

  • The robot has now made one step.

  • And I told you before about these sonar sensors.

  • From the sonar sensors, the robot has learned now that

  • there seems to be something reflecting at each of these

  • black dots.

  • It got a reflection from the black dots,

  • from the sonar sensors.

  • That means there's probably a wall there, or a person, or

  • something that, in principle, I should avoid.

  • And the red dots represent, OK, the obstacle is so close I

  • really can't get there.

  • So I'm excluded from the red spots because I'm too big.

  • The black spots seem to be an obstacle.

  • The red spots seem to be where I can't fit.

  • I still want to go from the where I am, purple, to where I

  • want to be, gold.

  • So what I do is I compute the new plan.

  • OK then, I start to take a step along that plan.

  • And as I'm stepping along, OK, so now, I think that I can't

  • go from where I started over to here.

  • I have to go around this wall that I

  • didn't know about initially.

  • So now I just start driving.

  • And it looks fine, right?

  • I'm getting there, right?

  • Now, I know I can go straight down here.

  • Oh, wait a minute.

  • There's another wall.

  • OK, what do I do now?

  • So as the robot goes along, it didn't know when it started

  • what kinds of obstacles it would encounter.

  • But as it's driving, it learned.

  • Oh, that didn't work.

  • Start over!

  • So the idea is that this robot is executing a very

  • complicated plan.

  • The plan has, in fact, many sub-plans.

  • And the sub-plans all involve uncertainty.

  • It didn't know where the walls were when it started.

  • And when it's all done, it's going to have figured out

  • where the walls were and--

  • provided there's a way--

  • presumably find the way to negotiate the maze and get to

  • the destination.

  • So the idea, then, is that if you were asked to write a

  • conventional kind of program for solving that, it might be

  • kind of hard because of the number of

  • contingencies involved.

  • What we will do is break down the problem and figure out

  • simple and elegant ways to deal not only with

  • uncertainty, but how do you make complex plans.

  • So as I said, our primary pedagogy is going to be

  • practice, theory, practice.

  • And so that ramifies in how the course is organized.

  • So this is a quick map of some of the aspects of the course.

  • So we'll have weekly lectures.

  • It's lecture unintensive.

  • In total, there's only 13 lectures.

  • We'll meet once a week here for lecture.

  • There's readings.

  • There's voluminous readings.

  • There's readings about every topic that we will talk about.

  • And the readings were specifically

  • designed for this course.

  • I highly recommend that you become

  • familiar with the readings.

  • If you have a question after lecture, it's probably there.

  • It's probably explained.

  • We will do online tutor problems.

  • We sent you an email if you pre-registered for the course.

  • So you may already know about this.

  • The idea is going to be that there's ways that you can

  • prepare for the course by doing computer exercises.

  • And we will also use those same kinds of exercises in all

  • of the class sessions.

  • We will have two kinds of lab experiences.

  • Besides lecture, the other two events that you have to attend

  • are a software lab and a design lab.

  • That's the practice part.

  • So after you learned a little bit about the theory by going

  • to lecture, by doing the reading, then you go to the

  • lab and try some things out.

  • We call the first lab a software lab.

  • It's a short lab.

  • It's an hour and a half.

  • You work individually.

  • You try things out.

  • You write little programs.

  • The courseware can check the program to see if it's OK.

  • And primarily, the exercises in the software lab are due

  • during the software lab.

  • But on occasion, there will be extra things due

  • a day or two later.

  • The due dates are very clearly written

  • in the tutor exercises.

  • Once a week, there's a design lab.

  • That's a three hour session in which you work with a partner.

  • The reason for the partner is that the intent--

  • the difference between the design labs and the software

  • labs is that the design labs ask you to solve slightly more

  • open-ended questions, the kind of question that you might

  • have no clue what we're asking.

  • Open-ended, the kind of thing that you will be asked to do

  • after you graduate.

  • Design the system.

  • What do you mean, design the system?

  • So the idea is that working with a partner will give you a

  • second, immediate source of help and a little more

  • confidence if neither of you knows the solution so that you

  • raise your hand and say, I don't have a clue

  • what's going on here.

  • So the idea is that once a week we do a software lab

  • individually.

  • Once a week, we do a design lab, a little more open-ended

  • with partners.

  • There's a little bit of written homework, four total.

  • It's not much compared to other subjects.

  • It's mostly practice.

  • There's a nano-quiz, just to help you keep pace to make

  • sure that you don't get too far behind.

  • The first 15 minutes of every design lab

  • starts with a nano-quiz.

  • The nano-quizzes are intended to be simple if you've caught

  • up, if you're up to date.

  • So the idea is that you go to design lab, the first thing

  • you do is a little, 15 minute nano-quiz.

  • The nano-quiz uses a tutor much like the homework tutor,

  • much like the Python tutor.

  • And it's intended to be simple.

  • But it does mean please get to the design lab on time.

  • The nano-quizzes are administered by the software.

  • It starts the hour when the design lab starts.

  • It times out 15 minutes later.

  • So if you come 10 minutes late, you will have 5 minutes

  • to do something that we planned to give

  • you 15 minutes for.

  • We will also have exams and interviews.

  • The interviews are intended to be a one-on-one conversation

  • about how the labs went.

  • And we will have two mid-terms and a final.

  • So that's kind of the logistics.

  • The idea behind the logistics is practice, theory, practice.

  • Come to the labs.

  • Try things out.

  • Make sure you understand.

  • Develop a little code.

  • Type it in.

  • See if it works.

  • If it works, you're on top of things.

  • You're ready to get the next batch of information from the

  • lecture and readings.

  • OK, let's go on, and let's talk about the technical

  • material in the first module of the course, in

  • the software module.

  • We kick the course off talking about software engineering for

  • two reasons.

  • We'd like you to know about software engineering.

  • It's an incredibly important part of our department.

  • It's an incredibly important part of the engineering of

  • absolutely any system, any modern system.

  • But we'd also like you to know about it because it provides a

  • very convenient way to think about-- it's a convenient

  • language to think about the design issues, the engineering

  • issues in all the other parts of the class.

  • So it's a very good place to start.

  • So what I will do today is talk about some of the very

  • simplest ideas about abstraction and modularity in

  • what I think of as the lowest level of granularity.

  • How do you think about abstraction and modularity at

  • the micro scale, at the individual

  • lines of code scale?

  • As I said earlier, we will, as we progress, look at

  • modularity and abstraction at the higher scale.

  • But we have to start somewhere.

  • And we're going to start by thinking about, how do you

  • think about abstraction and modularity at the micro scale?

  • Special note about programming.

  • So what we are trying to do is, in the first two weeks,

  • ramp everybody up to some level of software security,

  • where you feel comfortable.

  • So the first two weeks of this course is intended to make you

  • comfortable with programming.

  • We don't assume you've done extensive programming before.

  • We want you to become comfortable

  • that you're not behind.

  • And that's the focus of the first two weeks' exercises.

  • If you have little or no previous background, if you

  • are uncomfortable, please do the Python tutor exercises.

  • If you have not --

  • if you do not have a lot of experience programming, if

  • you're uncomfortable with the expectation that you can do

  • programming, do that first.

  • That takes priority over all the other assignments during

  • the first two weeks.

  • In particular, if you're uncomfortable, we will run a

  • special Python help session on Sunday.

  • And if you attend that, you can get a free extension.

  • The idea is completing the tutor exercises is intended to

  • make you feel comfortable that you have the software

  • background to finish the rest of the course.

  • Do that first.

  • We will forgive falling behind in other things so that you

  • feel comfortable with programming.

  • If, at the end of two weeks, you still feel uncomfortable,

  • we have a deal with 6.00, the Python programming class, that

  • they will allow you to switch your registration

  • from 6.01 to 6.00.

  • But that expires Valentine's Day.

  • [LAUGHTER]

  • So you have to make up your mind before Valentine's Day if

  • you'd like to use that option.

  • So the idea is we'd like you to be comfortable with

  • programming.

  • If you haven't programmed before, do the

  • Python tutor exercises.

  • Go to software lab.

  • Go to design lab, but work on the tutor exercises.

  • The staff will help you with them.

  • You can go to office hours.

  • There's office hours listed on the home page.

  • You should try to become comfortable, and you should

  • try to set as your goal --

  • I'm going to be comfortable before Valentine's Day.

  • And if you're not, talk to a staff member about that.

  • OK, so what do I want you to know about programming?

  • Well, we're going to use Python.

  • We selected Python because it's very simple and because

  • it lets us illustrate some very important ideas in

  • software engineering in a very simple context.

  • That's the reason.

  • One of the reasons that it's simple is that it's an

  • interpreter.

  • After some initialization, the behavior of Python is to fall

  • into an interpreter loop.

  • The interpreter loop is, ask the user what he would like me

  • to do, read what the user types, figure out what they're

  • talking about, and print the result, repeat--

  • very simple.

  • What that means is that you can learn by doing.

  • That's one of the points of today's software lab.

  • You can simply walk up to a computer,

  • type the word python--

  • what you type is in red.

  • Type the word "python." It will prompt you, so this

  • chevron, that says, I'd like you to tell me

  • something to do.

  • I have nothing to do.

  • If you type "2," Python tries to interpret that.

  • In this particular case, Python says, oh, I see.

  • That's a primitive data item.

  • That's an integer.

  • This person wants me to understand an integer.

  • And so it will echo 2, indicating that it thinks you

  • want it to understand a simple integer.

  • Similarly, if you type 5.7, it says, oh, I got that.

  • That's a float.

  • The person wants me to remember a

  • floating point number.

  • And it will similarly echo the float.

  • Now, of course, there's no exact representation for

  • floats, right?

  • There's too many of them, right?

  • There's a lot of them.

  • There's even more floats than there are ints, right?

  • So it has an approximation.

  • So it will print its approximation to the float

  • that it thinks you are interested in.

  • If you type a string, "Hello," it'll say, oh, primitive data

  • structure, string.

  • And it'll print out that string.

  • So the idea is one of the features of Python that makes

  • it easy to learn is the fact that it's interpreter based.

  • You can play around.

  • You can learn by doing.

  • Now, of course, if the only thing it did was simple data

  • structures, it would not be very useful.

  • So the next more complex thing that it can do is think about

  • combinations.

  • If you type "2 + 3," it says, oh, I got it.

  • This person's interested in a combination.

  • I should combine by the plus operator two ints, 2 and 3.

  • Oh, and if I do that, if I combine by the plus operator

  • two and three, I'll get 5.

  • So it prints 5.

  • So that's a way you know that it interprets "2 + 3" as 5.

  • Similarly here, except I've mixed types.

  • "5.7 + 3," it says, oh, this user wants me to apply the

  • plus operator on a float and an int.

  • OK, well I'll upgrade the int to a float.

  • I'll do the float version, and I'll get this, which is its

  • representation of 8.7.

  • So the idea is that it will first try to interpret what

  • you're saying as a simple data type.

  • If that works, it prints the result to tell you what it

  • thinks is going on.

  • It then will try to interpret it as an expression.

  • And sometimes, the expressions won't makes sense.

  • In particular, if you try to add an int to a string, it's

  • going to say, huh?

  • And over the course of the first two weeks, we hope that

  • you get familiar with interpreting

  • this kind of mess.

  • That's Python's attempt to tell you what it was trying to

  • do on your behalf and can't figure out what

  • you're talking about.

  • OK, so that was simple.

  • But it already illustrates something that's very

  • important, and that's the idea of a composition.

  • So the way Python works, the fact that when you added 3 to

  • 2 it came out 5, what we were doing was composing

  • complicated--

  • well, potentially complicated (that was pretty simple) --

  • potentially complicated expressions and reducing them

  • to a single data structure.

  • And so that means that, in some sense, this operation, 3

  • times 8, can be thought of as exactly the same as if the

  • user had typed in 24.

  • Whenever you can substitute for a complex expression a

  • simpler thing, we say that the system is compositional.

  • That's a very powerful idea.

  • Even though it's simple, it's a very powerful idea.

  • And it's an idea that you all know.

  • You've seen it before in algebra, in arithmetic.

  • So in arithmetic expressions, you can think about how the

  • sum of two integers is an int.

  • That's a closure.

  • That's a kind of a combination that makes the system

  • compositional and that provides a layer of

  • hierarchical thinking so that, in your head, even though it

  • says 3 times 8, you don't need to remember that anymore.

  • You can say, oh, for any purposes that follow, I might

  • just as well think of 3 times 8 as being a

  • single integer, 24.

  • It's part of many other kinds of systems, for example,

  • natural language.

  • The simplest example in natural language is that you

  • can think about "Apples are good as snacks".

  • "Apples" is a noun.

  • It's a plural noun.

  • Or you could substitute "Apples and oranges", and it

  • makes complete sense within that same structure.

  • So "Apples and oranges are good as snacks".

  • The combination of "apples" and "oranges" works in every

  • way from the point of view of the grammar in the same way

  • that a simple noun, "apples," worked.

  • What we would like to do is use that idea as the starting

  • point for a more general compositional system.

  • And a good way to think about that is by way of names.

  • What if we had some sequence of operations that we think is

  • particularly important so that we would like to somehow

  • canonize that so that, subsequently, we can use that

  • sequence of operations easily?

  • Python provides a very simple way to do it.

  • Every programming language does.

  • It's not unique to Python.

  • But the idea is --

  • so here's an example.

  • "2 times 2" --

  • I'm squaring 2 and get 4. "3 times 3" --

  • I'm squaring 3, and I'm getting 9.

  • "8 plus 4 times 8 plus 4", I'm squaring "8 plus 4".

  • "8 plus 4", well, I can think of that as 12.

  • I'm squaring 12, I'm getting 144.

  • The thing I'm trying to illustrate there is the notion

  • of squaring.

  • Squaring is a sequence of operations that I would like

  • to be able to canonize as a single entity so that, in

  • subsequent programs, I can think of the squaring

  • operation as a single operation just

  • like I think of times.

  • The way we say that in Python is "define square of x to be

  • return x squared".

  • Then, having made that definition, I can say "square

  • of 6", and the answer is 36.

  • OK, this is a very small step.

  • But it illustrates a very important point, the idea

  • being that Python provides a compositional facility.

  • And it's hierarchical.

  • Having defined square, I can use square just as though it

  • were a primitive operator.

  • And I can use square to define higher level operations.

  • So for example, what if I were interested in doing lots of

  • sums of squares?

  • Say I'm Pythagoreas, right?

  • So I might want to add the square of 2 and the square of

  • 4 to get 20, or the square of 3 with the

  • square of 4 to get 25.

  • Using that simple idea of composition, we can write a

  • new program, sumOfSquares.

  • sumOfSquares takes two arguments, x and y.

  • And it returns the square of x and the square of y.

  • SumOfSquares doesn't care about how

  • you compute the square.

  • It trusts that square knows how to do that.

  • So the work is smaller.

  • The idea is that square takes care of

  • squaring single numbers.

  • sumOfSquares doesn't have to know how to square numbers.

  • It just needs to know how to make a sum of squares.

  • So what we've done is we've broken a task, which was not

  • very complicated, but the whole idea is hierarchical.

  • We've taken a problem and broken it into two pieces.

  • We factored the problem into how do you do a square, and

  • how do you sum squares.

  • And the idea, then, is that this hierarchical structure is

  • a way of building complex systems out of simpler parts.

  • So that's the idea of how you would build programs that are

  • compositional.

  • Python also provides a utility for making lists, for making

  • data structures that are compositional.

  • The most primitive is a list.

  • So in Python, you can specify a list.

  • Here's a list of integers.

  • So the list says, beginning list, end of

  • list, elements of list.

  • So there's five elements in the list, the

  • integers 1, 2, 3, 4, 5.

  • Python doesn't care what the elements of a list are.

  • We'll see in a minute that that's really important.

  • But for the time being, the simplest thing that you can

  • imagine is a heterogeneous list.

  • It's not critical that the list contain just integers.

  • Here's a list that contains an int, a string,

  • an int, and a string.

  • Python doesn't care.

  • It's a list that has four elements.

  • The first element's an int.

  • The second element's a string, et cetera.

  • Here's an even more complex example.

  • Here's a list of lists.

  • How many elements are in that list?

  • Three.

  • How many elements are in that list?

  • So the idea is that you can build more complex data

  • structures out of simple ones.

  • That's the idea of compositional factoring

  • applied to data.

  • Just like it was important when we were thinking about

  • procedures, to associate names with procedures--

  • that's what "def" did--

  • we can also think about associating names with data

  • structures.

  • And that's what we use something that Python calls a

  • variable for.

  • So I can say "b is 3".

  • And that associates the data item, 3, with the label, b.

  • I can say, "x is 5 times 2.2".

  • Python will figure out what I mean by the

  • expression on the right.

  • It'll figure out that I'm composing by using the star

  • operator, which is multiply, an integer and a float, which

  • will give me a float.

  • The answer to that's going to be a floating point number.

  • And it will assign a label, x, to that floating point number.

  • You can have a more complicated list, a data

  • structure, and associate the name y with it.

  • Then, having associated the name y, you get many of the

  • same benefits of associating a name with a data structure

  • that we got previously in associating a

  • name with an operation.

  • So we can say, y(0).

  • And what that means is, what's the zero-th elements of the

  • data structure, y?

  • So the zero-th element of the data structure,

  • y, is a list, [1, 2, 3].

  • Python has some funky notations.

  • The -1 element is the last one.

  • So the -1th element of y is [7, 8, 9].

  • And it's completely hierarchical.

  • If I asked for the -1 element of y, I get [7, 8, 9].

  • But then, if I asked for the first element of that

  • result, I get 8.

  • OK?

  • Everything is clear?

  • OK, just to make sure everything is clear, I want to

  • ask you a question.

  • But to kick off the idea of working together, I'd like you

  • to think about this question with your neighbor.

  • So before thinking about this question, everybody stand up.

  • Introduce yourself to your neighbor.

  • [AUDIENCE TALKS]

  • So now, I'd like you to each discuss with your neighbor the

  • list that is best represented by which of the following

  • figures, 1, 2, 3, 4, or 5, or none of the above.

  • And in 30 seconds, I'm going to ask everybody to raise a

  • hand with a number of fingers indicating the right answer.

  • You're allowed to talk.

  • That's the whole point of having a partner.

  • [AUDIENCE TALKS]

  • OK.

  • I'd like everybody now to raise their hand.

  • Put up the number of fingers that show the answer.

  • And I want to tally.

  • Fantastic!

  • Everybody gets it.

  • OK, so which one do you like?

  • AUDIENCE: 3.

  • PROFESSOR: 3 --

  • why do you like three.

  • Somebody explain this to me?

  • It just looks good?

  • Its pattern recognition.

  • What's good about 3?

  • AUDIENCE: It shows the compositional

  • element of the list.

  • PROFESSOR: Compositional?

  • What is the compositional element in the pictures?

  • What represents what?

  • OK, 'a' represents a.

  • That's pretty easy, right?

  • So that takes care of the bulk of the figures.

  • What's the blue lines represent?

  • Someone else?

  • I didn't quite understand.

  • AUDIENCE: The angles represent like a list.

  • PROFESSOR: They represent a list.

  • Where is the list on the figures?

  • AUDIENCE: The vertex?

  • PROFESSOR: The vertex.

  • The vertices are lists.

  • So in 3 --

  • at the highest level, we have a list that's composed of how

  • many elements?

  • 2.

  • The first element of that list is?

  • AUDIENCE: a.

  • PROFESSOR: And the second element of that list is?

  • AUDIENCE: Another list.

  • PROFESSOR: Another list.

  • That's the hierarchical part, right?

  • That second list has how many elements?

  • AUDIENCE: 2.

  • PROFESSOR: Fine, good, recurse.

  • You got it.

  • What is the list represented by number 2?

  • A single list with five elements.

  • Square bracket, a, comma, b, comma, c, comma, d, comma, e,

  • square bracket, right?

  • What is the list represented by that one?

  • AUDIENCE: Not a list.

  • PROFESSOR: Agh!

  • It's not a list!

  • What is it?

  • Who knows?

  • AUDIENCE: Looking at the variable

  • names, it defines them.

  • You have variables.

  • You have a variable a, that defines a list that contains

  • b, and the variable, c, that defines another list that

  • contains d.

  • PROFESSOR: So we could make that a variable.

  • If we said a is a variable that comprises b and c, then

  • we have the problem of how we're going to associate

  • variables and elements into this list, right?

  • So the weird thing about this one and, let's

  • see, that one's weird.

  • This one's also kind of weird.

  • This one's weird because we're giving names to lists in a

  • fashion that's not showed up here, right?

  • That's not to say you couldn't invent a meaning.

  • It's just that it doesn't map very well to that

  • representation.

  • Similarly over here, we seem to be giving the name b to the

  • element a, and then the name c to the element b.

  • What on earth are you talking about?

  • It's not clear what we're doing their either.

  • So the point is to get you thinking about the abstract

  • representation of lists and how that maps into a complex

  • data structure.

  • That was the whole point.

  • OK, so we've talked about, then, four things so far.

  • How do you think about operations in a

  • hierarchical fashion.

  • And the idea was composition.

  • We think about composing simple operations to make

  • bigger, compound operations.

  • That's a way of saying, there's this set of operations

  • that I want to call foo.

  • So every time I do this complicated thing that has

  • three pages of code, that's one foo.

  • And that's a way that we can then combined foos in some

  • other horribly complicated way to make big foos.

  • So the idea is composition.

  • That's the first idea.

  • The second is associating a name with that composition.

  • That's what "def" does-- define name, name of a

  • sub-routine.

  • So we thought about composing operations,

  • associating names with them.

  • We composed data in terms of lists, and we associated names

  • with those lists in terms of variables.

  • The next thing we want to think about is a higher order

  • construct where we would like to conglomerate into one data

  • structure both data and procedures.

  • Python has a concept called a class that lets us do that.

  • In Python, you make a new class by saying to the Python

  • prompt, I want a new class called Student.

  • And then, under Student, there is this thing which we will

  • call an attribute.

  • An attribute to a class is simply a data item associated

  • with the class.

  • And a method--

  • a method is just a procedure that is

  • associated with the class.

  • So there's this single item class called Student that has

  • one piece of data, its attribute, school, and one

  • procedure, which is the method calculateFinalGrade.

  • So then, this is the kind of data structure you might

  • imagine that a registrar would have.

  • It's a way to associate.

  • So the idea here is that everybody here is a student.

  • They all have a school.

  • And they all have a way of calculating their final grade.

  • That's a very narrow view that maybe a registrar would have.

  • So classes, having defined them, we can then use the

  • class to define an instance.

  • So an instance is a data structure that inherits all of

  • the structure from the class but also provides a mechanism

  • for having specific data associated with the instance.

  • So in Python, I say Mary is a student.

  • By mentioning the name of the class and putting parenthesis

  • on it, I say, give me an instance of the student.

  • So now, Mary is a name associated with an instance of

  • the class, Student.

  • John is similarly an instance of the class, Student.

  • So both Mary and John have schools.

  • In fact, they're both the same.

  • The school of Mary and the school of John are both MIT.

  • But I can extend the instance of Mary to include a new

  • attribute, the section number, so that Mary's section number

  • is 3 and John's section number is 4.

  • So this provides a way--

  • it's a higher-order concept.

  • We thought of a way to aggregate operations into

  • complicated operation, data into complicated data.

  • Classes aggregate data and operations.

  • Classes allow us to create a structure and

  • then generate instances.

  • And then the instances have access to those features that

  • were defined in the class, but also have the ability to

  • define their own unique attributes and methods.

  • You can also use a class to define a subclass.

  • So here, I'm defining the subclass, Student601.

  • All Student601s are members of the class, Student.

  • The reverse is not true.

  • So all Student601 entities inherit everything that a

  • Student has.

  • But all 601 students share some other things.

  • Besides having a school which all students have, 601

  • students also have a lecture day, a lecture time, and a

  • method for calculating tutor scores.

  • Not all students have a method for calculating tutor scores.

  • But members of the class Student601 do.

  • So this, again, represents a way of organizing data and

  • operations in a way that makes it easier to compose higher,

  • bigger, more complex structures.

  • The final thing that I want to talk about today is the

  • specific, gory details for how Python manages the association

  • between names and entities.

  • We've already seen two of those.

  • Naming operations is via "def." And it gives rise to

  • the name of a procedure.

  • Variables are ways of naming data structures.

  • Now, we've seen a way of naming classes.

  • And in fact, it's helpful if you understand.

  • So Python associates names and entities in a very simple,

  • straightforward fashion.

  • And if you know the ground rules, it makes it very easy

  • to deal with.

  • And if you don't know the ground rules, it makes it very

  • hard to deal with.

  • So what's the ground rules?

  • Here's the gory details.

  • So Python associates names with values in what Python

  • calls a binding environment.

  • An environment is just a list that associates

  • a name and an entity.

  • So if you were to type b equals 3 what Python is

  • actually doing is it's building this environment.

  • When you type b equals 3, it adds to the environment a

  • name, b, and associates that name with the integer, 3.

  • When you type x equals 2.2, it adds a name, x, and associates

  • it with the float, 2.2.

  • When you say foo is minus 506 times 2, it makes the name,

  • foo, and associates it with an int, minus 1012.

  • Then, if you ask Python about b, the rule is look it up in

  • the environment and type the thing that b refers to.

  • So when you type "b," what Python really does is it goes

  • to the environment.

  • It says, do I have some entity called "b?" Well, yes I do.

  • It happens to be an int, 3.

  • So it prints 3.

  • If you ask, what is "a?" Python says, OK, in my

  • environment, do I have some name, "a?" It doesn't find it.

  • So it prints out this cryptic message that basically says,

  • sorry, guys, I can't find something called "a" in the

  • current environment.

  • That's the key to the way Python does all name bindings.

  • So in general, there's a global environment.

  • You start typing to Python.

  • It just starts adding and modifying the bindings in the

  • binding environment.

  • So if you type a equals 3 and then type "a," it'll find 3.

  • If you then type "b=a+2," it evaluates the right-hand side

  • relative to the current environment.

  • So it first looks here.

  • And it says, do I have something called "a?" Ah, yes.

  • It's an integer, 3.

  • Substitute that.

  • Do I know what 2 is?

  • Oh yeah, that's just an int.

  • Do I know what plus is?

  • Oh yeah, that's the thing that combines two ints.

  • So it decides that a plus 2--

  • it evaluates a plus 2 in the current environment.

  • It gets 5.

  • And it says, oh, I'm trying to do a new equals, a new

  • association, a new variable.

  • Make the name, b, points to this evaluated in the current

  • environment.

  • So b gets associated with int 5.

  • Then, if I do this line, it evaluates b plus 1 in the

  • current environment.

  • b is 5 in the current environment.

  • It adds 1.

  • It gets 6.

  • And then, it says, associate this thing, 6, with b.

  • So it overwrites the b, which had been bound to 5, and b is

  • now bound to 6.

  • OK?

  • So the whole thing, the way it treats variables, the way

  • Python associates a name with a value in a variable, is

  • evaluate the right-hand side according to the current

  • environment.

  • Then, change the current environment to

  • reflect the new binding.

  • What it does in the case of sub-routines is very similar.

  • So here's an illustration of the local environment that is

  • generated by this piece of code.

  • When I say a equals 2, it generates a name in the local

  • environment, a.

  • It evaluates the right-hand side and finds 2.

  • So it makes a binding in the local environment where the

  • name, a, is associated with the integer, 2.

  • Then, I say define square of x to be return x squared.

  • That's more complicated.

  • Python says, oh, I'm defining a new operation.

  • It's a procedure.

  • The procedure has a formal argument, x.

  • It has a body, return x times x.

  • I'm going to have to remember all of that stuff.

  • So I'm trying to define a new procedure called square.

  • It's going to make a binding for square.

  • So in the future, if somebody says the word square, it'll

  • find out, oh, square I remember that one.

  • square, it's a procedure.

  • Just like the binding for a variable might be an int, the

  • binding for a procedure is the name of the procedure.

  • Then, in the procedure, which is some other data structure

  • outside the environment, it's got to remember the formal

  • parameters--

  • in this case, x--

  • and the body.

  • And for the purpose of resolving what do the

  • variables mean, it needs to remember what was the binding

  • environment in which this sub-routine was defined.

  • So that's this arrow.

  • So this sequence says, make a new binding square, points to

  • a procedure.

  • The procedure has the formal argument, x.

  • It has the body return x times x.

  • And it has the binding.

  • It came from the environment, E1, the current environment.

  • OK, is everybody clear?

  • So the idea is that the environment associates names

  • with things.

  • The thing could be a data item, or

  • it could be a procedure.

  • Then, when you call a procedure, it makes a new

  • environment.

  • So what happens, then, when I try to evaluate a form, square

  • of a plus 2?

  • What Python does is it says, OK, I need to figure

  • out what square is.

  • So it looks it up in the environment, and it finds out

  • that square is a procedure.

  • Fine, I know how to deal with procedures.

  • So then, it figures out this procedure has a formal

  • argument, x.

  • Oh, OK, if I'm going to run this procedure, I'm going to

  • have to know what x means.

  • So Python makes a new environment--

  • here, it's labelled E2, separate from the global

  • environment, E1.

  • It makes a new environment that will

  • associate x with something.

  • Doesn't know what it is yet, it just knows that this square

  • is a procedure that takes a formal argument, x.

  • So Python makes a new environment, E2, with x

  • pointing to something.

  • Then, Python evaluates the argument a plus 2 in the

  • environment E1.

  • You called square of a plus 2 in the environment of E1.

  • So it figures out what did you mean by a plus 3.

  • Well, you were in the environment E1.

  • So it means whatever a plus 3 would have meant if he had

  • just typed a plus 3 in that environment.

  • So you evaluate a plus 3 in the environment

  • E1, and you get 5.

  • So then, this new environment, E2, that is set up for this

  • procedure, square, associates 5 with x.

  • Now it's ready to run the body.

  • So now, it runs this procedure, return x times x.

  • But now, what it's trying to resolve its variables, it

  • looks it up in E2.

  • So it says, I want to do the procedure, the

  • body, x times x.

  • I need to know what x is, and I need to know it twice.

  • Look up what x means, but I will look it up in my E2

  • environment that was built

  • specifically for this procedure.

  • And fortunately, there's an x there.

  • So it finds out that x is 5.

  • It multiplies 5 times 5.

  • It gets the answer is 25.

  • It returns 25.

  • And then, it destroys this environment, E2, because it

  • was only necessary for the time when it was running the

  • procedure body.

  • Is that clear?

  • OK, so a slightly more difficult example illustrates

  • what happens whenever everything is not defined in

  • the current local environment.

  • What if I type define biz of a?

  • Well, I create a new name in the local environment that

  • points to a procedure.

  • The procedure has a formal parameter, a, and a body that

  • returns a plus b.

  • The procedure also was defined within the environment E1,

  • which I'll keep track of.

  • Then, if I say b equals 6, that makes a new binding in

  • the global environment, b equals 6.

  • Then, if I try to run biz of 2, look up biz.

  • Oh, that's a procedure, formal parameter, a.

  • Make an environment, has an a in it.

  • What should I put in a?

  • Evaluate the argument, 2.

  • OK, a is 2.

  • Put two here.

  • Now, I'm ready to run the body.

  • Run the body in the environment, E2.

  • When I run return a plus b in E2, I have to

  • first figure out a.

  • Well, that's easy. a is 2.

  • Then, I have to figure out b.

  • What's b?

  • AUDIENCE: 6?

  • PROFESSOR: 6.

  • So how did you get 6?

  • AUDIENCE: [INAUDIBLE].

  • PROFESSOR: So this local environment that was created

  • for the formal parameter has, as its parent, E1 because

  • that's where the procedure was defined.

  • So it doesn't find b in this local environment.

  • So it goes to the parent.

  • Do you have a "b?" And it could, in principal, propagate

  • up a chain of environments.

  • So you could construct this hierarchically.

  • So it will resolve bindings in the most recent environment

  • that has that binding.

  • So the answer, then, is that when you run biz of 2, this b

  • gets associated with that b, OK?

  • So that's how the environments work for simple procedures and

  • simple data structures.

  • It's very similar for the way it works with classes.

  • So imagine that I had this data, and I wanted to

  • represent that in Python.

  • What I might do is look at the common features.

  • The courses are all the same.

  • The rooms are all the same.

  • The buildings are all the same.

  • The ages are highly variable.

  • So I might want to create a class that

  • has the common data.

  • So I might do this--

  • class Staff601.

  • The course is 601.

  • The building's 34.

  • The room is this.

  • The way Python implements a class is as an environment.

  • Executing this set of statements builds the class

  • environment.

  • This is it.

  • It's a list of bindings.

  • Here, I'm binding the name, course, to the

  • string, 601, et cetera.

  • If there were a method, I would do the same thing,

  • except it would look like a procedure then.

  • So this creates the Staff601 environment.

  • Staff601, because I executed this class statement, that

  • creates a binding in the local environment, Staff601, which

  • points to the new environment.

  • So now, in the future, when Python encounters the name

  • Staff601, it will discover that that's an environment.

  • Python implements classes as environments.

  • So now, when I want to access elements within a class, I use

  • a special notation.

  • It's a dot notation.

  • Python regards dots as ways of navigating an environment.

  • When Python parses staff.room, it looks up Staff601 in the

  • current environment.

  • If it finds an environment, it then says, oh, I know about

  • this .room thing.

  • All I do is I look up the room name in

  • the environment Staff601.

  • And when it does that, it gets the answer 501.

  • And the same sort of thing happens here.

  • It looks up Staff601.

  • It finds an environment.

  • It looks up coolness.

  • It finds out there is no such thing.

  • Well, no, that's not true.

  • So it creates coolness within 601 and assigns an

  • integer, 11, to it.

  • So then, the way Python treats methods is completely

  • analogous--

  • oh, excuse me, instances.

  • I'm doing instances first.

  • If I make pat be an instance of Staff601, pat is an

  • instance of the class Staff601.

  • pat is implemented as an environment.

  • So when I make pat, pat points to a new environment--

  • here, E3.

  • The parent of E3 is the class that pat belongs to,

  • which is, here, E2.

  • And when I make the instance, it's empty.

  • But now, if I ask what is pat.course, well, pat points

  • to this environment.

  • Does this environment have something called a course?

  • No.

  • Does the parent?

  • Yes.

  • Course is bound to the string 601.

  • So pat.course is 601 just the same as

  • Staff601.course had been 601.

  • pat is an instance.

  • It's a new environment with the class

  • environment as its parent.

  • You can add attributes to instances.

  • And all that does is populate the environment associated

  • with the instance.

  • You can add methods to classes.

  • And that does the same thing.

  • So here, I've got the class, Staff601, which has a method,

  • salutation, instance variables, course,

  • building, and room.

  • So when I build that structure, Staff601 points to

  • an environment that contains salutation, which is a

  • procedure, in addition to a bunch of instance variables.

  • So now, all of the rules that we've talked about with regard

  • to environments apply now to this class.

  • So in particular, I can say Staff601 salutation of pat.

  • When Python parses Staff601, it finds an environment.

  • It says dot salutation.

  • Oh, I know how to do that.

  • Within the environment, Staff601, look for a binding

  • for the name salutation.

  • Do I find one?

  • Well, yeah, there it is.

  • It points to a procedure.

  • So staff dot salutation is a procedure.

  • Do just the same things that we would have done with a

  • simple procedure.

  • The only difference here is that the

  • procedure came from a class.

  • In this particular case, the sub-routine that I define has

  • a formal parameter, self.

  • So then, that's going to have to build when I try to

  • evaluate it.

  • That has to build a binding for self, which is set to pat.

  • pat was an environment.

  • So self gets pointed to pat.

  • So now, when I run Staff601.salutation on pat, it

  • behaves as though that generic method was applied to the

  • instance pat.

  • We'll do that a lot.

  • It's a little bit of redundancy.

  • We know that pat is a member of Staff601.

  • So we will define a special form-- or I should say, Python

  • defines a special form-- that makes that easy to say.

  • This is the way we will usually say, the instance pat

  • should run the class method salutation on itself.

  • This is simply a simplified notation that means

  • precisely that, OK?

  • So what we covered today, then, was supposed to be the

  • most elementary ideas in how you construct modular

  • programs, Modularity at the small scale.

  • How do you make operations that are hierarchical, data

  • structures, and classes?

  • What we will do for the rest of the week is practice those

  • activities.

The following content is provided under a Creative

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it