The objective of this laboratory assignment is to introduce you to the notion of
"problem decomposition" using functions. We will focus on defining new functions,
calling functions, using return values, and debugging functions.
In addition, automated unit testing with **assert()** will be covered.
This assignment has the following steps:

- Generating random numbers
- Writing automated unit tests with assert()
- User defined functions
- Write a short function
- Run the program
- Debugging a program
- Submit Your Work

The **rand** function generates a random integer between 0 and RAND_MAX (a symbolic constant
defined in the <stdlib.h> header file). The minimum value of RAND_MAX must be at least 32767.
If we want a to generate random numbers to simulate the throw of a dice, then all we need is
numbers between 1 - 6. To achieve this the mod % operator is used:

1 + rand % 6 will return
a random number from 1 to 6.

The **rand** function is actually a pseudo-random number generator. Calling rand
repeatedly produces a sequence of numbers that appears to be random. However, the sequence
repeats itself each time the program is executed. The following example illustrates this.

The given program is a simulation of a very basic online Roulette spinning wheel. It is based on a single number bet. The returns usually are 35 to 1. Cut and paste this program into a cpp file and execute more than once. Follow the sequence of values closely.

//------------------------------------------------------- // Roulette.cpp // Program to demonstrate rand() and srand() functions. // Author Suchit Batheja // Fall 2003 //------------------------------------------------------- #include < iostream > #include < cstdlib > #include < ctime > using namespace std; int main() { int Number; double Bet; int Roule = 0; // Repeat until user quits char Ch = 'y'; while ((Ch == 'Y') || (Ch == 'y')) { // Get number Number = -1; while ((Number < 0) || (number > 36)) { cout << "enter number to bet on (between 0 - 36) " << endl; cin >> Number; } // Get bet Bet = 0.0; while (Bet <= 0.0) { cout << "enter bet amount" << endl; cin >> Bet; } // Spinning the wheel Roule = rand() % 37; // After Spinning cout << "lucky number is " << roule << endl; if (number == roule) cout << "congratulations!! you have won " << (35 * bet) << endl; else cout << "oops you lost. better luck next time :-(" << endl; cout << endl << "play again y/n" << endl; cin >> Ch; } return 0; }

If you noticed, the random number sequence generated over different executions
are the same. This is useful if you wish to run the same experiments again, but
not good for a game of chance. To overcome this problem a function called
**srand(unsigned int)** can be used to change the starting point of the sequence.

If the seed remains the same over multiple executions then the sequence
generated is again pseudo random. If the seed is made based on the system time, it
will be different every time we run the program and we will get a different
random sequence every time. Insert this line of code in your program:
**srand(time(NULL));** The seed is now set to the current time.
Now see how lucky you get.

Program output

Another useful function (actually its a macro) in the C++ standard
library is **assert()**. `assert()`

is
defined in the standard include file `cassert`

.
`assert()`

takes one parameter which is a boolean
expression. If the expression evaluates to true, then nothing happens
when the `assert()`

is executed. If the expression evaluates
to false, then the program halts at that point and prints a message indicating
the line and the expression of the failing `assert()`

.

`assert()`

statements can be added to your programs to test your code.
For instance, the following program uses `assert()`

to verify that the
`sum()`

function works correctly.

//------------------------------------------------------- // sum.cpp // Program to demonstrate assert() macro. // Author David Janzen // Fall 2005 //------------------------------------------------------- #include <iostream> #include <cassert> using namespace std; int sum(int min, int max); int main() { assert(sum(3,7)==25); assert(sum(-2,3)==3); assert(sum(-5,5)==0); cout << "No errors encountered" << endl; } // This function sums the integers // from min to max inclusive. // Pre: min < max // Post: return-value = min + (min+1) + ... // + (max-1) + max int sum(int min, int max) { int sum = 0; for(int i=min;i<=max;i++) { sum += i; } return sum; }

Add three more assert statements to test the `sum()`

function.
For instance, pass in two negative numbers or make both parameters the
same number.

Your main function

The following functions can be used to calculate the volumes of three different solids. Show how you should call each of these functions in the main function to perform the specified tasks. Make sure the data types on parameters and return values match the function definitions.

//------------------------------------------------------- // Author: John Gauch // Date: Fall 2003 //tests added by David Janzen Fall 2005 //------------------------------------------------------- #include <iostream> #include <cassert> using namespace std; // Function prototypes float cubeVolume( float sideLength ); double sphereVolume( float sidelength ); int cylinderVolume( float radius, int height ); // Calculate the volume of a cube float cubeVolume( float sideLength ) { return ( sideLength * sideLength * sideLength ); } // Calculate the colume of a sphere double sphereVolume( float radius ) { return ( (4.0 / 3.0) * 3.14159 * radius * radius * radius ); } // Calculate the volume of a cylinder int cylinderVolume( float radius, int height ) { return (int) ( 3.14159 * radius * radius * height ); } // Main function to test volume functions int main( int argc, char * argv[] ) { // Use assert() to write a test to compute the volume of a cube whose sides are 4 long // Use assert() to use a sphere radius and output volume // Use assert() to calculate the volume of a Pepsi can (or Coke if you prefer) cout << "No errors encountered" << endl; return 0; }

Your main function

N Factorial is equal to the product of all integers from 1 to N.
Specifically, factorial(N) = N x (N-1) x (N-2) x ... x 2 x 1. Write an
**iterative function** that performs the N Factorial calculation.
The function should take an int as a parameter and return an int as the
result of the function.

Write a short program that uses `assert()`

to test
your factorial function. Place all your `assert()`

statements in a `run_tests()`

function like this:

void run_tests(); int main() { run_tests(); } void run_tests() { { //test 1 assert( /* fill this in */ ); } //test 1 { //test 2 assert( /* fill this in */ ); } //test 2 }

Tests like these are called **unit tests**
because you are testing one unit (a function) of your program.
Writing tests after you have written some code is called
**test-last** programming. An alternative is to do **test-first**
programming where you write a test first, then write a function to make
the test pass, then repeat to write another test. Notice that
test-last programming primarily uses tests to verify that the code
works correctly, while test-first programming forces you to make design
decisions such as the function name, the function parameters, the function
return type, and the function's expected behavior when you are writing
the test. We will apply a test-first approach in lab next week.

Now that you have tested your factorial function, extend your program
so that it prompts the user for a value of the N to
calculate factorial. The program should output the result of the
calculation, then prompt the user again. It should prompt the user
until the user enters a value of zero. Then the program should exit.
Leave the tests in the program. You can comment out the call to
`run_tests()`

if you don't want them run.

Here is a sample of what your output might look like:

> Enter value of N: 3 Factorial(N) = 6 > Enter value of N: 5 Factorial(N) = 120 > Enter value of N: 0 End of program.

Your factorial program

Test the program you created by calculating two or three typical
values and copy the output of the program below. See if you can
"break" the program by changing what you input. Tests like these
are called **integration tests** because you are putting everything
together, or if the user is running them they are called **acceptance tests**
because you are seeing if the whole program functionality is acceptable.
Cut and paste your results below.

Your program output

The following program uses functions to generate the multiplication table of the number passed to the function. It was developed without any unit tests. Identify the errors present in the program and correct them. Add comments to the program to explain what each function does.

//------------------------------------------------------- // Author: Abhishek Shivadas // Date: Fall 2003 //------------------------------------------------------- #include <iostream> using namespace std; void multiply_by_two(int number); int multiply_by_three(int number); int main() { float number_two; char number_three; int number_four; cout << "Enter the Number to multiply by two:" << endl; cin >> number_two; cout << "Enter the Number to multiply by three:" << endl; cin >> number_three; cout << "Enter the Number to multiply by four:" << endl; cin >> number_four; } void multiply_by_two(float number) { int i; for(i = number; i <= 9; i++) cout << i << "times 2 is" << number * 2; return i; } int multiply_by_three(int number) { int i; for(i == number; i <= 9; i++) { number = number * 3; cout << i << "times 3 is" << number * 3; return number; } } int multiply_by_four(int number) { int i; boolean finished_calculating = true; for(i = number; i <= 9; i++) cout << i << "times 4 is" << number * 4; return finished_calculating; }

Create a C++ program called Number_Functions.cpp, and use "cut" and "paste" to copy the text above into the same. What errors do you get when you try to compile the program? Before you start correcting these errors, edit the file to add comments describing the purpose of the program, the author, and date at the top of Number_Functions.cpp. Now, start entering your corrections to make the compile errors go away. As a general rule, it is best to start with the first error message and recompile until that error is corrected.

For each correction, make a comment near the code you corrected indicating what you did. This way, you can remember what you did. When you work on joint programming projects everyone can keep track of changes to the code by reading everyone's comments. Ponder over the warnings which appear while compiling the code and if possible try to correct the warnings as well. The output of the above program should be like this:

"Number" times "2 or 3 or 4" is "Answer" . . . . . 9 times "2 or 3 or 4" is "Answer"

Corrected code

Output here

This lab assignment will be submitted electronically to the TAs once you fill in the fields below and click on the "submit" button. You do NOT need to print a copy of this document to hand in.

Your full name: | |

Your kuid number: |

If you are ready to send the lab to the grader, click on the submit button. Otherwise, go back and fill in any missing pieces and then submit your work.