Sunday, 8 September 2019

Github Repository for Principles and Practice

I have decided to move away from posting code on blogger as it's just getting more and more annoying with the code plug-in to keep code organised and somewhat readable with multiple file formats (and half the time it doesn't work anyway). So I have decided to step into the modern world and start a Git repository for the code. Whilst doing this, I am re-starting the entire book. When I started it 3 years ago, I had never programmed anything in my life and my comments on the blog posts on here are quite amusing to me now. 

I will try my best to only stick to using concepts introduced in each chapter (it's harder than I thought to not use other things; I kind of understand the users on Stack overflow now who tell you to just "use a map").

You can find the exercises and drills here:

Friday, 6 September 2019

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

Chapter 10 // Exercise 2

Write a program that creates a file of data in the form of the temperature Reading type defined in section 10.5. For testing, fill the file with at least 50 "temperature readings". Call this program store_temps.cpp and the file it creates raw_temps.txt.

Main.cpp

//--------------------------------------------//
//main.cpp
//--------------------------------------------//
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <conio.h>
using namespace std;
struct Reading
{
 int hour;
 double temperature;
};
int main()
{
 vector<Reading> temps;
 int hour;
 double temperature;
 cout << "Please enter temperatures in format HOUR TEMP. Example: 1 32.65    Press Ctrl+Z to stop.\n";
 while (cin >> hour >> temperature)
 {
  if (hour < 0 || hour > 23)
   cout << "Error. Hour out of range.\n" << endl;
  temps.push_back(Reading{ hour, temperature });
 }
 ofstream readOut{ "raw_temps.txt" };
 for (uint32_t i = 0; i < temps.size(); ++i)
  readOut << temps[i].hour << " " << temps[i].temperature << "\n";
 cout << "\nPress any key..."; _getch();
 return 0;
}




EDIT: 13/01/2020
New version on GitHub. This one has more error checking and actually parses the weird format instead of changing it. https://github.com/l-paz91/principles-practice/blob/master/Chapter%2010/Exercise%202

Thursday, 5 September 2019

Chapter 10 // Exercise 1 - Principles & Practice Using C++

Chapter 10 // Exercise 1

Write a program that produces the sum of all the numbers in a file of whitespace-separated integers.

Main.cpp
//--------------------------------------------//
//main.cpp
//--------------------------------------------//
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <conio.h>
using namespace std;
//create a file with white-space separated integers
void createFile()
{
 ofstream readOut{ "integers.txt" };
 if (!readOut)
  cout << "Error opening file" << endl;
 string integers;
 cout << "Enter a list of whitespace separated integers: (press enter when done)\n>>";
 getline(cin, integers);
 readOut << integers;
}
//read in from a file
vector<int> readInIntegersFromFile()
{
 vector<int> integers;
 ifstream readIn{ "integers.txt" };
 if(!readIn)
  cout << "Error opening file" << endl;
 int temp;
 while (!readIn.eof())
 {
  readIn >> temp;
  integers.push_back(temp);
 }
 return integers;
}
//add numbers together
int sumOfIntegers(vector<int>& v)
{
 int sum = 0;
 for (uint32_t i = 0; i < v.size(); ++i)
  sum += v[i];
 return sum;
}
int main()
{
 createFile();
 vector<int> integers = readInIntegersFromFile();
 int sum = sumOfIntegers(integers);
 cout << "Sum: " << sum << endl;
 cout << "\nPress any key..."; _getch();
 return 0;
}




EDIT: 13/01/2020

Tuesday, 3 September 2019

Chapter 10 // Drill 1, 2, 3, 4, 5, 6, 7 - Principles & Practice Using C++

Drill 1:
Start a program to work with points, discussed in section 10.4. Begin by defining the data type Point that has two coordinate members x and y.

#include <iostream>
#include <vector>
using namespace std;

struct Point
{
 double x, y;
};

int main()
{
 getchar();
 return 0;
}





Drill 2:
Using the code and discussion in section 10.4, prompt the user to input seven (,y) pairs. As the data is entered, store it in a vector of Points called original_points.

#include <iostream>
#include <vector>
using namespace std;

struct Point
{
 Point(double xcoor, double ycoor)
  : x(xcoor), y(ycoor) {}
 double x, y;
};

vector<Point> original_points;

int main()
{
 double x, y;
 cout << "Please enter 7 points (x,y) :" << endl;
 for (int i = 0; i < 7; ++i)
 {
  cout << "X: "; cin >> x;
  cout << "Y: "; cin >> y;
  original_points.emplace_back(x, y);
 }
 getchar();
 return 0;
}


Drill 3: 
Print the data in original_points to see what it looks like.
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;

struct Point
{
 Point(double xcoor, double ycoor)
  : x(xcoor), y(ycoor) {}
 double x, y;
};

ostream& operator<<(ostream& os, const vector<Point>& p)
{
 for (uint32_t i = 0; i < p.size(); ++i)
  os << "X: " << p[i].x << " | Y: " << p[i].y << endl;
 return os;
}

vector<Point> original_points;

int main()
{
 double x, y;

 cout << "Please enter 7 points (x,y) :" << endl;

 for (uint32_t i = 0; i < 7; ++i)
 {
  cout << "X: "; cin >> x;
  cout << "Y: "; cin >> y;
  original_points.emplace_back(x, y);
 }

 cout << original_points;

 _getch();
 return 0;
}

Drill 4:
Open an ofstream and output each point to a file named mydata.txt. On Windows, we suggest the .txt suffix to make it easier to look at the data with an ordinary text editor (such as WordPad)
#include <iostream>
#include <fstream>
#include <vector>
#include <conio.h>
using namespace std;

struct Point
{
 Point(double xcoor, double ycoor)
  : x(xcoor), y(ycoor) {}
 double x, y;
};

ostream& operator<<(ostream& os, const vector<Point>& p)
{
 for (uint32_t i = 0; i < p.size(); ++i)
  os << "X: " << p[i].x << " | Y: " << p[i].y << endl;
 return os;
}

vector<Point> original_points;
ofstream outFile{ "points.txt" };

int main()
{
 double x, y;

 cout << "Please enter 7 points (x,y) :" << endl;

 for (uint32_t i = 0; i < 7; ++i)
 {
  cout << "X: "; cin >> x;
  cout << "Y: "; cin >> y;
  original_points.emplace_back(x, y);
 }

 cout << original_points;
 outFile << original_points;

 _getch();
 return 0;
}

Drill 5:
Close the ofstream and then open an ifstream for mydata.txt. Read the data from mydata.txt and store it in a new vector called processed_points. 
//--------------------------------------------//
//main.cpp
//--------------------------------------------//

#include <iostream>
#include <fstream>
#include <vector>
#include <conio.h>
using namespace std;

// -----------------------------------------------------------------------------
struct Point
{
 Point(double xcoor, double ycoor)
  : x(xcoor), y(ycoor) {}
 double x, y;
};
// -----------------------------------------------------------------------------
//---VARIABLES---//
vector<Point> original_points, processed_points;
string filename = "mydata.txt";
ofstream outFile{ filename };
ifstream inFile{ filename };
// -----------------------------------------------------------------------------
//read in to a file
ostream& operator<<(ostream& os, const vector<Point>& p)
{
 for (uint32_t i = 0; i < p.size(); ++i)
  os << p[i].x << '\n' << p[i].y << endl;
 return os;
}
// -----------------------------------------------------------------------------
//read out from a file
ifstream& operator>>(ifstream& is, vector<Point>& p)
{
 double x, y;
 for (uint32_t i = 0; i < original_points.size(); ++i)
 {
  is >> x >> y;
  p.emplace_back(x, y);
 }
 return is;
}
// -----------------------------------------------------------------------------
//print out a vector of points
void printPointVector(const vector<Point>& p)
{
 for (uint32_t i = 0; i < p.size(); ++i)
  cout << "X: " << p[i].x << " | Y: " << p[i].y << endl;
 return;
}
// -----------------------------------------------------------------------------
int main()
{
 double x, y;
 cout << "Please enter 7 points (x,y) :" << endl;

 for (uint32_t i = 0; i < 7; ++i)
 {
  cout << "X: "; cin >> x;
  cout << "Y: "; cin >> y;
  original_points.emplace_back(x, y);
 }

 printPointVector(original_points);
 outFile << original_points;
 inFile >> processed_points;
 printPointVector(processed_points);

 cout << "\nPress any key..."; _getch();
 return 0;
}

OK so the problem I had here was that I was sending a whole bunch a characters to the outFile for formatting so it looked nice and readable. So, instead I created a new function for reading out to files and for printing those files. That way we can have nice pretty text on the screen but it's easy to read in and out of files. It's not great, however it beats parsing the file to ignore all the random characters. I did consider doing the parsing but thought to myself "is there a point, when the computer reads it in and outputs it all nice for you?" Isn't that the point of reading in from files? No one opens a jpg in notepad and goes "I wish this was more readable", so ultimately I decided to just leave things simplified.
Drill 6:
Print the data elements from both vectors. (NOT DONE)
This has been done in the previous exercise.
Drill 7:
Compare the two vectors and print Something's wrong! if the number of elements or the values of elements differ.

// -----------------------------------------------------------------------------
//compare the two vectors (added after ifstream& operator>>)

bool operator==(const vector<Point>& p1, const vector<Point>& p2)
{
 if (p1.size() != p2.size())
  return false;
 else
 {
  for (uint32_t i = 0; i < p1.size(); ++i)
  {
   if (p1[i].x != p2[i].x
    && p1[i].y != p2[i].y)
    return false;
  }
  return true;
 }
}


// -----------------------------------------------------------------------------

int main()
{
 double x, y;
 cout << "Please enter 7 points (x,y) :" << endl;

 for (uint32_t i = 0; i < 7; ++i)
 {
  cout << "X: "; cin >> x;
  cout << "Y: "; cin >> y;
  original_points.emplace_back(x, y);
 }

 printPointVector(original_points);
 outFile << original_points;
 inFile >> processed_points;
 printPointVector(processed_points);

 if (!(original_points == processed_points))
  cout << "Something's wrong!\n";

 cout << "\nPress any key..."; _getch();
 return 0;
}



Thursday, 22 August 2019

Chapter 9 // Exercise 16 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 9 // Exercise 16



Define an input operator (>>) that reads monetary amounts with currency denominations, such as USD1.23 and DKK5.00, into a Money variable. Also define a corresponding output operator.

main.cpp

//----------------------------------//
// main.cpp
//----------------------------------//

//INCLUDES//
#include "moneyClass.h"

int main()
{
 Money amount1(c_GBP, 3.34);
 amount1.printMoney();

 Money amount2(c_USD, 786.789);
 amount1.printMoney();

 //read in new money
 cin >> amount1;
 cin >> amount2;

 //print new amounts
 cout << amount1 << endl;
 cout << amount2 << endl;

 cout << "\nPress any key to quit...";
 _getch();

 return 0;
}

moneyClass.h

//----------------------------------//
// moneyClass.h
//----------------------------------//
// for calculations involving money
//----------------------------------//
#ifndef _MONEYCLASS_H_
#define _MONEYCLASS_H_

//INCLUDES//
#include <string>
#include <iostream>
#include <iomanip>
#include <conio.h>

using namespace std;

//----------------------------------//
// ENUM: Currencies
//----------------------------------//
enum Currencies
{
 c_GBP,
 c_USD
};

//----------------------------------//
// CLASS: Money
//----------------------------------//
class Money
{
public:
 Money();
 Money(Currencies currency, float amount);
 ~Money();

 void printMoney();

 Currencies getCurrency() { return m_currency; }
 void changeCurrency(Currencies currency) { m_currency = currency; }
 long int   getOutPutMoney() { return m_outputMoney; }
 double     getInputMoney()  { return m_inputMoney; }

private:
 //variables//
 Currencies m_currency;
 long int m_outputMoney; //cents
 double m_inputMoney; //dollars

};

//OPERATOR OVERLOADS//
void operator+(Money& money1, Money& money2);
ostream& operator<<(ostream& os, Money& money);
istream& operator>>(istream& is, Money& money);

#endif // !_MONEYCLASS_H_


moneyClass.cpp

//----------------------------------//
// moneyClass.cpp
//----------------------------------//
// for calculations involving money
//----------------------------------//

//INCLUDES//
#include "moneyClass.h"

//VARIABLES//
double gbp2usd = 1.26;
double usd2gbp = 0.79;


Money::Money() {}

Money::Money(Currencies currency, float amount) 
{
 m_currency = currency;
 m_inputMoney = amount;
}

Money::~Money() {}

//print output as dollars
void Money::printMoney()
{
 m_outputMoney = round(m_inputMoney * 100.0f);

 switch (m_currency)
 {
 case c_USD:
  cout << "-----USD----" << endl;
  cout << "Dollars: $" << fixed << setprecision(2) << m_inputMoney << endl;
  cout << "Cents: " << fixed << setprecision(0) << m_outputMoney << endl;
  break;
 case c_GBP:
  cout << "-----GBP----" << endl;
  cout << "Pounds: £" << fixed << setprecision(2) << m_inputMoney << endl;
  cout << "Pennies: " << fixed << setprecision(0) << m_outputMoney << "p" << endl;
  break;
 default:
  cout << "Bad output";
  break;
 }
}

//OPERATOR OVERLOADS//

//add currencies together - converts money if not the same
void operator+(Money& money1, Money& money2)
{
 cout << "\n";
 if (money1.getCurrency() == money2.getCurrency())
  //currencies are the same, no conversion needed, just add
  cout << fixed << setprecision(2) << money1.getInputMoney() + money2.getInputMoney();
 else if (money1.getCurrency() == c_GBP && money2.getCurrency() == c_USD)
 {
  //return pounds
  cout << fixed << setprecision(2) << "£" << (money2.getInputMoney() * usd2gbp) + money1.getInputMoney() << endl;
 }
 else if (money1.getCurrency() == c_USD && money2.getCurrency() == c_GBP)
 {
  //return dollars
  cout << fixed << setprecision(2) << "$" << (money2.getInputMoney() * gbp2usd) + money1.getInputMoney() << endl;
 }
}

//print out money
ostream& operator<<(ostream& os, Money& money)
{
 switch (money.getCurrency())
 {
 case c_GBP:
  return os << fixed << setprecision(2) << "\n£" << money.getInputMoney() << endl;
  break;
 case c_USD:
  return os << fixed << setprecision(2) << "\n$" << money.getInputMoney() << endl;
  break;
 default:
  return os << "Bad output";
  break;
 }
}

//read money into a Money variable
istream& operator>>(istream& is, Money& money)
{
 cout << "Please enter currency, followed by amount. For example GBP3.45" << endl;
 cout << "Currencies available: GBP || USD" << endl;

 string getMoney;
 cin >> getMoney;

 string denomination, amount;
 double mon;

 for (int i = 0; i < getMoney.size(); ++i)
 {
  if (i < 3)
   denomination += getMoney[i];
  else
   amount += getMoney[i];
 }

 //convert string to double
 mon = stod(amount);

 //update money variable
 if (denomination == "GBP")
 {
  money = Money(c_GBP, mon);
  money.changeCurrency(c_GBP);
 }
 else if (denomination == "USD")
 {
  money = Money(c_USD, mon);
  money.changeCurrency(c_USD);
 }
 else
 {
  cout << "bad input.";
 }

 return is;
}

My example is omitting some error checking due to time constraints so don't put in any illegal values otherwise it'll break however it does what he has asked for. When using cin >> with a Money variable it allows the user to input a new monetary value as well as change the currency. The << was already implemented in the last exercise. I also learnt in this exercise that there is a whole load of functions in the standard library for converting strings to almost any type of decimal. Bless the standard library.

Wednesday, 21 August 2019

Chapter 9 // Exercise 15 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 9 // Exercise 15



Refine the Money class by adding a currency (given as a constructor argument). Accept a floating-point initializer as long as it can be exactly represented as a long int. Don't accept illegal operations. For example, Money*Money doesn't make sense, and USD1.23+DKK5.00 makes sense only if you provide a conversion table defining the conversion factor between U.S. dollars (USD) and Danish kroner (DKK).

...I literally have no idea what he wants me to do here. So we add a currency in the constructor, say GBP as a string along with a floating-point value. We've already been doing that but now we have to to do a check to ensure that it will fit in a long int. A long int is 32 bits in size and a double is 64 bits. (If anyone is interested, in a programming interview I was asked about the size of a struct and it contained all the fundamental types, so it's worth learning the sizes of each type). A float is 32 bits so perhaps we should change m_dollars to a float instead. The worst that would happen if we didn't is that we would lose some bits as they would get truncated to fit. I don't understand what he means by illegal operations though. Does he mean, don't allow Money*Money in the initialiser? It wouldn't compile anyway in the code as there is no definition for it. And for USD1.23+DKK5.00 where is this called? By the programmer writing the code or is it an argument passed to the program via input from the user? If it was the latter, I suppose you would take it in as a string and parse each value, then pass the currency and value to the money class to be constructed with that value. You can construct new classes at run time but it's far beyond what's been taught in the book so far. This is not well constructed exercise.

main.cpp

//----------------------------------//
// main.cpp
//----------------------------------//

//INCLUDES//
#include "moneyClass.h"

int main()
{
 Money gbp(c_GBP, 3.34);
 gbp.printMoney();

 Money usd(c_USD, 786.789);
 usd.printMoney();

 gbp + usd;
 usd + gbp;

 cout << "\nPress any key to quit...";
 _getch();

 return 0;
}

moneyClass.h

//----------------------------------//
// moneyClass.h
//----------------------------------//
// for calculations involving money
//----------------------------------//
#ifndef _MONEYCLASS_H_
#define _MONEYCLASS_H_

//INCLUDES//
#include <iostream>
#include <iomanip>
#include <conio.h>

using namespace std;

//----------------------------------//
// ENUM: Currencies
//----------------------------------//
enum Currencies
{
 c_GBP,
 c_USD
};

//----------------------------------//
// CLASS: Money
//----------------------------------//
class Money
{
public:
 Money(Currencies currency, float amount);
 ~Money();

 void printMoney();

 Currencies getCurrency()    { return m_currency; }
 long int   getOutPutMoney() { return m_outputMoney; }
 double     getInputMoney()  { return m_inputMoney; }

private:
 //variables//
 Currencies m_currency;
 long int m_outputMoney; //cents
 double m_inputMoney; //dollars

};

//OPERATOR OVERLOADS//
void operator+(Money& money1, Money& money2);
ostream& operator<<(ostream& os, Money& money);

#endif // !_MONEYCLASS_H_


moneyClass.cpp

//----------------------------------//
// moneyClass.cpp
//----------------------------------//
// for calculations involving money
//----------------------------------//

//INCLUDES//
#include "moneyClass.h"

//VARIABLES//
double gbp2usd = 1.26;
double usd2gbp = 0.79;

Money::Money(Currencies currency, float amount) 
{
 m_currency = currency;
 m_inputMoney = amount;
}

Money::~Money() {}

//print output as dollars
void Money::printMoney()
{
 m_outputMoney = round(m_inputMoney * 100.0f);

 switch (m_currency)
 {
 case c_USD:
  cout << "-----USD----" << endl;
  cout << "Dollars: $" << fixed << setprecision(2) << m_inputMoney << endl;
  cout << "Cents: " << fixed << setprecision(0) << m_outputMoney << endl;
  break;
 case c_GBP:
  cout << "-----GBP----" << endl;
  cout << "Pounds: £" << fixed << setprecision(2) << m_inputMoney << endl;
  cout << "Pennies: " << fixed << setprecision(0) << m_outputMoney << "p" << endl;
  break;
 default:
  cout << "Bad output";
  break;
 }
}

//OPERATOR OVERLOADS//

//add currencies together - converts money if not the same
void operator+(Money& money1, Money& money2)
{
 cout << "\n";
 if (money1.getCurrency() == money2.getCurrency())
  //currencies are the same, no conversion needed, just add
  cout << fixed << setprecision(2) << money1.getInputMoney() + money2.getInputMoney();
 else if (money1.getCurrency() == c_GBP && money2.getCurrency() == c_USD)
 {
  //return pounds
  cout << fixed << setprecision(2) << "£" << (money2.getInputMoney() * usd2gbp) + money1.getInputMoney() << endl;
 }
 else if (money1.getCurrency() == c_USD && money2.getCurrency() == c_GBP)
 {
  //return dollars
  cout << fixed << setprecision(2) << "$" << (money2.getInputMoney() * gbp2usd) + money1.getInputMoney() << endl;
 }
}

//print out money
ostream& operator<<(ostream& os, Money& money)
{
 switch (money.getCurrency())
 {
 case c_GBP:
  return os << "\n£" << money.getInputMoney() << endl;
  break;
 case c_USD:
  return os << "\n$" << money.getInputMoney() << endl;
  break;
 default:
  return os << "Bad output";
  break;
 }
}

I'm still not entirely sure if this is what he wanted us to do but it takes in a currency (and you can add more to the enum, just provide converters in moneyClass.cpp). I even added some operator overloads to print out the money and add different currencies together.

Tuesday, 20 August 2019

Chapter 9 // Exercise 14 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 9 // Exercise 14



Design and implement a Money class for calculations involving dollars and cents where arithmetic has to be accurate to the last cent using the 4/5 rounding rule (.5 of a cent rounds up; anything less than .5 rounds down). Represent a monetary amount as a number of cents in a long int, but input and output as dollars and cents, e.g., $123.45. Do not worry about amounts that don't fit into a long int.

main.cpp

//----------------------------------//
// main.cpp
//----------------------------------//

//INCLUDES//
#include <iostream>
#include <iomanip>
#include <conio.h>

using namespace std;

int main()
{
 double cents, dollars;
 cout << "$";
 cin >> dollars;

 cents = dollars * 100.0f;
 cents = round(cents);

 cout << "Dollars: $" << fixed << setprecision(2) << dollars << endl;
 cout << "Cents: " << fixed << setprecision(0) << cents << endl;

 system("pause");
 return 0;
}

My first attempt I felt I had not done it correctly as it seemed a little too simple. It was the rounding rule that got me. Where did we need the code to round? When converting dollars to cents you just multiply it by 100. Then divide it by 100 to convert it back to dollars. I'm guessing he means that if someone inputs $2.298 he wants that figure rounded to $2.30 then stored as cents in a long int. I created a simple rounding program as seen above. This does exactly what he specifies. I then re-jigged it into the class format below as we expand on it in the next few exercises.

main.cpp

//----------------------------------//
// main.cpp
//----------------------------------//

//INCLUDES//
#include "moneyClass.h"

int main()
{
 Money money;
 money.menu();

 return 0;
}

moneyClass.h

//----------------------------------//
// moneyClass.h
//----------------------------------//
// for calculations involving dollars
// and cents
//----------------------------------//
#ifndef _MONEYCLASS_H_
#define _MONEYCLASS_H_

//INCLUDES//
#include <iostream>
#include <iomanip>
#include <conio.h>

using namespace std;

//----------------------------------//
// CLASS: Money
//----------------------------------//
class Money
{
public:
 Money();
 ~Money();

 void menu();

private:
 void getInput();
 void printDollars();

 void convertToCents();

 //variables//
 long int m_cents;
 double m_dollars;

};

#endif // !_MONEYCLASS_H_


moneyClass.cpp

//----------------------------------//
// moneyClass.cpp
//----------------------------------//
// for calculations involving dollars
// and cents
//----------------------------------//

//INCLUDES//
#include "moneyClass.h"

Money::Money() {}

Money::~Money() {}

//main menu
void Money::menu()
{
 cout << "-----Money Class----" << endl;

 getInput();
 convertToCents();
 printDollars();
}

//get input as $0.00
void Money::getInput()
{
 double input;
 cout << "Please enter dollars: \n$";
 cin >> input;

 m_dollars = input;
}

//convert dollars to cents
void Money::convertToCents()
{
 //100 cents == $1
 m_cents = round(m_dollars * 100.0f);
}

//print output as dollars
void Money::printDollars()
{
 cout << "Dollars: $" << fixed << setprecision(2) << m_dollars << endl;
 cout << "Cents: " << fixed << setprecision(0) << m_cents << endl;

 //return to main menu
 system("pause");
 system("CLS");
 m_cents = m_dollars = 0;
 menu();
}

A lot of people seem to go a bit crazy when it comes to rounding. The standard library provides a function called round() which generally adheres to the 4/5 rounding rule so there's no need to implement it yourself. Also, I used a float at first to store the currency however it came with some issues to I switched to a double to store the initial dollars in. I then just manipulated the output using cout functions to make them specific to certain decimal points.

Monday, 19 August 2019

Chapter 9 // Exercise 13 - Principles & Practice Using C++

In this exercise I am using Visual Studio Community 2017 and the header file "std_lib_facilities.h" which can be found here:

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


Chapter 9 // Exercise 13



Design and implement a rational number class, Rational. A rational number has two parts: a numerator and a denominator, for example, 5/6 (five-sixths, also known as approximately 0.83333). Look up the definition if you need to. Provide assignment, addition, subtraction, multiplication, division and equality operators. Also, provide a conversion to double. Why would people want to use a Rational class?

This one took me a while as I planned out exactly how to go around it. Bjarne made the exercise vague enough for it to be interpreted a number of ways (pun intended). This was not a hard exercise, however it did make me think about class structure and the time was spent rearranging functions. This isn't perfect as I've omitted quite a few error checks, which you obviously wouldn't do if the public were to use this. 

I probably spent more time than is necessary on formatting but I just wanted it to look pretty. We could have gone the whole calculator route as well and done a new version which took in a string of say "4:5 * 7:5" with ':' denoting the separator as we'd need that sign for division however I instead left it for the user to just implement what they'd like in code.

This kind of class would be very useful to people like me who get flustered when they see things like "5/16ths of inch". I've never really been that great at working with fractions so something that works it out for you is quite useful. However, you could just use Google...like I do.

As I've used quite a few files, here is the full code drop:
https://github.com/l-paz91/principles-practice/tree/master/Chapter%209/Exercise%2013

EDIT 03/12/2019 - The link above is a link to a new version that I completed today. To be honest I can't even remember what I did now for the original but it sounds stupidly complicated.

I found the following sites useful:
Rational Numbers
Finding Greatest Common Divisor

Tuesday, 25 June 2019

Blog Update // A New Adventure

It's been a while since this blog has seen some action. I promised myself I would finally finish P+P over last summer however, I started stressing about my dissertation and enjoyed being free for a while. Then I started the final year of my degree and well, it's the hardest year for a reason. I'm happy to announce that I have just graduated with a First with distinction.

In other news, I have received a job offer at a Microsoft game studio as a software engineer intern. I'll be working in the game engine department which I'm very happy about as that was the route I wanted to go. It's strange, all I've ever known is working minimum wage jobs. I was a waitress from 13-18, then a receptionist from 18-27 (and briefly a flight attendant at 22) and I always thought dream jobs were for people in movies or TV shows. I dropped out of college and a career to me was moving up from receptionist to head receptionist and maybe even getting on the management track. Then I decided to go back to school and get a degree. Now I'm actually getting paid to create video games; I still can't fully comprehend it.

I start in a couple of weeks and I'm terrified. Because I never did any programming before starting the course I can't stop thinking about how unprepared I am compared to youngsters these days who have been modding games since since they were kids. When I was kid we had a Windows 95 PC with a staggering 250mb hard drive and, wait for it, 32 whole megabytes of RAM. I remember having boxes of floppy disks filled with midi files from my favourite games. MP3's took too long to download so midi files had to do. Funny story, the first MP3 I ever downloaded was "Eyes on Me" from Final Fantasy 8 and it was 5mb. It took 2 and half hours to download and my mum kept having a go at me because she wanted to use the phone...ah the nineties.

Anyway, I will get Principle and Practice finished as I kind of need to be an excellent C++ programmer now. I also have a lot of projects that I want to start and I have some plans for this blog. My dissertation on the Super Nintendo went well and I ended up creating a program that converts bitmap images to SNES format as well as writing a short introduction on how to program the SNES. That's going to get cleaned up and hopefully this site can help others start their retro game-dev journey. The SNES fascinates me; as does Assembly programming and I'm trying my best to learn x86. 

After P&P, I'll be eventually posting full tutorials on how to create 2D and 3D games engines using DirectX 9 and 11 with C++. DX9 may be depreciated now but it still works on Windows 10 and it's a fantastic way to ease yourself into custom engine creation as 11 and 12 are headaches. Then, I'll be rounding it out with some Android tutorials. I've begrudgingly learnt Java (and I hate every second of using it) and hope that some apps will help bring in a little bit of extra money to pay the rent. I may switch to C# and Xamarin though, just because I hate Java that much.

The end goal eventually is to move back to my home town and start up my own games studio using my own engine; but we're talking 10 year goals here. I may even start Let's Playing as indie horror games (especially the terrible ones) are just the best thing. 

But anyway, ramble over. This blog has not been forgotten and I've already got a lot of exercises scheduled as I want to get several done so there are no long gaps again. I move in a couple of days but hopefully things should start up properly in August; I may start sooner though. Thanks again and happy programming.