Thought For The Day

“If you have something to say of any worth then people
will listen to you.”

Oscar Peterson

 

C++ Programming: Design Patterns and Suggestions 1/2

In the object-oriented programming series, so far we have learned a lot of different concepts, both general and language specific.  Now we are able to express our ideas using a programming language and we are comfortable with the constructions of the language itself.  This is a process every programmer has to go through, and it is about constantly perfecting your skills.  Another important thing we should notice is that, as you are progressing, you will be thinking on higher levels of abstraction.  What this means is that you will eventually stop thinking about technical, language-specific things.  Instead, you will be thinking in a more abstract way, thinking about concepts and ideas, because there will be no barrier in the form of syntax or programming constructs to stop you.

In programming, and particularly in object-oriented programming, it's not enough to just write a program.  There are certain rules, conventions and guidelines which should be followed.  This is especially true for object-oriented programming: the object hierarchy itself allows for many useful mechanisms, but only if used correctly.  When you are learning how to program, for example, in C++, and you already feel comfortable with the constructions and syntax of the language, you can improve by introducing a higher level of abstraction.  You can do this by thinking about the following things:

  • Reusability - whether you are an amateur or a professional programmer, you will be in a situation where you have already written thousands of lines of code for a project.  One of the goals a programmer should have is making the code reusable.  This can be achieved by modularization and proper organization.
  • Robustness - code is "robust" when it handles errors in an elegant way.  This means that the program will remain as stable as possible in case of an error, wrong user input or other unexpected situations.
  • Modifications - one of the most important things to consider when programming is the following: how easily is the code modified?  This is especially significant when working in a team.  Often times you will have to work with other people, and make modifications and improvements on their code (and vice versa).  This is why it is so important to correctly utilize the object-oriented concepts we have learned about.

 

In order to help and guide the programmer with the issues listed above, a concept called design patterns was introduced to object-oriented programming (and software engineering in general).  A design pattern is a general reusable solution to a commonly occurring problem in software design.  A design pattern isn't a finished design that can be transformed directly into code.  It is a description or template for how to solve a problem that can be used in many different situations.  These patterns are useful because they provide a way to make your code reusable, modularized, robust and easy to modify.  They also help to avoid any misunderstandings when working in a team.

There are many different groups of design patterns, and many classifications.  Most commonly, design patterns are divided into the following categories:

  • creational patterns
  • structural patterns
  • behavioral patterns
  • concurrency patterns.

 

Design patterns gained popularity in computer science after the book Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994 by the so-called "Gang of Four" (Gamma et al.), which is frequently abbreviated as "GoF".  However, there are many authors and many pages written about this topic.  In the next article we are going to discuss design patterns in more detail, explain different groups of patterns and some notable representatives of those groups, and give illustrative examples.

5 Tips for Entering the World of Freelancing

Whether you're just starting out in your career or you've been employed for a long time, freelancing can be a lucrative way to add to your income.  Do it successfully and you may even be able to quit your day job.  If the thought of freelancing sounds appealing to you, here are some tips to get you started:

  1. Choose your Niche.  Think about what you're good at.  Do you have 1,000+ Twitter followers?  Can you write rings around your peers?  If so, you may have a freelancing future in social media management or writing.  However, if these aren't your areas of expertise, don't worry.  Just about any skill can be freelanced with the right branding.  This brings us to our next tip...

  2. Create an Attractive Profile.  Once you've determined your freelancing objective, you'll want to create a professional website or a freelancing profile.  Consider your primary skillset and how you want to market it.  To get some ideas, take a look at your competitors' branding.

  3. Bid Often.  When you're first starting out in freelancing, it's not uncommon to submit 10 proposals before getting your first job.  Recognize that frequent bidding is the key to developing your freelancing career.

  4. Be Prepared to Bid Low.  Unfortunately, if you're just beginning your career, you'll find that you're often competing with freelancers who have more experience.  To overcome this problem, you may need to offer bids lower than what you feel you're worth.  However, don't look at this as a long-term thing.  Once you've begun to develop your reputation, feel free to place higher bids.

  5. Build your Portfolio.  As a freelancer, your portfolio is a calling card of sorts.  Once you've successfully completed a job, include the work in your portfolio.  You may even want to ask previous clients for testimonials.  By doing this, you'll not only impress potential clients but you'll also be able to command higher fees.

4 Rituals to Make Mondays More Enjoyable

After having the weekend off, it can be a real chore to drag yourself into the office on Monday morning.  However, there are things you can do to make your Mondays less grim, more grin.  Check out 4 rituals to improve your Mondays:

  1. Plan Ahead.  Rather than haphazardly throwing an outfit together in the AM, take the time to select your clothing the night before.  For bonus points, choose an outfit that you really like—feeling good about what you're wearing is a wonderful way to start your Monday morning off on the right foot.  And if you pack a lunch for work, consider packing your meals in advance on Sunday and then throwing them in the freezer so you don't have to waste time digging through the fridge in the morning.  These simple activities will reduce your Monday morning stress.

  2. Look Forward to Mondays.  Attitude can make or break your day.  Rather than approaching Monday with a negative mindset, think about the day differently.  For example, you might focus on how much you enjoy getting to catch up with your coworkers after the weekend, rather than the full email inbox that awaits you.  This simple change in perspective can have a big impact on how enjoyable your day is.

  3. Engage in a Favorite Pastime.  Consider setting the alarm 15 minutes earlier on Monday morning.  Then, engage in an activity that you find soothing.  This can be anything from relaxing over a cup of coffee to reading the morning paper, meditating, or doing yoga.  Try to leave the house with the calm, centered feeling that your activity created.

  4. Start the Day Off Slowly.  Rather than packing your Monday full of meetings, don't schedule anything before lunch.  This will give you time to read your emails and slowly acclimate yourself to the workday.

C++ Programming: OpenMP

In the last article we gave a short introduction to parallelisation - we've mentioned different levels of parallelism, different mechanisms and also, things to consider when writing parallel programs.  Unfortunately, successful parallelization of a program (or writing a parallel program from the beginning) can often prove to be a difficult task.  This is why many tools were developed to aid the programmer in these tasks: one of such tools is OpenMP (Open Multi-Processing).

OpenMP gives programmers a simple and flexible interface for developing parallel applications for platforms ranging from the standard desktop computer to the supercomputer.  It is a C/C++/Fortran compiler extension that allows to add parallelism into existing source code without having to rewrite it entirely.  Most compilers support OpenMP, and building OpenMP C++ code is as simple as adding the "-fopenmp" option in the linking process.

The easiest way to demonstrate the power and simplicity of OpenMP is by giving an example:

#include <cmath>

int main()
{
  const int size = 256;
  double array[size];
    
  #pragma omp parallel for
  for(int i = 0; i < size; ++i)
    array[i] = std::sin(2 * M_PI * i / size);
}
Let's discuss this example: the code is simply initializing the values of an array.  The calculations performed are relatively demanding, which will allow us to measure performances of the serial and parallel versions.  If you ignore the #pragma omp parallel for line, the code looks exactly the same as the serial version.  This is one of the greatest advantages of OpenMP.  This code divides the array initialization into multiple threads, which are run simultaneously.  Each thread initializes a portion of the array, and all of this is done with only one line of code.  Another obvious advantage of OpenMP is its high level of abstraction: you do not see how each thread is created and initialized; you don't see a function declaration for the code each thread executes and you also don't know exactly how the array is divided between the threads.  In most other parallel programming systems, you will have to write code for all of this and more.
Note: When interpreting OpenMP code, your compiler will most likely determine the number of threads it will instantiate based on the number of CPU cores.  For example, a 4-core CPU can, theoretically, improve the performance 4 times.  We encourage the reader to experiment with this; measure the performances of serial and parallel versions and compare them.  This shouldn't be too difficult - to get the serial version of your OpenMP program, just comment the lines starting with #pragma omp.
OpenMP also enables the programmer to get and set the number of threads with these library functions:
omp_get_thread_num()
omp_set_num_threads()

 

Consider this simple example:

for(int i = 0; i < n; ++i)
{
   sum += array[i];
}
Here, we have to have some kind of a mechanism of protecting the correctness of the result: since OpenMP is a shared-memory model, threads would always override the value of sum, producing a wrong result.  This is elegantly solved in OpenMP, with the reduction clause:
#pragma omp parallel for reduction(+:sum)
{
  for(int i = 0; i < n; ++i)
  {
    sum += array[i];
  }
}
Here, + is the reduction operand (some other reduction operands in C++ are -, *, | etc).

 

OpenMP provides many more powerful concepts for C++ parallel programming - this is just the beggining, which will hopefully inspire readers to learn more about it.