Lec 3 | MIT 6.00 Introduction to Computer Science and Programming, Fall 2008

Lec 3 | MIT 6.00 Introduction to Computer Science and Programming, Fall 2008

Introduction

The professor introduces the lecture and outlines what has been covered in previous lectures. He highlights the basic elements of programming, which include data, operations, and commands/statements.

Programming Basics

  • The lecture covers three basic elements of programming: data, operations, and commands/statements.
  • Data includes numbers, strings, and Booleans.
  • Operations include addition, multiplication (for numbers and strings), AND/OR (for Booleans), among others.
  • Commands/statements include assignment, input/output (e.g., print for output), conditionals/branches (to change flow of control), and loops (e.g., while).

Programming Style

  • The professor emphasizes good programming style throughout the lecture. This includes using comments to highlight code functionality for debugging purposes; checking types of operands before applying operators; using descriptive variable names to document code; testing all possible branches through a piece of code with conditionals to ensure desired outputs are obtained.

Building Common Code Patterns

The lecture focuses on building common patterns of code that solve specific problems beyond the basics covered earlier.

Common Code Patterns

  • Beyond the basics covered earlier in the course, common patterns of code are introduced to tackle specific classes of problems.
  • These patterns build upon the basics by combining them in useful ways to solve more complex problems.

Iterative Programming

In this section, the speaker discusses the steps involved in tackling a problem in an iterative manner.

Steps for Iterative Programming

  • Choose a variable that will count and change every time the code is run.
  • Initialize the variable outside of the loop and set it up to start where you want it to.
  • Set up the right end test involving the variable to know when you are done with the loop.
  • Construct a block of code that will be executed each time through the loop, changing only the value of variables or data structures.
  • Ensure that you are changing the counting variable inside of your block of code.
  • Decide what to do when you are done.

Finding Square Roots

In this section, the speaker uses an example to demonstrate how to apply iterative programming techniques.

Steps for Finding Square Roots

  • Start at 1 and call x as what we're trying to find square root of
  • Square 1 and check if it's greater than x. If not, take 2 and square it. Repeat until we get a number whose square is greater than x.
  • When we get greater than x, we've gone past where we want to be. If we get something whose square is equal to x, then we have found our answer.

Flow Charts

The speaker also mentions flow charts as another tool for thinking about how to structure code but does not provide further details on this topic.

Flow Chart for a Loop

In this section, the speaker explains how to create a flow chart for a loop. The flow chart is used to visualize where the loop is and make sure that the variable is initialized and checked correctly.

Creating the Flow Chart

  • Start by drawing a rectangle with rounded corners.
  • Identify a variable and give it a name (ANS). Initialize it to 0 in a square box.
  • Test an end test by checking if ANS times ANS is less than or equal to x using a diamond shape.
  • If yes, change the counter by going to ANS is ANS plus 1 and repeat the process again.
  • If no, go to print statement in trapezoid shape and print out ANS. Add stop box below it.

Comparison of Complexity in Code

In this section, the speaker compares two different types of complexity in code: simple branching programs and linear processes.

Simple Branching Programs

  • A flow chart for simple branching programs involves taking x, doing integer division by 2, multiplying it by 2, and checking if that was the same as x.
  • If yes, print even. If no, print odd.

Linear Processes

  • Linear processes depend on the size of x because they involve cycling around loops enough times to get to an answer.
  • The number of times you go around the loop is directly related to the size of the argument.

Introduction to Code Simulation

In this section, Professor Eric Grimson introduces the concept of simulating code and its importance in debugging. He demonstrates how to simulate a piece of code using a simple example.

Simulating Code

  • Simulating code is an important tool for debugging.
  • Hand simulation is valuable because it allows you to check if the code is doing the right thing.
  • To simulate a piece of code, pick a simple set of values and walk through it to see what happens.
  • Simulating on simple examples lets you check if the code terminates and if it gives back the right answer.

Checking Code Accuracy

In this section, Professor Eric Grimson asks two questions about a piece of code: for what values of x does it terminate? And for what values of x does it give back the right answer?

Termination and Correctness

  • For positive integers, the loop will terminate when ANS squared is greater than x.
  • For negative integers, there will be no termination because ANS squared will always be greater than x.
  • The algorithm gives back the correct answer for perfect squares but not for other numbers.

Does this code terminate?

In this section, the professor discusses how to ensure that a looping construct will always terminate and give back a reasonable answer. He uses an example of finding the square root of a number to illustrate his points.

Basic implementation

  • The professor asks if the code terminates and confirms that it does.
  • However, he notes that it does not give the right answer in all cases.
  • He highlights the importance of being able to check whether a loop gives back a reasonable answer.

Better implementation

  • The professor introduces a better way to write the code using defensive programming.
  • He explains how this new implementation checks for negative numbers and perfect squares before giving an answer.
  • The professor emphasizes the importance of defensive programming in ensuring that there is a path through the code for all possible inputs without causing errors or infinite loops.

Defensive Programming

In this section, the professor talks about the importance of defensive programming and how it can help prevent errors in code. He emphasizes that programmers should assume that users and other parts of the program may make mistakes, and therefore, they should write programs with lots of different tests to catch any potential issues.

Writing Defensive Code

  • Programmers should assume that users and other parts of the program may make mistakes.
  • Defensive programming involves writing programs with lots of different tests to catch any potential issues.
  • It's important to get into the habit of writing defensive code up front, even if it takes extra time.
  • Avoiding defensive programming can lead to bad habits and potentially haunt you later on down the road.

Exhaustive Enumeration

  • The style of program we just wrote is called exhaustive enumeration.
  • Exhaustive enumeration involves walking through all possible values of some parameter or element until finding a solution.
  • While exhaustive enumeration can be expensive for certain computations (e.g., searching all pages on Google), it is often the right way to do things for many others.

Finding Divisors

  • Another example problem is finding all divisors that go evenly into an integer.
  • A simple way to solve this problem is by starting at 1 and checking if each number divides evenly into x.
  • This approach follows the same form as exhaustive enumeration: pick what you want to vary, initialize outside the loop, walk through a little loop where you check something.

Introduction to FOR Loops

In this section, the speaker introduces the concept of FOR loops and how they can be used to iterate through a collection of data.

Basic Form of a FOR Loop

  • A FOR loop is a construct that allows for iterating through a collection of data.
  • The basic form of a FOR loop is: FOR <variable> IN <collection>: <block of code>
  • The variable acts as a placeholder and walks through the collection executing the block of code for each element in the collection.
  • One advantage of using a FOR loop is that it automatically updates the variable and ensures that the loop will terminate.

Using FOR Loops with Arbitrary Collections

In this section, the speaker discusses how FOR loops can be used with arbitrary collections and provides examples.

Advantages of Using FOR Loops with Arbitrary Collections

  • A major advantage of using FOR loops with arbitrary collections is that it allows for iterating through non-procedural collections such as prime numbers or batting averages.
  • Another advantage is that it simplifies code by automatically updating variables and ensuring termination.

Example: Finding Divisors Using a FOR Loop

  • The speaker provides an example where they use a FOR loop to find divisors for a given number.
  • The basic structure involves iterating through all possible divisors and printing them out.

Introduction to Tuples

In this section, we learn about tuples as a compound data structure. We explore how to create and access elements of a tuple.

Creating a Tuple

  • A tuple is an ordered sequence of elements that cannot be changed.
  • To create a tuple, use square brackets with elements separated by commas and enclosed in closed square brackets.
  • Example: test = (1, 2, 3)
  • Accessing elements of a tuple is done using square brackets with the index of the element.
  • The first element has an index of 0.
  • Negative indices can also be used to access elements from the end of the tuple.

Slicing a Tuple

  • Slicing allows us to extract parts of a tuple.
  • Use square brackets with two indices separated by a colon to slice a tuple.
  • The first index is the starting position (inclusive).
  • The second index is the ending position (exclusive).
  • Omitting one or both indices will slice from the beginning or until the end respectively.

Using Tuples for Divisors

In this section, we see how tuples can be used in solving problems such as finding divisors.

Finding Divisors

  • We can use tuples to store pairs of divisors for a given number.
  • Iterate through all numbers up to half of the given number and check if it divides evenly into it.
  • If so, add both numbers as a pair into our list/tuple.

Collecting Data with Tuples and Strings

In this section, the professor introduces tuples as an ordered collection of things and demonstrates how to collect data together using looping structures. He also shows how strings behave as an ordered collection of characters and can be manipulated in similar ways to tuples.

Tuples as Ordered Collections

  • Tuples are an ordered collection of things.
  • A tuple can be created by enclosing a sequence of values in parentheses.
  • Once a tuple is created, its elements cannot be modified.
  • Looping structures can be used to iterate over the elements of a tuple.
  • The in operator can be used to check if an element is present in a tuple.

Collecting Data with Loops

  • A loop can be used to collect data together into a tuple.
  • To do this, create an empty tuple and then append each desired element to it within the loop.
  • The += operator can be used to concatenate two tuples together.

Strings as Ordered Collections

  • Strings behave similarly to tuples as they are also an ordered collection of things (characters).
  • Elements of a string can be accessed using indexing or slicing operations.
  • Slicing operations return a new string that contains only the specified portion of the original string.

Complex Data Structures

  • Tuples and strings are examples of complex data structures that share common behaviors such as ordering and manipulation through loops and slicing operations.

Adding Digits in a Number

In this section, the instructor explains how to add up all the digits inside of a number using looping mechanisms.

Using FOR Loop to Add Digits

  • An easy way to add up all the digits inside of a number is by using a FOR loop.
  • The number needs to be converted into a string so that it can be treated as an ordered sequence of characters.
  • The loop will iterate through each character in the string and convert it back into an integer before adding it into some digits.
  • After walking through the loop, print out the total sum of digits.

Generalizing Iteration

In this section, the instructor discusses how iteration can be generalized into a pattern that can be applied to different examples.

Generalized Iteration Pattern

  • To generalize iteration, figure out what you're trying to walk through, what you want to do at each stage, what the end test is, and what you're going to do at the end of it.
  • Write it explicitly or use a FOR loop. This pattern applies to every example discussed so far.
  • More complex data structures can also be used for iteration.

Turing Complete Language

In this section, the instructor explains how with just a set of constructs like lists and loops anything algorithmic can be computed.

Computing with Lists and Loops

  • With just lists and loops anything algorithmic can be computed.
  • The fundamental basics of computation are captured in this set of mechanisms.
  • The real issue is figuring out how to build constructs out of this that tackle particular problems.