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;
}