Part 0: Setup for the semester

You had 210sync in IC210 (of 204sync in SI204) that allowed you to keep the ic210 directory on your VM sync'd with the ic210 directory on you cs lab account. We will set things up to do the same thing with a directory named ic211 and a script called 211sync.

Note: this assumes you have already done the initial setup with github and your VM.

1. Copy and paste the following command into a shell on your lab machine:

   curl https://faculty.cs.usna.edu/~wcbrown/courses/S24IC211/211setup.sh > 211setup.sh && source 211setup.sh && rm -f 211setup.sh

2. Give the command "211sync" (once again, no quotes!) and if you get an "Everything up-to-date" message you are good.
Now, whenever you start or finish doing some work, run "211sync" to synchronized your work.

Part 0.5: Setup for this lab

In the ic211 directory, create a sub-directory lab01 and cd into it. This is where you will do your work for this lab.

Step 1. Writing/Compiling/Running Java code

  1. Using your favorite text editor (as long as it's emacs or vi) put the following Java code into a file named Lab1a.java:
    public class Lab1a 
    {
      public static void main(String[] args) 
      {
            
      }
    }
    Note: The name of the file must be exactly Lab1a.java. Yes, upper-case vs. lower-case matters!
  2. Add the following to the main method (aka function):
    int[] x = new int[10];
    int k = 0;
    while(K < 10) 
    {
       x[k] = k*k;
       k++;
    }
    for (int j = 0; j < 10; j++) 
    {
       System.out.println(j + " squared is " + x[j]);
    }
    What do you think it will do when run?
  3. Now it is time to compile this program. You do this by typing the command
    javac Lab1a.java
    (javac = "java compiler"). If you typed it in exactly as above, you should have gotten an error. Take a look at it, and notice how helpful javac is being. Fix the error.
  4. Recompile the program (so you got no errors). If you type
    ls
    you'll notice a new file, Lab1a.class, which is the bytecode to be run by the java interpreter. Run the interpreter on your program with the command
    java Lab1a
  5. Modify the program by replacing the while loop with a for loop. Compile it and run it again.

Step 2. Your first Program

  1. Make a new file called Lab1b.java. Write the lines you need to write to make it a Java program.
  2. Add the line
    import java.util.*;
    at the very top of the file. This is like #include <iostream> in C++. It allows us to use the Scanner class, which is what we'll use to read input.
  3. Add the following code to main. Run to see what it does:
    Scanner in = new Scanner(System.in);
    System.out.print("Please input an integer ");
    int n = in.nextInt();
    System.out.print("Please input a second integer ");
    int k = in.nextInt();
    System.out.println("The two ints were " + n + " and " + k);
  4. What happens if you type your name instead of an integer? Try it! What you should see is that the JVM prints out the call stack, i.e. the stack of function call records as it appeared when the error occurred. One nice feature of an interpreted language is that when a run-time error occurs, the interpreter can tell you all sorts of things about the state of the program when the error occurred. This is really nice. For programs running on the CPU, the only information you get when a run-time error occurs is a message like "seg-fault".
  5. Scanner is a class that is part of Java's utility package (java.util). A package is "roughly" analogous to a C++ library. Scanner is used to facilitate reading information from an input stream. In this case, we are reading from System.in which is that standard input stream. In order to use the Scanner class, you have to import the java.util package. That's the purpose of the 'import' line of the file.
  6. Did you know that if you want to play a simple lottery where there are n possible numbers (the number of balls), and you have to pick k of them, then your odds of winning are 1 in (n * (n-1) * (n-2) * ... * (n-k+1))/k!, where ! means "factorial". If not, don't worry. Your probs and stats course will teach you these kinds of things. Just accept this formula for purposes of the lab.
  7. Anyway, modify your program so that it reads in the n and k, and computes the odds as described above. You should be able to do this with code that (not counting I/O) looks just like C++.
    Note: to cast an int x to a double in Java you do this (double)x ... just sayin'.
    ~/$ java Lab1b
    Please input an integer 8
    Please input a second integer 5
    The two ints were 8 and 5
    numerator = 6720
    denomintor = 120
    odds = 1 in 56 = 0.017857142857142856 
    ~/$ java Lab1b
    Please input an integer 9
    Please input a second integer 1
    The two ints were 9 and 1
    numerator = 9
    denomintor = 1
    odds = 1 in 9 = 0.1111111111111111 
    ~/$ java Lab1b
    Please input an integer 13
    Please input a second integer 7
    The two ints were 13 and 7
    numerator = 8648640
    denomintor = 5040
    odds = 1 in 1716 = 5.827505827505828E-4 
  8. You may wonder what else the Scanner class can do. The Scanner class, and much of the rest of what is built into Java, is described in your book. Documentation for the complete "Java API", i.e. descriptions of all packages/classes that are part of the language standard, is available online: Java 11 API Documentation. To find Scanner, use the search box on the upper right. (Or google jdk11 scanner.) You'll notice a long list of functions included in the Scanner class. Which one do you think will read in a whole line? What type does it return? Change your code so that before the integers are entered, the user enters name (spaces allowed!), which is printed back in the final println() command.
    ~/$ java Lab1b
    Enter your name: Alfred E. Newman
    Please input an integer 11
    Please input a second integer 4
    The two ints were 11 and 4
    numerator = 7920
    denomintor = 24
    odds = 1 in 330 = 0.0030303030303030303 
    Goodbye Alfred E. Newman. 
    ~/$ java Lab1b
    Enter your name: Roger Federer
    Please input an integer 14
    Please input a second integer 5
    The two ints were 14 and 5
    numerator = 240240
    denomintor = 120
    odds = 1 in 2002 = 4.995004995004995E-4 
    Goodbye Roger Federer.
  9. Add a function which takes an int and returns the factorial of that integer. Place that function immediately before the main function, i.e. still inside the class definition. Functions (for now) should start with the magic incantation public static, otherwise they look just like C++ functions. Note that, unlike C++, there are no function prototypes separate from function definitions. Test your function before continuing on.
  10. Add another function which, given n and k from the above program, returns the product n*(n-1)*...*(n-k+1).
  11. Modify your main function to use these two new functions to calculate and output the odds from the above section.

Step 3: using String[] args

The "main" function takes a single parameter, args, which is an array of Strings. So what's that about? Well, when you execute your program, whatever comes after the classname on the command line is split up into separate strings (with spaces providing the separator) and put into the array args, which is what "main" gets as an argument when it is called.
$ java Ex1 foo bar rats leopard peach
There are 5 arguments
args[0] = foo
args[1] = bar
args[2] = rats
args[3] = leopard
args[4] = peach

Write a program Lab1c.java that does exactly what Lab1b does, except that the name and the number n and k are taken from the args array rather than read in from standard input. Here are some examples:

$ java Lab1c Roger Federer 14 5
The two ints were 14 and 5
numerator = 240240
denomintor = 120
odds = 1 in 2002 = 4.995004995004995E-4
Goodbye Roger Federer.
$ java Lab1c Alfred E. Newman 11 4
The two ints were 11 and 4
numerator = 7920
denomintor = 24
odds = 1 in 330 = 0.0030303030303030303
Goodbye Alfred E. Newman.
$ java Lab1c Prince 7 2
The two ints were 7 and 2
numerator = 42
denomintor = 2
odds = 1 in 21 = 0.047619047619047616
Goodbye Prince.

Note: The numbers n and k come from the args array, which means they are of type String, not int. Look in the JDK 11 documentation for class "Integer" for a method (aka function) called parseInt. Note: this will be called as Integer.parseInt(...), which means "the parseInt method/function from the class Integer".

Step 4. Your third program

The following line creates a pseudo-random number generator, seeded on the current time in milliseconds.
Random rand = new Random(System.currentTimeMillis());
After that point, every time we call rand.nextInt(k), where k must be an int, it will return a random number between 0 (inclusive) and k (exclusive). Random, by the way, is in java.util, and has a lot more interesting functions you can see in your book ... or in the Java11 API Documentation for Random.

Write a program Lab1d.java that generates a random number between 0 and 10 (inclusive!), and then asks the user for a guess until they get it correct. The more violent the berating on each wrong guess, the better. Code this in a file called Lab1c.java.

~/$ java Lab1c
Guess a number between 0 and 10: 0
<Insert Snarky Message> Guess again: 5
<Insert Snarky Message> Guess again: 3
<Insert Snarky Message> Guess again: 10
<Insert Snarky Message> Guess again: 6
<Insert Snarky Message> Guess again: 8
Right after 6 guesses!
Note: Instead of submitting, demo this for your instructor.

Submission instructions

submit -c=IC211 -p=lab01 Lab1b.java Lab1c.java