Sunday, 24 July 2016

Chapter 4 Exercise // 5 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.5

Write a program that performs as a very simple calculator. Your calculator should be able to handle the four basic math operations - add, subtract, multiply, and divide - on two input values. Your program should prompt the user to enter three arguments: two double values and a character to represent an operation. If the entry arguments are 35.6, 24.1 and '+', the program should be "The sum of 35.6 and 24.1 is 59.7. In Chapter 6 we look at a much more sophisticated simple calculator.


#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
char loop = 'y';
double val1;
double val2;
char operation;

cout << "This is a simple calculator.\n";

while (loop == 'y')
{
cout << "Please enter your first numeric value: \n";
cin >> val1;
cout << "Please enter your second numeric value: \n";
cin >> val2;
cout << "Please enter an operation, '+', '-', '*' or '/': \n";
cin >> operation;

if (operation != '+' && operation != '-' && operation != '*' && operation != '/')
{
cout << "Sorry, that operation is not recognised. Please try again: \n";
cin >> operation;
}

double add = val1 + val2;
double minus = val1 - val2;
double mult = val1*val2;
double div = val1 / val2;

switch (operation)
{
case '+':
cout << "The sum of " << val1 << " and " << val2 << " is: " << add << endl;
break;
case '-':
cout << val1 << " minus " << val2 << " is: " << minus << endl;
break;
case '*':
cout << val1 << " multiplied by " << val2 << " is: " << mult << endl;
break;
case '/':
cout << val1 << " divided by " << val2 << " is: " << div << endl;
break;
}

cout << "\nWould you like to use the calculator again? y / n\n";
cin >> loop;

if (loop != 'y' && loop != 'n')
{
cout << "Sorry, not recognised. Try again. y / n: \n";
cin >> loop;
}

val1 = 0;
val2 = 0;
operation = 0;
}

keep_window_open();

return 0;
}

This was quite easy but also made me smile because it was the first time I had just sat down, wrote the code I saw in my head and when I pressed build, there were no errors. It's the little things in life...

So, we pretty much built a calculator in Exercise 3.10 but I wanted this one to be a bit more sophisticated. I wanted it to loop if you wanted to continue using it or exit if you didn't. That's why I created the char 'loop'. At the end of the loop it will ask if you want to continue and reads a char into 'loop'. If it's 'y' you go round again until you enter 'n' and it will take you out of the loop. 

I also created variables to store the operations mainly because I didn't want the lines becoming too long and it just leaves less room for error.  Also, a switch statement is much cleaner in this instance than using if and actually makes the code easier to read.

Friday, 22 July 2016

Chapter 4 Exercise // 4 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.4

Write a program to play a numbers guessing game. The user thinks of a number between 1 and 100 and your program asks questions to figure out what the number is (e.g. "Is the number you are thinking of less than 50?"). Your program should be able to identify the number after asking no more than seven questions. Hint: Use the < and <= operators and the if-else construct.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
char answer;
int guess = 50;
int questions = 0;

vector<int> dif(6);
dif[0] = 25;
dif[1] = 13;
dif[2] = 6;
dif[3] = 3;
dif[4] = 2;
dif[5] = 1;

cout << "Lets play a game...\n" << endl;
cout << "Think of a number between 1 and 100. \n";
cout << "c = correct  l = lower   h = higher\n";
cout << "Is it 50?\n";

while (cin >> answer)
{
++questions;

if (answer == 'c')
{
cout << "Knew it! Thanks for playing!\n";
{
if (questions == 1)
{
cout << "It took me " << questions << " question to guess your number!\n";
cout << "Please press ctrl + z and then enter to exit.\n";
}
else
{
cout << "It took me " << questions << " questions to guess your number!\n";
cout << "Please press ctrl + z and then enter to exit.\n";
}
}
}

else
{
{
if (answer == 'l' && questions <= dif.size())
guess -= dif[questions - 1];
}

{
if (answer == 'h' && questions <= dif.size())
guess += dif[questions - 1];

}

{
if (answer != 'l' && answer != 'h' && answer != 'c')
{
cout << "Sorry, that's not a valid answer. Use l (lower), h (higher) or c (correct)\n";
--questions;
}
}
cout << "\nIs it: " << guess << '\n';
}
}

keep_window_open();

return 0;
}

Holy moly did this one take me a while. I originally started off with just a load of if statements but my code was running into about 300 lines and I thought there had to be an easier way to do this using only functions we had been taught so far.

So I did a little digging on guessing games, especially since Bjarne said it should be able to guess in 7 tries. Turns out you can guess any number between 1 and 100 in 7 tries thanks to this:

http://math.stackexchange.com/questions/512994/guessing-a-number-between-1-and-100-in-7-guesses-or-less

So with this on board I set up a vector holding the various half way points. The if statements add or subtracts various half way points depending on how many questions have been asked already and then stores that guess for the next round to see if its correct or not.


Wednesday, 20 July 2016

Chapter 4 Exercise // 3 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.3

Read a sequence of double values into a vector. Think of each value as the distance between two citis along a given route. Compute and print the total distance (the sum of all distances). Find and print the smallest and greatest distance between two neighboring cities. Find and print the mean distance between two neighboring cities.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
vector<double> distances;
double miles;
cout << "Please enter distances between 2 cities, press enter, ctrl+z, then enter again to finish: \n";

while (cin >> miles)
distances.push_back(miles);

if (distances.size() == 0)
{
cout << "No values entered, Please try again. \n";
}

else
{
//sum
double sum = 0;

for (double i : distances)
sum += i;

cout << "The sum of all distances is: " << sum << endl;

//largest & smallest
sort(distances);
cout << "The smallest distance is: " << distances[0] << endl;
cout << "The largest distance is: " << distances[distances.size() - 1] << endl;

//mean
cout << "The mean of all distances is: " << sum / distances.size() << endl;
}


keep_window_open();

return 0;

}

Monday, 18 July 2016

Chapter 4 Exercise // 2 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 Exercise // 4.2

If we define the median of a sequence as a "number so that exactly as many elements come before it in the sequence as come after it," fix the program in 4.6.3 so that it always prints out a median. Hint: A median need not be an element of the sequence.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
vector<double> temps;

cout << "Please enter integers to find mean & median, press enter, ctrl+z, then enter again to finish: \n";

for (double temp; cin >> temp;)
temps.push_back(temp);

//compute mean temp
double sum = 0;
for (double x : temps) sum += x;
cout << "Average temperature: " << sum / temps.size() << '\n';

//compute median temp
sort(temps);

if (temps.size() % 2 == 0)
cout << "Median temperature: " << (temps[temps.size() / 2 - 1] + temps[temps.size() / 2]) / 2 << endl;
else
cout << "Median Temperature: " << temps[temps.size() / 2] << endl;

keep_window_open();

return 0;

}

Ok this one took me a while, not because I don't know how to calculate the median but I just completely forgot that values inputted into a vector are not labelled 1,2,3,4 etc...but 0,1,2,3,4 etc....

The median on an even amount of numbers is calculated as so:
Lets say we put the numbers 1, 2, 3,4 in. In a vector these are labelled as 1[0], 2[1], 3[2], 4[3]. Therefore when we divide the size by 2 it will return 2 which is the number 3 (it's confusing right?) So temps[temps.size() / 2 - 1] will now return 2 and then we add it to temps[temps.size() /2] to give us 5. We then divide all that by 2 to get 2.5 which is the median.

I made the mistake of having +1 in my calculations and got very annoyed as didn't work, especially since in normal maths terms it should've worked. I've seen the above code a lot whilst I was searching for answers and not one person replied with "vectors start at 0, just -1 instead of +1". Just the standard "Use this instead"....

Saturday, 16 July 2016

Chapter 4 Exercise // Try This - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 4 - Try This pg 105

Use the example as a model for a program that converts yen ('y'), kroner ('k), and pounds ('p') into dollars. If you like realism, you can find conversion rates on the web.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
double amount;
string currency;

cout << "Please select which currency you would like to convert: \n";
cout << "Y = Yen \nK = Kroner \nP = GB Pound\n";
cin >> currency;

cout << "Please enter the amount to convert to dollars: \n";
cin >> amount;

const double yToD = amount*0.0096;
const double kToD = amount*0.15;
const double pToD = amount*1.47;

if (currency == "Y" || currency == "y")
cout << "That is $" << yToD << endl;
else if (currency == "K" || currency == "k")
cout << "That is $" << kToD << endl;
else if (currency == "P" || currency == "p")
cout << "That is $" << pToD << endl;
else cout << "Sorry, that is an invalid unit. Please try again.";


keep_window_open();

return 0;

}

Chapter 4 - Try This pg 109

Rewrite the currency converter from the previous try this to use a switch-statement. Add conversions from yuan and kroner. Which version is easier to write, understand and modify? Why?

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
double amount;
char currency;

cout << "Please select which currency you would like to convert: \n";
cout << "Y = Yen \nK = Danish Kroner \nP = GB Pound\nC = Chinese Yuan\nS = Swedish Krona\n";
cin >> currency;

cout << "Please enter the amount to convert to dollars: \n";
cin >> amount;

const double yToD = amount*0.0096;
const double kToD = amount*0.15;
const double pToD = amount*1.47;
const double cToD = amount*0.15;
const double sToD = amount*0.12;

switch (currency)
{
case 'Y': case 'y':
cout << "That is $" << yToD << endl;
break;
case 'K': case 'k':
cout << "That is $" << kToD << endl;
break;
case 'P': case 'p':
cout << "That is $" << pToD << endl;
break;
case 'C': case 'c':
cout << "That is $" << cToD << endl;
break;
case 'S' : case 's':
cout << "That is $" << sToD << endl;
break;
default:
cout << "Sorry, that is an invalid unit, please try again.\n";
}


keep_window_open();

return 0;
}


I am a big fan of the If and Else If formula however the switch is much easier to read. That said, you can't compare strings on a switch but for numbers and chars it's much more ideal.

Chapter 4 - Try This pg 111

The character 'b' is char('a'+1), 'c' is char('a'+2), etc. Use a loop to write out a table of characters with their corresponding integer values.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{
int i = 'a';
char a = 'a';

while (i < 'z')
{
cout << a << '\t' << i << '\n';
++i;
++a;
}

keep_window_open();

return 0;

}


This took me so long to figure out mainly because I didn't understand exactly what he wanted me to do at first, it was only after some head scratching and other people being as confused as me online that I realized he was talking about the actual char numbers. It seems obvious now I've been learning for a few months but when you're a complete newbie I was like, where the eff are you getting these numbers from?


Chapter 4 - Try This pg 113


Rewrite the character value example from the previous try this to use a for-statement. Then modify your program to to also write out a table of the integer value for uppercase letters and digits.

Part 1 

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{

for (char a = 'a'; a < 'z'; ++a)
{
cout << a << '\t' << int(a) << '\n';
++a;
}

keep_window_open();

return 0;
}

Part 2

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;


int main()
{

for (char a = '0'; a < 'z'; ++a)
{
cout << a << '\t' << int(a) << '\n';
}

keep_window_open();

return 0;

}


It took me a while to figure this one out initially, mainly because I kept thinking that I had to keep both variables but then I remembered you can easily convert between char and int.

Chapter 4 - Try This pg 116

Implement square() without the multiplication operator; that is, do the x*x by repeated addition (start a variable result at 0 and add x to it x times). Then run some version of the "first program" using that square.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

int square(int x)
{
//this variable will become x (the inputted value)
int y = 0;

//while z is less than x(inputted value), ++z and add x
//to y until z equals x. So if 2 is entered, 2 will be      added 
//to y until z equals 2.
for (int z = 0; z < x; ++z)
y += x;

return y;
}


int main()
{


cout << "Please enter a value to square: \n";
int value;
cin >> value;

cout << value << " squared is: " << square(value) << endl;

keep_window_open();

return 0;

}


I'm adding some extra comments to this mainly because I couldn't quite wrap my head around how the loop worked. Maths isn't my strongest subject (but that doesn't stop me from enjoying it) and a lot of explanations on the web just didn't explain it in dunce terms enough. So for those of you like me square() works like this:

  • (int x) will become whatever is written in the variable value
  • y is going to become the squared number that we will return.
  • z is created to count how many times we need to loop and add x to y. So if we enter 5, x becomes 5, the loop will check to see if z is smaller than 5. If it is, z will be incremented by 1 and x(5) will be added to y. This continues until z matches x, at which point y will have had x added to it enough times to create the squared number.

I know this loop is stupidly simple to most but for me it would have been great to find a explanation somewhere like this without some expert coming in and going "you noob, go learn some math". Now I've wrapped my head around it, I understand it but everyone learns at different rates and in different ways.


Chapter 4 - Try This pg 125


Write a program that "bleeps" out words you don't like; that is, you read in words using cin and print them again on cout. If a word is among a few you have defined, write out BLEEP instead of that word. Start with one "disliked word" such as:

string disliked = "broccoli";

When that works, add a few more.

//
#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;



int main()
{
vector<string> words;
string disliked = "broccoli";
string replacement = "BLEEP";

cout << "Please enter words, press enter then Ctrl + Z when finished: \n";

//read whitespaced words into enterWords
for (string enterWords; cin >> enterWords;)
words.push_back(enterWords);
 

//sort them 
sort(words);


//loop to print all words entered, so if 5 words
//are entered, each word will be printed until
//a == 4
for (int a = 0; a < words.size(); ++a)
{
if (words[a] != disliked)
cout << words[a] << endl;

else
cout << replacement << endl;
}

keep_window_open();

return 0;
}

OK, this one was a bit of an arse mainly because ctrl+z doesn't actually seem to stop input in a loop, well not on my computer anyway. I spent a long time searching the internet for answers as well but again came up with know-it-alls saying "oh just do this" (something we haven't learnt yet or can even understand) or "why are you even bothering?". 

For some reason when I press ctrl+z in my loop it shows "^Z" and would read this into the input stream because it's a valid character. The trick I learnt to get it to actually work though was to press enter, then press ctrl+z, then press enter again. This ended the input loop and proceeded to the next part of the program.

#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
#include <vector>
using namespace std;



int main()
{
vector<string> words;
string d1 = "broccoli";
string d2 = "donald";
string d3 = "manbearpig";
string d4 = "marmite";
string replacement = "BLEEP";

cout << "Please enter words, press enter then Ctrl + Z when finished: \n";

//read whitespaced words into enterWords
for (string enterWords; cin >> enterWords;)
words.push_back(enterWords);
 

//sort them 
sort(words);


//loop to print all words entered, so if 5 words
//are entered, each word will be printed until
//a == 4
for (int a = 0; a < words.size(); ++a)
{
if (words[a] == d1 || words[a] == d2 || words[a] == d3 || words[a] == d4)
cout << replacement << endl;
else
cout << words[a] << endl;
}

keep_window_open();

return 0;
}

I originally tried to use another vector containing a bunch of strings however, as I tried to compare the two vectors I realised that it was a little beyond me as of yet.