teaching machines

CS 1: Lecture 9 – Return Values and Parameters

Dear students,

Last time we saw how methods capture a process into a reusable component. Methods have some really nice advantages:

  • They drop us into a smaller world with a smaller problem to solve. Instead of thinking about the grand mission of our program, we think about the baby step of the method.
  • They can be written and tested independently of the larger program. Considering how many mistakes we are going to make, this is good news.
  • They are insulated from other parts of our program. A method can’t clobber data in another method.

That insulation is our concern for today. When we declare a variable, it’s scope begins. That variable is only accessible until the closing curly brace of the block in which it was declared. A variable’s scope is its lifetime. Methods have independent scopes and are therefore insulated from each other. But if methods can’t access each other’s data, how do they share stuff across the Wall of Braces? Through two mechanisms: return values and parameters.

I like to think of methods as vending machines. From the perspective of a customer, I drop some things in (the parameters), and some unhealthy food pops out (the return value). What happens in between is largely a mystery to me.

We will be more than customers, however. We will design our own vending machines.

Let’s discuss return values first. To write a method that yields a result to the customer or client or caller of the method, we must do a couple of things:

  1. Announce the type of data that will be sent back. This is announced right before the method’s name, where we’ve been writing void up to this point.
  2. Add a statement that catapults the data back to the caller, clearing the Wall of Braces.

We’ll now start to see this pattern in our code:

public static RETURN-TYPE methodName() {
  ...
  return SOME-EXPRESSION-HAVING-RETURN-TYPE;
}

Let’s write a method that generates a random letter, perhaps used to assign someone to a group. We could write it like this:

public static char getRandomLetter() {
  Random generator = new Random();
  int ordinal = generator.nextInt(26) + 1;
  char letter = (char) ('A' + ordinal);
  return letter;
}

Or we could generate a random index into a String holding the alphabet:

public static char getRandomLetter() {
  Random generator = new Random();
  String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  char letter = alphabet.charAt(generator.nextInt(26));
  return letter;
}

Now let’s introduce parameters. Generally, we add parameters to let the caller influence the behavior of the method. In a vending machine, for example, we give the customer some choice of what will be dispensed. They might enter C7 to get Reese’s Peanut Butter Cups—which is the only unhealthy food worth eating.

We add parameters by declaring—but not assigning—variables in the method’s parentheses:

public static RETURN-TYPE methodName(TYPE1 id1, TYPE2 id2, ...) {
  ...
  return SOME-EXPRESSION-HAVING-RETURN-TYPE;
}

These variables are now available to the statements of the method. In the case of getRandomLetter, it’d be nice to generalize the method so that the user could decide alphabet to choose from. We do this like so:

public static char getRandomLetter(String alphabet) {
  Random generator = new Random();
  char letter = alphabet.charAt(generator.nextInt(26));
  return letter;
}

Now in the caller we must supply the value for alphabet:

System.out.println(getRandomLetter("ABCDEFGHIJKLMNPOQRSTUVWXYZ"));
System.out.println(getRandomLetter("AB"));
System.out.println(getRandomLetter("HT"));
System.out.println(getRandomLetter("HHHHHHHHHHHHHHHT"));

Let’s write another method, one that yields the number of digits in a number. What is the return type? int. What parameters must we accept? A single int. There are several ways to answer this. We’ll convert the number to a String:

public static int getDigitCount(int n) {
  String nAsString = "" + Math.abs(n);
  return n.length();
}

We could also have solved this with logarithms. Or a loop that chisels away at the number digit by digit until we get to 0.

Methods are providers of abstraction. They hide away low-level details. We can think of them as black boxes, exposing certain inputs and one output but obscuring their inner workings. What goes on inside the box is not relevant to the purpose who just wants the job done, allowing that person to operate more quickly and at a higher level.

Now let’s have you write a method:

Write on paper a method that takes one or more parameters, using only the types we’ve discussed so far. For the body of the method, compute a simple value based on the parameters. Have it return the value. For example, I might write this mysterious method:
public static int mystery(int x) {
  int value = x + 1;
  return value;
}
Tell a neighbor what the parameter types and return type of your method are—without telling or showing them how your method is implemented. Neighbor, guess values of the parameters and try to figure out what’s going on inside the blackbox based on the returned values.

For our next exercise, let’s demonstrate something what happens in software industries all across the world: cooperation. Let’s split a larger task up into smaller pieces, and different sections of the class can complete the smaller pieces independently. The overall task is to compute the area of a circular bow. Here are the bite-sized pieces:

  • Left third, write a method that computes the area of a circle.
  • Middle third, write a method that computes the area of a ring.
  • Right third, write a method that computes the area of a bow.

Assume that your classmates write their methods correctly. Use their work to make your own easier!

Here’s your TODO list to complete before next class:

  • Attend a peer review session during lab this week to claim your Blugolds.
  • Start homework 2, which is due before October 6. You’ll need to Team / Pull… from the template repository to get the new SpecChecker. Recall that early and often commit-pushes earn you more points. You should be committing and pushing after every coding session.
  • CS 145, your lab 3 is posted. Feel free to start early.

See you next class!

Sincerely,

P.S. It’s time for a haiku!

Grandma’s Meatloaf Plus
Her recipe had some blanks
You just never knew

P.P.S. Here’s the code we wrote together in class…

Subjects.java

package lecture0925;

import java.util.Random;

public class Subjects {
  public static void main(String[] args) {
    
//    for (int i = 10; i < 100; ++i) {
//      System.out.printf("%4d - %c\t", i, (char) i);
//      if (i % 6 == 0) {
//        System.out.println();
//      }
//    }
//    System.out.println();
    
    System.out.println("Nick is in group " + getRandomLetter("HHHHHHHHHHHHHHHHHHHHT"));
    System.out.println("Noah is in group " + getRandomLetter("HT"));
    System.out.println("Matt is in group " + getRandomLetter("HT"));
    System.out.println("Alec is in group " + getRandomLetter("HT"));
  }
  
  public static char getRandomLetter(String alphabet) {
    Random generator = new Random();
    int ordinal = generator.nextInt(alphabet.length());
    char letter = alphabet.charAt(ordinal);
    return letter;
  }
  
  public static char getRandomLetter() {
    Random generator = new Random();
    String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int ordinal = generator.nextInt(26);
    char letter = alphabet.charAt(ordinal);
    return letter;
  }
  
  public static char getRandomLetter2() {
    Random generator = new Random();
    int ordinal = generator.nextInt(26) + 10;
    char letter = (char) ('A' + ordinal);
    return letter;
  }
}

IntMethod.java

package lecture0925;

import java.util.Scanner;

public class IntMethod {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.print("Gimme a number, please: ");
    int number = in.nextInt();
    System.out.println(getDigitCount(number));
  }
  
  public static int getDigitCount(int n) {
    String nAsString = "" + Math.abs(n);
    return nAsString.length();
  }
}

Circles.java

package lecture0925;

public class Circles {
  public static double getCircleArea(double radius) {
    return Math.PI * radius * radius;
  }
  
  public static double getRingArea(double radiusA, double radiusB) {
    double areaA = getCircleArea(radiusA);
    double areaB = getCircleArea(radiusB);
    return Math.abs(areaA - areaB);
  }
  
  public static double getBowArea(double radiusA, double radiusB) {
    return getRingArea(radiusA, radiusB) / 2;
  }
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *