About the CSCI 235 and 245 Progress Inventory

What this is

This is a tool to help students in the first two semesters of Wheaton's computer science program assess how well they're picking up programming. We've noticed that students in Programming I and II often are unclear on what concepts and skills need to be mastered by what time in the semester, and that they sometimes have trouble judging how well they've attained them. So we've put together a colllection of small-to-medium-size problems, not unlike what one would find on a test, that students can use to identify what they need to work on.

But shouldn't labs, projects, practice problems, quizzes, and tests already do that? Well, yes. But we know how it goes. You get help on labs and projects from the TA and the instructor. It takes time to grade projects, so feedback isn't as swift as it should be. You didn't completely get the lab last week, but now that we're onto a new topic you don't think about it any more. Practice problems before the test are too little, too late to give you enough time to catch up. And tests are way too late to help.

So this inventory provides a wide range of practice problems throughout the two semesters that students can use for immediate feedback on how well they're getting the latest material in class as well as how well they've retained the earlier stuff.

This inventory is divided up into 20 "levels", which each cover a programming concept, technique, skill, or language construct. They are keyed to points in the two semesters of Programming I and I. For example, Level 5 is about linked lists, and it's keyed to week 11 in CSCI 235. What that means is the end of week 11 is about when you should be able to get all the problems in that level.

How to use this inventory

This is about how to use this inventory to assess your progress and to learn. For the nuts and bolts about downloading and running the inventory, see the instructions.

Let's suppose you're a few weeks into Programming I. You've seen ifs and loops and Strings and arrays, and you've recently learned about (static) methods. You're ready for Level 1. Level 1 has "static-method problems", which means that each problem requires you to write the body of a static method, and each problem is in its own file. Here's what Problem A looks like:

/**
 * A_CountOccurrences
 * 
 * Part of an inventory of problems to help students
 * assess their progress in Programming I and Programming II
 * at Wheaton College.
 * 
 * Level 1: Basic algorithms, arrays, and methods.
 * Problem A: Counting occurrences of a value in an array
 * 
 * @author Thomas VanDrunen
 * July 20, 2015
 */
public class A_CountOccurrences {

    /**
     * Return the number of times a given value appears
     * in a given array.
     * @param array The array in which to search, assumed not null.
     * @param value The value for which to search.
     * @return the number of times the given value occurs in the given
     * array.
     */
    public static int countOccurrences(int[] array, int value) {
        return -1;
    }
}

Your task is fill-in the body of countOccurrence. (Delete the line return -1;. It's just there so that the program will compiled out of the box.) The problem itself is given in the documentation for that method. Then use the JUnit test Test_A_Count to check your answer, to see whether it passes or not. If it doesn't pass, then look at your answer more carefully to see if you can find out what went wrong.

Other levels have what we'll call "instance-method problems." Problems like these require you to complete an instance method for a class. Each problem is its own method, but since they're part of a class, they're all in the same file. You won't need to change anything else about the class, though. You won't need to add new instance variables or helper methods; everything you'll need will already be there. For example, Level 5 has the following class:

/**
 * LinkedList
 * 
 * Part of an inventory of problems to help students
 * assess their progress in Programming I and Programming II
 * at Wheaton College.
 * 
 * Level 5: Linked lists, basic iterative algorithms
 * Problem A: 
 * 
 * @author Thomas VanDrunen
 * July 21, 2015
 */
public class LinkedList {

    /**
     * The head node of the list
     */
    protected Node head;

    /**
     * Perfunctory constructor
     */
    public LinkedList() { head = null; }

    /**
     * Add an item to the front of the list.
     * @param item The item to add to the list.
     * POSTCONDITION: The size of the list has increased by one,
     * with the given item at the front of the list.
     */
    public void addFront(int item) { head = new Node(item, head); }
    
    // Problem A. Count nodes.
    /**
     * Count the number of nodes/values in this list.
     * @return The number of values in this list.
     */
    public int count() {
        return -1;
    }
    
    // Problem B. Sum the values
    /**
     * Sum the values in the list.
     * @return The sum of the values in this list.
     */
    public int sum() {
        return 0;
    }
...

You're given a class that already has the one instance variable it needs, a constructor, and one simple method. Again, the problems are described in the methods' documentation. Each problem requires you to complete one method in this file. The problems are independent of one another---you could do them in any order, and they're checked separately. When you finish Problem B, for example, you can check it using the JUnit test Test_B_Sum.

In other levels the problems are "class problems", which means you need to finish a class, including the instance variables, the constructor, and several methods. Each problem is its own class and, therefore, its own file. Take Level 12, Problem A:

/**
 * A_CountOccurrences
 * 
 * Part of an inventory of problems to help students
 * assess their progress in Programming I and Programming II
 * at Wheaton College.
 * 
 * Level 12: Writing basic iterators.
 * Problem A: Array iterator.
 * 
 * Class to encapsulate iteration over an array. When given
 * a reference to an array by its constructor, an instance of
 * this class will return the elements of the array, in order,
 * from successive calls to the next() method.
 * 
 * @author Thomas VanDrunen
 * July 22, 2015
 */
public class A_ArrayIterator implements Iterator {
    
    /**
     * Constructor.
     * @param array The array on which to iterate.
     */
    public A_ArrayIterator(int[] array) {

    }

    /**
     * Are there any more elements to return?
     */
    public boolean hasNext() {
        return false;
    }

    /**
     * Return the next element in the iteration (ie, the
     * next element in the array).
     */
    public Integer next() {
        return -1;
    }

    // ignore
    public void remove() {
        throw new UnsupportedOperationException();
    }

    // sample use
    // should print 5, 12, 13, 3, 4, 21 each on a separate line
    public static void main(String[] args) {

        int[] a = new int[] { 5, 12, 13, 3, 4, 21 };
   
        for (Iterator it = new A_ArrayIterator(a); it.hasNext(); )
            System.out.println(it.next());
    }
}

It already has stubs for the methods you need to write and the required constructor. The problem itself is described in the class documentation at the top, although the method documentation will clarify specific points. Also there is a main() method to show sample use of the class. Your task is to determine what instance variables need to be there, to initialize those instance variables in the constructor, and to implement the instance methods. Together they constitute one problem, so when the whole class is finished, you can test it out using Test_A_ArrayIterator.

As you take Programming I and II, keep an eye on the course schedule. When you get to various points, try the practice problems in the inventory that correspond to what has been covered recently, or earlier problems, for review.

When you do these problems, do them by yourself without help. Try not to use your notes or old labs and projects or the textbook. Absolutely don't use StackOverflow or similar resources from the internet. Do them on your own, just as you would when taking a test.

If your solution is wrong---that is, some of the JUnit tests fail---then look carefully at what you've done and try again. We're not letting you see the source code for the JUnit tests, but the name of the test and some of the feedback that JUnit gives you will provide some clues about the problem: for example, you should be able to tell whether there was an exception of some kind or you solution returned the wrong value.

When you try again don't just randomly mutate your code to see if you can nudge it into working. It's very tempting to do that, but that will defeat the purpose of these practice problems. If you can't get a problem after a few tries, then stop trying. Now that you know what you're having trouble with, it's time to go off and study. Go back to your notes and handouts from class; read up on the topic in the textbook; go back to the labs and projects where you had to work with these ideas; and ask a classmate, the TA, or the instructor for help.

The limitiations of this tool

This inventory is a tool to help you assess your progress, but it's not the final word on how you're doing. Edsger Dijkstra said, "Testing can prove only the existence of bugs, not their absence." Similarly, if there are practice problems you can't get, that proves there's something you haven't mastered yet. But if you can get all the practice problems, that doesn't guarantee you've attained all the goals of these courses.

This inventory tests only that you can produce correct code for well-defined, close-ended programming problems. It does not test for things like adherence to coding conventions and other stylistic concerns, efficiency, or design, all of which are part of Programming I and II. Since all the problems give you starter code, including method stubs, they don't test whether you can produce code from scratch. Similarly they don't assess how well you've acquired the vocabulary or how well you can do on pencil problems like type analysis or analysis of algorithms. The problems are aslo all in Java; the C material in Programming II isn't exercised here.

With these limitations in mind, we hope you'll find this inventory useful in determining roughly how well you're keeping up in CSCI 235 and 245.


Thomas VanDrunen
Last modified: Thu Jul 23 12:50:59 CDT 2015