Control Flow Exercises |
Home Class Info Links |
Lectures Newsgroup Assignments |

Below are exercises suitable for submission to the Code Critic after reading Chapters 1 through 6 of the textbook. Don't forget the rules of the queue.

The exercises are:

Chapter 4 of the textbook adds a new member function,
`determineClassAverage()`

, to the `GradeBook`

class. Unfortunately, as defined, you have to manually enter
grades at the terminal to test it. *This is a very bad design.*
Every time you make changes to the code, you'll either have to run
those manual tests, or, more likely, you'll skip that step
and hope you didn't break anything.

A better approach is test-driven development (TDD), where you write testing code first. This naturally leads you to design programs for fast automatic testing.

Here are the basic steps. First, start with your GradeBook test file from this exercise.

Add a new test function called `testClassAverage()`

that
creates one or more gradebooks and repeatedly

- calls the (not yet defined) member function
GradeBook::addGrade(
*n*) to add integer grades to the gradebook, one at a time - after each grade is added, calls
`CPPUNIT_ASSERT_DOUBLES_EQUAL`

to test the return value of the member function GradeBook::determineClassAverage( )

When there are no grades, GradeBook::determineClassAverage( ) should return 0. Think about what would be a good sequence of grades to test the average calculation.

Compile and run your project. It shouldn't even compile, much less do the right thing.

Now, using or following the code from Figures 4.12 and 4.13 implement the member functions. Changes you need to make to the Deitel code include:

- Making the variables for the total and number of grades data members, not local function variables
- Defining addGrade( ) to update those variables appropriately
- Changing determineClassAverage( ) to calculate and return the average value (a double), instead of reading and printing

Neither addGrade( ) nor determineClassAverage( ) should read or print anything in your new code.

Don't forget to update both `GradeBook.h`

and
`GradeBook.cpp`

with the new member function information.

Recompile and run. If any tests fail, fix and re-run.

**Submit to Code Critic:**

- the function
`testDetermineClassAverage()`

(not the entire test fixture) `GradeBook.cpp`

`GradeBook.h`

Remember to put a header comment at the start of the two code files that identifies which file they are.

When the above has been approved via the Code Critic, run make handin.

**Email** the Zip archive produced by your Makefile
with the **Subject** EECS 211: Class Average.

Use TDD to develop the following global functions integers:

`int integerPower( int`

-- returns*m*, int*n*)*m*, where^{n}*n*is greater than or equal to 0 (Exercise 6.18). Don't worry about testing for overflow, i.e., when*m*is too big for an integer value.^{n}`int integerRoot( int`

-- returns the largest integer*m*, int*n*)*k*such that*k*is less than or equal to^{n}*m*, where*m*is greater than or equal to 0 and*n*is greater than 0. For example,`integerRoot(36, 2)`

should return 6,`integerRoot(55, 2)`

should return 7, and`integerRoot(97, 4)`

should return 3.

There should be **no**
reading or printing in any of the above functions.

Put the tests in `PowerTests.cpp`

, and the solution code
in `Power.h`

and `Power.cpp`

.

**Use TDD** and write your tests for these functions first.
Think about both easy cases, like the ones above, and possible
the tricky cases.
Submit your tests
first to the Code Critic. You can work on the
implementation while waiting for feedback but do not submit your solution
until your tests have been approved.

Do **not** use any standard math library functions for these, just
the basic arithmetic operators and control structures. This rule is
for this exercise -- in general, using library functions is the correct
thing to do.

**Test your tests.** Try trivial definitions like always returning *m*,
and make sure the right tests fail, before doing the real code.

**Submit to Code Critic:**

- First submit just
`PowerTests.cpp`

. - When your tests have been approved, and your code passes the approved tests,
submit
`Power.cpp`

and`Power.h`

in one submission for review.

Remember to put a header comment at the start of these files that identifies what file they are.

When the above has been approved via the Code Critic, run make handin.

**Email** the Zip archive produced by your Makefile
with the **Subject** EECS 211: Integer Powers.

Use TDD to develop the following global functions from simple number theory:

`bool isPerfect( int`

-- returns true if*n*)*n*is a positive perfect integer; see Exercise 6.29`bool isPrime( int`

-- returns true if*n*)*n*is a positive prime integer; see Exercise 6.30`int GCD( int`

-- returns the greatest common divisor of two integers; see Exercises 6.32 and 6.45. (Note on 6.45: the algorithm can be done recursively or iteratively, and the comment in brackets is wrong. The algorithm doesn't care which argument is bigger.)*m*, int*n*)`int LCM( int`

-- returns the least common multiple of two integers; Google if you don't know what this is.*m*, int*n*)

There should be **no**
reading or printing in any of the above functions.

Put the tests in `MathTests.cpp`

, and the solution code
in `Math.h`

and `Math.cpp`

.

`GCD()`

and `LCM()`

should accept
zero and negative values, but always return non-negative results.
For example,
the GCD of 49 and -91 should be 7 and the LCM of those numbers
should be 637. The GCD of 0 and any number is the
number itself, and the LCM of 0 and any number is 0.

**Use TDD** and develop these one function at a time. Focusing
on one function will help you get familiar with the concepts involved.

**Don't repeat yourself (DRY)**. There are some common operations needed to
implement these functions that should be refactored into subfunctions.

**Don't reinvent the wheel.** E.g., don't reinvent what's in
standard libraries like `cstdlib`

or `cmath`

.

- Test your tests. Try trivial definitions like always returning true or 1 and make sure the right tests fail, before doing the real code.
- With the perfect and prime predicates, be sure to test for both true and false cases.
- For
`isPerfect()`

be sure to test the four perfect numbers known to the Greeks. - For the GCD and LCM, be sure to test for positive, negative and zero arguments in various combinations and orders.
- Be sure to test that the LCM is found even for very large integers, as long as the result is within the range of integers. If the real LCM is too large, it doesn't matter what your program does.

**Submit to Code Critic:**

- First submit just
`MathTests.cpp`

. - After your tests have been approved, and your code passes the approved tests,
submit
`Math.cpp`

and`Math.h`

in one submission for review.

Remember to put a header comment at the start of these files that identifies what file they are.

When the above has been approved via the Code Critic, run make handin.

**Email** the Zip archive produced by your Makefile
with the **Subject** EECS 211: Number Theory.

Use TDD to develop the global generic **template** functions (Section 6.18)
`tmax()`

and `tmin()`

. ("T" is for template.)

These should be defined to handle
2 or 3 parameters. `tmax()`

should return the largest of
the arguments passed, `tmin()`

the smallest.
The only restriction when calling these functions is that the three parameters
have the same type, and that type can be compared using
`<`

.

To handle 2 versus 3 parameters, use overloaded function definitions (Section 6.17).

There should be **no**
reading or printing in any of the above functions. Do not use any
standard C++ libraries in your definitions.

Put the tests in `GenericMathTests.cpp`

, and the solution code
in `GenericMath.h`

.

Put all template code in header files. Otherwise, the compiler won't know about them when translating your code.

Make different test functions for each overloaded function, i.e., one
for `tmax()`

with 2 arguments, another for `tmax()`

with
3 arguments, etc. Each test function should at least test with
integers, doubles, characters, and C++ strings.

*Avoid repeated code.*
Make good use of the *conditional operator*. (Warning: The book has an
answer that's way too verbose.)

**Submit to Code Critic:**

- The test file and the header file in one submission for review.
Note that the only
`.cpp`

file is the testing code.

Remember to put a header comment at the start of these files that identifies what file they are.

When the above has been approved via the Code Critic, run make handin.

**Email** the Zip archive produced by your Makefile
with the **Subject** EECS 211: Generic Math.

*Comments?*
Contact the Prof!