PA 0: Arithmetic

Objective

This is a very simple "programming assignment" designed to make sure that your development environment is set up correctly and to familiarize you with the PA completion process in CS 240.

PLEASE READ THIS DOCUMENT CAREFULLY! Although this project spec is rather lengthy, the amount of code you will need to write is very small (fewer than ten lines). Use this opportunity to become more comfortable with the tools that you be using throughout the semester (the compiler, the make system, the test suite, the debugger, etc.) without the stress of a "real" programming assignment.

If you have questions or run into issues, please post a question on Piazza or come to office hours.

Introduction

Here are the starter files for this project:

The two versions contain identical files, and differ only in the container format. If you are using GNU/Linux or Mac OS X, you probably want to use the tarball (.tar.gz) and if you're using Windows you probably want to use the zip file.

The rest of this section contains step-by-step instructions for setting up your working environment. Pay close attention to this process; future project descriptions will not contain this level of detail.

First you will need to create a folder in which to work. We recommend using version control software (e.g., Git or Mercural) to track your changes, or keeping your project files in a location that is automatically backed up (e.g., using Dropbox). Download one of the starter files linked above and put it in the working folder.

Next, unzip the starter files into the project folder. If you're using the tarball, use a command like the following:

tar -zxvf 00_arith.tar.gz

On some operating systems, you can create a folder, download the starter files, and unzip them using a graphical interface. That's fine. For the rest of the steps, however, you will want to open a terminal and cd to the folder where the unzipped project files are.

First, do an ls to see what files you have to work with. For this project, the results should look like this:

$ ls
arith.c     arith.h     main.c      testsuite.c

Notice that there is currently no makefile. Because the Makefile needs to be customized for various operating systems, we will NOT be distributing makefiles with the other starter files. However, we have posted generic makefiles for each supported operating system on Piazza in the "Generic C Makefiles" thread. Open this thread and download the appropriate file into the project folder.

For example, suppose you were on an ISAT 250 lab machine running Mint Linux. Consulting the Piazza thread, you will find that the correct makefile for that environment is Makefile.ubuntu. After downloading that file to the working folder, you should see it in ls results:

$ ls
Makefile.ubuntu arith.c         arith.h         main.c          testsuite.c

Rename the file to remove the .ubuntu extension because it is no longer necessary:

$ mv Makefile.ubuntu Makefile

$ ls
Makefile    arith.c     arith.h     main.c      testsuite.c

Take a moment to look over the Makefile. It includes very generic support for compiling a main.c module and a testsuite.c module (both of which should be included in the starter files). Before you compile, you will need to update the Makefile to include any extra modules or libraries needed by the project. This may require modifying the following section:

# application-specific settings and run target

EXE=main
TEST=testsuite
MODS=
LIBS=

For this project, you can see from the provided files that there is one additional module: arith.c. Thus, you will need to modify the Makefile, adding the extra module to the MODS variable. The new line should look like this:

MODS=arith.o

IMPORTANT: Even though you are adding an entry for the arith.c code file, you need to put arith.o (with the ".o" extension) in the makefile. Recall that the make build process runs on target information; i.e., a list of things that need to be built. All you need to do is tell make what you want to build, and the generic makefile has rules and patterns to help make figure out how to do it.

Also note that we didn't have to include main.o and testsuite.o in that list. We only have to list any extra code objects beyond the basic main.o and testsuite.o objects, which are already accounted for elsewhere in the generic makefile.

In addition, if the project requires any library linking options (e.g., -lm for the math library), you would need to add them to the LIBS definition. However, this particular project does not need any external libraries.

At this point, you should be able to build and run the project:

$ make
gcc -c -g -O0 -Wall --std=c99 -pedantic main.c
gcc -c -g -O0 -Wall --std=c99 -pedantic arith.c
gcc -g -O0 -o main main.o arith.o

$ ./main
|2| + |3| = 0

You can see that the result is incorrect; this is because you have not yet completed the project.

Project Description

This project is very simple. You must implement a single function in arith.c as follows:

  • int add_abs(int a, int b)

    Takes two integer parameters and returns the sum of their absolute values.

Project Testing

Public Tests

If you have the Check unit testing framework installed (highly recommended!), you can run the test suite with the make test target. If you run it before working on the project, you will see output that looks like the following:

$ make test
gcc -c -g -O0 -Wall --std=c99 -pedantic -Wno-gnu-zero-variadic-macro-arguments testsuite.c
gcc -L/opt/local/lib -o testsuite testsuite.o arith.o  -lcheck -lm -lpthread
./testsuite
Running suite(s): Default
0%: Checks: 1, Failures: 1, Errors: 0
testsuite.c:11:F:Core:add_pos:0: Assertion 'add_abs(2, 3)==5' failed: add_abs(2, 3)==0, 5==5
FAILURE: At least one test failed or crashed.
make: *** [test] Error 1

You can see that the test suite ran a single check that failed. To see the actual test, look at the testsuite.c file for the test name (the label after "Core" in the printout: in this case, "add_pos"):

START_TEST (add_pos)
{ ck_assert_int_eq(add_abs(2, 3), 5); }
END_TEST

As you can see, this test calls add_abs with parameters 2 and 3, expecting the result to be 5. The test output indicates that the result is in fact 0. If you haven't started work on the project, this makes sense considering that the starter file contains a non-functional implementation of the add_abs function:

int add_abs(int a, int b)
{
    return 0;   // TODO: finish this function!
}

Alternatively, if you HAD already done some work on the project and had thus been expecting the test to pass, the tests results would indicate that the add_abs function is a good place to start debugging.

After you have implemented the function using a native solution ("return a + b;"), the test should pass:

$ make test
gcc -c -g -O0 -Wall --std=c99 -pedantic arith.c
gcc -L/opt/local/lib -o testsuite testsuite.o arith.o  -lcheck -lm -lpthread
./testsuite
Running suite(s): Default
100%: Checks: 1, Failures: 0, Errors: 0
SUCCESS: All current tests passed!

At this point, it is tempting to consider your work done. After all, you have passed the test! However, this is only a single test, and may not be exhaustive (in fact, it is by design NOT exhaustive for this assignment). Thus, your code might not in fact be fully compliant with the project specification and would therefore not be eligible for full credit.

In fact, there is a key type of input that the provided public testsuite does not test for. Can you figure out what it is?

Private Tests

For this assignment (and this assignment ONLY) we have posted the full "private" testsuite in the Files section of Canvas. It is strongly recommended that you download this testsuite, replace the original (public) version of testsuite.c, and then re-run the tests to make sure that your code passes.

Look carefully at the private testsuite; you should now be able to see the class of inputs that the public testsuite does not check for. You should think about how you could have anticipated that class of inputs from the project description without seeing the private test suite.

This is why it is very important to write your own tests while working on PAs in this class; as stated in the course syllabus, we will be testing your code at least partially based on test cases that you will not be aware of when you submit. This reflects a typical software development situation in industry, where clients often have "hidden" requirements that only surface after you have delivered the project. In many cases, even the client is unaware of these requirements (e.g., compatibility issues with legacy systems). Thus, the ability to write good tests is an important skill that you will find very valuable in your career.

One important difference between this class and dealing with clients in industry is that in this class we will be providing exceptionally clear project specifications. This should enable you to anticipate the full range of tests that we might apply. To write your own tests, you can use the Check testing framework and add more tests to testsuite.c, or you can write your own ad-hoc testing methods in main.c.

Feel free to share and discuss test cases on Piazza; however, be aware that test cases provided by other students may not be entirely true to the project spec. Always read the spec carefully and test your code thoroughly!

Submission

DUE DATE: Friday, September 11, 2015 at 23:59 EDT (11:59pm)

Submit ONLY your completed arith.c file on Canvas using the appropriate assignment submission. Make sure the file contains a comment field at the top with your name and a statement of compliance with the JMU honor code.

Please check your code carefully and make sure that it complies with the project specification. In addition, make sure that your code adheres to general good coding style guidelines. Fix any spelling mistakes, incorrect code formatting, and inconsistent whitespace before submitting. Make sure you include any appropriate documentation.