Showing posts with label Cpp. Show all posts
Showing posts with label Cpp. Show all posts

Tuesday, April 12, 2016

Approach for Studying cppreference.com

My approach for reading the cpp reference materials is to start by reading each of the high level topics (ie each page that is directly linked from the main cppreference landing page. Once I have made a sweep of the high level topics, I'll go back to do more in depth reading of the lower level material.

There is a lot of material, so it is easy to feel overwhelmed. Even the basic concepts page has mentioned many things that I need to review/learn (like translation, parameter packs, and odr-used). I'll have to find the right balance of digging in and challenging myself to really know what I say I know, yet also moving on from a topic so that I don't become bored and frustrated and quit before I should.

I took a quick look at each of those unfamiliar topics I just mentioned and after reading just a little, things weren't nearly as initmidating as before. Translation is just a series of steps to go from the code we type into our text editors to a format that computers can run. Parameter packs are a group of parameters for templates. They are a somewhat newer feature of the C++ language so I don't feel so bad that I don't know them well. And odr-used is an awkward spelling/grammatical phrase describing the concept that things must have unique definitions (unlike declarations).

So this is the start of my cppreference reading journey. Let's see how it goes.

Saturday, March 26, 2016

Studying cppreference

I have been writing programs in C++ for several years now, but there are many concepts that I don't know very well. My knowledge of the subject feels so shallow. I want to make a a concerted effort to fill in these holes. So, I'm going to commit to another goal.

I'm going to read each of the references documents in the Standard C++ reference, and then summarize them in my own words.

I like this commitment because it has a well defined ending. I think and hope it will be a worthwhile endeavor.

Update I have heard that the cpluscplus.com website may not be the best reference material to read. It seems like http://en.cppreference.com/w/ may be the more respected source. So, I'll base my studies off of cppreference instead.

See my reports below

Sunday, January 25, 2015

Building a Sudoku Solver

Sudoku Solver

A couple of weeks ago I tried my hand at building a game, Tic-tac-toe. Today, I finished building something else. I wrote a command line program that solves Sudoku puzzles. The input to the program is a series of numbers representing a sudoku puzzle board, and the output is printed to a terminal screen.

What did I do?

I built the program in C++ with the help of 3 different libraries (google test/mock for testing, boost for handling command line arguments, and ncurses for drawing to the terminal). I had already used google test and boost before, so it was simple to use them in this project. Ncurses was new for me, but it basically worked right out of the box (after updating the link line and including the header). I think I could have written this program without any of these libraries, but it would have been a lot more painful and buggier.

The program is designed to have a MVC (Model, View, Controller) architecture. The model is the puzzle board data, the view is the command line terminal, and the controller is something that observes the model and calls the view to draw. TODO: Learn more about the MVC pattern. Then make my code conform the pattern better, or stop calling what I wrote "MVC".

The business logic of this program was to solve a Sudoku puzzle. The reason I started writing this program was to practice writing a backtracking dynamic programming algorithm. For the current version, I chose a pretty simple algorithm that walks through the grid cell by cell in order. It works for the few test inputs that I gave. However, there is lots of room for improvement.

What did I spend my time on?

I spent almost all of my time setting up the apparatus for the game - ingesting input, updating the view, connecting the components together, etc ... I spent very little time on the algorithm used to calculate the answer. Now that the apparatus works ok, (if I want to) I can work on improving the solving algorithm.

Takeaways

Building a real application can be a good way to learn, but it's easy to fall into the trap of only reusing techniques, approaches and tools that you are already familiar with. Unless you keep asking yourself, "is there a better way to do this?", you may never expand your skills.

Positive feedback is really important. It feels good to see your unit tests passing and your output displayed on some screen. That sense of accomplishment can keep you motivated when you are lacking the motivation to finish a project.

Sunday, November 30, 2014

Building Tic Tac Toe

This Saturday, I had some free time, so I decided to do some coding.

I thought it might be fun to build a puzzle type of game. It would involve using some complex data structures and algorithms that I have been reading about.

But as I started planning, I realized building a new game from scratch seemed a little bit daunting. Instead, I decided to write a program where I could simple play Tic Tac Toe.

I figured this would give me a decent framework in which I can build more complex games later.

Version 0.1 of this game is done and available here.

Monday, August 12, 2013

Simple C++ program with Google test

I have little to no experience with unit testing.  I want to change that.

In principle, unit testing sounds simple.  Unit tests are used to isolate and validate small parts of a program are working.  In practice, I don't really know how it's done.

As a first attempt, I tried to build a simple program with tests using google test, https://code.google.com/p/googletest/.  After downloading and unzipping the library, I moved it into a folder -- SomeDirectory/libs/gtest-1.6.0.  I then copied these files into a separate directory.
  • Makefile -- this is used by make to build both the test program and my program.
  • sample1.h, sample1.cc -- These define some functions that are linked into the test program and into my program.
  • sample_unittest.cc -- This defines test macros that are run in the test program.
If you put these files into a directory, you are almost ready to run the test.  You will have to update the paths in the Makefile.
  • GTEST_DIR = SomeDirectory/libs/gtest-1.6.0
  • USER_DIR = ./ 
You can run then run "make" followed by "sample1_unittest" and you should see some successful test output.

I wanted to add a real program with this test suite, so I wrote this:
To build the program I updated the Makefile to build "my_program" like this:
TESTS = sample1_unittest my_program
and then I added this to the end of the Makefile:
my_program : sample1.o main.o 
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

After running make, I had two programs.  "sample1_unittest" was the original test program and "my_program" was the 'real' program that I was testing.

Saturday, April 6, 2013

Hello World with MacBook Air in C++

I like having a bare-bones setup to write code.  All I need is a dream and:
  • a text editor ( vi, vim, gvim ) 
  • a compiler ( g++ )
  • a terminal
Given that Mac OS X is backed by Unix, I thought it would be simple to get up and running.  As always, it took me longer than expected.  Here's what I did.

Instead of gvim, I installed macvim.  As suggested I moved the MacVim icon to the applications folder.  I also made a copy of the mvim script to /usr/local/bin folder.
  sudo cp ~/Downloads/MacVim-snapshot-66/mvim /usr/local/bin

Now I can open macvim from any terminal directory with commands like:
  mvim
  mvim main.cpp

In order to get the compiler working I installed xcode.  You can write, compile and run code all from xcode, but the compiler isn't available on the command line.  To install the command line tools:
  open xcode -->
    open the xcode menu -->
      open preferences -->
        open the downloads and install the command line tools.

After it all installs, you should be able write a simple c++ file and compile it in the terminal with commands like:
  g++ main.cpp
  ./a.out

Sunday, March 31, 2013

Quick Sort in C++

In my ongoing attempts to improve my programming skills, I've just read about quick sort.  Here is my quick/vague/one line/summary description of quick sort.  The quicksort algorithm works by recursively putting smaller elements to the left of a pivot and larger elements to the right of a pivot until your array is sorted.

Below is my attempt at coding up a working algorithm in C++.  The basic framework of the algorithm is as follows.
void quick_sort( vector & v, int start, int end ) {
    // partition the vector 
    int pivot = partition( v, start, end-1 );

    // recursive calls for each half.
    if ( start < pivot -1 ) 
        quick_sort( v, start, pivot-1 );
    if ( pivot < end ) 
        quick_sort( v, pivot, end );

    return;
}
The meat of the algorithm is in the partition() function. In this function, we do a few things.
  1. Pick a pivot value.
  2. Move all elements that are less than the pivot to the left of the pivot value.
  3. Move all elements that are greater than the pivot value to the right of the pivot value.
  4. Return the position of the pivot.  
Here's my code for a pivot function.
int partition( vector & v, int start, int end ) {
    int pivot =  v[ (start + end) / 2 ];

    while( start <= end ) {
       while( v[ start ] < pivot ) start++;
       while( v[ end ] > pivot ) end--;

       // swap values
       if ( start <= end ) {
           int tmp = v[start];
           v[start] = v[end];
           v[end] = tmp;

           start++;
           end--;
       }
    }
    return start;
}
Notes on quick sort.

  • I think there are several other ways to write this algorithm.  Different implementations can affect things like how much memory is used, whether it is stable sort, and the overall performance.  
  • One example where the implementation can affect performance is the choice of pivot.  I set the pivot as the mid point of the array, but it can be any value. If the input was already sorted, reverse sorted, or random, the pivot position can affect the performance of the algorithm (for better or worse).
  • It took me a while to get the algorithm working because it was pretty easy to to have an off by one error in many places.  

Wednesday, March 20, 2013

Heap Sort with C++

In my attempt to improve my programming skills, I just read about the heap sort algorithm.
Here are my notes and code where I try to understand and implement the heapsort algorithm in C++.

Step one of the heapsort is to build a valid heap.  When someone says heap sort, we are looking at a binary heap.  A binary heap is a binary tree where all levels of a heap are filled (except possibly the last level) and where every parent is greater than either of its children.

For example, if you have an array or vector with these values:
[ 6,  8, 1 , 5, 7, 3,  2... ]
A binary heap would have this shape:
          6
      8        1
    5   7    3   2
...
and we would say 6 is the parent of 8 and 1, 8 is the parent of 5 and 7, etc ...  However, while this binary heap has the right shape, it fails to meet the criteria where every parent is greater than or equal to either of its children.

In order to transform an invalid heap to a valid one, I wrote the functions heapify() and shiftDown():
void heapify( vector & v, int start, int end )  {
    int midPos = ( end - start ) / 2;
    for ( int pos = midPos; pos >= 0; pos-- ) {
        shiftDown( v, pos, end );
    }
}
void shiftDown( vector & v, int parent_pos, int end_pos ) {

    // Sift the parent down the right child?
    int right_child_pos = ( parent_pos * 2 ) + 2;
    if ( right_child_pos < end_pos &&
         v[ parent_pos ] < v[ right_child_pos ] ) {
         int tmp = v[ parent_pos ];
         v[ parent_pos ] = v[ right_child_pos ];
         v[ right_child_pos ] = tmp;
         shiftDown( v, right_child_pos, end_pos );
     }

    // Sift the parent down the left child?
    int left_child_pos = ( parent_pos * 2 ) + 1;
    if ( left_child_pos < end_pos &&
         v[ parent_pos ] < v[ left_child_pos ] ) {
         int tmp = v[ parent_pos ];
         v[ parent_pos ] = v[ left_child_pos ];
         v[ left_child_pos ] = tmp;
         shiftDown( v, left_child_pos, end_pos );
     }

}
The heapify()  function walks from the parent that is on the lowest level of the heap (sits at n/2) to the parent at the top of the heap (position = 0).
For each parent, we use shiftDown() to shift values down the tree until the rule where any parent is greater than or equal to any child is fulfilled.

Given the above functions, we have a partially sorted list where the larger values are at the top of the heap, which is the start of the array.  To get a sorted array where the values go from smallest to largest, we cherry pick the top of the heap to get the max value then rebuild the heap, as follows:
void heapSort( vector & v )  {
    int numItems = v.size();
    heapify( v, 0, numItems - 1);

    for ( int end_pos = numItems - 1; end_pos >= 0; end_pos-- ) {
        int tmp = v[ 0 ]; 
        v[ 0 ] = v[ end_pos ];
        v[ end_pos ] = tmp;

        heapify( v, 0, end_pos);
    }
}

For the sake of testing I also wrote this function to print the array to look like a heap.
void print_as_heap( const vector & v ) {
    int max_row_size = 1;
    int row_size = 0;
    vector::const_iterator it ;
    for ( it = v.begin(); it != v.end(); it ++ ) {
        std::cout << " " << *it;
        row_size++;

        if ( row_size == max_row_size ) {
            std::cout << std::endl;
            row_size = 0;
            max_row_size *= 2;
        }
    }
    std::cout << std::endl;
}
The end.

Monday, January 28, 2013

Effective Javascript

I've started reading my second "Effective" software book.

The first one I read before was Effective C++, by Scott Meyers,and the one I'm reading now is Effective JavaScript, by David Herman.

I like these books because:
  • The books are light, literally!  I hate heavy books.  Heavy books look good in libraries, but are pretty crappy everywhere else.
  • The reading is light, figuratively. Each of the points more or less stands alone and is only a few pages long.  This means you can read a couple of pages and still get something out of it.  
  • For me, the best part of these books is when I find a specific point that clearly points out that I've been doing something wrong for the last few years.  In these aha moments, I can 'feel' my future code improving.