teaching machines

CS1: Lecture 3 – More Math

Dear students,

Last time we started writing programs that performed little mathematical calculations for us. We used text to talk to the user in a more friendly way than the calculator. We used int for whole number data, and double for numbers with fractions. We used Scanner to get input.

Writing programs is a new enough experience for many of you that will continue writing little programs today. But let’s start with a little fill-in-the-blanks exercise to warm up our brains.

With your neighbor, discuss what should appear in blanks ___A___ through ___I___:

public ___A___ FairPizza {
  public static void main(String[] args) {
    Scanner in = new ___B___(System.in);
    ___C___ nDegreesInPizza = 360;
     
    ___D___.out.___E___("How many people? ");
    int ___F___ = in.___G___;

    double nDegreesPerSlice = ___H___ / ___I___;
    System.out.println("Each person gets a slice of " + nDegreesPerSlice);
  }
}

Problems

Now let’s write some programs that solve these problems:

  • What was my car’s most recent MPG?
  • How much space in square miles does each person get in the country of _______?
  • A farmer sells as many full cartons of eggs as possible, and eats the rest. How many does she eat?
  • 183 days from now, something big will happen. What day of the week is that?

Modular Arithmetic

The % or mod operator is surprisingly useful in our programs, despite getting very little mention in our high school mathematics courses. It’s definition doesn’t make it sound all that useful: for positive numbers, a % b gives us the remainder of dividing a by b.

But % does something amazing to progressions of numbers. Let’s discover what this is through Desmos.

As we’ll see, % wraps the sequence around when it reaches the denominator. It keeps the progression in the range [0, b – 1]. Sometimes this is called clock arithmetic. % effectively puts the range of numbers on a clock face, and when we roll over to the next day, we automatically start back at 0. It is useful in lots of situations where this wrap-around behavior is expected, including the following:

  • In games where a player goes off the edge of the screen only to come back on the other side (i.e., games played on a torus).
  • In shift cyphers, where each letter is replaced by the letter N steps away. At the end of the alphabet, we must wrap back to the beginning.
  • In scenarios where we abbreviate a number of its smallest units. For instance, years are often abbreviated to their last two digits—e.g., 19 for 2019. We can say year % 100 to compute this suffix.

We will use the mod operator a lot this semester. It is beautiful.

Mod Squad

To practice with the mod operator, let’s play a little game that we’ll call Mod Squad.

  • Gather N people together into a line. They are your squad.
  • Number the people 0 through N – 1.
  • On the count of 3, each person randomly holds out some number of fingers—not just the middle, you barbarian!
  • Count the total number of fingers.
  • The winner is the person whose number is total % N.

TODO

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

  • Play one round of Mod Squad with a group that includes some non-CS1 students. Everyone else must do something nice for the winner before midnight.
  • CS 145: lab 1 is posted. If you would like to start early, I encourage you to do so. You do not need to work with a partner if you complete the lab ahead of time. You can submit your checkpoints right away at the beginning of lab and then leave, giving the rest of us more space! No pressure, however.

See you next class!

Sincerely,

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

How to fix our world
Mod income by six figures
Mod age by 40

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

Keywords.java

package lecture0909.cs145;

public class Keywords {
  public static void main(String[] args) {
    var i = 42 + 5 + 27 + 7;
  }
}

Mileage.java

package lecture0909.cs145;

import java.util.Scanner;

public class Mileage {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    System.out.print("Start: ");
    double startingMiles = in.nextDouble();

    System.out.print("End: ");
    double endingMiles = in.nextDouble();

    System.out.print("Gallons: ");
    double gallons = in.nextDouble();

    double mileage = (endingMiles - startingMiles) / gallons;
    System.out.println(mileage);
  }
}

Farmer.java

package lecture0909.cs145;

import java.util.Scanner;

public class Farmer {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    System.out.print("Hey, farmer. How many eggs? ");
    int nEggs = in.nextInt();
    int nLeftover = nEggs % 12;

    System.out.println("You get " + nLeftover + " \uD83E\uDD5A.");
  }
}

SomethingBig.java

package lecture0909.cs145;

public class SomethingBig {
  public static void main(String[] args) {
    int today = 1;
    int offset = 183;
    int bigDay = (today + offset) % 7;
    System.out.println(bigDay);
  }
}

SerialOdd.java

package lecture0909.cs148;

import java.util.Scanner;

public class SerialOdd {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    int serial;
    do {
      System.out.print("Enter a positive serial number: ");

      while (!in.hasNextInt()) {
        in.nextLine();
        System.out.print("Enter an integer, silly: ");
      }

      serial = in.nextInt();
    } while (serial <= 0);
    System.out.println(serial * 2 - 1);
  }
}

Comments

Leave a Reply

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