A little bit of fun with face detection in Windows Phone 8

To start off

If anybody is actually looking for Face Detection Libraries for Windows Phone and haven’t tried this one, this is for them. It’s a neat library popping off facedetecionwp7 library by Julia Schwarz. And you can do pretty cool stuffs with it with pretty less hassle.

Let’s have a little fun

Let’s go ahead and get ourselves started with a Windows Phone 8 Project. Our job would be try this library and detect faces in a picture and have some fun with it, say overlay the face with the classic troll face with the laugh. 😛


Now, no matter what that sounds, let’s give it a shot. I’ve jotted down a very simple GUI to do this one. And it’s as following:


If you want to have a closer look at the XAML it will look the following:

<Grid x:Name="LayoutRoot" Background="Transparent">
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="Face Detection in Windows Phone" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button x:Name="CaptureImageButton" Content="Capture Image" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Top" Width="267" Click="CaptureImageButton_Click"/>
            <Image Name="facesPic" HorizontalAlignment="Center" Height="388" Margin="0,170,0,0" VerticalAlignment="Top" Width="427"/>


Now, you can definitely see that this is a very basic UI. We have a Button with a click event CaptureImageButton_Click and a Image named facesPic.

Now, before we get our hands dirty, let’s go ahead and add reference to a library we will need. We will need WritableBitmapEx from here. This lib is already available on Nuget too, so you can get it from there too.

After you added that in your project reference, you will need a bunch of libraries from FaceDetectionWP8 to make this things work. You can get the classes on there from the following link too.

After you download the .zip , unzip it and include all the classes inside in your project. I added them under a separate folder named FaceDetector.

Let’s move to our MainPage.xaml.cs

Now, the first thing to do is to pick a picture and the best thing to use for that is PhotoChooserTask . Let’s hook up the following snippet in CaptureImageButton_Click event.

private void CaptureImageButton_Click(object sender, RoutedEventArgs e)
            PhotoChooserTask photo = new PhotoChooserTask();
            photo.Completed += new EventHandler&lt;PhotoResult&gt;(photoChooserTask_Completed);
            photo.ShowCamera = true;

Now, the next thing to write is definitely photoChooserTask_Completed event handler. Let’s go ahead and write it. First thing to do would be get the chosen photo into a  WritableBitmap as we are going to do some changes on it.

    BitmapImage SourceBitmap = new BitmapImage();
    WriteableBitmap SourceWritableBitmap = new WriteableBitmap(SourceBitmap);


Now, the next thing we need to do is downsample the image a bit as most of the Windows Phone devices pack a pretty powerful camera and often the pictures are oversampled. I personally suggest you downsize the image a bit too. I din’t do it in this demo but if you want a faster performance, you really should try that too. I added the following code segment inside the if block.

byte[] downsampledImage = new byte[SourceWritableBitmap.PixelWidth / _downsampleFactor * SourceWritableBitmap.PixelHeight / _downsampleFactor];

Utils.DownSample(SourceWritableBitmap.ToByteArray(), SourceWritableBitmap.PixelWidth, SourceWritableBitmap.PixelHeight, ref downsampledImage, _downsampleFactor);

SourceWritableBitmap = SourceWritableBitmap.FromByteArray(downsampledImage);

The code segment is pretty straight forward here now. The Utils class here is from the FaceDetectionWP8 library. The first argument for Utils.DownSample used here is a Byte Array of the SourceWritableBitmap and it used the WritableBitmapEx we added here before. The second one is the width of the source bitmap and the third one is the height. The last argument passed here is the downsample factor. This was defined as the following in the MainPage class.

int _downsampleFactor = 2;

And then the SourceWritableBitmap is reinitiazed with a downsampled version of it’s own.

The next thing to do would be getting the faces detected of course. 😀 So, why wait? I added the following sinppet for that.

List<FaceDetector.Rectangle> faces = new List<FaceDetector.Rectangle>();
faces = _detector.getFaces(SourceWritableBitmap, 2f, 1.25f, 0.1f, 1, false, true);

I used the defaults here except the last argument that determines whether it should detect multiple faces and I kept it true.  You can have fun with the other params if you want to tweak your haar cascade detection parameters here.

here comes the fun part, now we are going to replace the face/faces in the picture with the troll laugh picture. :P. We can see it returns the faces as a List<FaceDetector.Rectangle>. All we have to do now is paint the Troll laugh in the rectangles returned by the method. fun, huh?

Now, before replacing the Source Image with the Troll Laugh, we need to load it in another WritableBitmap so we can blend the both of them.

StreamResourceInfo MaskImageSri = Application.GetResourceStream(new Uri("Images/Troll.png", UriKind.Relative));
BitmapImage MaskImageBitmap = new BitmapImage();

WriteableBitmap MaskWritableBitmap = new WriteableBitmap(MaskImageBitmap);

As we got our Troll.png, why don’t we paste it on the source bitmap?

foreach (var r in faces)
   int x = Convert.ToInt32(r.X);
   int y = Convert.ToInt32(r.Y);
   int width = Convert.ToInt32(r.Width);
   int height = Convert.ToInt32(r.Height);                    

   System.Windows.Rect destRect = new Rect(x, y, width, height);
   System.Windows.Rect srcRect = new Rect(0, 0, MaskWritableBitmap.PixelWidth, MaskWritableBitmap.PixelHeight);

   SourceWritableBitmap.Blit(destRect, MaskWritableBitmap, srcRect);

   facesPic.Source = SourceWritableBitmap;

Now, this is pretty straight forward too. All we need is we iterated over the faces and we created to separate rect structs. One is from the MaskWritableBitmap so we can get the rect of the portion of the image we are pasting, in this case, the full one and the destination rect is the face rectangle on the source image we are pasting this troll laugh on.

The next thing to do is invoke Blit() method as this one is responsible to blend these two WritableBitmaps. It comes with the WritableBitmapEx library we added before. The first parameter is the destination rectangle where the source rectangle will be pasted. In this case the face rectangle that will be replaced by the troll laughter image. The second parameter would be the WritableBitmap where the rect that would be posted in the source is found. Here this one is the Troll Image and the last one is the rect in the Troll Image that would be transferred to the main bitmap.

We called it on SourceWritableBitmap as we want to paste the troll Laugh on it. And when all is said and done we set facesPic source to the SourceWritableBitmap.

Now all we have to do is build and test the app. And the result is as following:


So, what are waiting for? Test the demo project here of the article and have fun!

Windows Phone For Newbies: Episode 1 – Introduction

আপনি যদি আগে কখনোই উইন্ডোজ ফোনে কাজ না করে থাকেন তাহলে এই ভিডিও সিরিজ টি আপনার জন্যে। এটি উইন্ডোজ ফোন ৮.১ এর একটি বাংলা টিউটোরিয়াল সিরিজ যা আপনাকে একদম শুরু থেকে উইন্ডোজ ফোনে কাজ করার জন্য সম্যক সকল কিছু জানিয়ে দেবে।

এটি সিরিজটির প্রথম পর্ব

ইউটিউব প্লেলিস্টটি পাচ্ছেন এইখানে

প্রোজেক্ট সোর্স কোড পাচ্ছেন এইখানে

Making a quick rating user control for Windows Phone 8.1

First Words

Usually when someone is working on Windows Phone 8.1 and usually if he’s the guy who just came from Windows Phone 8 development, the first thing he misses is all the toolkits lying around like the Windows Phone Toolkit or Coding4Fun Toolkits. Thus, missing a rating control is not new. So, let’s get our hands dirty and make a little 5 starred rating control fast enough to solve our problem at least to a minimum extent.

Design First!

Okay, to do this thing fast, we might need to make at least a little bit of groundwork in design, I’m going to use Microsoft Expression Design for it. You guys can get the free version from here. It’s pretty lightweight and we can practically export stuff straight to Blend for Visual Studio!

So, let’s go over Microsoft Expression Blend and create a new document. Take a size to your preference as you need it. Let’s draw some stars! To get started, look on the left toolbar and select Polygons.


After you select polygons, drag your mouse pointer in the artboard to draw anything that pops off. Now, it might be any kind of polygon, starting from a triangle, like the following came up with too much of points.


To rectify this, we need to make sure it has 5 points and an inner depth above 40% and close to 50% so it looks like a star, you can modify the existing one you made or set the proper settings and make a new one. To do that, look on the right on Edit Polygon dialog and change the points to 5 and move the innder depth to 47%. If you want to create a new one you will see the dialog name is Create Polygon. You can go for anything in between 45% tp 50%, I used 47% in this case.

3 4



Now, with the proper settings set with the polygon give it a yellowish shade and no borders please. And copy the stars and set them side by side so you can have 5 stars in a line that resembles a regular rating control. So, in the artboard it might look pretty close to the one following:


Now, what we want to do is put these together on a gradient so it resembles more to the rating control. But before we go do that, we need to make the stars act as a compound path together. So, lets go ahead and select all of them and select Object -> Compound Path -> Make so all the stars can work as a compound path.


Now, it’s time to put a gradient over it. Select a yellow to white gradient and put it on your rating control from left to right. Now, there comes a trick, at first you will see the color melted down in the middle, in a rating control we need a clear difference of color to make sure that it looks like one.


Now, click on the gradient bar in the middle to put a gradient stop in there.


Now, drag the midpoints (the dots over the gradient bar) and put them together to make the color difference more prominent.


Now, if we move the Gradient Stop now, we will see the color changes are more prominent and the starts look a lot like rating control now.


Now let’s go over Visual Studio and create a Windows Phone 8.1 Project. Let’s put a Right Click on the solution name and add a user control.



Now, lets select the user control and open it on blend. Let’s select all the stars, copy it and just paste it on the grid of the user control. To your surprise, this thing will just get copied to blend just fine. And let’s make the height of the user control to 40 and the width to 200 just to get the user control to appropriate proportion. I copied a set of stars and put the background to a very light gray color and put it behind the ones we copied at first so it looks a bit more prominent even in a white background.


Now, the xaml for the usercontrol will look somewhat like the following:


        <Path Stretch="Fill"
              Data="M -1346.6,-259.247L -1358.76,-305.451L -1321.61,-335.489L -1369.31,-338.197L -1386.39,-382.816L -1403.71,-338.285L -1451.43,-335.823L -1414.43,-305.594L -1426.83,-259.454L -1386.65,-285.302L -1346.6,-259.247 Z M -1067.9,-259.247L -1080.07,-305.451L -1042.91,-335.489L -1090.61,-338.197L -1107.7,-382.816L -1125.01,-338.285L -1172.73,-335.823L -1135.73,-305.594L -1148.13,-259.453L -1107.95,-285.301L -1067.9,-259.247 Z M -1207.25,-259.247L -1219.41,-305.451L -1182.26,-335.489L -1229.96,-338.197L -1247.05,-382.816L -1264.36,-338.285L -1312.08,-335.823L -1275.08,-305.594L -1287.48,-259.453L -1247.3,-285.301L -1207.25,-259.247 Z M -928.552,-259.247L -940.718,-305.451L -903.562,-335.489L -951.264,-338.197L -968.35,-382.816L -985.666,-338.285L -1033.38,-335.823L -996.382,-305.594L -1008.79,-259.453L -968.602,-285.301L -928.552,-259.247 Z M -789.204,-259.247L -801.369,-305.451L -764.214,-335.489L -811.916,-338.197L -829.002,-382.816L -846.318,-338.285L -894.034,-335.823L -857.033,-305.594L -869.437,-259.453L -829.254,-285.301L -789.204,-259.247 Z "  
              Height="Auto" Width="Auto" Fill="#FFDEDEDE"/>
        <Path Stretch="Fill"
              Data="M -1346.6,-259.247L -1358.76,-305.451L -1321.61,-335.489L -1369.31,-338.197L -1386.39,-382.816L -1403.71,-338.285L -1451.43,-335.823L -1414.43,-305.594L -1426.83,-259.454L -1386.65,-285.302L -1346.6,-259.247 Z M -1067.9,-259.247L -1080.07,-305.451L -1042.91,-335.489L -1090.61,-338.197L -1107.7,-382.816L -1125.01,-338.285L -1172.73,-335.823L -1135.73,-305.594L -1148.13,-259.453L -1107.95,-285.301L -1067.9,-259.247 Z M -1207.25,-259.247L -1219.41,-305.451L -1182.26,-335.489L -1229.96,-338.197L -1247.05,-382.816L -1264.36,-338.285L -1312.08,-335.823L -1275.08,-305.594L -1287.48,-259.453L -1247.3,-285.301L -1207.25,-259.247 Z M -928.552,-259.247L -940.718,-305.451L -903.562,-335.489L -951.264,-338.197L -968.35,-382.816L -985.666,-338.285L -1033.38,-335.823L -996.382,-305.594L -1008.79,-259.453L -968.602,-285.301L -928.552,-259.247 Z M -789.204,-259.247L -801.369,-305.451L -764.214,-335.489L -811.916,-338.197L -829.002,-382.816L -846.318,-338.285L -894.034,-335.823L -857.033,-305.594L -869.437,-259.453L -829.254,-285.301L -789.204,-259.247 Z "  
              Height="Auto" Width="Auto">
                <LinearGradientBrush StartPoint="3.55262e-007,0.500002" EndPoint="1,0.500001">
                    <GradientStop Color="#FFFFCC00" Offset="0.6"/>
                    <GradientStop Color="#06FCFCFC" Offset="0.6"/>


Code Comes Along

Now if we remember stuff clearly, when we moved the gradient stop in blend it looked like the rating bar value is changing. We just need to emulate that in code, that’s it. So, all we need to is change the Offset of <GradientStop> ‘s in LinearGradientBrush entry inside <Path.Fill>. So, we have to databind the offset from backend so we can access it from the usercontrol. And please remember this have to be 0.0 to 1 of course as thats the range for the offset value.

I renamed my user control to RatingControl and let’s move back to the code backend of RatingControl.xaml

public partial class RatingControl : UserControl
        public RatingControl()

        DependencyProperty RateValueProperty = DependencyProperty.Register("RateValue", typeof(double), typeof(RatingControl), new PropertyMetadata(0.1, UpdateValue));

        private static void UpdateValue(DependencyObject d, DependencyPropertyChangedEventArgs e)
            RatingControl control = d as RatingControl;
            control.Value = (double)e.NewValue;

        private double Value
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }

        private static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(double), typeof(RatingControl), new PropertyMetadata(0.1));

        public double RateValue
                return (double)GetValue(RateValueProperty);
                SetValue(RateValueProperty, value);


Now, our job was to hook up the Value provided from backend. Now I used two DependencyProperty here instead of one because we are going to attach the value in the xaml using a element binding. The first DependencyProperty RateValueProperty has a PropertyMetadata of 0.1 and a function is attached to update the value in the xaml control (update the offset from the xaml).

And Value is the actual DependencyProperty Attached to the control and as it’s private it’s accessible only from inside. So we are exposing it using the RateValueProperty and update it with the Value Dependency Property. You can only use Value and expose it if you want.

Now all we have to do is hook it up in the xaml:

Let’s add a name to the Rating Control. Lets just add x:Name=”UserControl” in the UserControl Tag. And let’s tag the GradientStop property Offset on the ElementName “UserControl”. So, let’s modify the GradientStop tags as following:

     <LinearGradientBrush StartPoint="3.55262e-007,0.500002" EndPoint="1,0.500001">
          <GradientStop Color="#FFFFCC00" Offset="{Binding Value, ElementName=UserControl}"/>
          <GradientStop Color="#06FCFCFC" Offset="{Binding Value, ElementName=UserControl}"/>

And voila! We are done!

Using the control

Using the control is pretty easy, add xmlns:local=”using:RatingControlTest” in the page tag and use it just like the following:

    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <local:RatingControl Width="200" Height="40" RateValue="0.5"></local:RatingControl>

And it will look like the following:


Demo Project:

The demo project is here so you can test it yourself. Hope this helps! 😉

Using SQLite as local database with Universal Apps

The First Words

Usually when we are moving our existing Windows Phone 8 / Windows Phone Silverlight projects to Universal Apps, in most of the cases the common question that rises up is what should we use as a local database on it. And SQLite does a perfect job serving the universal apps a perfect local database. So, please keep your eyes posted here if you want to use the same database for both your projects in your universal app. So, why not get started?

Universal Apps

Univeresal Apps are the newest App Models designed for Windows Store to serve Apps in Windows Store and Windows Phone Store from a same project with shared codes as per your liking. To the ones who doesn’t know what an Uinversal App is, kindly visit this link so you can get a full idea how it works. To the ones who already know this, please continue.

SQLite With Universal App

To get SQLite going with your universal app, the first thing we should do is get SQLite for both Windows Phone 8.1 and Windows Runtime 8.1as Universal App points to both of the apps.

To install SQLite for Windows Store please visit:


And you will stumble upon a screen like the following:

So, definitely the next thing to do is download this one, as soon as the VSIX installer is downloaded, install it. As, now we have SQLite for Windows Store here, let’s move so we can have SQLite for Windows Phone.

To install SQLite for Windows Phone 8.1 please visit:


This will lead to a similiar page, download the VSIX installer and install it too. The next thing we should check for whether we have installed what we need in our Visual Studio. I’m using a Visual Studio 2013 Ultimate version here and let’s go over Tools -> Extensions and Updates and go to the “SDK” section after under “Installed”. You will stumble upon SQLite for Windows Runtime and SQLite for Windows Phone 8.1 is listed as installed in your pc.


As now we are pretty sure that we have SQLite for Windows Phone 8.1 and Windows Store Apps, let’s create a new Universal App Project in Visual Studio.

SQLite With Universal App

Creating Univresal Apps are pretty same like other projects in Visual Studio. Just go over File->New Project and under Store Apps, let’s create a blank Universal App named UniversalSQLite.


In the Solution Explorer, you will see your projects divided into Windows Store, Windows Phone and Shared. Our job now is to reference SQLite into both Windows Store and Windows Phone projects so both of the projects has access to SQLite. In Windows 8.1 Solution, go over your references and add reference to the newly added SQLite libraries under extensions.


And do the same with Windows Phone 8.1 solution too. Go over references and add reference to the newly installed SQLite for Windows Phone 8.1 Libraries.

You will see some yellow excalamtion signs over the newly referenced libraries and the best thing to do right now is to build this. The first problem you are bound to see when you build is this:


Actually the problem says the solution itself. As these native libraries are extremely machine dependent the best thing to do here would be just go over configuration manager and set x86 as Platform for both projects.

7 8

Trying out x64 ended up XAML designer not rendering UI. So x86 is the safe choice. Don’t worry,  this will not prevent you to create the different platform version to be deployed on the store.

When you are ready just use the “Create App Packages” command. The best way to get that would be right clicking on the solution name and move over to store menu. But that’s later.


Get sqlite-net from Nuget

Well, if you put a build now, you will see everything has smoothed out. Now, what’d left is using SQLite. The first thing we need is a nuget package to cover all the internal intricacies we have on SQLite, thus comes in help sqlite-net  . This little nuget package is extremely handy and all you need to do to use this is to go over references and manage nuget packages. Search for sqlite-net and add it when the search results pop up.


This has to be done for both the Windows 8.1 and Windows Phone 8.1 projects of course as we intend to use this for both of them. You will see two classes named SQLite.cs and SQLiteAsync.cs is created into both of the projects. Just to remove duplicacies we can move them to shared project under a folder if you like.


Let’s get our hands dirty

So, lets get busy with some code, shall we?

Creating/Opening A Database:

To create/open a database all you have to do is someting like the following. This will actually create a database if it’s non existing or open connection to one if it’s existing.

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);

So, before doing that you might want to check whether the database exists or not.

public async Task&amp;lt;bool&amp;gt; DoesDbExist(string DatabaseName)
      bool dbexist = true;
         StorageFile storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync(DatabaseName);

         dbexist = false;

      return dbexist;

The reason we are looking at ApplicationData.Current.LocalFolder is sqlite-net creates database by default in that place.

Creating/Opening A Database:

Before creating a table you need to have a model to define a row on that specific table. The model might look like the following:

using SQLite;

namespace UniversalSqlLite.Model
    public class Student
        [PrimaryKey, AutoIncrement]
        public int id { get; set; }

        public string Name { get; set; }

        public string EnrolledCourse { get; set; }


Now you can just go ahead an create a Table as per your wish.

public async void CreateDatabase()
   SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
   await connection.CreateTableAsync&amp;lt;Student&amp;gt;();

CreateTableAsync will create the table if it’s not there. And it will update the table description if the Model is changed in any way than the previous one. As far now, it only supports column addition. It will not destroy any existing SQLite Table. So, you don’t have to worry about redoing this with an existing table.

If you look closely, you can see that you can adore the classes and the properties in the model with attributes defined in sqllite-net library. It’s almost the same you might see in Entitiy Framework.

The full list is to be found here:

Class attribute:

  • [Table(Name)]

Property attributes:

  • [AutoIncrement]
  • [PrimaryKey]
  • [Column(Name)]
  • [Indexed] | [Indexed(string name, int order)]
  • [Unique]
  • [Ignore]
  • [MaxLength(int length)]
  • [Collation(string name)]
  • [NotNull]

Dropping a Table:

Dropping table is a piece of cake too:

public async void DropDatabase()
    SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
    await connection.DropTableAsync&amp;lt;Student&amp;gt;();

Adding Records in the Table:

Inserting into SQLite is easy as the following:

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
var Student=new Student()
   Name=&quot;Swagata Prateek&quot;,
   EnrolledCourse=&quot;CSE 4203&quot;
await connection.InsertAsync(Student);

And if you feel like inserting a lot of stuff at a time why not using a list?

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);

var StudentList = new List&amp;lt;Student&amp;gt;()
    new Student()
        Name=&quot;Swagata Prateek&quot;,
        EnrolledCourse=&quot;CSE 4203&quot;
        new Student()
            Name=&quot;Abidur Rahman&quot;,
            EnrolledCourse=&quot;CSE 4203&quot;
        new Student()
            Name=&quot;Ashiqur Rahman&quot;,
            EnrolledCourse=&quot;CSE 4203&quot;
await connection.InsertAllAsync(StudentList);

Pursue a Query

You can go for a Query in SQLite in quiet a number of ways. Let’s check out if we want to do it using LINQ, how would it be:

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
var queryVar=await connection.Table&amp;lt;Student&amp;gt;().Where(x=&amp;gt;x.Name.StartsWith(&quot;Swagata&quot;));

var queryResult = await queryVar.ToListAsync();
foreach (var item in queryResult)
    //Do your stuff

You can even do a manual SQL query if you feel like that:

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
var result = await connection.QueryAsync&amp;lt;Student&amp;gt;(&quot;Select Name FROM Students WHERE EnrolledCourse = ?&quot;, new object[] { &quot;CSE 4203&quot;});
foreach (var item in result)
    //Do your stuff

Update and Delete a Record

Any record can be updated as soon as it’s retrieved and updated back into the table.

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
var Student=await connection.Table&amp;lt;Student&amp;gt;().Where(x=&amp;gt;x.Name.StartsWith(&quot;Swagata&quot;)).FirstOrDefaultAsync();

if(Student != null)
    Student.EnrolledCourse = &quot;CSE 4503&quot;;
    await connection.UpdateAsync(Student);

If you want to delete the same record all you have to do is:

SQLiteAsyncConnection connection = new SQLiteAsyncConnection(&quot;Student.db&quot;);
var Student=await connection.Table&amp;lt;Student&amp;gt;().Where(x=&amp;gt;x.Name.StartsWith(&quot;Swagata&quot;)).FirstOrDefaultAsync();

if(Student != null)
    await connection.DeleteAsync(Student);

Summing up

We are going to take a little deep dive on the queries and make a sample app out of it in the next post. Meanwhile you can even go through Nicolò Carandini’s blog on SQLite with Universal app on the following links.

  1. Universal App With Sqlite Part -1
  2. Universal App With Sqlite Part -2

Hope you guys had fun!

সোজা সাপ্টা ম্যাশিন লার্নিং – কে নিয়ারেস্ট নেইবর (K Nearest Neighbour)

সত্যি কথা বলতে কি, আমরা সবাই একটা বেশ লম্বা থিসিস করে আসি চতুর্থ বর্ষে, আমি জানিনা অন্যদের কথা, কিন্তু অনেক কিছুই আমি ঠিকমতো বুঝিনাই, তাই ঠিকমতো বোঝার ইচ্ছা টা যায়নাই। সেই চেষ্টায় ভাবলাম, যেটুকু বুঝি , লিখে ফেলি। ম্যাশিন লার্নিং জিনিসটা ভারিক্কী শোনালেও জিনিস টার কাজ একটাই, একটা গবেট প্রকৃতির ম্যাশিন কে আপনি কোন নির্দিষ্ট ব্যাপারে ঠিক যে ভাবে চিন্তা করেন সেভাবে তাকে ভাবতে শিখানো বা অন্তত কাছাকাছি কিছু একটা চেষ্টা করা।

ম্যাশিন লার্নিং এ আমার মতো যারা নবিশ তাদের জন্য কিছু বলতে হলে বলা লাগে, যদি ম্যাশিন লার্নিং কে একটু ক্ল্যাসিফাই করার চেষ্টা করি তাহলে দুটো বড়সড় ভাগ পাবেন। প্রথমটার নাম সুপারভাইজড লার্নিং, আরেকটা আনসুপারভাইজড লার্নিং। কোনটা কি এগুলোর সংজ্ঞা নিয়ে ভটভট করার মতো জ্ঞান আমার নাই। তাই সোজা সহজ ভাবে বলি। যদি একটা ম্যাশিন কে শুরু থেকে কিছু শেখানো হয়, তারপর সে কিছু ঠিকঠাক মতো করতে পারে, সেটা দাঁড়ায় সুপারভাইজড লার্নিং এর দলে। বাকিটা হচ্ছে আনসুপারভাইজড।

ম্যাশিন লার্নিং থেকে ম্যাশিন শব্দ টা সরিয়ে ফেলুন, মনে করুন আপনি একটা ম্যাশিন। একটু সুবিধাজনক একটা পরিবেশ চিন্তা করতে গেলে আপনাকে একটু বোকা হতে হবে। ম্যাশিন সাধারণত বোকাসোকা হয়। তাহলে কি করা? চলুন ফেরত যাই ছোটবেলায়। একদম যখন ছোট ছিলেন আপনি তখন নিশ্চই আপনি এতো কিছু জানতেন না। তো সেই হিসাবে সেই সময়টায় আপনি এখনকার একটা বোকা ম্যাশিন এর মতোই ছিলেন। এখন বাকি থাকলো লার্নিং শব্দটা। সহজ কথায় শিক্ষা। আসুন ছোটবেলার আপনাকে কিছু শেখানো যাক।

ভয় নেই। বেশিদূর যাওয়া লাগবেনা। আপনার মার কথাই মনে করুন। আপনার মাই সম্ভবত আপনাকে শিখিয়েছেন সব কিছু্। চিন্তা করুন, আপনার মা আপনাকে চিনতে শিখিয়েছে কোনটা কি? ধরে নিলাম আপনার মা আপনাকে চিনিয়েছে আপেল, ধরে নিলাম, প্রথম আপেলটির রং ছিলো হালকা লাল। পরেরদিন আপনার মা আপনাকে দিলো একটি হালকা সবুজ রঙের আপেল, পরেরদিন একটু গাড় রঙের আরেকটি। চিন্তা করুন একবার, খুবই সাধারণ মনে হওয়া এই ঘটনাটি আসলে ম্যাশিন লার্নিং এর একটি অসাধারন উদাহরণ। আপনি (ম্যাশিন) প্রতিদিন দেখেছেন একটি ভিন্ন আপেল, ভিন্ন রং, ভিন্ন আকার এবং হতে পারে একটু ভিন্ন স্বাদের। কিন্তু আপনি জেনেছেন সব ই আপেল। যদি এমন হতো, প্রতিদিন এক ই রঙের, আকারের আপেল দেখতেন, আপনি হয়তো কোনদিন বিশ্বাস করতে পারতেন নাম আপেল অন্য আকার বা রঙের হয়। আপনার মা খুব নিভৃতে আপনাকে শিখিয়েছেন একটি সাধারণ আপেল দেখতে কেমন হয়। এটাকে সহজ কথায় Generalization বলে। যে কারণগুলো একটা আপেল থেকে বাকিগুলোকে আলাদা করেছে সেগুলোই Feature. একটু ভেবে দেখুন, যদি আমরা গোলকার আকৃতি এবং লাল রং কে আপেলকে অন্য সব কিছু থেকে আলাদা করার Feature হিসেবে ঘোষনা করি, তাহলে আপেলটা দিনশেষে কিছু লাল বলের সাথে গিয়ে জমা হতে পারে। এটিকে বলে Over generalization. আবার উল্টোটি হলে under generalization  ও হয়ে যেতে পারে। 🙂

সুতরাং বোঝাই যাচ্ছে ঘাপলাটা কোথায়। আপনাকে আপেল থেকে অন্য কিছু আলাদা করার জন্যে ঠিক সেই Feature গুলোই গ্রহণ করতে হবে যেগুলো over বা under generalization তৈরী করবেননা। এর মানে হচ্ছে গোলাকার আকৃতি Feature হিসেবে খুব একটা সুবিধার না, অনেক কিছুই গোলাকার হতে পারে। কিভাবে ভালো Feature বের করতে হয় সেটা নিয়ে আমরা ভটভট পরে করবো কোন এক দিন। আসেন কোন কিছু নিয়ে ভটভট করি। আমাদের আজকের লক্ষ্য K-Nearest Neighbor Algorithm দেখা, এটি আসলে একটি Classification Algorithm, সহজ কথায় যেগুলো দিয়ে অনেক কিছু থেকে জিনিসপত্র ভিন্ন ভিন্ন প্রকারে ভাগ করা হয়।

K-Nearest Neighbor Algorithm

K-Nearest Neighbour এর নাম ই যথেষ্ট আসলে এটি কি করে সেটা বোঝানোর জন্যে। সহজ বাংলায় এটি কোন কিছুকে ক্ল্যাসিফাই করে অনেকটা সে জিনিসটার আশেপাশের জিনিসগুলো কোন প্রকারের তার উপর থেকে। ধরুন আপনি একটি গোলাকার জিনিস অনেকগুলো আপেল আর বলের মধ্যে রাখলেন । কে নিয়ারেস্ট নেইবর যেটা বলে সেটা হচ্ছে  আপনার রাখা নতুন বস্তুটি আশেপাশের অধিকাংশ বস্তু যে প্রকারের সেই প্রকারের মধ্যে পরে। যদি আশেপাশের অধিকাংশ জিনিস বল হয়, তাহলে সেটি বল অথবা সেটি আপেল। আজগুবি ঠেকলেও ভুলে যাবেন না, আপনি কিন্তু যে কোন জায়গায় আপনার অজানা জিনিসটি বসাতে পারবেন না। বসাবেন আসলে তার ফিচারের ভিত্তিতে। যদি সেটি সত্যি আপেল হয় এবং আপনার ফিচার ঠিকমতো নির্ণয় করা হয়ে থাকে তাহলে সেটি অবস্থান নেবে আপেলদের পাশেই। তার মানে এই নাম এই অ্যালগরিদম একেবারেই ভুল করেনা। তবে সেটা নিয়ে পরে কথা বলি না হয়।

ছোট্ট একটি উদাহরণ:

মনে করুন, আপনার কাছে এইরকম একটি ডাটাসেট আছে।

Rooms Area Type
1 350 apartment
2 300 apartment
3 300 apartment
4 250 apartment
4 500 apartment
4 400 apartment
5 450 apartment
7 850 house
7 900 house
7 1200 house
8 1500 house
9 1300 house
8 1240 house
10 1700 house
9 1000 house
1 800 flat
3 900 flat
2 700 flat
1 900 flat
2 1150 flat
1 1000 flat
2 1200 flat
1 1300 flat

দেখেই বোঝা যাচ্ছে এটি আকার এবং রুম সংখ্যার ভিত্তিতে আপনার বাসাটি অ্যাপার্টমেন্ট, ফ্ল্যাট না হাউজ সেটার প্রকারভেদ। তাহলে এখানে সহজ কথায় রুম সংখ্যা এবং আকার আমাদের ফিচার। এই স্যাম্পল সেটটি যদি আমরা কোন ম্যাশিন কে শিখাই, তাহলে এটার উপর ভিত্তি করে সে নতুন কোন নোড এই কোন ক্যাটাগরিতে পরে সেটা আপনাকে জানিয়ে দেবে। প্রশ্ন হচ্ছে কিভাবে। আমরা যেটা করবো এখন সেটি হচ্ছে একটি দ্বিমাত্রিক কার্তেসীয় স্থানাংক ব্যবস্হায় X অক্ষ বরাবর Room সংখ্যা এবং Y অক্ষ বরাবর বসাবো Area. এখন এই ছকে নতুন কোন বাসা যখন আসবে তখন সেটিও হবে আসলে একটি ডাটা পয়েন্ট মাত্র। আমরা সেটির আশে পাশের K সংখ্যক ডাটা পয়েন্ট গুলো থেকে দেখে নিবো সেটি কোন প্রকারে পরে। সহজ বাংলায় আমাদের অ্যালগরিদম টা দাঁড়ায় এরকম :

১. স্যাম্পল ডাটা সহ যে সকল Mystery Point (যেগুলো কোন প্রকারে পরে আমরা জানিনা)  বসিয়ে দিন ছকে
২. বের করে নিন Mystery Point গুলো থেকে সকল পয়েন্ট এর দূরত্ব। ৩. এরপর বেছে নিন কাছের K সংখ্যক প্রতিবেশী পয়েন্ট কে।
৪. k সংখ্যক প্রতিবেশীদের সর্বোচ্চ সংখ্যক প্রতিবেশী যে প্রকারের আপনার Mystery Point ও সেই প্রকারের।

আসুন আমরা ছোট্ট একটা কোডে চলে যাই।


আমি কোড করার প্ল্যাটফরম হিসেবে নিয়েছি উইন্ডোজ ফোন ৮ এবং আমি চার্ট এর জন্যে ব্যবহার করছি আমার পছন্দের Telerik Rad Controls. আপনারা চাইলে স্প্যারো টুলকিট ব্যবহার করতে পারেন। এটি ফ্রি এবং চমৎকার। চাইলে যে কোন ল্যাংগুয়েজে কোড করে ফেলতে পারেন। আমি এখানে অসম্ভব crude code করে গেছি এবং চেষ্টা করে গেছি কোড বড় হলেও বোধগম্য রাখার। আপনি আপনার মতো সাজিয়ে নেবেন। 🙂

আমরা প্রথমে Node  এবং NodeList নামের দুটি ক্লাস নিয়ে কাজ করবো।

class Node শুরুতে দেখতে অনেকটাই এরকম:

public class Node
public int Rooms { get; set; }
public int Area { get; set; }
private NodeType _type = NodeType.unknown;
public NodeType Type {
{ return _type; }
_type = value;


private void SetForeground()
if (_type == NodeType.apartment)
Foreground = new SolidColorBrush(Colors.Red);
else if (_type == NodeType.flat)
Foreground = new SolidColorBrush(Colors.Green);
else if (_type == NodeType.house)
Foreground = new SolidColorBrush(Colors.Blue);
Foreground = new SolidColorBrush(Colors.White);

public SolidColorBrush Foreground { get; set; }

public ObservableCollection Neighbours { get; set; }

public double Distance { get; set; }

public Node()



এখানে প্রথমে যেটা চোখে পরে, সেটা হচ্ছে শুরুতেই Rooms এবং Area বলে দেয়া শুরুতে। এই দুটো আমাদের ফিচার, একটি Node একটি বাসাকে প্রকাশ করে এখানে। সুতরাং এগুলো শুরুতেই ডিফাইন করা। এরপর দেখা যাচ্ছে NodeType বলে দেয়া এবং NodeType এর ভিত্তিতে একটি Foreground বলে দেয়া। এটি করা হয়েছে শুরু চার্ট তৈরী করার সুবিধার্থে। আসুন দেখে নেই NodeType enum টি কিরকম।

public enum NodeType

স্পষ্টতই দেখা যচ্ছে টাইপ গুলো আমরা আমাদের স্যাম্পল ডাটার মতো বলে নিয়েছি। শুধু unknown টাইপটি আমাদের Mystery Point এর জন্যে। যাতে আমরা চার্টে আলাদা করতে পারি কোনটার টাইপ আমি জানিনা। এবার আসুন NodeList ক্লাসটি কিরকম দেখে নেই

public class NodeList
        private int MinAreas { get; set; }
        private int MinRooms { get; set; }

        private int MaxAreas { get; set; }

        private int MaxRooms { get; set; }

        public ObservableCollection<Node> Nodes { get; set; }
        public int K { get; set; }

        public NodeList()
            MinAreas = MinRooms = 100000;
            MaxAreas = MaxRooms = 0;


এখানে দেখা যাচ্ছে MinAreas, MaxAreas এবং MinRooms, MaxRooms নামের কয়েকটি প্রোপার্টি ডিফাইন করা। এগুলো আরো সহজেই করা যায়। কিন্তু কাজের এবং বোঝার সুবিধার্থে আলাদা করে লেখা। যে দুটি প্রোপার্টি জরুরী তা হচ্ছে Nodes এবং K . Nodes হচ্ছে আপনার ম্যাশিনের শেখা সমগ্র নোড গুলো (উপরের বাসার লিস্ট) এবং K হচ্ছে কতজন প্রতিবেশী নোড কে আমরা বিবেচনায় আনবো সেটির সংখ্যা। আপনি চাইলে Nodes কালেকশনটি কনস্ট্রাকটর ডিপেন্ডেন্সি তে ঢুকিয়ে দিতে পারেন। কিন্তু আমি আগেই বলেছি, এই পুরো লেখার উদ্দেশ্য বোঝানো, তাই কোডের এই দুরবস্থা। 😛
আসুন আর একটু আগানো যাক। এখন আমাদের Mystery Point থেকে সকল পয়েন্ট এর দূরত্ব বের করার কথা। কিন্তু তার আগে কিছু কথা বলা প্রয়োজন।


একটু ভালো করে দেখুন, আমাদের দেয়া স্যাম্পল ডাটাতে রুম সংখ্যা ১ থেকে ১০ এর মধ্যে এবং রুম সাইজ ২৫০ তে ১৭০০ এর মধ্যে। তার মানে আমাদের x অক্ষ বরাবর বিন্দুগুলোর দূরত্ব Y অক্ষ বরাবর বিন্দুগুলোর দূরত্ব হতে গড়ে কম হবে। এটিতে যেটা হতে পারে, একটি বাসা ছকে তার সর্ব্বোচ্চ কাছাকাছি বিন্দু হতে অপেক্ষাকৃত দূরে সরে যেতে পারে এবং ভুল বিন্দুর কাছে X অক্ষ বরাবর কাছে চলে আসতে পারে। ফলে আপনার অ্যালগরিদম এর ফলাফল ক্ষতিগ্রস্ত হতে পারে। আসুন সব ভ্যালু গুলোকে আমরা ০ হতে ১ এর মধ্যে নিয়ে আসি। সহজ বাংলায় আমরা আমাদের গ্রাফটিকে বর্গাকার করে নিচ্ছি যাতে X অক্ষ এবং Y অক্ষ এর গুরুত্ব সমান থাকে। আপনি যদি চান আপনার ক্ল্যাসিফিকেশনে রুম সংখ্যা বেশি গুরুত্ব পাবে। তাহলে আপনি যেকোন অক্ষের দুরত্ব কমিয়ে আনতে পারেন। একে Weighting বলে। সেটা না হয় পরে।

দুই অক্ষের সকল ভ্যালু ০ হতে ১ এর মধ্যে আনতে হলে দুই অক্ষের সর্ব্বোচ্চ এবং সর্বনিম্ন মান আমাদের জানতে হবে এবং সেটাকে অক্ষভেদে মানের পার্থক্য দিয়ে ভাগ দিতে হবে। আসুন কোড দেখে বুঝে নেই:

        private void CalculateRanges()
            if(Nodes!=null && Nodes.Count>0)

                foreach (var node in Nodes)
                    if (node.Rooms < MinRooms)
                        MinRooms = node.Rooms;
                    if (node.Rooms > MaxRooms)
                        MaxRooms = node.Rooms;

                    if (node.Area < MinAreas)
                        MinAreas = node.Area;
                    if (node.Area > MaxAreas)
                        MaxAreas = node.Area;

CalculateRanges() মেথডটি NodeList ক্লাসে যোগ করা। দেখেই বোঝা যাচ্ছে খুবই আনাড়ি কোড কিন্তু বোঝার জন্যে এটি অসাধারণ। খেয়াল করে দেখুন CalculateRanges() শুধুমাত্র room এবং area (আমাদের x এবং y অক্ষ) এর সর্ব্বোচ্চ এবং সর্বনিম্ন মান খুঁজে বের করছে। আর কিছু নয়। এখন যেহেতু আমাদের হাতে দুই অক্ষের সর্ব্বোচ্চ এবং সর্বিনম্ন মান আছে সেহেতু আমরা মূল অ্যালগরিদমে প্রবেশ করতে পারি।

public void DetermineUnknown()
            //start the calculation of range;

            foreach (var node in Nodes)
                if(node.Type == NodeType.unknown)
                    node.Neighbours = new ObservableCollection<Node>();
                    foreach (var NNode in Nodes)
                        if (NNode.Type == NodeType.unknown)


                    //Measure Distance Now

                    node.MeasureDistances(MaxRooms - MinRooms, MaxAreas - MinAreas);

                    //Sort it out
                    node.Neighbours = new ObservableCollection<Node>(node.Neighbours.OrderBy(x => x.Distance).ToList());

                    //Guess the type

এক বস্তা জিনিস এক সাথে লিখে ফেললাম, এই তো? আসুন আস্তে আস্তে আগাই। আমরা CalculateRanges() আগেই দেখেছি। শুরুতেই লুপে ঘুরছে আমাদের সব স্যাম্পল ডাটা (যেখানে আমাদের Classification না জানা Mystery Points গুলো, মানে যে বাসাগুলো কোন প্রকারের আমরা জানিনা সেগুলোও আছে এবং অবশ্যই স্যাম্পল ডাটা সেট ও আছে)। দেখা হয়েছে NodeType unknown কিনা, হলে সেটিই সেই বাসা যেটির প্রকার আমরা জানিনা, তার মানে সেটি Mystery Point গুলোর একটি। আসুন সেটিকে classify এর ব্যবস্থা করি। শুরুতে ই লাগবে সকল প্রতিবেশী সকল নোড হতে দূরত্ব্। না হলে কাছের গুলো বের করবেন কিভাবে। সেজন্যে MeasureDistances() ব্যবহার করা। দেখে আসি মেথডটি দেখতে কেমন হতে পারে। খেয়াল করে দেখুন, আরগুমেন্ট দুটি হচ্ছে Rooms এবং Areas এর মানের পার্থক্য। এটি আমাদের Normalize করতে সাহায্য করবে।

        internal void MeasureDistances(int RoomRange, int AreaRange)
            foreach (var neighbour in Neighbours)
                double delta_rooms = neighbour.Rooms - this.Rooms;
                delta_rooms = delta_rooms / (double)RoomRange;

                double delta_area = neighbour.Area - this.Area;
                delta_area = delta_area / (double)AreaRange;

                neighbour.Distance = Math.Sqrt(delta_rooms * delta_rooms + delta_area * delta_area);


এখানে দূরত্ব বের করার আগে Normalization করো হয়েছে। তার মানে আমরা প্রতিটি প্রতিবেশীর Room এবং Area এর মানের পার্থক্য কে Room এবং Area এর সর্বোচ্চ এবং সর্বনিম্ন মানের পার্থক্য দিয়ে ভাগ দিয়ে এই মানগুলোকে ০ হতে ১ এর মধ্যে নিয়ে আসছি। এর পর আমরা পিথাগোরাসীয় দূরত্ব বের করছি। একটি জিনিস লক্ষ্য করে দেখুন। আমাদের ফিচার সংখ্যা দুইটি হওয়ায় আমরা দ্বিমাত্রিক কার্তেসীয় স্থানাংক ব্যবস্থায় আমরা বিন্দুগুলোকে X অক্ষ এবং Y অক্ষে আলাদা করে লিখেছি। এইজন্য দ্বিমাত্রিক দুটি বিন্দুর দূরত্ব বের করার সূত্র হচ্ছে Math.Sqrt(x * x + y * y)
যদি আপনার ফিচার তিনটি হতো তাহলে ছকটি ত্রিমাত্রিক স্থানাংক ব্যবস্থায় চলে আসতো। তখন দুই বিন্দুর দূরত্ব হতো Math.Sqrt(x * x + y * y+ z*z)
এইভাবে n সংখ্যক ফিচারের জন্য n মাত্রিক স্থানাংক ব্যবস্থায় দুই বিন্দুর দূরত্ব হতো Math.Sqrt(x * x + y * y+ z*z+ …..+ n*n)
আপনি চাইলে একটি n মাত্রিক স্থানাংক ব্যবস্থাকে কমিয়ে এনে দ্বিমাত্রিক ব্যবস্থায় প্রোজেক্ট করতে পারেন। তবে সেগুলো অন্য কোন দিন। যেটা আমি এখানে বোঝাতে চেয়েছিলাম সেটি হচ্ছে এটিই KNN এর ক্ষমতার পরিচায়ক, আপনার ফিচার সংখ্যা যাই হোক না কেন, সেটি আরামসে কাজ করতে পারে। তবে মনে রাখবেন বেশি ফিচার মানেই ভালো ক্ল্যাসিফিকেশন তা নয়। তাতে সেই generalization সংক্রান্ত জটিলতায় পড়তে পারেন।

তো MeasureDistances() এর পরে আমাদের কাজ হচ্ছে দূরত্বের ভিত্তিতে প্রতিটি নোডের প্রতিবেশীর লিস্ট কে সর্ট করা। কারণ আমরা k সংখ্যক কাছের প্রতিবেশী নিয়ে আগ্রহী। এর পরেই চলে আসে Mystery Point টি যেটির প্রকার আমরা জানিনা (যে বাসাটি ফ্ল্যাট, অ্যাপার্টমেন্ট না হাউজ আমরা জানিনা) সেটির প্রকার খুঁজে বের করা। সেই কাজটি করে GuessType()

internal void GuessType(int k)
            int[] TypeVotes = new int[4]; //There are three types;

            var EligibleNeighbours = this.Neighbours.Take(k).ToList();

            foreach(var eligibleNode in EligibleNeighbours)
                TypeVotes[(int)eligibleNode.Type] ++;


            NodeType GuessedType = (NodeType)TypeVotes.Max();

            MessageBox.Show("Guessed type for node is " + GuessedType.ToString());

            this.Type = GuessedType;

আমরা চলে এসেছি প্রায় শেষে, দেখুন এটি কোন নোডের প্রতিবেশী হতে খুঁজে বের করে সর্বোচ্চ কাছের k সংখ্যক প্রতিবেশী কে । এবং এদের থেকে সর্বোচ্চ সংখ্যক প্রতিবেশী যে প্রকারের আপনার Mystery Point টি ও সেই প্রকারের বলে ঘোষনা করে। মানে এখানেই আপনি জেনে যাবেন আপনার বাসাটি কোন প্রকারের।

উইন্ডোজ ফোনে উদাহরণ:

‌উইন্ডোজ ফোনে আমি একটি ছোট্ট MVVM অ্যাপ বানিয়ে পরীক্ষা করেছি অ্যালগরিদম টি। পুরো কোড শেষে দেয়া আছে। তাই MainviewModel এর কিছু অংশ আমি তুলে দিচ্ছি:

        public MainViewModel()

            TestKnnCommand = new RelayCommand(TestKnnAction);

        private void TestKnnAction()

        private void LoadSamples()

            using(StreamReader reader= new StreamReader("SampleData.txt"))
                var data = reader.ReadToEnd();
                List<Node> datArray = JsonConvert.DeserializeObject<List<Node>>(data, new StringToEnumConverter());
                var _sampleCollection = new ObservableCollection<Node>(datArray);

                NodeCollection = new NodeList();
                NodeCollection.K = 3;
                NodeCollection.Nodes = _sampleCollection;



        private void AddASample()
            Node newNode = new Node() { Area = 500, Rooms = 2, Type = NodeType.unknown };

আমি শুধু শুরুতে লোড করে নিয়েছি আমার স্যাম্পল ডাটা গুলো। এরপর যোগ করে নিয়েছি একটি অজানা Mystery Point , মানে এমন একটি বাসা যেটি কোন প্রকারের আমি জানিনা। K এখানে ৩, তার অর্থ হচ্ছে আমি ৩ টি কাছের প্রতিবেশী ব্যবহার করবো classification এর জন্যে।
TestKnnAction() একটি action যেটি একটি বাটন হতে command এর সাহায্যে invoke করা হয়। এবং এটি অজানা পয়েন্ট টির ক্ল্যাসিফিকেশন বের করার জন্য DetermineUnknown() ব্যবহার করে। আপনি চাইলে একাধিক স্যাম্পল যোগ করে অ্যালগরিদম টি চালিয়ে দেখতে পারেন।

জেনে রাখা ভালো:

অন্য সকল ক্লাসিফিকেশন অ্যালগরিদম এর মতোই এটিতেও সমস্যা আছে। আপনার ডাটা সেট যদি পৃথক করার যোগ্য (Separable) হয় তবেই এটি বেশ ভালো কাজ করে। আর যদি তা না হয় আপনি এমন একটি ছক পাবেন যেটায় বিন্দু গুলো সব জায়গায় ছড়িয়ে আছে এবং ফলশ্রুতিতে আপনি ভালো ফলাফল পাবেন না। বরং আপনি যদি ছকে দেখেন বিন্দুগুলো cluster বা গুচ্ছে গুচ্ছে বিভক্ত তাহলে বুঝবেন এটি Separable বা পৃথক করার যোগ্য। আরেকটি জিনিস, নোডসংখ্যা বাড়লে আপনার ক্যালকুলেশন টাইম ও বাড়বে। তাই আপনি চাইলে Pruning করতে পারেন। যেমন যে বাসার Room সংখ্যা ২ তার জন্যে যে সকল বাসা যাদের room সংখ্যা ৬ এর অধিক তাদের সাথে দূরত্ব বের করা অর্থহীন।

আশা করি সবার ভালো লাগবে। অ্যাপ এর দুটি স্ক্রিনশট তুলে দিলাম।

Initial KNN Graph

classification result

কোডটুকু পাওয়া যাবে এখানে। যদিও আপনার Telerik Rad Controls for Windows Phone 8 এর লাইসেন্স থাকা লাগবে এটি বিল্ড করার জন্যে। তবুও দিয়ে দিলাম : http://1drv.ms/1DOTVu8

Bus Map Dhaka – What can be next and how it can be done

Usually I talk about pretty current stuffs, let’s talk future now. And the future is needed to be talked now. Because after some days in this young app industry simple rss readers won’t be considered a quality app anymore. If you look around, Windows Phone in Bangladesh has walked a pretty silent but significant path. And I’m quiet happy that I walked a little too.

I hope the one who is reading this do know Bus Map Dhaka for Windows Phone. If you dont know, the following is the link: http://www.windowsphone.com/en-bd/store/app/bus-map-dhaka/3795f088-028a-4958-bea6-a2d0eb243bd

Now, let’s start talking how this was made. When I started doing this, the first thing that came into my mind is the actual scenario of Dhaka, if you really expect a local bus to come in the very right time exactly every day,  I guess you have optimism as your profession. So, along with finding the best route and other basic operations, I had to believe someday I would face the challenge which will “actually” solve the problem.

Traffic jams are usually one of the common phenomena here, very common as in like brushing your teeth everyday. If it’s not there, you get surprised. But it’s not the only thing that can keep you getting on the right bus. There’s bad road situations, there’s bus shortage, possibly anything that you can’t predict or manage.

I thought big big plans, like putting devices on buses and tracking down each one of them. But think once, just once. When nobody is even curious about putting proper fitness checks on a bus, maintaining  a device would be a overkill for them, and of course will lead my dream service to perish.

What I had it mind was a pretty simple one. If you ever heard of Ant Colony Optimization, I believe in case of Dhaka, it would come to a greater use . Because the shortest path is not always the “right path”.

If you want to know about ant colony optimization algorithm do a wiki read here:

I wanted to follow the traditional Ant Colony Optimization trait here. Let’s put a small city like Dhaka with us like below:


Pretty simple for Dhaka, eh? 😀 Let’s keep it simple for understanding. You will see Node D is kind of the hub of the city, much like our motijheel, mohakhali or other big bus junctions, right? Now, in this city there can be a number of buses, right? Essentially a Bus Route is nothing but a number of these nodes ordered by bus stops.

Let’s make some bus routes, shall we?
1. A-C-E

2. C-D-E-B-A

3. D-E-C-A

For simplicity lets assume all these bus goes and comes back in the same order. Now, I know what you guys are thinking, if I put “distance metrics” on these paths, it’s easy to find a suitable bus route. Like, if you want to take A trip from A to D you can chose bus number 2 or 3. Question is which one should you pick? What if there is more traffic jam in B-E junction and less in C-E? These data changes over time, even in fraction of ten minutes.  You can’t possibly decide every time.

Here ant colony comes so handy. The very basics of Ant Colony Optimization is based on how ants find best paths. In the natural world, ants  wander randomly and after finding food return to their colony while they continuously lay down pheromone trails. If other ants find such a path, they are likely not to keep traveling at random, but to instead follow the trail, returning and reinforcing it if they eventually find food. So, the fact is who knows the best path right now, the bus that just has gone to that path a few minutes ago. Just like the ant. The only deficit we have here is pheromone trail left by ants. Now, remember what we have in hand. We cant put too much on a local bus as they wont take care of it properly.

But what about known bus counters? If we manage to find only time-stamps of a bus arriving at a bus-stoppage somehow, we don’t need to know which one came, just spotting one on a counter, much like spotting an ant on a node.   And based on the frequency of that timestamp, you can actually verify the frequency of buses coming down there. If the adjacent roads are not doing well with traffic jams, you are bound to have a lesser frequency and if it’s smooth sailing you will have a solid frequency. Even if that sounds awkward we can even track ticket sales, although that would be far off, still a usable heuristic metric to understand whether people are actually getting up on a bus or not.

Now, based on that. We want to go to D from A.

We have two bus routes, 2 and 3. Now which to pick? All we have to do is check the pheromone/our very own heuristic cost metric trails and the route that currently has a more favorable reinforcement/feedback. No matter what comes in the road, traffic jams or stuff, within minutes, these would be updated. And as the buses are continuously traveling, the metric will always be updated. And further more, you can even predict a possible next bus time from this too. Or predict a best possible route to go from one place to another on a car. I know, for Dhaka, it might be a bit long shot, still…worth a try.

So, if you believe every bus is a ant running on a direction (although these are defined rather than random). Actually that makes us one step closer to goal. Because logically ant colony optimization finds a best path. As our possible paths are already defined, we don’t have to go through the first state.

There should be usually two steps of ant colony optimization:
1. Edge selection
2. Pheromone Update

As our paths are already defined, edge selection is basically finding eligible bus routes to go from one place to another, it could be a multiple bus journey but I will write about that later.

procedure BMD_Heuristic
    end while
  end procedure

Let me know what you guys think of it and how can you help NerdCats take it to the next level. See ya!

Windows Phone micro UI hacks – simple drop shadows

Well, I was pretty upset when they took off effects support from silverlight, I really was. It was something I really loved thus I could’ve added a little bit of depth in design. I get the idea that it might help improving performance of UI rendering in a device.

So, I was trying out some little hacks, or you might say some faulty impersonations of making a drop shadow, so far I’m not close to that “quality” but I did try.

Let’s assume you want to put a rectangle with a drop shadow. Effectively if you break down a drop shadow you will find a black to grey gradient alpha mask of your rectangle, in easy words, nothing but a blurry grey scale representation of your rectangle lying back. Now, that’s what I tried out here. I took a rectangle, copied it behind it and kept it with a black and grey shades. I could’ve used just one gradient gray shaded rectangle but it doesn’t look that good.

Now, let’s see how that looks.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Rectangle x:Name="tb1" Fill="Black" Opacity="0.2" Margin="1,3,0,0"  Height="{Binding Height, ElementName=tb5}" Width="{Binding Width, ElementName=tb5}"/>
            <Rectangle x:Name="tb2" Fill="Black" Opacity="0.2" Margin="-1,3,0,0"  Height="{Binding Height, ElementName=tb5}" Width="{Binding Width, ElementName=tb5}"/>
            <Rectangle x:Name="tb3" Fill="Black" Opacity="0.4" Margin="0,2,0,0"  Height="{Binding Height, ElementName=tb5}" Width="{Binding Width, ElementName=tb5}"/>
            <Rectangle  x:Name="tb4" Fill="Black" Opacity="0.2" Margin="0,3,0,0" Height="{Binding Height, ElementName=tb5}" Width="{Binding Width, ElementName=tb5}"  />
            <Rectangle Width="250" Height="100" x:Name="tb5" Fill="#FFE63939"  />

This is a very basic try of course. I’m going to make a usercontrol out of it somehow. And if I do, you will find it right here on my blog and looks like somehow I have to fake the blur too.

Well, until next time then. And by the way, it looks like below on the screen:
Rectangle Drop Shadow test

বাংলায় উইন্ডোজ ফোন — Introduction to MVMMLight

আবার ফিরে এলাম অনেকদিন পর। আজকের ভিডিওটি mvvmlight toolkit এর ওপর। mvvmlight অসম্ভব জনপ্রিয় একটি mvvm toolkit. আসুন দেখে নেই mvvm এর বেসিক কিছু কাজ কিভাবে এটি দিয়ে খুব সহজেই করে নেয়া যায়।

বাংলায় উইন্ডোজ ফোন – DelegateCommand, The Reusable ICommand

অনেকদিন পর ফেরত আসলাম। আজকের টিউটোরিয়াল ICommand এর একটি সহজ ও Reusable Implementation যার নাম DelegateCommand, তার উপরে। DelegateCommand implement হয় ICommand interface দিয়েই এবং এটি ICommand এর ব্যবহারকে অনেকটাই সহজ করে দেয়। আশা করি সবার ভালো লাগবে।

পুনশ্চ: যদি আপনি Introduction to ICommand দেখে না থাকেন তাহলে অনুগ্রহ করে দেখে আসুন।


প্রজেক্ট সোর্স পাওয়া যাবে এই লিংকে – http://sdrv.ms/1dYX3pT

উইন্ডোজ ফোন স্টোরে বাংলা অ্যাপ সাবমিশন – কি কি মনে রাখা উচিত

উইন্ডোজ ফোন স্টোরে যারা সাধারনত অ্যাপ পাবলিশ করছেন, অন্তত বাংলাদেশ থেকে, প্রথম প্রথম এই প্রশ্নটা মাথায় না আসাটা স্বাভাবিক কারণ সাধারণত অ্যাপগুলোর প্রধান ভাষা হয় ইংরেজী। কিন্তু উইন্ডোজ ফোন ৮ আসার পর লোকাল অ্যাপ নিয়ে কাজ করার প্রচলন টা লক্ষণীয়। এবং প্রথম যে প্রশ্নের সামনে আমরা পড়ি তা হচ্ছে, আমি কি করে একটি বাংলা অ্যাপ বানাবো এবং সেটা স্টোরে সাবমিট করবো। আমার আজকের উদ্দেশ্য এই প্রশ্নগুলোর উত্তর দেয়া।

বাংলা অ্যাপ বানানো:

বাংলা অ্যাপ বানানোর প্রথম সাবধানতা হচ্ছে যাদ আপনি সমগ্র অ্যাপটি বাংলায় করতে চান তাহলে অবশ্যই কোন নির্দিষ্ট ইউনিকোড ফন্ট (উদাহরণ: সিয়াম রূপালী) ব্যবহার করবেন সমগ্র অ্যাপটিতে । আপনি চাইলে উইন্ডোজ ফোনের ডিফল্ট ফন্ট যেটা আসে বাংলা লিখলে (নির্মলা) ব্যবহার করতে পারেন তবে নির্দিষ্ট কিছু যুক্তাক্ষরে সমস্যা হয় সুতরাং খেয়াল রাখবেন। অন্যক্ষেত্রে এটি দেখতেও বেশ সুন্দর, ব্যবহারেও বেশ ভালো।

অ্যাপ এর নাম অনায়াসে বাংলা দিতে পারেন। কোন সমস্যা নেই। তবে উইন্ডোজ ফোন ৭.৮ সহ টার্গেট করলে না দেয়া সমীচিন। তাতে উইন্ডোজ ফোন ৭.৮ এ আপনার অ্যাপ এর নাম দেখতে সমস্যা হবে।

খেয়াল রাখ‍বেন সার্চ কিওয়ার্ড এ আপনার অ্যাপ এর নাম এর সম্ভাব্য সকল ইংরেজী নাম দিয়ে দিতে। কেননা অাপনার অ্যাপ টি সার্চ করে তো পাওয়া লাগবে।

অ্যাপ এ যদি সার্চ রাখতে চান বাংলা চন্দ্রবিন্দু একমাত্র ভরসা এখন পর্যন্ত। কারো যদি দরকার হয় কাস্টম কন্ট্রোলটি, যোগাযোগ করুন আমার সাথে। 🙂 আমি সাধ্যমতো চেষ্টা করবো।

এইবার আসি লোকালাইজেশন এর কথায়। আপনি চাইলেই অ্যাপটি লোকালাইজড করতে পারেন। এ নিয়ে বিস্তারিত পাবেন এখানে । আপনার যদি একটি ইন্টারন্যাশনাল অ্যাপ থাকে যার কন্টেন্ট দেশ ও স্থান অনুসারে ভাষা বদলায়, তার জন্যে খুব ভালো অ্যাপ্রোচ এটি।

বাংলা অ্যাপ সাবমিশন:

বাংলা অ্যাপ সাবমিশন টা মোটেও কঠিন নয়। অনেকেই ভাবেন আমি লিখলাম সমগ্র অ্যাপ এর কন্টেন্ট বাংলায়। কিন্তু ভাষা দেখাচ্ছে স্টোরে এখনো ইংরেজী। কি করে ঠিক করি। আসুন দেখে নেই।


১. প্রথমে চলে যান আপনার সলুশ্যন এক্সপ্লোরার এর প্রোপার্টিজ এর মধ্যে WMAppManifest.xml এ। এর Packaging ট্যাব এ গেলে আপনি দেখতে পাবেন Default Language নামের ড্রপডাউন লিস্টে Bengali, Bengali (Bangladesh) এবং Bengali (India) আছে।

Capture 2

এবং নিচে খেয়াল করে দেখুন Supported Language নামক একটি লিস্ট আছে

Capture3খেয়াল করে দেখুন এখানেও Bengali, Bengali (Bangladesh), Bengali (India) আছে। আপনি Bengali এবং Bengali(Bangladesh) অবশ্যই চেক করে দিন এবং প্রয়োজনে Bengali (India) চেক করে দিন। কারণ আপনার সমর্থিত ভাষার উপর আপনার মার্কেট সিলেকশন নির্ভর করে । আপনি নিশ্চই চান না আপনার অ্যাপ টি কোন মার্কেটের কোন বাংলাভাষী থেকে দূরে থাকুক।

এবার আসুন Default language এর ব্যাপারে। অনেকেই আমাকে প্রশ্ন করেছেন যে যদি Default Language আমি বাংলা দেই তাতে সমস্যা কি? সমস্যা নেই। তবে পরবর্তীতে যখন অ্যাপ সাবমিট করবেন, মার্কেট সিলেকশনে শুধু বাংলা ভাষা সমর্থিত মার্কেট সিলেক্ট করতে হবে। নাহলে certification fail করতে পারেন। আর অনেকেই US market, UK market এ থাকেন দেশ ও দেশের বাইরে। আপনি নিশ্চই চান না আপনার অ্যাপ এর সম্ভাব্য গ্রাহক হারাতে। সুতরাং ডিফল্ট ল্যাংগুয়েজ ইংরেজী রাখুন।

তাহলে? যদি কেউ ভুল করে ডাউনলোড করে এবং না বুঝে বাজে রেটিং দেয়? সেজন্য অ্যাপ ডেসক্রিপশনে লিখে দিন “The official language for this app is bangla”. প্রথম লাইন হলে ভালো হয়। আর অবশ্যই একটি বাংলা বিবরণ রাখবেন। ভুলবেন না যেন। আর সার্টিফিকেশন কিন্তু অটোমেটেড প্রসেস না। সব কিছুই বেশ ভালো মতো পরীক্ষা করা হয়।

আশা করি সবার সব প্রশ্নের সমাধান হয়েছে।  🙂