Saturday, 3 December 2016

Parallell execution with threads in C# - Old Stars finder

This article will present parallell execution of threads in C# to find old stars in a star formation known as W5 in the constellation of Cassiopeia with the Spitzer Space telescope. The code is from the book "C# Multithreaded and Parallell programming" by Packt Publishing by author Rodney Ringler et. al.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Drawing.Imaging;


namespace OldStarsFinder
{
    public partial class Form1 : Form
    {

        //The number of processors or cores available in the computer for this application
        private int priProcessorCount = Environment.ProcessorCount;
        //The bitmaps list
        private List<Bitmap> prloBitmapList;
        //The long list with the old stars count 
        private List<long> prliOldStarsCount;
        //The threads list
        private List<Thread> prloThreadList;
        //The original huge infrared bitmap portrait
        Bitmap proOriginalBitmap; 

        public Form1()
        {
            InitializeComponent();
        }

        public bool IsOldStar(Color poPixelColor)
        {
            //Hue between 150 and 258
            //Saturation more than 0.10 
            //Brightness more than 0.90
            return ((poPixelColor.GetHue() >= 150 && (poPixelColor.GetHue() <= 258)) &&
                (poPixelColor.GetSaturation() >= 0.10) &&
                (poPixelColor.GetBrightness() >= 0.90)); 
        }

        private Bitmap CropBitmap(Bitmap proBitmap, Rectangle proRectangle)
        {
            //Create a new bitmap copying the portion of the original defined by proRectangle and keeping the PixelFormat 
            var loCroppedBitmap = proBitmap.Clone(proRectangle, proBitmap.PixelFormat);
            //Return the cropped bitmap 
            return loCroppedBitmap;
        }

        private void ThreadOldStarsFinder(object poThreadParameter)
        {
            //Retrieve the thread number reeived in object poThreadParameter 
            int liThreadNumber = (int) poThreadParameter;
            //The pixel matrix (bitmap) row number (Y)
            int liRow;
            //The pixel matrix (bitmap col number (X)
            int liCol;
            //The pixel color 
            Color loPixelColor;
            //Get my bitmap part from the bitmap list 
            Bitmap loBitmap = prloBitmapList[liThreadNumber];

            //Reset my old stars counter 
            prliOldStarsCount[liThreadNumber] = 0;
            //Iterate through each pixel matrix (bitmap) row 
            for (liRow = 0; liRow < loBitmap.Height; liRow++)
            {
                //Iterate through each pixel matrix (bitmap) cols 
                for(liCol = 0; liCol < loBitmap.Width; liCol++)
                {
                    //Get the pixel color for liCol and liRow 
                    loPixelColor = loBitmap.GetPixel(liCol, liRow);
                    //Get the pixel color for liCol and liRow 
                    if (IsOldStar(loPixelColor))
                    {
                        //The color range correspons to an old star
                        //Change its color to a pure blue 
                        loBitmap.SetPixel(liCol, liRow, Color.Blue);
                        //Increase the old stars counter 
                        prliOldStarsCount[liThreadNumber]++;
                    }
                    else
                    {
                        loBitmap.SetPixel(liCol, liRow, Color.FromArgb(128, loPixelColor));
                    }
                }
            }
            //Simulate heavy processing
            Random rnd = new Random();
            Thread.Sleep(rnd.Next(2000, 2500)); 
        }

        private void WaitForThreadsToDie()
        {
            //A bool flag 
            bool lbContinue = true;
            int liDeadThreads = 0;
            int liThreadNumber;
            while (lbContinue)
            {
                for(liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
                {
                    if (prloThreadList[liThreadNumber].IsAlive)
                    {
                        //One of the threads is still alive
                        //exit the for loop and sleep 100 milliseconds 
                        break;
                    }
                    else
                    {
                        //Increase the dead threads count 
                        liDeadThreads++;

                        progressBar1.Value = (int) ((liDeadThreads * 1.0 / priProcessorCount * 1.0) * 100.0);
                    }
                }

                if (liDeadThreads == priProcessorCount)
                {
                    //All the threads are dead, exit the while loop 
                    break; 
                }
                Thread.Sleep(100);
                liDeadThreads = 0; 
            }
        }

        private void ShowBitmapWithOldStars()
        {
            int liThreadNumber;
            //Each bitmap portion 
            Bitmap loBitmap;
            //The starting row in each iteration 
            int liStartRow = 0;

            //Calculate each bitmap's height 
            int liEachBitmapHeight = ((int) (proOriginalBitmap.Height / priProcessorCount)) + 1;

            //Create a new bitmap with the whole width and height 
            loBitmap = new Bitmap(proOriginalBitmap.Width, proOriginalBitmap.Height);
            Graphics g = Graphics.FromImage((Image) loBitmap);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            for (liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
            {
                //Draw each portion in its corresponding absolute starting row 
                g.DrawImage(prloBitmapList[liThreadNumber], 0, liStartRow);
                //Increase the starting row 
                liStartRow += liEachBitmapHeight;        
            }

            //Show the bitmap in the PictureBox picStarsBitmap 
            picStarsBitmap.Image = loBitmap;

            g.Dispose(); 
        }

        private void butFindOldStars_Click(object sender, EventArgs e)
        {
            progressBar1.Visible = true;

            proOriginalBitmap = new Bitmap(pictureBox1.Image);

            //Thread number 
            int liThreadNumber;
            //Create the thread list, the long list and the bitmap list 
            prloThreadList = new List<Thread>(priProcessorCount);
            prliOldStarsCount = new List<long>(priProcessorCount);
            prloBitmapList = new List<Bitmap>(priProcessorCount);

            int liStartRow = 0;

            int liEachBitmapHeight = ((int) (proOriginalBitmap.Height / priProcessorCount)) + 1;

            int liHeightToAdd = proOriginalBitmap.Height;
            Bitmap loBitmap; 

            //Initialize the threads 

            for (liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
            {
                //Just to occupy the number 
                prliOldStarsCount.Add(0); 

                if (liEachBitmapHeight > liHeightToAdd)
                {
                    //The last bitmap height perhaps is less than the other bitmap height
                    liEachBitmapHeight = liHeightToAdd; 
                }

                loBitmap = CropBitmap(proOriginalBitmap, new Rectangle(0, liStartRow, proOriginalBitmap.Width, liEachBitmapHeight));
                liHeightToAdd -= liEachBitmapHeight;
                liStartRow += liEachBitmapHeight;
                prloBitmapList.Add(loBitmap);

  

                //Add the new thread, with a parameterized start (to allow parameters)
                prloThreadList.Add(new Thread(new ParameterizedThreadStart(ThreadOldStarsFinder))); 
            }

            //Now, start the threads
            for (liThreadNumber = 0; liThreadNumber < priProcessorCount; liThreadNumber++)
            {
                prloThreadList[liThreadNumber].Start(liThreadNumber); 
            }

            WaitForThreadsToDie();

            ShowBitmapWithOldStars();

            progressBar1.Visible = false;
        }

    }
}

The code is available as a Windows Forms application in a Visual 2015 Solution available for download (zip) below:
Old Stars Finder (.zip) W5 image (NASA website): W5 image

Sunday, 27 November 2016

Making a simple accordion in Bootstrap 3


Creating an accordion for a web site is a breeze with Bootstrap 3. Just including the Bootstrap CSS and Javascript files and jQuery, we can start building an accordion. The accordion is a menu that shows one menu item a time. These menu items are panels and an accordion resembles a tab control with tabs, but is vertically stacked default. The following HTML page renders a simple accordion with Boostrap, CSS, Javascript and HTML.

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="container">

  <div id="accordion" class="panel-group">
  
   <div class="panel panel-success">
    <div class="panel-heading">
     <h4 class="panel-title"><a href="#collapse1" data-toggle="collapse" data-parent="#accordion">Collapsible panel 1</a></h4>
    </div>
    <div id="collapse1" class="panel-collapse collapse">
     <div class="panel-body"><div class="well">This is a nice collapsible panel.</div><p>This is a test.</p></div>
     <div class="panel-footer">Panel footer</div>
    </div>   
   </div>
   
    <div class="panel panel-warning">
    <div class="panel-heading">
     <h4 class="panel-title"><a href="#collapse2" data-toggle="collapse" data-parent="#accordion">Collapsible panel 2</a></h4>
    </div>
    <div id="collapse2" class="panel-collapse collapse">
     <div class="panel-body">This is another nice panel</div>
     <div class="panel-footer">Hey a panel footer too!</div>
    </div>   
   </div>
   
    <div class="panel panel-default">
    <div class="panel-heading">
     <h4 class="panel-title"><a href="#collapse3" data-toggle="collapse" data-parent="#accordion">Collapsible panel 3</a></h4>
    </div>
    <div id="collapse3" class="panel-collapse collapse">
     <div class="panel-body">Omg a third panel!</div>
     <div class="panel-footer">Let's have another Panel footer too!</div>
    </div>   
   </div>
  
  </div>  
  
</div>

</body>
</html>

Make note that we here use the data-parent HTML5 extension to point to the parent element to get the accordion effect of only showing one panel at a time. Each panel consists of a panel with a panel heading, having a panel title and then a panel body and finally a panel footer. We use the CSS framework of Bootstrap to achieve this.

Sunday, 6 November 2016

Twitter 3 Bootstrap Autocomplete control for MVC 5 - Typeahead.js



This article will present a reusable user control for MVC applications using Twitter Bootstrap autocomplete feature. This feature is known as the Twitter Bootstrap typeahead. There is a lot of articles covering this topic on the Internet, my version will present a simple reusable control using MVC html helper that generates input fields of type text and hidden, i.e. a textbox and a hidden field to save the value. The MVC model binder will therefore be able to save the selected value in the list showing up in the autocomplete-enabled textbox into the target property specified. Of course, your needs for autocomplete feature will vary. The control described in this article will suit many developer's needs as they call up a controller action to get the desired data and then filter the drop down and also use the Bloodhound engine of Twitter to mark up the matches quite nicely. The end result is a very useful and nicely styled autocomplete textbox! It also supports keyboard navigation with arrow keys and Enter! Read on! Let's first look at the MVC Html helper itself first:

using System;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace TwitterBootstrapAutoCompleteControl.HtmlHelpers
{

    public static class CustomMvcHelpers
    {

        public static MvcHtmlString AutoCompleteFor<TModel, TResult>(this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TResult>> propertyToSet, string fetchUrl)
        {
            var metaData = ModelMetadata.FromLambdaExpression(propertyToSet, htmlHelper.ViewData);
            string propertyName = metaData.PropertyName;
            string jsComponent = string.Format(
            @"
              <input type ='hidden' id='{0}' />   
              <input type='text' id='{1}' class='typeahead form-control' placeholder='Search some values' />             
              <script type='text/javascript'> 
              <!-- AutoCompleteFor -->
              $(function() {{

                var suggestionEngine = new Bloodhound({{
                limit: 300,
                datumTokenizer: function(datum) {{
                    Bloodhound.tokenizers.obj.whitespace('value')
                }},
                queryTokenizer: Bloodhound.tokenizers.whitespace,
                remote:
                {{
                    url: '{2}',
                    filter: function(response) {{
                    var matches = [];
                    $.map(response, function(item) {{
                            var query = $('#{1}').val().toLowerCase();
                            var itemKey = item.Text.toLowerCase();                          
                            if (itemKey.indexOf(query) >= 0)
                            {{
                                matches.push(item);
                                //console.log(item);
                            }}
                        }});

                        return matches;
                    }}
                }}
            }});

            suggestionEngine.initialize();

            $('#{1}').typeahead({{
                hint: true,
                highlight: true,
                minLength: 1,           
        }}   , {{
                limit: 30,
                displayKey: 'Text',
                source: suggestionEngine.ttAdapter(),
                filter: function(data) {{
                    console.log(data);
                    return data;
                }},            
                templates:
                {{
                    suggestion: function(data) {{
                        return '<p>' + data.Text + '</p>';
                    }},
                empty: [
                '<div>',
                'No results matching',
                '</div>'
                ].join('\n'),
            }}
            }});

            $('#{1}').bind('typeahead:select', function(ev, suggestion) {{
             //console.log('Selection: ' + suggestion.Text);
         
            $('#{0}').val(suggestion.Id); 

           }});

          }});

        </script>

     ", propertyName, propertyName + "TextBox", fetchUrl);


            return MvcHtmlString.Create(jsComponent);
        }

    }

}

The MVC html helper will generate the HTML and the javascript that is required to generate a textbox and a hidden field with the autocomplete feature. Your MVC solution needs to include both jQuery and Twitter Bootstrap, plus the Twitter typeahead.js Nuget packages. In addition, you need to include the Bloodhound javascript file. Let's look at a controller action return Json data to our Html helper, which will use javascript to call that method:

        public ActionResult SomeData()
        {
            var countries = new List
            {
            new IdTextItem {Id = "US", Text = "United States"},
            new IdTextItem {Id = "CA", Text = "Canada"},
            new IdTextItem {Id = "AF", Text = "Afghanistan"},
            new IdTextItem {Id = "AL", Text = "Albania"},
            new IdTextItem {Id = "DZ", Text = "Algeria"},
            new IdTextItem {Id = "DS", Text = "American Samoa"},
            new IdTextItem {Id = "AD", Text = "Andorra"},
            new IdTextItem {Id = "AO", Text = "Angola"},
            new IdTextItem {Id = "AI", Text = "Anguilla"},
            new IdTextItem {Id = "AQ", Text = "Antarctica"},
            new IdTextItem {Id = "AG", Text = "Antigua and/or Barbuda"}
            };

            return Json(countries, JsonRequestBehavior.AllowGet);

        }

The Json method returns a JsonResult that is called once by this html helper. We filter the data on the client as can be seen in the Html Helper code. Let's look at the script bundle added in BundleConfig

   bundles.Add(new ScriptBundle("~/bundles/typeahead").Include(
                "~/Scripts/bloodhound.js",
                "~/Scripts/typeahead.bundle.js"
                ));

This Html helper will fetch data on load, while it is the text that the user is typing that filters the autocomplete list. If you need to pass in a text and use that in your fetchUrl, the html helper's filtering most likely can be adjusted, also look into the prefetch property of the typeahead. We also move up jQuery bundle to the top as the default MVC template has this bundle in the footer and not in the header, as will be required by the typeahead feature. Place in the section of _Layout.cshtml: @Scripts.Render("~/bundles/jquery") And in the bottom of the element of that same file: @Scripts.Render("~/bundles/typeahead") The html helper expects that your class contains the properties Id and Text. You can of course use an anonymous type to avoid creating a new type in your C#-code. The type could be a string or an integer for the Id.

 public class IdTextItem
    {

        public string Id { get; set; }

        public string Text { get; set; }

    }

We also do some adjustments to the style, since the default setting of the typeahead is borishingly looking. Add the following css styling to your view - or better - in a standalone css to be included in _Layout.cshtml. Save the following content into typeahead.css file which you place in the Content folder:
 

.tt-query {
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
  color: #999
}

.tt-menu {    /* used to be tt-dropdown-menu in older versions */
  width: 422px;
  margin-top: 4px;
  cursor: pointer;
  padding: 4px 0;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
          box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
  padding: 3px 20px;
  line-height: 24px;
}

.tt-suggestion.tt-cursor,.tt-suggestion:hover {
  color: #fff;
  background-color: #0097cf;

}

.tt-suggestion p {
  margin: 0;
}

Then adjust the StyleBundle in BundleConfig to include this css file:
      bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css",
                      "~/Content/typeahead.css"));
Finally, here is an example of how to use this Html Helper:

<div class="row">
    <div class="col-md-4">    
        <h2>Autocomplete control html helper:</h2>   
        @Html.AutoCompleteFor(m => m.SomeProperty, Url.Action("SomeData", "Home"))
    </div>
</div>

The call to the html helper provides as the first argument the property of the Model of the MVC View and the second argument is an url to the action to fetch the data. This HTML helper should match a lot of developer's needs, but can of course be adjusted. The benefit of using a MVC Html helper is that you get reusability. You avoid having to fiddle with Javascript for each field you want to add to your MVC view where you want some autocomplete feature. Maybe you want to adjust the HTML helper to fit your needs. I have provided a link to a zip file of this Html Helper in a Visual Studio 2015 below, let me know if there are some tips or improvement you have in case you evaluate and test out this Html helper and find improvements. Note that the chosen value in the autocomplete list is set to a hidden field. The textbox will be named "propertyname"TextBox and the hidden field will be named "propertyname"

Download the source code for the autocomplete control (VS 2015 solution):

Download zip file [.zip | 31,7 MB] Reading material: