# 5.x — Chapter 5 comprehensive quiz

Quick review

If statements allow us to execute a statement based on whether some condition is true. Else statements execute if the associated if statement is false. You can chain together multiple if and else statements.

Switch statements provide a cleaner and faster method for selecting between a number of discrete items. Switch statements pair great with enumerations.

Goto statements allow the program to jump to somewhere else in the code. Don’t use these.

While loops allow the program to loop as long as a given condition is true. The condition is evaluated before the loop executes.

Do while loops are the same as while loops, but the condition is evaluated after the loop execution. They’re great for menus or things that need to execute at least once.

For loops are the most used loop, and are perfect when you need to loop a specific number of times.

Break statements allow us to break out of a switch, while, do while, or for loop. Or a for each loop, which we haven’t covered yet.

Continue statements allow us to move immediately to the next loop iteration. Be careful when using these with while and do while loops, as your loop counter may not get incremented properly.

And finally, random numbers give us a way to make our programs behave different each time they are run. We’ll see an example of this in the quiz below!

Quiz time!

Warning: The quizzes start getting harder from this point forward, but you can do it. Let’s rock these quizzes!

1) In the chapter 2 comprehensive quiz, we wrote a program to simulate a ball falling off of a tower. Because we didn’t have loops yet, the ball could only fall for 5 seconds.

Take the program below and modify it so that the ball falls for as many seconds as needed until it reaches the ground.

In constants.h:

Show Solution

2a) Implement a game of hi-lo. First, your program should pick a random integer between 1 and 100. The user is given 7 tries to guess the number.

If the user does not guess the correct number, the program should tell them whether they guessed too high or too low. If the user guesses the right number, the program should tell them they won. If they run out of guesses, the program should tell them they lost, and what the correct number is. At the end of the game, the user should be asked if they want to play again. If the user doesn’t enter ‘y’ or ‘n’, ask them again.

Note: You do not need to implement error handling for the user’s guess.

Here’s what your output should look like:

```Let's play a game.  I'm thinking of a number.  You have 7 tries to guess what it is.
Guess #1: 64
Guess #2: 32
Guess #3: 54
Guess #4: 51
Correct! You win!
Would you like to play again (y/n)? y
Let's play a game.  I'm thinking of a number.  You have 7 tries to guess what it is.
Guess #1: 64
Guess #2: 32
Guess #3: 54
Guess #4: 51
Guess #5: 36
Guess #6: 45
Guess #7: 48
Sorry, you lose.  The correct number was 49.
Would you like to play again (y/n)? q
Would you like to play again (y/n)? f
Would you like to play again (y/n)? n
Thank you for playing.
```

Hints:
* If your compiler is C++11 capable, use the Mersenne Twister algorithm from chapter 5.9 -- Random number generation to pick a random number.
* If your compiler is not C++11 capable, you can use rand() (also presented in chapter 5.9 -- Random number generation) to pick a random number
* Write a function that allows the user to play a single game of hi-lo.
* Write a function that asks the user if they want to play again and handles the looping logic for an incorrect input.

Show Solution

2b) Update your previous solution to handle invalid input (e.g. ‘x’) or valid input with extraneous characters (e.g. “43x”) when the user is guessing a number.

Hint: Write a separate function to handle the user inputting their guess (along with the associated error handling).

Show Solution

 6.1 -- Arrays (Part I) Index 5.11 -- Introduction to testing your code

### 485 comments to 5.x — Chapter 5 comprehensive quiz

• Gapo

What do you guys say about my code here ?

• Alex

Your program is called srand() every time you play again. You should only call it once at the top of main().
Your randomNumGenerator() function has a lot of magic numbers, what are they doing?

• bily salazar

after two days of struggling with this assignment and almost giving up, i poured through all of the lessons again and looked up different ways of doing things.  here is what i came up with.  about 40 more lines than yours but i just finished it and haven't done a second pass to clean it up.

thank you so much for these tutorials!

• Hugh Mungus

Alex, can you take a look at my solution for the second question?

• Alex

Looks good.

• Ignacio

This is my solution for the game, but Alex's solution is cleaner

• Jeppe

Been following this tutorial for a while and just wanted to say thanks Alex, it is very awesome!

My version of Quiz 1, less funtions but i think it does the job:

This is my solution to the second quiz, is there anything to be improved? I have used the Mersenne Twister to generate the random number.

• Ryo

Hello, this is my solution to question nr.2

I made this after taking a break for 1 month from learning, so I hope it atleast follows the proper conventions of C++ that we have been taught so far.

• Preston

Hey Alex, what do you think of my solution to question 2? Unfortunately, using what I've covered so far I couldn't find a way to reject decimal inputs, e.g. 18.5. I tried adding an extra std::cin after I import a value to x to see if there is more data waiting in the buffer - such as a period - but that only works if the user actually entered a decimal value. If the user entered an integer, then computer asks the user to input more data, defeating the purpose. My compromise was to have std::cin truncated decimals and then use cin.ignore to clear the rest of the buffer. Any ideas?

• Alex

Seems fine to me -- let std::cin extract to the integer, and then discard any extraneous input with std::cin.ignore().

• Preston

That's what I'm currently doing. My question was, can you think of a way to have the program spit out an error if someone types in a decimal

• Alex

One way would be to have the user enter a string, then validate that the string is the proper format before converting it into an integer. I cover a little bit about input validation in lesson 13.5.

There may be a better way to do this using cin directly -- but C++ I/O isn't my strong point.

• Raquib

Hi Alex,

I have done the quiz 2. It is working fine, and I don't see a problem so far. So I would love if you make some comments on how I can improve it, whether I have followed the norms of good programming in your opinion, etc.

//function.h

//main.cpp

Thanks. I am thoroughly enjoying how stuffs are building up slowly 🙂 Can't wait to do object oriented programming and exception chapters.

• Raquib

************************UPDATE*******************************************

I have found some bugs here so I am updating the code a little bit-----

//in functions.cpp

//And in functions.cpp

Thanks.

• Logan

Hey Alex. Is this okay for the ball drop? I modified it a little so it can handle initial velocity.

• Alex

Yes, this is great. The only thing I would change is that I'd move the definition of dropSpeed below the loop, since the loop doesn't use it. Declare your variables as close to their first use as possible. Well done.

• Damien

Hi Alex,

If you have time, would you please be able to give some critique on my solution for question 2. I didn't see the hints before i did it so my answer is a bit different. My main concern is that my program is hard to follow, with functions being inside the loops and it causing the path to jump around a bit. Still, this exercise was fun.

Thanks again!

io.h

io.cpp

main.cpp

• Alex

Your program actually looks pretty good, except for one thing. playGame() calls anotherGame(), which calls playGame(), which calls anotherGame()... If a user were to play this game enough times, the program would eventually run out of stack space and crash.

It would be better to add a while loop into main() to continually call playGame() until anotherGame() returns false. That way, anotherGame() doesn't explicitly have to call playGame().

• hussein

actually that was my question, the code compiles and i don't know why it doesn't give me error!

• Alex

Did you declare a variable named t somewhere in constants.h? If you did, then it would be getting copied into your main file since you #include constants.h.

That's the only thing I can think of.

• hussein

Hey Alex, can you look at this code and tell me what you think

#include "stdafx.h"
#include <iostream>
#include "constants.h"

[using namespace std;
using namespace constants;
double distanceFallen(double initialHeight, int t)
{

return initialHeight - (gravity*t*t) / 2;
}
int main()
{

cout << " Enter initial height of the ball: ";
double initialHeight;
cin >> initialHeight;
int count = 0;
for (t = 0; distanceFallen(initialHeight, t) >= 0; t++)
cout << " At " << t << " seconds the ball is at height " << distanceFallen(initialHeight, t) << endl;
cout << " ...And finally the all hits the ground in " << t << " seconds " << endl;

}]

• Alex

Generally looks good, except you use variable t in function main() without defining it.

• Bw793

Hi Alex! I just want to thank you for your great work with the lessons, which are clear and well based. Thanks also for your dedication to clarify doubts!

How can my code be improved?

• Alex

You could use a do-while loop instead of a while loop to remove the redundant call to playGame(). You could use demorgan's law to distribute the ! sign inside playAgain(). srand() should only be called once at the start of the program, not every time a random number is picked.

• Nicolas

Hey, after first creating a very complex but functional program for question 1, I came up with this final solution. I was just wondering what you thought about it, and if you would have change anything (I know i should have put the constant in a header file but I didn’t for simplicity)

• Alex

My suggestions for improvement:
1) Give your variables better names
2) A few comments explaining what your functions are doing would go a long way
3) You have redundant calls to calculateHeight(). This isn't necessarily a problem, but is inefficient.

Hello again

...and sorry for the persistence. So far, I have read your tutorial page by page, never going forward until the current lesson has sunked in. There may be some vague feelings but I suspect they'll be gone with enough practise.

For every page that had a quiz, I made sure I solved it without looking back in the lessons (one or two exceptions where the compiler complained about my syntax...), or in the q&a, or cheat by peeking under the hood. Again, I didn't move forward until I have solved the problem.

But these were fairly simple, the only reward was getting to the next chapter. This quiz, however, proved more challenging, because there already is quite a bit of knowledge to juggle with -- this coming from someone who only knew a few miligrams of programming, and not even those well enough. But I kept to my stubborn way and, well, I did it. I admit it took me a day (on-off, as time allowed), and towards the later part there was more hammering than logic, but I did it.

Why am I saying this? Because, at this point, while I am comparing myself with the official result and others from the q&a, I am left wondering about how well I actually did. So, Alex, if I post the code, could you please be [extra-]critic about my results? I could really use some form of feedback, good or bad.

Quiz 1 (additional printing of time@touchdown):

constants.h

main.cpp

--------------
Quiz 2 (additional choice after executing the program and some exceptions):

main.cpp

I apologize if this turns out to be a very lengthy post.

• Alex

Without commenting on specific items, I'll say that for where you are in the tutorials, I think you're doing a reasonably good job. I like that you've clearly labeled your "hacks" or things that you're uncertain about. I don't see anything egregious here, just a lot of room for optimization.

Thank you, I have noone to turn to for answers here so even a "no" would have meant a feedback. Fortunately, it's more than that. 🙂 I know I am far from having the current chapter level, but, maybe with enough practise...

I wanted to try a Newton-Raphson solver, but I don't know yet how to parse a string and extract the terms into an array or some sort. I don't see a 20th order equation entyered, term by term, with enter after each one, only to realize you made a mistake at term 19. Stackexchange has solutions, but they go over my head now, and I took a peak at the index only to reveal that I probably won't be having any solver until chapter 13. Ah well, I have patience.

Thank you for making this *understandable*.

• Alex

You're welcome. Extracting stuff from a string is harder in practice that it seems like it should be, especially if the format of the string can vary.

I thought it might be so judging by the amount of answers, each pulling its own way and everyone having very different arguments to each. OTOH, it's tempting to think that people using the program would not have the intent to crash it, instead of finding out the roots. But Murphy did have some excellent points...

• joe

I found that if you change calculateAndPrintHeight to a double, and return height, you can run this in main and it works just fine.

[code]
int main()
{
const double initialHeight = getInitialHeight();

int seconds(0);
while (calculateAndPrintHeight(initialHeight, seconds) >= 0)
++seconds;

return 0;

}

• Nyap

insult my work plz

question 1
http://pastebin.com/U6ECcjTQ

question 2
http://pastebin.com/xdLQjjtV

I feel like i've rushed this chapter, so I know that there has to be at least 1 thing wrong with them xD
I'll go over this chapter again tommorow

• Hussain

Thanks Alex for the amazing tutorials!

I have a question with regard to Q1 if I may:

I changed the manual seconds inputs (in the main function) with the following loop:

I didn't change anything else. Is that an acceptable approach?!

• Alex

Depends on what you mean by acceptable. It may produce the right answer, but it's a bit inefficient since calculateAndPrintHeight() is calculating the height to do its job, and then you're calling calculateHeight() again. That's a bit redundant.

• J3ANP3T3R

on test 1 :

bool calculateAndPrintHeight(double initialHeight, int seconds)  // Changed from void to bool
{
double height = calculateHeight(initialHeight, seconds);
printHeight(height, seconds);

if (height <= 0.0)      // Added condition
return 1;    // on the ground
else
return 0;       // Still flying
}

int main()
{
const double initialHeight = getInitialHeight();

int sec{ 0 };                                             // Added variable for the loop
while (!calculateAndPrintHeight(initialHeight, sec))      // print till ball hits the ground
{
++sec;
}

return 0;
}

is the result the same ?

• J3ANP3T3R

Weird ... i get the same number 80% of the time.

by the way my visual studio 2015 community edition is going to expire in 14 days i thought it was free :3

• Alex

Visual Studio is free beyond 30 days if you register an account with Microsoft. There should be some way to do that through the application.

• Alex

Looks like it would work the same. You really should return true and false instead of 1 and 2.

It's also not intuitive what the meaning of the return value of your calculateAndPrintHeight function is.

• J3ANP3T3R

oh right the enums. i forgot about that.

• Ola Sh

Your solution is really good especially in terms of performance and understandability. I would like to know what you think about my solution for future references. I understand I should have called the function for the hi-Lo game preferably once. Thanks ahead.

• Alex

The only other thing I see is that the "else continue" is redundant.

• Ola Sh

Thanks for that. I see that now.

• Chris

I don't know how to gauge the readability of my program since it just makes sense to me but I want to know if this is too jumpy or too complicated. I realize some things can be condensed after looking at your solution but I was wondering if my attempt was passable. There are sooo many different ways to solve something it feels like the more you look at your code the more efficient you can make it almost like an artist spending too much time on their painting.

• Alex

The overall structure looks pretty good. The logic in playGame() is a little convoluted in that it handles both individual guesses and new games. Seems like this could be separated a bit for ease of comprehension.

• Chris

Ah, I see thank you very much! I know you said in one of your earlier lessons that one function should serve one purpose, so should function calling be as limited as possible in other functions and be better reserved for main()? In other words, if I can help it, always call from main? (I know it's inevitable that functions will need to call other functions to get values and such).

• Alex

A well-written function should only serve one purpose, but that purpose could be to call a few other functions to do something useful.

For example, a function named runGame() could look like this:

This function calls three other functions to do its job, but it still has one goal: to run the game until the player dies.

There's nothing special about calling a function from main() as opposed to some other function.

• Chris

Thank you for the replies! I was thinking more about for ease of comprehension rather than special-ness but I think I understand better now. I thought you meant that calling playAgain() in my program inside my playGame() function made it convoluted. Rather, it was the logic statements which handled more than one purpose. Thank you so much for these tutorials, that's awesome of you! Have a great day!

• Veer

Hey Alex, I just wanted to point out that in the first question, the headers are included two times.

• Alex

Thanks, fixed!

• Indorfin

Is there any reason not to combine a PRNG with the remainder symbol %? For example, if I wanted to get a random number between 1-100, couldn't I just let it generate its random number between 0 and 37,xxx, then take the remainder after dividing by 100 to be my "random selection"?

• Alex

Yes, you can do this if you don't care about getting a slightly uneven distribution.

• orbit

Got a question. Might be I'm missing something but I can't figure it out.
It's the function bool playAgain()

How can a bool return a char? 😮
How would the compiler know (ch == 'y') to be true?

• Alex

A bool doesn't return a char.

First, the function returns a boolean value.

Second, the return expression is (ch == 'y'). The job of operator== in this function is to compare ch and 'y' and see if they are equal. If so, this operator evaluates to true, otherwise it evaluates to false. And this boolean value is then returned by the function.

• orbit

omg...kinda feel stupid for thinking it assigned "y" to ch - thx for making me see clearer 😉

• Domenic D

I am amazed at how far I have come so far and I'm not saying it was easy either but I am still amazed and very appreciative for this tutorial.Seems like this is how I am going to learn C++. I have enrolled in on-line video based courses but for some reason it won't stick.I do watch them for refreshing purposes.

Thanks Alex.

• ImDaW

Hi Alex!
I just want to tell you that your guide is the best!
That's my solution for the second quiz!
Thanks for all!

• sandy

For the second quiz hi-lo, when the game asks for guess, if the user enters dd or any characters instead of integers the console went crazy!!! Do you know why? and how to prevent it since its a run time error.

• Alex

Yes, this happens because the extraction to an integer fails when you enter a non-integer input, and then all further input stops working until the problem is resolved. You can fix this by detecting the error and resolving it like so:

• Shiva

Alex, I also spotted a small mistake in the solution to Quiz #2:

The second else if inside the playGame() function is unnecessary. Only else is needed, as what the if statement checks is the only remaining possibility.

• Alex

Not a mistake so much as an inefficiency. I've updated the solution. Thanks for pointing that out.