Saturday, November 22, 2014

Understanding Code Execution in Javascript

If you are doing any form of programming in Javascript then understanding its eventloop is very important.

Any javascript engine has three kinds of memory models:


  1. Stack, which has the current function pointer an gets executed sequentially.
  2. Heap, this stores all the objects, functions basically anything that is initiated is stored here.
  3. Queue, all things to be executed is stored here and stack picks up tasks to do from the queue.
So, to understand this further, when a function is getting executed its loaded in the stack and if it encounters any setTimeouts then it would be added in the queue and when the current stack gets empty then the new function to be executed from the queue.

This code run will explain the process:

console.log("Add this code to queue");

setTimeout(function() {                                                //This goes and sits in the queue.
                           console.log("Running next event from the queue.");
                 },0);

function a(x) {
     console.log("Function a added to the stack!");
     b(x);
     console.log("Function a removed from the stack!");
}

function b(x) {
      console.log("Function b is added to the stack.");
      console.log("Value passed is "+x);
      console.log("Function b is removed from the stack.");
}

console.log("starting work for this stack");
a(22);
console.log("Stopping work for this stack. stack would be empty after this.");


The output of this code is self explanatory:


Add this code to queue 
starting work for this stack 
Function a added to the stack! 
Function b is added to the stack. 
Value passed is 22 
Function b is removed from the stack. 
Function a removed from the stack! 
Stopping work for this stack. stack would be empty after this. 
Running next event from the queue. 


So what happened here?
Stack is initialized with current code.
Only thing to notice is that at setTimeout call anonymous function is added to the queue. //Remember closures.
Then the function a is added to the heap.
Then function b is added to the heap.
a is called that means from heap function a is loaded on the stack.
b is called that means from heap function b is loaded on the stack.
b is removed from the stack.
a is removed from the stack.
current code execution gets over, stack becomes empty.
next execution is loaded on the stack from the queue.

This should help one understand how JS memory model works

Wednesday, October 22, 2014

Inbox From Google: Review

In an another attempt to reorganise the way email communications work Google has come out with Inbox.


Here, google has attempted to use machine learning and nlp for better organise email with a more intuitive UX.

I believe this time they have utilised there learnings from Wave failure and have not attempted to change the core email component. But as people are slowly getting use to the timeline kind of UX, they have attempted to preserve that in email and top it up with the new features which they have always wanted to try but restricted by the plain UX of email, like "See pull request", "See flight status."
Moreover, seems like this being designed specifically for phone devices.

Lets see how useful this cool thing becomes. Never the less, please request an invite by sending a mail to inbox@google.com.

I have requested mine and write a review as soon as I get an invite.

I got an invite and have started using Inbox. I did not find it majorly innovative.  There was nothing which was apparent to me that I was not able to do with the current version of Gmail. So, I would get straight to listing down the pros and cons.



Pros:

  • Easy to use UI, quickly can organise mails.
  • Nice timeline view.
Cons:
  • No feature which I can't already do with Gmail.
  • Just a sexy UI.

I have just used it for a few days. But this is an honest feeling I got. I might still have to explore more to realise some new features but on the look of things I was disappointed.

Leave a comment with your email id if you need an invite.
Request others to share there invites with the people commented.

Workaround to get in without invite:

Install inbox on your android phone. Then ask a friend who has an invite to login and use inbox app for 5 minutes. Then ask him to log out and you log in. Hurray!! google inbox would remain active for you.

Tuesday, October 14, 2014

Flatten a Binary Search Tree into a LinkedList in Java

package com.biplav.algorithms;

public class FlattenBST {
 
 public static class TreeNode {
  public TreeNode left;
  public TreeNode right;
  public int value;
  public TreeNode(TreeNode left, TreeNode right, int value) {
   super();
   this.left = left;
   this.right = right;
   this.value = value;
  }
  
 }
 
 public static class ListNode {
  public ListNode next;
  public int value;
  public ListNode(ListNode next, int value) {
   super();
   this.next = next;
   this.value = value;
  }  
 }
 
 public static ListNode flatten(TreeNode root) {
  ListNode left = root.left != null ? flatten(root.left) : null;
  ListNode base = new ListNode(null,root.value);
  ListNode right = root.right != null ? flatten(root.right) : null; 
  base.next = right != null ? right : null;
  if(left == null) return base;
  else {
   ListNode home = left;
   while(left.next != null) left = left.next;
   left.next= base;
   return home;
  }
 }
 /*
  *          6
  *      3       8
  *   2    4   7  10
  */
 
 public static void main(String[] args) {
  TreeNode t3 = new TreeNode(null, null, 2);
  TreeNode t2 = new TreeNode(null, null, 4);
  TreeNode t4 = new TreeNode(t3, t2, 3);
  TreeNode t7 = new TreeNode(null, null, 7);
  TreeNode t10 = new TreeNode(null, null, 10);
  TreeNode t8 = new TreeNode(t7, t10, 8);
  TreeNode t6 = new TreeNode(t4, t8, 6);
  ListNode root = flatten(t6);
  while(root != null) {
   System.out.println(root.value);
   root = root.next;
  }
 }
 
 

}

Monday, October 13, 2014

Alogrithm to sort a huge list of numbers in O(n) complexity in Java

A large file of numbers can be sorted in O(n) complexity by using a large bit array of the size same as the largest number in the list of numbers to be sorted. It can be done in Java using BitSet.


package com.biplav.algorithms;

import java.util.Arrays;

import com.biplav.ds.BitArray;


public class SortMillionNumbersWithGivenMax { //n+m


public static int[] sort(int[] list, int max) {
int[] sortedList = new int[list.length];
//BitSet bitSet = new BitSet(max);
BitArray bitSet = new BitArray(max);
for(int n:list) bitSet.set(n); //n
int index=0;
for(int i =0 ; i<=  max; i++) { //m
if(bitSet.get(i)) {
sortedList[index++] = i;
}
}
return sortedList;
}

public static void main(String[] args) {
int[] list = new int[]{1,2,3,4,5,9,15,18,25,7,11};
System.out.println(Arrays.toString(sort(list, 27)));
}
}

I have used BitArray defined by me. Its implementation is:

package com.biplav.ds;

public class BitArray {
 private byte[] arrayOfSize8bit;

 public BitArray(int size) {
  arrayOfSize8bit = new byte[(size / 8) + (size % 8 == 0 ? 0 : 1)];
 }

 public boolean get(int location) {
  return (arrayOfSize8bit[location / 8] & 1 << location % 8) != 0;
 }

 public void set(int location, boolean value) {
  byte b8 = arrayOfSize8bit[location / 8];
  byte posBit = (byte) (1 << (location % 8));
  if (value) {
   b8 = (byte) (b8 | posBit);
  } else {
   b8 = (byte) (b8 & (255 - posBit));
  }
  arrayOfSize8bit[location / 8] = b8;
 }

 public void set(int location) {
  set(location, true);
 }

 public void unset(int location) {
  set(location, false);
 }
}

Instead of BitArray BitSet can also be used which uses long[] instead of Byte array to achieve something similar.

Friday, October 10, 2014

Fibonacci Series With Matrix Multiplication in Java with recursion.

Attempting to solve the fibonacci series using matrix multiplication applying divide and conquer to reduce the complexity to O(logN)
package com.biplav.algorithms;
public class FibonacciSeries {
//2*2 matrix
static int[][] multiply(int[][] X, int[][] Y) {
int[][] response = new int[2][2];
response[0][0] = X[0][0]*Y[0][0] + X[0][1]*Y[1][0];
response[0][1] = X[0][0]*Y[0][1] + X[0][1]*Y[1][1];
response[1][0] = X[1][0]*Y[0][0] + X[1][1]*Y[1][0];
response[1][1] = X[1][0]*Y[0][1] + X[1][1]*Y[1][1];
return response;}
static int[][] power(int[][] X, int N) {
if(N == 1) {
return X;} else {
int[][] X2 = power(X,N/2);
return multiply(X2,X2);
}
}
public static int get(int n) {int[][] X = new int[][] {{1,1},{1,0}};
return power(X,n)[0][0];
}
public static void main(String[] args) {
System.out.println(get(4));
}
}

Tuesday, October 7, 2014

Attendance.gov.in is First Modern looking site by Indian Government

The http://attendance.gov.in/ is by far one of the first modern looking website by Indian Government.


It uses bootstrap and Free bootstrap 2 theme sb-admin http://startbootstrap.com/template-overviews/sb-admin/


Impressed by this sudden technology choices shift in the Indian Government websites, I decided to deep dive more on there technology stack and it was good to see there choices are improving.
See the builtwith result here: http://builtwith.com/attendance.gov.in

Suprising there is no hint of the organisation created the site. But, I am happy to see the first mobile ready website of Indian Govt! :)




Flipkart Apology Email for bloopers on The Big Billion Day Sale.

Here is the email which flipkart sent today apologising for bloopers on The Big Billion Day Sale.

Apologies, from Flipkart

regarding The Big Billion DayUnsubscribe

Flipkart.com
Download Flipkart AppFlipkart First

Dear Customer, 

Yesterday was a big day for us. And we really wanted it to be a great day for you. But at the end of the day, we know that your experience was less than pleasant. We did not live up to the promises we made and for that we are really and truly sorry. 

It took enormous effort from everyone at Flipkart, many months of preparation and pushing our capabilities and systems to the limit to be able to create this day. We were looking at fulfilling the dreams of millions of Indian consumers through deals and offers we had painstakingly put together for months. 

And though we saw unprecedented interest in our products and traffic like never before, we also realized that we were not adequately prepared for the sheer scale of the event. We didn't source enough products and deals in advance to cater to your requirements. To add to this, the load on our server led to intermittent outages, further impacting your shopping experience on our site. 

An unprecedented 1.5 million people shopped at Flipkart yesterday. While we stand humbled by the sheer faith that such a large number of customers have shown in us, we are unhappy that we were unable to live up to the expectations of millions more who wanted to buy from us yesterday. 

And this is not acceptable to us. 

Delighting you, and every single one of our customers, is absolutely the top most priority for Flipkart and we have worked very hard over the last seven years to earn your trust. Yesterday, we failed that trust. We have learnt some valuable lessons from this and have started working doubly hard to address all the issues that cropped up during this sale. 

Price Changes As we were preparing various deals and promotional pricing in the lead up to the sale, the pricing of several products got ​changed to their non-discounted rates for a few hours​. We realise that this breaks the trust our customers have put in us. We are truly sorry for this and will ensure that this never happens again.

Out-of-stock Issues We ran out of the stock for many products within a few minutes (and in some cases, seconds) of the sale going live. For example, most of our special deals were sold out as soon as they went live. We had ensured availability, anywhere from hundreds to a few lakh units for various products, but it was nowhere near the actual demand. We promise to plan much better for future promotions and ensure that we minimise the out-of-stock issues. 

Cancellations We had large number of people buying specific products simultaneously. This led to some instances of an order getting over-booked for a product that was sold out just a few seconds ago. We are working round-the-clock to ensure availability of additional units for these products and will do our level best to ensure that we minimise any cancellations. 

Website Issues ​We realise that the shopping experience for many of you was frustrating due to errors and unavailability of the website at times. We had deployed nearly 5000 servers and had prepared for 20 times the traffic growth - but the volume of traffic at different times of the day was much higher than this. We are continuing to significantly scale up all our back end systems so that we do a much, much better job next time. 

Everything that we have achieved at Flipkart is purely on the basis of our customer's trust and faith. This is why we come to work each day and continue to remain extremely passionate about building the best possible customer experience for Indian consumers. We failed to live up to this promise yesterday and would like to apologise once again to every single customer for our failure. 

Thank you. 
Sachin and Binny

Friday, September 26, 2014

Tuning ActiveMQ for Performance

Recently I needed to optimize our ActiveMQ configuration for performance.

Let me explain our deployment, we had a Jetty based Java app with GWT for the UI. We use gwt-ActiveMq with long polling to send messages to the UI. We were using activemq for everything, for out SM design, or async event listener architecture. We have no plans to scale from more then one box and for us the performance is critical.

So things done were:
  • Non-persisten messaging. Its atleast 20x faster. This can be achieved by:
  1. Set the NON_PERSISTENT message delivery flag on your MessageProducer.
  2. Set the persistent=false flag in the  element of the Xml Configuration or on the property BrokerService.
  • Remove the network. We used vm:// as transport so that the entire queue is in memory. No need to go over the network as our broker is embedded in the same context as the producer. You would have to change the broker address in the web.xml of the server as you won't get messages on the UI.
  • Serialization is barrier to speed. We used vm as transport and configured objectMessageSerializationDefered to true. As we are using them on the same box, there is no point in serializing and deserializing the messages. This would allow us to use same hiberante objects across states. No need to clone and store them.
  • Set alwaysSessionAsync=true. This reduces the context switching. There is lots of context switching which occurs when message is wrote on the queue and read from it.
  • Set dispatchAsync=false. This again reduces context switching.
  • Set optimizeAcknowledge=true. All the messages are acknowledged. This allows a more optimized way of acknowledging  the messages. Need to explore more for exact implementation details.
  • Don't prefetch messages in StateMachine. In case of our StateMachines, we always had 1 message which goes from one state to another. So, here there is no point prefetching messages.
  • Prefetch Topic Listners. But with topics, its better to prefetch messages.
  • Switch off flow control. If flow control is On, then the slowest consumers dictate the speed of the message. In activeMQ, the messages go into a message store as it is dispatched, if flow control is on, then the dispatch is done only on acknowledgments from the consumers and flow rate is determined based on the acknowledgments received. 
Final Configuration:

<amq:broker id="broker" useJmx="false" persistent="false" useShutdownHook="true" schedulerSupport="true">
<amq:transportConnectors>
<amq:transportConnector uri="vm://localhost?async=false" />
</amq:transportConnectors>
</amq:broker>

<amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost?async=false"
copyMessageOnSend="false" objectMessageSerializationDefered="true" alwaysSessionAsync="false"
dispatchAsync="false" optimizeAcknowledge="true" useAsyncSend="true" optimizedMessageDispatch="true"/>



Bibligraphy:

Entire details is available in the webinar:
http://download.progress.com/5331/open/adobe/prc/psc/perf_tuning_activemq/index.htm

Rest of the details are in the below links:
http://activemq.apache.org/how-should-i-use-the-vm-transport.html
http://activemq.apache.org/how-do-i-disable-persistence.html
https://code.google.com/p/gwt-activemq/http://activemq.apache.org/message-cursors.html 

Monday, September 22, 2014

How to configure google app engine when your site is deployed on Heroku and uses CNAME for naked domain?

When we configure Heroku App to our domain we configure it using CNAME records. This means two entry in our DNS records, one for naked domain or xyz.com and other for www.xyz.com.

Now, if you want to receive mails over email ids configured with same domain with google apps, gmail then you need to configure MX records for xyz.com. Please see the previous post on this topic .

But there is a problem here, as CNAME record has higher priority, your domain wont return MX rule and always return CNAME rule and MX record validation would fail on the Google Domains page.

So, how to solve it:


  • Have A records entry if possible, with heroku this is  not possible.
  • Remove CNAME record from DNS entry for xyz.com and configure google domain, naked redirect to www.xyz.com.
  • Remove CNAME record from DNS entry for xyz.com and use Alias from Domian Control Panel.
  • Remove CNAME record from DNS entry for xyz.com and use Domain Forwarding service for xyz.com to www.xyz.com on the Domain Control Panel. This would be like a 301 redirect.

Hope this helps.

Tuesday, September 16, 2014

JS Event Bubbling Vs Event Capturing.

In Javascript or HTML DOM to be precise, there are two methods of event propagation, those are:

  1. Event Capturing.
  2. Event Bubbling.
This defines the way event flow in case of multiple event listeners.
Suppose you have a img  element inside a div element then and both have an event listener defined, then whose event listener should be called first?

  1. In case of event bubbling, the inner most elements event listener will be called first and it would be propagated out. So first the event listener of img will be called followed by the event listener of div element.
  2. In case of event capturing, the outer most elements event listener is called first followed by inner elements. So, in above example,
    div's event listener would be called first followed by inner most element that is img's event listener.
The event propagation method can be selected by passing third optional boolean argument to addEventListener method of JS. The syntax is:
addEventListner(event,event_handler,usecapture)
The default value is false, hence, by default event bubbling is supported.

How to do this in JQuery?

You can't do this in Jquery. Jquery does not support this as not all browser support this method. And the goal of Jquery is cross-browser JS framework.
Browser older then IE8 and Opera 7.0 does not support event capturing method.

Wednesday, September 10, 2014

Twitter typehead.js basic example with token field.

A simple example for twitter typehead.js.

The server should return an array of type:

[ { name: "asas", value: "1234" }, { name: "asas", value: "121212" } ]


Include following CSS and js:

<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link href="tokenfield-typeahead.css" rel="stylesheet">
<link href="bootstrap-tokenfield.css" rel="stylesheet">
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
     <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
     <script src="http://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.4/typeahead.bundle.min.js" ></script>

     <script src="bootstrap-tokenfield.js" ></script>

Style ur typeahead:

      <style>
.tt-query,
.tt-hint {
    width: 396px;
    height: 30px;
    padding: 8px 12px;
    font-size: 24px;
    line-height: 30px;
    border: 2px solid #ccc;
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
    outline: none;
}

.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-dropdown-menu {
    width: 422px;
    margin-top: 12px;
    padding: 8px 0;
    background-color: #fff;
    border: 1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
    -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;
    font-size: 18px;
    line-height: 24px;
}

.tt-suggestion.tt-is-under-cursor {
    color: #fff;
    background-color: #0097cf;

}

JS for intializing typehead,  tokenizer and bloodhound:

 <script>
      $(function() {
      
  var engine = new Bloodhound({
  datumTokenizer: function(d) {
  return Bloodhound.tokenizers.whitespace(d.value); 
  },
  queryTokenizer: function(d) {
  return Bloodhound.tokenizers.whitespace(d.name); 
  },
  prefetch: '/contact/fetch?host=lifesize.com&user=bsaraf&password=testing!!123&term=S',
  remote: '/contact/fetch?host=lifesize.com&user=bsaraf&password=testing!!123&term=%QUERY'
});
 
engine.initialize();
 
   $('#exampleInputEmail1').tokenfield({
  typeahead: [null, {  source: engine.ttAdapter() }]
});
   $('#exampleInputEmail1').tokenfield();
   $(document).ajaxSend(function(event, jqXHR, settings) {
       console.log("Loading");
   $('.tt-hint').css('background-repeat', 'no-repeat');
   $('.tt-hint').css('background-position', '98%');
   $('.tt-hint').css('background-image', 'url("http://primefaces-rocks.appspot.com/design/ajaxloading.gif")');
   });

   $(document).ajaxComplete(function(event, jqXHR, settings) {
      console.log("Loaded.");
   $('.tt-hint').css('background', '');
   });
});
 </script>

And a simple html:

<input type="text" class="form-control" id="exampleInputEmail1" placeholder="Enter email">


And what you get is:




The Bloodhound docuementation is available at: https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md#remote


I had to do dynamic change the url to fetch results in bloodhound based on some paramters.
This I achieved by:


var engine = new Bloodhound({
           datumTokenizer: function(d) {
                   return Bloodhound.tokenizers.whitespace(d.value)
           },
           queryTokenizer: function(d) {
                   return Bloodhound.tokenizers.whitespace(d.name)
           },
           prefetch: '/contact/fetch?host=lifesize.com&user=bsaraf&password=testing!!123&term=S',
           remote:{
                        'url' : '/contact/fetch?term=%QUERY',
                        'replace' : function(url,query) {
                                var q = '/contact/fetch?host='+$('#exampleInputHostName').val()+'&user='
                                                + encodeURIComponent($('#exampleInputUser').val())
                                                + '&password='
                                                + encodeURIComponent($('#exampleInputPassword1').val())
                                                + '&term='
                                                + query;
                                return q;
                        }
          }

        });


If you see the above code remote has a new replace method which fetched the values from input  fields and appends them to url. Note, here method takes query as argument to give the exact term typed in by user.


Friday, September 5, 2014

Cafes around Indranagar and Koramangala for Work or Chill

I found a nice discussion on PMIT with the requirements of Cafe suggestion in around Koramangala or Indranagar with following:

1. You spot less/same crowd lazing around the whole day. 
2. You spot people hanging out with their books.
3. Bean bags around.
4. Lite music, bright light, decent Wi-Fi.
5. Nobody bothers to wake you up (even if you doze off  ) 


So I decided to put my own list:


COSTA COFFEE, Koramangala

Address: 80 feet, Road Koramangala.



No bean bags. Has WIFI but unreliable. Less Crowded during Weekdays, very crowded during weekends. You can spots likes of Bansals of Flipkart fame at times here. Lite music bright light. One of my Fav to Work

COFFEE ON CANVAS, Koramangala

Address: 1st Cross, 80 Feet Main Rd, Koramangala 4 Block



Bean Bags. Has WIFI but unreliable, Seems to get noisy on weekends and evenings. Light music, bright light. Good food. One of my Fav to Chill

Atta Gallata, Koramangala

Address: 134, 1st A Main Road KHB Colony, 5th Block Koramangala



Has Wifi, quiet not too noisy, light music, less crowd. have events on weekends. Not that bright lights. One of My Fav to Work in quiet environment.

Yoga House, Indranagar

Address: 89, 11th Cross, 60ft Road,, Indiranagar 2nd stage


Bright Lights, Pet friendly, Very Fast and Reliable Wifi, Less Crowded. Apt for Work.




Wednesday, September 3, 2014

Download playlist or songs from 8tracks.

Many times I come across songs on 8tracks which I am not able to find from other sources. Little bit of googling and searching around, I didn't find a reliable way of doing the same. So, I decided to write a script for me to do that.

For the benefit of larger audience, I have hosted it on one of my servers. You can access it from:

http://beedio.com/8tracks.html



Just go there an paste the 8tracks playlist url in the input field and press Fetch.

Its a simple Js script which utilises the 8tracks apis to simulate the play of the song and allow a download or play link where the permissions are available. The urls to download or play individual songs would get listed.

As it simulates play of song, so this script would take some time to go and fetch all the urls for download. Ideally, one should press fetch and then come back after few hours to the tab to see all the urls in the list.

I have tried to follow the norms of 8tracks as much as possible, if any infringement of  copyright or api usage policy is found then please do let me know and I would take it offline.

Tuesday, September 2, 2014

Z-Index computed as auto even though it is set with a value on Chrome

This is a little known fact about z-index and usually missed.  If you read the article on w3schools then also you might miss this. It says:

Note: z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).

What this essentially mean that the element on which you are applying z-index, you need to have position attribute specified on it. Ideally use one of the above position values. If position attribute in the css style is not set z-index would be computed as auto. Google Chrome is quiet strict about this. Use a syntax like below.

img {
    position: relative;
    z-index: 100;
}

Thats the reason, why many times we don't see z-index working on out elements. 

Sources:
http://www.w3schools.com/cssref/pr_pos_z-index.asp
https://code.google.com/p/chromium/issues/detail?id=39426





Wednesday, August 27, 2014

Unique unconventional Arty Farty gift options in Bangalore

A list of unique arty-farty  gift options in Bangalore.


Caricature from BLOT STUDIO



    
Blot Studio is a one stop shop catering to all your creative needs delivered with utmost professionalism. Established in 2002, the studio has catered to various clients - corporates as well as individuals. We rely upon detailed ideation, artistic illustrations and a passionate approach in our efforts to achieve creative brilliance. Furthermore, we seek to build a collaborative relationship with those with whom we work.
At Blot Studio we strive to enhance our vision with every project we undertake. Our studio comprises of artists who are experienced, witty and creative. It shall always be our endeavor to provide quality work within available time frames and budgets.


Charcoal Painting by PENCIL CHAAP

Phone 9902857298
Email bindra.ashmeet@gmail.com

Look at the world with your big eyes, capture the moment and create it into a beautiful art! That's what all is Pencil Chhaap about. Giving a meaning to life with all the hardwork, here I will provide you with glimpse of my artwork and insanity!

Painting made out of Cofee 

from Distractor's Coffee Art



Website http://www.distractor.in
Who said coffee is just for drinking. 
A cuppa joe can make some beautiful splashes. Splashes so good they look like Marylin Monroe or your own face. ;)
Description
coffee - you either love it or you hate it. 

We took the love for coffee to the next level and started using it as a medium to paint with. Paintings (if you can call them that) are available in 8x10, 12x10 and 12x16 (as of now) and are customizable. Unfortunately they come at a price, so ping me and name your price. I usually say 'yes' to whatever you say unless you quote a price that is lower in sea level than Australia.

If you don't love your painting any more just add some milk or water on to it and bingo your coffee is ready to be consumed or not.

A shining piece from OWL



Website http://www.objectswithlight.in/
Handmade Eco friendly decorative lighting products.To order any product write to us at owl.objectswithlight@gmail.com .We also customize products based on your requirement.Ph- 9900315432.http://www.objectswithlight.in/
Company Overview
Light has long been a metaphor for knowledge,discovery and new creation.

OWL lighting is intricate yet simple using mathematical shapes to create a functional form that has aesthetical appeal while using the material in an intelligent manner that definitely suits contemporary and minimalist spaces. 

The Material that we use is completely recyclable and contains on an average about 50-60% recycled component and we produce each light shade with minimal waste. It is chemically unreactive,biologically inert and food contact safe with no plasticisers
Every product from OWL is hand crafted and made in our Bangalore Studio . 
To Order any Product write to 
owl.objectswithlight@gmail.com


Madhubani Paininting from Pretty Pallete




Email prettypalette94@gmail.com

Stand there, watch and you will find yourself indulging in the beauty of the art - be it oil, tanjore
madhubani, textured, glass painting etc etc.,

Handcrafted Jewellery by Kakoli Roy


Email: kakoli.roy@gmail.com


Cookies from Patisserie Nitash



#12 , 2nd cross Hutchins Road,Off Wheeler road Extension, St.Thomas Town.
Bangalore, India 560084
Today 9:00am - 4:30pm
Phone +91 80 41670364 or on +91 98454 27364(mobile)
Website http://www.nitash.in

Comfy Cottons From Indian Yards



Phone 096 63 144494
Email indianyards@gmail.com
Website http://www.indianyards.com

Indian Yards takes custom orders for below mentioned quilts and bedspreads:

•Photo quilts/Bedspread
Tee Shirt quilts/Bedspread (check photos) 
•Old baby clothes quilts/Bedspread (check photos)
•Memory quilts/Bedspread (Check Photos)
•Patchwork quilts/Bedspread (check photos)
•Patchwork Curtains

Indian Yards is founded by Sunita Suhas, a self taught quilter. Indian Yards reaches out to women from economically weaker section of the society and trains them on the indigenous art of patchwork quilt making. Indian Yards is based in Mysore and intends to have a full fledged training unit so more women can be empowered in the longer run. We make custom quilts, bags, table runners, patchwork curtains, gadget sleeves, cushion covers and all other home decor utility products. We are interested in bulk and overseas orders.

Crafty Card from Growing Crafts



Phone 096 19 462335
Email soniya@growingcraft.com
Website http://www.growingcraft.com

Gift your loved ones their precious memories with a touch of love.. A personalised Scrapbook, Photoalbum and cards.. 

Sports Car Designed Cake from GiftmyCake 



Phone 9342837640
Email ramesh@giftmycake.com
Website http://www.giftmycake.com

What comprise our pricing:

Creativity and passion in making your dear one's Birthday Unique
Imported ingredients from Malaysia
The selective and qualified manpower


Mojaris from Jodhpuris.



Phone 093 42 422245

Rajasthan, the land of Rajas (kings), is world renowned for its art and craft. Within the state, more so Jodhpur enjoys a distinguished reputation for producing elegant and artistic handicrafts.

We bring you products from the heart of Rajasthan, an array of handcrafted objects which reflects its rootedness to this indigenous history and traditions.

Jodhpuri’s houses one of the finest collections of intricately hand crafted artifacts, each product a masterpiece. We shall be privileged to satisfy one and all, both individual clients as well as businesses dealing in handicrafts, in any corner of the world.


Classic Vinyl Records from Avenue Road




Seetha Phone Company.





Building Successful Products in the Maze of a Large Organization

  *Image is generated using AI Large organizations offer a treasure trove of resources and stability for product development. However, navig...