Saturday 18 June 2011

On vacation from coding


I am taking a vacation from coding and as a result, I may not be updating the blog for some time to come.

I will still try my best to moderate the comments and reply to them as far as possible.

If you are interested in C++, I recommend that you join the C++ professional group on Linkedin and there are lots of interesting discussions going on, on a regular basis. There is also the other websites page that links other interesting sites on C++.

For the time being, Adieu!

Tuesday 14 June 2011

When true != true

If we define a boolean variable, say:
bool xyz;

then when we have to do some kind of a comparison we may do this as follows:
if(xyz == true)

When I used to be a new programmer, I used to always do this as follows:
if(true == xyz)

I think the way I did it is more robust and less error prone because you can by mistake do as follows:
if(xyz = true) //Single = instead of ==

The problem with my approach is that the code readability is affected and most people hate to see code like this. Instead, I started doing what normal people would do but making sure that I always use '==' and not '='.

Now some of you may be thinking why not:
if(xyz)

True, in case of Boolean this is a simplest way to do it and I had personally no problem with it until recently. While reviewing some code, I noticed that an engineer had changed a piece of code from:
if(xyz == true) to if(xyz)

Initially I thought that it may be that he did not like the '==' as its redundant. So when I checked his other code, I realised that he may have done this for a reason. Executing his code in the debug mode worked fine. So I changed:
if(xyz) back to if(xyz == true) and lo and behold, the test started to fail.

Putting a breakpoint I can see that while on the statement:
if(xyz == true)
the debugger shows xyz is 'true' but the comparison fails.

As usual digging into the problem further, I found that in one of the constructors, xyz was not initialised and the default garbage value appeared to show it as 'true'.

So its again got me into thinking that it may be better to write if(xyz == true) instead of if(xyz) as it may help in catching uninitialised variables. The best thing of course would be to make sure all variables in the class, whether public, protected or private are initialised.

Opinions welcome!

Tuesday 7 June 2011

Multisets and Multimaps

I was trying to understand where multisets would be used as compared to multimaps and I didnt find any straightforward answer. I found this simple explanation at StackOverflow:

multimap

  • With ZIP code as a key, all people which have that ZIP code
  • With account ID as key, all open orders of that person/account
  • A dictionary, with per keyword various explanations

multiset

is in essence a map with a key and a integer count.

  • The inventory of a shop, all products have their key and the amount still available is the value
  • accumulated sales data of a shop, every time a product is sold the product id get's added to the multiset thereby increasing the amount sold

As a result I created this example below. This is probably not the best of examples but I didnt want to change it. The main problem below is that multimap's are not strictly speaking required in the example below. I could have used a map. Multimap would be needed if there was no quantity_ in the class and then I can add the products one by one. I could have then used the count method to get the quantity.

Anyway, program as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Simple example of multiset

#include <iostream>
#include <string>
#include <set>
#include <map>
#include <algorithm>

using namespace
std;

class
Product //Keeping this simple
{
public
:
Product(string name, int code, int price) :
name_(name), productCode_(code), price_(price)
{

quantity_ = 10; //Lets fix this value for simplicity
}
bool
availableForSale()
{

if
(quantity_ > 0)
{

quantity_--;
return
true;
}

return
false;
}

string name_;
int
productCode_;
int
price_;
int
quantity_;
private
:
Product(); //Disabled the default constructor
};

void
sellProduct(string name, multimap<string, Product*>& inventory, multiset <int> &soldItems)
{

multimap<string, Product*>::iterator it = inventory.find(name);
if
(it != inventory.end())
{

if
((*it->second).availableForSale())
{

soldItems.insert((*it->second).productCode_);
}
}

else

{

cout << "Unknown product : " << name << endl;
}
}


void
soldItemsList(multimap<string, Product*>& inventory, multiset <int> &soldItems)
{

multimap<string, Product*>::iterator it = inventory.begin();
for
(it = inventory.begin(); it != inventory.end(); ++it)
{

int
soldCount = soldItems.count((*it->second).productCode_);
cout<<"Product = " << (*it->second).name_ << ", Quantity Sold = " << soldCount << endl;
}
}


int
checkSales(multimap<string, Product*>& inventory, multiset <int> &soldItems)
{

int
totalSales = 0;
multimap<string, Product*>::iterator it;
for
(it = inventory.begin(); it != inventory.end(); ++it)
{

int
soldCount = soldItems.count((*it->second).productCode_);
totalSales += soldCount * (*it->second).price_;
}

return
totalSales;
}


int
main()
{

//There is no special reason to use multimap instead of a map
//If you wanted to add same product and create quantity multimap is required
multimap<string, Product*> inventory;
Product* prod1 = new Product("product1", 2334, 10);
Product* prod2 = new Product("product2", 4556, 50);
inventory.insert(pair<string, Product*>("product1",prod1));
inventory.insert(pair<string, Product*>("product2",prod2));

multiset <int> soldItems;

sellProduct("product1", inventory, soldItems);
sellProduct("product2", inventory, soldItems);
sellProduct("apple", inventory, soldItems);
sellProduct("product1", inventory, soldItems);
sellProduct("product1", inventory, soldItems);
sellProduct("product2", inventory, soldItems);

soldItemsList(inventory, soldItems);

cout<<"Total sales = " << checkSales(inventory, soldItems) << endl;

delete
prod1;
delete
prod2;
return
0;
}



The output as follows:

Thursday 2 June 2011

Example of Multisets

Took this one from Java2s and modified it slightly to show a bit more info.

Example as follows:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Simple example of multiset

#include <iostream>
#include <set>
#include <algorithm>

using namespace
std;

int
main()
{

int
a[ 10 ] = { 7, 22, 9, 1, 18, 30, 100, 22, 85, 13 };
int
aSize = sizeof(a) / sizeof(int);
std::multiset< int, std::less< int > > intMultiset(a, a + aSize);

cout << "Printing out all the values in the multiset : ";
multiset<int>::iterator it;
for
( it = intMultiset.begin(); it != intMultiset.end(); ++it)
cout << " " << *it;
cout << endl << endl;

std::ostream_iterator< int > output( cout, " " );

cout << "There are currently " << intMultiset.count( 15 )
<<
" values of 15 in the multiset\n\n";

intMultiset.insert( 15 );
intMultiset.insert( 15 );

cout << "After two inserts, there are currently " << intMultiset.count( 15 )
<<
" values of 15 in the multiset\n\n";

cout << "Printing out all the values in the multiset : ";
for
( it = intMultiset.begin(); it != intMultiset.end(); ++it)
cout << " " << *it;
cout << endl << endl;

return
0;
}



Output as follows: