14 May 2016

11 May 2016

The 3D hologram on the smartphone actually works!


A colleague of my classmate showed me an article & video of a hologram created on a smartphone, and I didn't quite believe it.
 

It did make me curious though. Holograms & VR are something I'd love to work on, so I actually tried it out.

Find a CD case or even transparent plastic or glass. Perhaps even a plastic bottle as one person did.


Cut out four pieces of a trapezium from it. Drawing a diamond shape as shown below is by far the most convenient and space-efficient way of doing it. Once you've cut it out on paper, stick it to the plastic with cello-tape and carefully cut the plastic.
 
You end up with this

Super-glue would be a better option for sticking it, but I just used cello-tape. Make sure the 1cm edge part is even, because that's the part you'll be keeping on your smartphone.

Now take your pick from the various videos available.


and watch it come alive!






Turns out there are far more impressive holographic illusions than the smartphone illusion. Play the one below and see.




And all this isn't modern technology. Such illusions have existed since the year 1584. There are plenty of examples scattered across history

It all began when an Italian scientist named Giambattista della Porta created the illusion of what later came to be known as Pepper's ghost.

This is how the illusion works:


Modern technology comes into play when you want to actually touch the hologram. As of today, that's made possible in a small way with lasers.




Beautiful!



How the smartphone hologram illusion works

In reality, the smartphone hologram is not a hologram at all. It's simply a reflection that can be viewed from all 4 sides. I remember when a person first showed me the video, my first question to him was "what happens if we remove one of the plastic panes?"

While the video is playing, try putting your finger into the middle of the plastic pyramid you created. You'll still be able to see the 'hologram' because your finger isn't blocking anything. In-fact, instead of creating four trapezium's, if you held just one pane of plastic or glass at that angle, facing you, you'd still be able to see the 'hologram'.

When you stand 2 feet in front of a mirror, your mirror image appears to be 2 feet behind the glass. That's the exact same illusion the plastic trapezium creates. At that angle, it just reflects the video, making you think the image is somewhere behind the plastic, in the air. The reflections from the other three panes aren't visible to you because they are at angles that don't reflect or refract the light in your direction. The only way having 4 trapeziums helps, is that you get to see the reflection suspended in the air, in the four directions you view it from. It also creates the illusion that an object that looks three dimensional, is contained within the pyramid shaped container you created. That's all there is to it.
Still...impressive!

Makes me wonder....could a rainbow be called a real hologram?


07 May 2016

More concepts of Apache Storm you need to know

As my mentor tells me -  
"To be able to program in Storm, you first need to think in Storm".


That's very true. Storm is designed in a way that allows you to structure your application design in a way that allows it to scale. But before you begin that journey, there are a few concepts you need to know, which aren't explained in the official documentation (or sometimes not explained clearly enough).




The Constructor concept
[Thanks to Matthias J. Sax on the Storm mailing list for explaining this]

When you create a Spout or a Bolt, Storm calls that class constructor only once. After that, the class gets serialized and from then on, whenever Storm needs to create a new instance of the Spout or Bolt, Storm uses the serialized instance to do so.

But for every new instance Storm creates, Storm will call the open() function for Spouts and the prepare() function for Bolts.
So open() and prepare() are like constructors.



Making your Spouts or Bolts do things at specified intervals

Use tick tuples.



The reason you should exit the nextTuple() function ASAP
[Thanks to Spico Florin on the Storm mailing list for explaining this]

I had created a while loop in nextTuple() of my Spout to emit multiple tuples, but I didn't receive any ack's at all.
Turns out that nextTuple() and the ack() method are called in the same thread by the framework. So if you have  heavy computation in the next tuple, your ack() method will never be called and the buffers that are responsible for receiving the ack messages will not be emptied. The nextTuple() acts as producer for the these buffers while ack() as a consumer.

So remember to emit a tuple and exit the nextTuple() function immediately.
For those who don't know about the ack() method, you can override it (and the fail() method) in your Spout like this:

    @Override
    public void ack(Object msgId) {
        System.out.println("Ack received for Spout"+msgId);
        tupleAck = true;
    }   
   
    @Override
    public void fail(Object msgId) {
        System.out.println("Failed tuple msgID: "+msgId);
        //---tuple replay logic should be here
    }


This helps you know whether your tuple was received and processed by the Bolt or whether the transmission or processing failed.



More creative topology structures
[Thanks to Matthias J. Sax on the Storm mailing list for the idea]

When learning Storm, we come across simple examples and are conditioned into thinking that way.



It doesn't have to be that way though. When you use streams and the various techniques of grouping, you'll find a whole new world open up.

Example:
If you want to create a topology where the spout notifies the end bolts that it has no more input, you can do it this way:

Just specify a separate stream in the spout and emit the notification tuples. When creating the topology, specify an allGrouping for the receiving bolts. What happens is that no matter how many instances of the bolt are created, the spout will send the tuple to all of them. It's like a broadcast.

So the topology would be created like this:

TopologyBuilder b = new TopologyBuilder();

b.setSpout("SpoutA_name", new SpoutA(), 1)
.setNumTasks(1);      
     
b.setBolt("boltA_name", new boltA(), 2)
.shuffleGrouping("SpoutA_name");

b.setBolt("boltB_name", new boltB(), 5)
.fieldsGrouping("boltA_name", new Fields(someID))
.allGrouping("SpoutA_name", "StreamName");



This is how the spout sends a stream to the bolts at the end:

@Override
public void declareOutputFields(OutputFieldsDeclarer ofd) {
    ofd.declare(new Fields("theNormalTuple"));
    ofd.declareStream("StreamName", new Fields("someID"));//this specifies the stream that reaches the end bolt B
}
   
@Override
public void nextTuple() {       

    if (nothingMoreToProcess) {
        collector.emit("StreamName", new Values(someID));//this emits the stream to bolts B
    }       
    else {
        collector.emit(new Values(someTuples), someTuples);//this emits to bolts A
    }
}     



...and this is how the bolt receives it:

@Override
public void execute(Tuple tuple) {
    
    if (("StreamName").equals(tuple.getSourceStreamId())) {//recognizes the stream from the spout
        //do whatever you do when there is nothing more to process
    }
    else {  
        //do your usual processing
    }
}


Don't stop here. There are plenty more ways to think of emitting streams and directing the flow. Remember that Storm is designed to be a Directed Acyclic Graph. You can design your topology as such.




In the code, which are the tasks and executors?

There's a confusion about tasks and executors, because in this case:

builder.setBolt("bolt1", new BoltA(), 3)
                .setNumTasks(2)

Storm creates 3 executors and 2 tasks.

but

In this case (if you don't specify setNumTasks)

builder.setBolt("bolt1", new BoltA(), 2) 

Storm creates 2 executors and 2 tasks.

Remember that a task is an instantiation of a serialized instance of BoltA class (see the constructor concept at the top of this page). An executor is just a thread which processes a task class. If an executor has to process two task classes, then the executor will process the first one and only then process the second one.





Additional links:

If you are looking for a simple tutorial or code sample for Storm, they are here:

Say thank you or donate

01 May 2016

Mass brainwashing

Do you know that diamonds are not a woman's best friend?
Well, allow me to introduce you to the diamond myth:

"...diamonds only came into popularity in the 20th century...But in 1870, a huge cache of diamonds was unearthed in South Africa...With a voluble increase in available diamonds, how could they be priced for their scarcity and rareness? Diamond mine financiers realized that they needed to protect their interests...And that’s how De Beers — which held a monopoly on diamond mining and pricing — was created...

In the 1930s...to promote diamond story lines, place engagement rings in films and get diamonds into the hands of burgeoning celebrities...in the 1940s, a series of lectures was promoted in high schools...

All the advertising, film and television placement and mass psychology worked. After 20 years on the campaign...the younger generation had successfully been implanted with the idea that diamonds were a de rigeur part of courtship. To this new generation a diamond ring is considered a necessity to engagements...

...De Beers sold the idea that a diamond was an expensive but necessary token of affection...Conversely, a woman who didn’t have an engagement ring –who wasn’t showered with diamonds throughout her relationship — was somehow “less loved” than her diamond-swathed counterparts....It’s a lie that started less than a 100 years ago, and it’s a lie the diamond industry has been banking on ever since."

I found this report very intriguing. Haven't we all been brainwashed in similar ways? Made to feel that doing certain things were an absolute necessity to be accepted in society?

Even before mass advertising took over the planet, there were Shaman's, Rainmakers, Soothsayers, Witch doctors, Oracles, Astrologers. After that came the need to drink Complan to gain height. To drink Bournvita to gain capability. To remember only Maggi for a quick snack. To drink only Coca Cola / beer when thirsty. To drink Boost / Glucon D for energy.
As though there were no other cheaper, healthier and much much better alternatives available!


Religion

Take religion for example. What exactly does your religion actually want you to do?

To help people. To respect and be kind to others. To live peacefully. To recognize and appreciate that a beautiful universe may have been created by a much wiser, powerful being.

Is this what some religious people actually do? It's very surprising that even grown adults don't realize that they would have been following the rituals of some other religion if they were born into that family. It isn't surprising though, that most people think they are being religious by simply following rituals. They forget what their religion actually wants them to do. Such is the power of mass brainwashing, fear and hysteria.


Social Customs

Same applies to other social customs. Going out for a movie and dinner is somehow considered cool. Having a party at a club, going out for a company-sponsored lunch, volunteering grandly for one hour...

These may be enjoyable sometimes. These may be enjoyable to some people. But do you really enjoy it?
Would you find it more enjoyable to read an interesting book? To go on a long drive? To explore places?


A comic by Zen Pencils captures this nicely: http://zenpencils.com/comic/nerdist/


We live in a society that sees someone doing something they love, see the happiness on their faces and somehow believe that if we do the same thing, we would be happy too. What would really make you happy is the removal of the pressure to imitate others. To realize your interests and to do what makes you happy, no matter what the brainwashed masses think of it. It is in that moment that we find true peace and joy.
- Navin


That's also when you realize the true meaning of "Be yourself".

Of course, it's also important to keep in mind the laws of the land, the practicalities of finance, your dependents and responsibilities of life.

Think for yourself, people. You own your mind, you have the right to know the truth and to live life the way you wish.

27 April 2016

18 April 2016

A simple Apache Storm tutorial [Part 2: Implementing failsafes]


Continued from part1


If you really want to understand what the Value class is, what the Tuple class is etc., the best place to look, is not the tutorials on the internet. Look at the actual Storm source code.
It's available here: https://github.com/apache/storm
Go into the "storm-core/src/jvm/org/apache/storm" folder and have a look at those Java files. The code is very simple to understand and I promise you, it will be an enlightening experience.

Now, onto the ack and fail aspects of Storm.

Given below, is the exact same program as Part 1 of this tutorial. The added sections and sections that need your attention are highlighted.


BasicStorm.java:

package com.sdint.basicstorm;

import org.apache.storm.Config;

import java.util.concurrent.TimeUnit;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;

public class BasicStorm {

    public static void main(String[] cmdArgs) {
       
        Config config = new Config();
        //config.put(Config.TOPOLOGY_DEBUG, false);
        config.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, 1);
        config.put(Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS, 10);//alters the default 30 second of tuple timeout to 10 second
       
        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout("myDataSpout", new DataSpout());
       
        builder.setBolt("proBolt", new ProcessingBolt()).shuffleGrouping("myDataSpout");
       
        LocalCluster localCluster = new LocalCluster();
        localCluster.submitTopology("BasicStorm", config, builder.createTopology());
       
        System.out.println("\n\n\nTopology submitted\n\n\n");
        pause(120);//pause for 120 seconds during which the emitting of tuples will happen
       
        //localCluster.killTopology("BasicStorm");
        localCluster.shutdown();
    }//main


    public static void pause(int timeToPause_InSeconds) {
        try {TimeUnit.SECONDS.sleep(timeToPause_InSeconds);} 
        catch (InterruptedException e) {System.out.println(e.getCause());}
    }
 }//class


DataSpout.java:

package com.sdint.basicstorm;

import java.util.Map;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;

import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DataSpout extends BaseRichSpout {
    private TopologyContext context;
    private SpoutOutputCollector collector;
   
    //---logger
    private final Logger logger = LoggerFactory.getLogger(DataSpout.class);
   
    private boolean tupleAck = true;
    private Long oldTupleValue;
   
   
    @Override
    public void open(Map map, TopologyContext tc, SpoutOutputCollector soc) {
        this.context = tc;
        this.collector = soc;
       
        System.out.println("\n\n\nopen of DataSpout\n\n\n");      
    }
   
    public DataSpout() {
        System.out.println("\n\n\nDataSpout ctor called\n\n\n");
    }//ctor

    @Override
    public void declareOutputFields(OutputFieldsDeclarer ofd) {
        System.out.println("\n\n\ndeclareoutputfields of DataSpout\n\n\n");
       
        ofd.declare(new Fields("line"));
    }

    @Override
    public void nextTuple() {
        System.out.println("\n\n\nnexttuple of DataSpout\n\n\n");
       
        Long newTupleValue;
        if (tupleAck) {
            newTupleValue = System.currentTimeMillis() % 1000;
            oldTupleValue = newTupleValue;
        }
        else {newTupleValue = oldTupleValue;}

       
        this.collector.emit(new Values(newTupleValue), newTupleValue);
        System.out.println("\n\n\nEmitting "+newTupleValue+"\n\n\n");
        pause(1);
    }
   
    @Override
    public void ack(Object msgId) {
        System.out.println("\n\n\nAck received for DataSpout"+msgId+"\n\n\n");
        tupleAck = true;
    }   
   
    @Override
    public void fail(Object msgId) {
        System.out.println("\n\n\nFailed tuple msgID: "+msgId+"\n\n\n");
        //replay logic should be here
        tupleAck = false;
    }

 

    public void pause(int timeToPause_InSeconds) {
        try {TimeUnit.SECONDS.sleep(timeToPause_InSeconds);} 
        catch (InterruptedException e) {System.out.println(e.getCause());}
    }
    
}//class



ProcessingBolt.java:

package com.sdint.basicstorm;

import java.util.Map;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.tuple.Tuple;

public class ProcessingBolt extends BaseRichBolt {
    private OutputCollector collector;

    @Override
    public void declareOutputFields(OutputFieldsDeclarer ofd) {
        System.out.println("\n\n\ndeclareOutputFields of ProcessingBolt called\n\n\n");
    }

    @Override
    public void prepare(Map map, TopologyContext tc, OutputCollector oc) {
        System.out.println("\n\n\nprepare of ProcessingBolt called\n\n\n");
        collector = oc;
    }

    @Override
    public void execute(Tuple tuple) {
        System.out.println("\n\n\nTuple received in ProcessingBolt:"+tuple+" \n\n\n");
        collector.ack(tuple);
    }

   
}



Notice that this time when you run the program, the ack function in the Spout will get called whenever the Bolt executes the collector.ack(tuple); statement.

But suppose you comment out collector.ack(tuple);, then after a certain time period (normally 30 seconds, but in our program we made it 10 seconds), the fail function will get called.

This is how the Spout (and we) know whether a tuple has been received by the Bolt and acknowledged or not. The above program basically uses the System time as a Tuple and in case the Bolt does not acknowledge that it has received the Tuple, then the Spout sends the same old Tuple to the Bolt again.




And before getting into hardcore Storm programming, there is this important thing:

Apache Storm concepts you really need to know.




Say thank you or donate

A simple Apache Storm tutorial [Part1]

Apache Storm is actually well documented. Problem is, you won't understand any of it until you actually try out some code (even if it's in the form of a nice explanation by Chandan Prakash), and there's a dearth of simple code available on the internet. NRecursions comes to your rescue :-)

To run this program, you can either do it with Gradle (which I've used mainly so that the jar dependency management would automatically be handled by Gradle) or you could simply create a normal Java project and manually add the necessary jar's. The jar's you'll need are:
  • asm-5.0.3.jar
  • bson4jackson-2.7.0.jar
  • clojure-1.7.0.jar
  • disruptor-3.3.2.jar
  • kryo-3.0.3.jar
  • log4j-api-2.1.jar
  • log4j-core-2.1.jar
  • log4j-over-slf4j-1.6.6.jar
  • log4j-slf4j-impl-2.1.jar
  • logback-classic-1.1.3.jar
  • logback-core-1.1.3.jar
  • logback-core-1.1.3.jar
  • minlog-1.3.0.jar
  • objeneiss-2.1.jar
  • reflectasm-1.10.1.jar
  • servlet-api-2.5.jar
  • slf4j-api-1.7.12.jar
  • storm-core-1.0.0.jar

Create a Gradle project named "BasicStorm" and create a source package named "com.sdint.basicstorm".

Within that package, create BasicStorm.java
 
package com.sdint.basicstorm;

import org.apache.storm.Config;
import java.util.concurrent.TimeUnit;
import org.apache.storm.LocalCluster;
import org.apache.storm.topology.TopologyBuilder;

public class BasicStorm {

 public static void main(String[] cmdArgs) {

 Config config = new Config();
 //config.put(Config.TOPOLOGY_DEBUG, false);
 config.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, 1);
 config.put(Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS, 10);//alters the default 30 second of tuple timeout to 10 second

 TopologyBuilder builder = new TopologyBuilder();
 builder.setSpout("myDataSpout", new DataSpout());

 builder.setBolt("proBolt", new ProcessingBolt()).shuffleGrouping("myDataSpout");

 LocalCluster localCluster = new LocalCluster();
 localCluster.submitTopology("BasicStorm", config, builder.createTopology());

 System.out.println("\n\n\nTopology submitted\n\n\n");
 pause(120);//pause for 120 seconds during which the emitting of tuples will happen

 //localCluster.killTopology("BasicStorm");
 localCluster.shutdown();
 }//main

 public static void pause(int timeToPause_InSeconds) {
    try {TimeUnit.SECONDS.sleep(timeToPause_InSeconds);}
    catch (InterruptedException e) {System.out.println(e.getCause());}
}

}//class


and DataSpout.java
 
package com.sdint.basicstorm;

import java.util.Map;
import org.apache.storm.spout.SpoutOutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichSpout;
import org.apache.storm.tuple.Fields;
import org.apache.storm.tuple.Values;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DataSpout extends BaseRichSpout {
 private TopologyContext context;
 private SpoutOutputCollector collector;

 //---logger
 private final Logger logger = LoggerFactory.getLogger(DataSpout.class);

 @Override
 public void open(Map map, TopologyContext tc, SpoutOutputCollector soc) {
 this.context = tc;
 this.collector = soc;

 System.out.println("\n\n\nopen of DataSpout\n\n\n");
 }

 public DataSpout() {
 System.out.println("\n\n\nDataSpout constructor called\n\n\n");
 }//ctor

 @Override
 public void declareOutputFields(OutputFieldsDeclarer ofd) {
 System.out.println("\n\n\ndeclareoutputfields of DataSpout\n\n\n");

 ofd.declare(new Fields("line"));
 }

 @Override
 public void nextTuple() {
 System.out.println("\n\n\nnexttuple of DataSpout\n\n\n");

 Long newTupleValue =System.currentTimeMillis() % 1000;

 this.collector.emit(new Values(newTupleValue), newTupleValue);
 System.out.println("\n\n\nEmitting "+newTupleValue+"\n\n\n");
 pause(1);
 }

 public void pause(int timeToPause_InSeconds) {
    try {TimeUnit.SECONDS.sleep(timeToPause_InSeconds);}
    catch (InterruptedException e) {System.out.println(e.getCause());}}
}//class


and ProcessingBolt.java
 
package com.sdint.basicstorm;

import java.util.Map;
import org.apache.storm.task.OutputCollector;
import org.apache.storm.task.TopologyContext;
import org.apache.storm.topology.OutputFieldsDeclarer;
import org.apache.storm.topology.base.BaseRichBolt;
import org.apache.storm.tuple.Tuple;

public class ProcessingBolt extends BaseRichBolt {
 private OutputCollector collector;

 @Override
 public void declareOutputFields(OutputFieldsDeclarer ofd) {
 System.out.println("\n\n\ndeclareOutputFields of ProcessingBolt called\n\n\n");
 }

 @Override
 public void prepare(Map map, TopologyContext tc, OutputCollector oc) {
 System.out.println("\n\n\nprepare of ProcessingBolt called\n\n\n");
 collector = oc;
 }

 @Override
 public void execute(Tuple tuple) {
 System.out.println("\n\n\nTuple received in ProcessingBolt:"+tuple+" \n\n\n");
 collector.ack(tuple);
 }

}


Your build.gradle file would look like this (if you choose to create a Gradle project. You won't need this if you're creating a simple Java project):

apply plugin: 'java'
apply plugin: 'eclipse'

defaultTasks 'jar'

jar {
 from {
        (configurations.runtime).collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }   
    manifest {
        attributes 'Main-Class': 'com.sdint.basicstorm.BasicStorm'
    }
}

sourceCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

if (!hasProperty('mainClass')) {
    ext.mainClass = 'com.sdint.basicstorm.BasicStorm'
}

repositories {
    mavenCentral()
}

dependencies { 
    //---apache storm
    compile 'org.apache.storm:storm-core:1.0.0'  //compile 'org.apache.storm:storm-core:0.10.0'
    //---logging
    compile "org.slf4j:slf4j-api:1.7.12"
    compile 'ch.qos.logback:logback-classic:1.1.3'
    compile 'ch.qos.logback:logback-core:1.1.3'   
       
    testCompile group: 'junit', name: 'junit', version: '4.10'

}



Hope you've already read a little about how the Spout's and Bolt's work in Storm.

This is what happens in BasicStorm:

  • The moment a Spout or Bolt is instantiated, its declareOutputFields function gets called. For our simple program we don't need to know what it is, so let's ignore it for now.
  • When the topology is submitted to Storm, the open function gets called for Spouts, and this function gets called only once for a Spout instance.
  • For Bolts, the equivalent of open is the prepare function which gets called. You can use open and prepare to do initializations, declarations etc. for your program.
  • After submitting the topology, we pause for a while in main() (pause(120);) so that Storm would get time to run the topology. This is the time during which Storm calls nextTuple() of the Spout, and when the Spout emits a Tuple, the Tuple is sent to the Bolt (because in main() we configured the Bolt to receive Tuples from the Spout. See the line builder.setBolt("proBolt", new ProcessingBolt()).shuffleGrouping("myDataSpout");). 
  • When the Bolt receives the value, the execute() function of the Bolt is called.
  • BasicStorm is designed for a simple task. DataSpout emits a Long value (it's a Tuple), ProcessingBolt receives it and ProcessingBolt acknowledges (the collector.ack(tuple); line) that it has received the Long value and that the data processing for the tuple is complete.
  • When DataSpout receives the acknowledgement, it calls nextTuple() again and another tuple gets emitted.
  • This process keeps going on for the 120 seconds we have paused the main() thread for. After that, the topology shuts down.

Try tweaking the values here and there to find out how the program works. Try substituting some other value in place of the Long for the Tuple. Try substituting it with a class object. Remember that if you substitute it like that, you'll have to extend that class with Serializable.

One more thing to try out:
Try commenting out collector.ack(tuple); in ProcessingBolt.java. You'll basically not be telling the Spout that the tuple has been received by the Bolt. So after some time, the Spout will emit the tuple again. The interval of time the Spout waits for an acknowledgement (ack) is normally 30 seconds, but if you scroll up, you'll see that in main() we had set the time to 10 seconds (config.put(Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS, 10);), so the Spout will wait just ten seconds before emitting the tuple again.



Continued in Part 2



Say thank you or donate

06 April 2016

A comfortable Git branching model

Git has a very flexible approach toward branching, and workflows. The best I've seen yet.
Novices would probably be happy using the popular branching model Vincent Driessen has shown on his webpage: http://nvie.com/posts/a-successful-git-branching-model/



I've learnt from and liked Vincent's work, but during the course of working with the branching model, it has been more comfortable to use a slightly different model, especially when collaborating with other developers.



What I propose to be different...

...is simply that instead using the master branch to maintain the "stable" version of the code, it is more comfortable to have the master branch as the branch that the entire team collaborates on

A separate branch named "stable" (see; even the name is more appropriate than 'master') is created, which is also pushed to the remote/blessed repository, and that's the branch that keeps your stable version of the code that is ready for release.

It's not only about the comfort that the master branch affords you for collaborative development: ie: simply using "git pull" instead of "git pull origin development" etc.

It's also the fact that you'll have to do fewer merges between branches, which could end up looking like this:


The above screenshot is from GitUp. One of the best Git clients I've seen. Once you do a merge, you can actually undo it too (only available for MacOS though. When I wanted to port it to Linux myself, I saw the developers post that he's used too much of Objective C code for the graphics to be able to port it).

29 March 2016

How to play LAN games using a wireless router



This is for people owning a WiFi router, who are just looking to setup a simple LAN game on their personal LAN network. Not via internet.

Assuming you have two systems: A PC and a laptop, with two different versions of Windows OS. Let's say Windows XP and Windows 8.


Setting the IP address:
  • Connect the wireless router to the PC using a LAN cable and connect it to a power source.
  • Switch on the PC.
  • Goto Windows network settings, click on the network properties and in IPv4, set the IP address of the PC to 192.168.1.10. Set the subnet mask to 255.255.255.0.
  • Switch on the laptop and allow it to connect to the wireless connection from the router.
  • Goto the laptop's Windows network settings, click on the network properties and in IPv4, set the IP address to 192.168.1.11. Set the subnet mask to 255.255.255.0.
  • Like this you could add a few more computers if you want, ensuring that you set the IP address to a different number.

Ensuring that the computers can talk to each other:
  • Temporarily switch off the firewalls on both computers (and ensure that they aren't connected to the internet for safety reasons). You could also keep the firewall on and allow the specific ports that the LAN games require for communication, but switching the firewall off is the easiest way.
  • Open up a DOS terminal (cmd.exe) in both computers.
  • In the PC, type ping 192.168.1.11
  • In the laptop, type ping 192.168.1.10
  • In both terminals, you should see a successful ping happening with no losses. If it happens, then you are ready to start gaming. If not, you need to check why the networks aren't able to connect with each other.

Now open up the game on both computers and enjoy!


13 March 2016

Waterproofing and cement

When it comes to finding good workmanship in India for plumbing, masonry or electrical work, it's hard to find good people (I hear HR departments in all companies face that difficulty too).
Once you find people with good workmanship, you are at times presented with the danger of them ripping you off.


Insider lingo

Something that helps in such situations, is in knowing what are called "insider terms". When giving your car for servicing, if the mechanic starts speaking about the "manifold" and you don't know what that means, he's likely to recommend cleaning the pipes that lead to and lead out of it. What he doesn't tell you is that it's going to cost a small fortune to unmount it and clean it. But if you know the lingo and the recommended servicing mentioned in the manual, you can flatly refuse the cleaning which is actually un-necessary.

Same goes with other small work. A mason may tell you about the "white cement" (with an expression on his face that it's something very great) he's going to use on your house, along with waterproofing cement and some other cement. But he does not want to be questioned about anything and he's going to charge a fixed price.

Don't fall for it. Find out. Also search for complaints on Mouthshut.com or one of the many consumer complaints forums.


Cement is...

Unless you know what cement is, why sand is added to it and what kind of cement can give you proper waterproofing, the contractor or the mason can rip you off, by citing the high cost/quality of the materials they use or the so-called extra care they take to do the work very well.

Here are some things you need to know:

How hydraulic cement is created: 
Put simply, limestone is crushed to a powder and heated at 3500 degrees Celsius. This causes the Hydrogen molecules in it to escape, and the resulting powder is cement. During construction, you add water to the cement, and the hydrogen from the water combines with the cement to become hard. One such hydraulic cement is called "Portland cement". Hydraulic cements can be used to seal even swimming pools. Some of these cements can be used even underwater.

Mike Haduck explains it well, and I recommend his other videos too where he explains various types of masonry work.




Why sand is added to cement:
Sand has Silica, which increases the strength of the cement. Sand also happens to be an additive, which like other additives (fiber-glass, gravel, stones), adds to the compressive strength of the cement. Basically, too much sand or too much cement can make the resultant concrete/mortar brittle.
Cement is basically the binder that binds all the aggregates like sand and stone into a solid mass called concrete.

What is concrete and mortar?
  • Cement + water + sand + gravel = concrete
  • Cement + water + sand                = plaster
  • Cement + water + sand + lime    = mortar

Cement is just the dry powder you get. When it's added to water and sand, it becomes hard, and that's called concrete.
If you have to use cement with brick-work, make sure you use mortar instead of Portland concrete. For side-walks, patio's, highways, swimming pools, roof-work etc, Portland is better.

How much of waterproofing liquid should I add to the cement?
You add waterproofing liquid to the water; not the cement. The liquid will be miscible and you then add the mixture to the cement. The packet will have instructions on what ratio to follow. Generally, the waterproofing liquid should not be more than 2% to 5% of the cement. There are people who say that if the quality of the sand is not good enough, then it's ok to add upto 20% of the liquid.
Careful though, since the purpose of the waterproofing liquid is just to give the cement more plasticity. If you add too much, the cement will lose its strength. Hydraulic concrete by itself has a sufficient amount of waterproofing property. Make sure you cure it well.

What is curing and how much of it should I do?
The hardening of concrete happens by a process called "hydration", during which the mineral hydrates solidify. For hydraulic cements like Portland cement, the concrete hardens better not if you leave it alone to dry, but it hardens better if there's moisture present during the hardening. Remember I mentioned that the hydrogen molecules from the water go back to the cement and make it hard?
If you don't have curing oils/compounds or plastic shields, then the simpler way of ensuring that the moisture remains with the cement, is to use a gunny bag or cloth that's placed on the cement and to pour water over it. Make sure the moisture is retained for around 28 days, as this is the curing time that it is designed for. Of course, this may also vary based on the additives and mixture chosen.

What is so great about white cement?
Actually, nothing. Grey cement and white cement have almost the same chemical composition. All cements when manufactured, are white. It's the additives that change the colour of the cement. White cement has certain ferrous or other metallic oxides added to it. For decorative purposes, other additives may be added to give the white cement some other colour.


When you know just this much of information and speak to a mason, you'll see that they don't really know much about their job. They've been taught through the years to use certain materials and ratios, but they have no clue why. It's always better to

Find an engineer or a contractor who:
  • Knows the what and why of the ratios of materials to mix.
  • Patiently explains the process to you and allows you to ask doubts.
  • Allows you to supervise the cementing process (though they prefer it if you stay out of their hair when the work is going on)
  • Asks his workers to use protective gloves and masks (the contents of cement and waterproofing agents are harmful chemicals)

Search for people with knowledge. Get people who don't rip you off.




Your best bet is in learning what needs to be learnt and consulting with many contractors. Don't wait for the day you badly need plumbing/masonry work to be done. Search for these people even when you don't have any emergency, so that you'll get the right person during an emergency.

04 March 2016

Generate a gitignore for Netbeans, Eclipse, IntelliJ Idea, Gradle or anything else!

I've written about gitignore for Netbeans, but recently came across something much better. There's actually a gitignore generator which can generate the file and folder list that Git should ignore. It's available for 255 types of IDE's, OS'es etc.

Either just type the name of the IDE, OS or programming language and click "Generate"...

OR

... install the commandline version of it and at the terminal, simply type:

gi <IDE or language or OS name>

and the custom gitignore gets generated.

or if you want to directly generate the file, just add the redirection operator:

gi <IDE or language or OS name>  >>  .gitignore

or if you don't want to generate specific gitignores for every project, simply generate a global one.

Eg:
gi linux, netbeans >> ~/.gitignore_global



As simple as that. It's quite amazing that someone took the time to actually create a gitignore generator. Thoughtful, and very much a gem for programmers around the world!



A little video if you still need help:

28 February 2016

National science day: The cultivation of scientific temper

Today was Breakthrough Society's celebration of National Science Day and the observation of the "Cultivation of scientific temper". It included many school children and adults who were invited to the Raman Research Institute at Bangalore for a seminar and an exhibition.





It was my first visit to the campus, and I just loved the beauty of it. Reminded me of Bangalore, the way it was before concrete, asphalt and smoke took over the city!




The conference touched upon topics of scientific importance, about the need for research in India, the realization that people should have about science and the way it impacts humanity and an appeal that people go through some trouble in life; even if it involves some amount of struggle, so that their research and discoveries can bring greater good to humanity.

The seminar was followed by a documentary on Dr.C.V.Raman's life.




and a visit to the science museum, where there were various exhibits and publications of Dr.C.V.Raman.

We were shown how Dr.Raman (at the age of 16 or 17), had questioned why the Veena sounded like a human, and pursued the question. Even though Helmholtz had said that a plucked string could oscillate in only an odd number of ways (1, 3 or 5) etc..., Dr.Raman went on to prove that the Veena could even oscillate in even numbers, hence producing sounds similar to that of a human. This was because Helmholtz had experimented with a Violin, whereas the strings of a Veena are strung very differently, and when plucked, they oscillate differently.

Dr.Raman also dropped a metal bearing on glass and noticed the circular crack it made on impact. He tried the same on quartz crystals and noticed that here, the cracks were triangular in shape. Typical scientist :-)

The science museum has a large collection of objects he studied and collected. Said to be the largest collection any scientist has. Photos were forbidden since they said that if the photos were shared on social media, that would dampen the curiosity of the children. I disagree. The collection is so unique and amazing, that people would actually want to send their kids to actually see it. Believe me; there are no photographs that can capture the glimmer and wonder of those stones which are captured by the eye.

Also on display were some interesting quotes:






There was also an interesting quote from Einstein, which I followed up on:
I have now reached the point where I may indicate briefly what to me constitutes the essence of the crisis of our time. It concerns the relationship of the individual to society. The individual has become more conscious than ever of his dependence upon society. But he does not experience this dependence as a positive asset, as an organic tie, as a protective force, but rather as a threat to his natural rights, or even to his economic existence. Moreover, his position in society is such that the egotistical drives of his make-up are constantly being accentuated, while his social drives, which are by nature weaker, progressively deteriorate. All human beings, whatever their position in society, are suffering from this process of deterioration. Unknowingly prisoners of their own egotism, they feel insecure, lonely, and deprived of the naive, simple, and unsophisticated enjoyment of life. Man can find meaning in life, short and perilous as it is, only through devoting himself to society.
The economic anarchy of capitalist society as it exists today is, in my opinion, the real source of the evil. We see before us a huge community of producers the members of which are unceasingly striving to deprive each other of the fruits of their collective labor—not by force, but on the whole in faithful compliance with legally established rules. In this respect, it is important to realize that the means of production—that is to say, the entire productive capacity that is needed for producing consumer goods as well as additional capital goods—may legally be, and for the most part are, the private property of individuals.

But perhaps one of the most important quotes the community was missing out on, was this one:


It's not really about the survival of the strongest or the most intelligent. It is about the one that is most responsive to change.

My view

We see many protests in our country about growing intolerance and the lack of promotion of science. Makes me wonder why this happens. Many decades ago, it was the will of certain curious people which helped them make discoveries, helped the world to advance and brought pride to the nation. Any government would be happy to encourage such people and I believe this is why science was given importance. This is why we had impressive research institutes and dedicated people.

It created value for the nation.

As the years passed by, did something else create more value for the nation? Did research cease to add as much value as something else? Did our nation become self-reliant enough that it no longer needed science? Is it more economical to purchase a technology from a neighboring nation than to invest in our own research? Does the work of private enterprises add more value to our nation?

As Darwin's quote in the above picture says; it is the species that is most responsive to change that survives. Has our scientific community adapted to the changes? We live at an age that has seen more peace on Earth than in historical times. Is this an age where the entire world works as one (except North Korea)? Where research in basic sciences, can be done at select countries so that other countries can focus on other things? Does a country really need to worry that it is not doing enough research?

What exactly is the bigger picture here? I'm quite sure that if a nation needed more research, the government would have actively pursued it. If a government isn't doing so, there's a reason. What is that reason?

Is our advanced, industrialized society really deteriorating (as Einstein said) and becoming focused on the trivialities of life?

I believe things will change. Not by dissent; not by protest. The change will be brought about by a mind that conceives such a thought, that it would alter the very way we live our lives. In the same way that a hundred years ago, everyone who predicted the future did not in the least bit take into account or conceptualize the advent of software.

There is hope.

27 February 2016

Descriptive names

We've all been through our initial programming lessons, creating for loops as for(int i = 0; i<10; ++i) and so on. float s = d / t.

Variable names didn't matter much then.

The confusion begins, when you enter the professional world, write large programs, forget about them and months later, look at the code and wonder what in the world you had written long back. Class names, variable names and function names don't make any sense at all!!!
If you took care to write comments, then they are a saving grace, but only for a while.

Which of these would make more sense to you?

//check if customer age is equal to threshold
void check(double v
{
   if (val == v) {print("yes");} else {print("no");}
}

or

void checkIfCustomerAgeIsEqualToAgeThreshold(double customerAge
{
   if (ageThreshold == customerAge) {print("yes");} else {print("no");}
}

See the difference? No need of comments. No confusion. You understand what the function and variables are there for, just by looking at the code.

The other big advantage is that if you decided to do some refactoring, you wouldn't have to bother changing any comments, because the class/function/variable name itself is the comment!

Same goes with macros.
I see a lot of C++ programmers using...

#if 0
//some code
#endif

...to temporarily deactivate some code. If these programmers get hit by a bus or even if they look at the code many years later, they won't have a clue of why the code was deactivated and whether it is ok to simply delete it.

What if they used this instead:

#ifdef YEAR_CALCULATION_CODE_TEMPORARILY_DEACTIVATED_DONT_DELETE
//some code
#endif

or

#ifdef CODE_FOR_DEBUGGING_DELETEME_ANYTIME

or

#ifdef SWITCH_ON_COLOR_OUTPUT


Same goes with class names. Which makes more sense?:

class Filter{}
class MicroFilter extends Filter {}

or

class AirFilterSuperclass {}
class SpecializedMicroFilterOfCompanyABC extends AirFilterSuperclass {}


  • It makes a world of a difference to the person who maintains the code.
  • It makes another world of a difference to the person who reviews your code.
  • And it makes an entirely different world of a difference to the business that profits because developers, tech leads and QA teams spent lesser time figuring out the code and spent more time in being able to create a splendid product!

08 February 2016

Aha!

 Continued from the previous Aha!


Signatures
Share with this link




After the sneeze
Share with this link



Continued in the next Aha!