 MIT 6.030:  Introduction to Interactive Programming

Laboratory 1:Expressions, Statements, and InteractionsSolutions

Pre-Lab

B. Finger exercises

• Chapter 5
1. In Java, every expression has a type. Assume that the following declarations apply:
int i, j, c;
double d;
short s;
long l;
float f;
boolean b;
For each expression below, if it is syntactially lega Java, indicate its type (not its value). If it is not syntactically valid, indicate why.
1. 6 is type int.
2. 24L is type long.
3. +3.5 is type double.
4. 3.5f is type float.
5. 2e-16 is type double.
6. -25b is not valid Java. b is not a valid suffix.
7. i is type int.
8. i+3 is type int.
9. i+3.0 is type double.
10. i+s is type int.
11. l+d is type double.
12. f+s is type float.
13. i / 0 is not valid Java. You cannot divide by zero.
14. 4 * 3.2 is type double.
15. i = 0 is type int.
16. i == 0 is type boolean.
17. b = 0 is not valid Java. A boolean cannot have value 0.
18. b == 0 is not valid Java. You cannot compare a boolean to an int.
19. 'c' is type char.
20. "An expression in double-quotes" is type String.
2. Give examples of each of the following:
1. An expression whose type is int and whose value is more than a previously defined int, x.
x + 1
2. An expression whose type is boolean and whose value is true when x is between 5 and 15.
(x > 5) && (x < 15)
3. An expression whose type is double and whose value is half of x's, where x is the aforementioned int.
x / 2.0
4. An expression whose type is long and whose value is the remainder when x is divided by 7.
x % 7L
5. An expression whose type is boolean and whose value is the opposite of a previously defined coolean, b.
!b
6. An expression whose type is boolean and whose value is true exactly when the int x is evenly divisible by 5.
(x % 5) == 0
7. An expression whose type is String and whose value is read from the user's keyboard.
• Chapter 6
1. What will the value of d be after each of the following statements? Also, indicate any other changes that may occur as a result of executing the statement. You may assume that they are executed in the order given.
1. double d = 3.5;
The value of d is 3.5.
2. d = d * 3;
The value of d is 10.5.
3. if (d < 8 )
{
Console.println( "d is pretty small" );
}

The value of d remains 10.5. The code inside the if block is not executed.
4. d = 2.0
This problem has a typo. There is no semicolon at the end of the line. One acceptable answer is that it is not a statement and will not compile. Another acceptable answer is that the value of d is 2.0.
5. while ( d < 30 )
{
d = d * 2;
}

At the beginning of the while loop, the value of d is 2.0. The code inside the block is executed 4 times. Then the while condition is false and the loop exits. d was doubled 4 times, so its final value is 32.0.

Laboratory

Static Positioning
1. Write Horizontal and Vertical rules that will place the ball in position (10, 20).

2. Horiz rule:    return 10;
Vert. rule:    return 20;
3. Use the Horizontal rule for both rules.  What do you expect would happen?

4. The ball will go to (10,10).
5. Use the Horizontal and Vertical rules separately again. Use the mouse to manually move the ball to another position (see Advanced Environment Options).  Do this several times.  What happens?  Explain. [In lab: Can you "fix" this behavior?]

6. The ball will stay at the position where you drop it briefly, and then quickly returns to position (10,20).  To "fix" the behavior (i.e., make it stay in place), simply use the rule return pos; for both rules.
Implementing Velocity
1. Write a pair of rules to make the ball move horizontally from left to right.  Can you control how fast the ball moves (i.e., velocity) by changing your code?
2. (Note: this question only asks you to move the ball from left to right, and not necessarily back from right to left.)

To make the ball move to the right with a velocity of 1, we can use the following rules:

Vert. Rule:     return 0;
Horiz. Rule:    return pos + 1;

This says that the new horizontal position will be 1 more than the current horizontal position -- i.e., the ball will move to the right 1 step every time the horizontal rule is called.  (Note that the Spirograph program takes care of periodically calling the rules -- you don't have to do that yourself.)  To make the ball move faster, we simply increase the amount we add to pos.  (Remember that velocity is the rate of change of position.)

A slightly redundant, but sometimes more readable, way of writing this rule is as follows:

double velocity = 5;   // change this number to change the velocity
double newPos;       // the new position will be stored in newPos

newPos = pos + velocity; // compute next position

return newPos;

(Note that the name velocity here is a new local variable we create, and is not the same as vel, which is a parameter supplied to the rule.)

3. Use the horizontal rule for both rules.  What do you expect would happen?  Explain.

4. The ball moves in a 45 deg. line.  This is because it moves the same distance horizontally as it does vertically.
5. What happens if the horizontal and vertical rules have different effective velocities? (How do you make this happen?)

6. You can make it happen by using a different value for velocity in the horizontal and vertical rules.  The angle of the line changes, depending on which axis the ball is moving faster.
7. Use the mouse to move the dot to a different position.  What happens?  Explain.
8. The answer to this depends on your implementation.  With the code above, moving the ball to a different position causes the ball to continue moving with the same velocity, but starting from the position you moved it to.  This is because the new position is computed relative to the current position, so it doesn't matter what the current position is.

Implementing Acceleration

Now that you can implement velocity using position controls, implement acceleration.  Note that you cannot use vel and otherVel, since these are always 0 in position-control mode.  (Hint: use fields.)  Write your code so you can change the initial velocity and acceleration by changing the code.

Just as velocity is the rate of change in position, acceleration is the rate of change in velocity.  Thus, to implement acceleration, we can start with the code for velocity above, and then just increment velocity each time the rule is called.  That is, the rule will now be:

double velocity = 5;          // change this number to set the velocity
double acceleration = 1; // change this number to set acceleration

double newPos;       // the new position will be stored in newPos

newPos = pos + velocity; // compute next position
velocity = velocity + acceleration;

return newPos;

However, if you run this code as-is, you will find that the velocity will not change.  This is because right now, a new "shoebox" with the name velocity is created everytime the rule is called, and it loses its value after the rule returns.  To make velocity keep its value across calls to the rule, we must make it a field.  Thus, the correct(ed) code for acceleration is as follows:

In the fields box:

// Press "Load" to initialize these fields
double velocity = 5; // change this to set *initial* velocity
double acceleration = 1; // change this to set acceleration

In the rule box:

double newPos;       // the new position will be stored in newPos

newPos = pos + velocity; // compute next position
velocity = velocity + acceleration; // compute next velocity

return newPos;

Note that we don't really need to give the acceleration a name, since it is constant.  If we knew we would only be interested in doing accelerations of value 1, then we can just say velocity = velocity + 1; instead.   However, using a name (acceleration) makes the code much more readable.  It also makes it more flexible.  If we wanted to change the acceleration (and/or the velocity) during run-time, we only need to assign a new value to the fields acceleration and velocity; we don't need to recompile our code.

Note that unlike velocity and acceleration, newPos is still a local variable. This is because newPos is essentially used only for temporary storage -- it is assigned a completely new value every time the rule is called, and there is no need or reason for us to keep its old value around.  Thus, although making newPos into a field will not change the behavior of this code, it is more appropriate to keep it as a local variable.

Can you make the dot go in a parabolic path? (Hint: what accelerations does it need?)

One way to do this is to use a constant horizontal velocity, a constant vertical acceleration, and an initial vertical velocity in the opposite directions as the vertical acceleration.  (Note that this is what happens when you shoot a cannonball into the air.)

To do this, use the acceleration code above, with the different initial values for the fields:

Horiz. fields:     double velocity = 5;
double acceleration = 0;

Vert. fields:       double velocity = 15;
double acceleration = -1;

(Note: In Spirograph, you need to press "Load" to initialize the fields.)

Wraparound and other boundary conditions

1. Modify your code to make it emulate the behavior of wrap-around mode while using no-wrap-around mode.
2. double newPos = pos + velocity;        // compute next position
velocity = velocity + acceleration; // compute next velocity
if (newPos > maxPos) {    // if new position is too high
newPos = -maxPos;      // wrap-around to low end
} else if (newPos < -maxPos) {    // if new position is too low
newPos = maxPos;               // wrap-around to high end
}
// at this point, newPos can never be > maxPos or < maxPos
// therefore, it is now safe to return newPos;
return newPos;

(This solution assumes that velocity and acceleration are still fields.)

3. Can you make the dot bounce when it hits the end?
4. One way to do it is as follows:

double newPos = pos + velocity;        // compute next position
velocity = velocity + acceleration; // compute next velocity
if (newPos > maxPos) {    // if new position is too high
newPos = maxPos;      // stay at maxPos
velocity = -velocity;  // but turn around (negate velocity)
} else if (newPos < -maxPos) {    // if new position is too low
newPos = -maxPos;               // stay at -maxPos
velocity = -velocity;  // but turn around (negate velocity)
}
// at this point, newPos can never be > maxPos or < maxPos
// therefore, it is now safe to return newPos;

return newPos;

Again, this assumes velocity and acceleration fields.  There is no way to make the ball bounce without using some field, but there are many different ways to use a field to accomplish bouncing.

Other cool stuff
• Implement a function plotter.  Write the code to plot the following:
• y = x^2;
• y = sin( x );
• y = 1/x;
One way to do this is to use the otherPos parameter you are provided with as follows:

Horiz. Rule:
return pos + 1;    // just move horizontally at constant vel.

Vert. Rule:
// move y position to x*x (whatever the current x position is)
return (otherPos*otherPos);

To do the other functions, just replace the last line with:
return Math.sin( otherPos );    // this calls the Math.sin
// library method.
or,
return (1/otherPos);

By default, the ball will start at (0,0) and then start plotting on the right half of the screen.  To make it plot the left half too, you can either manually move the ball to the left half with the mouse, or you can modify the wrap-around code above so that the ball will go to the left half when it reaches the right edge of the screen.

You may notice that the plots do not look very interesting.  This is because of the scale of the plot.  For example, the magnitude of sin( x ) is always <= 1, so the plot looks almost like a flat line.  You can fix this problem by scaling the position values appropriately.  For example:

Vert. Rule:
double scaledOtherPos;    // scaled version of otherPos
double newPos;            // holds computed position
double scaledNewPos;      // scaled version of newPos

// divide otherPos by 50 to "stretch" out Horiz. axis.
// (e.g., if the range of the screen is -200 to +200, then
// we make it effectively only -4 to + 4)
scaledOtherPos = otherPos / 50;

// compute function
newPos = Math.sin( scaledOtherPos );

// "magnify" the newPos
scaledNewPos = newPos * 50;

return scaledNewPos;

(Don't worry if you don't understand scaling at this point.  You are not required to.  If you're interested in this sort of stuff, however, don't hesitate to talk to the staff about it.)

Using Velocity and Acceleration Controls
3.  Write code that will draw a parabola.

You can do this by giving the ball the appropriate accelerations, and initial velocity, as we did above (in position control mode).  For example, in acceleration mode, we might say:

Horiz Rule.:    return 0;    Vert. Rule:    return - 5;

And then, you can use the Advanced Environment Options to set its velocity to 5 and 15, for x and y respectively.

Challenge: Write code that will draw a circle.

(Note: this is presented here only for those interested in it.  It is relatively challenging material, even for experienced programmers, and deals more with Physics and Math than with programming.  You are not required to understand this for 6.096.)

One way to draw a circle in acceleration-control mode is by using the centripetal  force equation a=v^2/r.  If you use the following code as both rules, and give the ball an appropriate initial position (e.g., use the mouse to move it to (100,0) ), and initial velocity (e.g., use Advanced Environment Options to set the velocity to (0,8)), it should plot a circle:

double r = Math.sqrt( pos*pos + otherPos*otherPos );
// compute velocity magnitude
double v = Math.sqrt( vel*vel + otherVel*otherVel );
// compute projection angle "theta" for this dimension
double th = Math.atan2( otherPos, pos );
// compute acceleration component for this dimension
double a = (-( v * v / r ) * Math.cos( th ));

// return acceleration
return a;

Explaining why these equations work is beyond the scope of this solution set, but if you're interested in this sort of stuff, feel free to talk to us about it.

This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.  