Showing posts with label computers. Show all posts
Showing posts with label computers. Show all posts

Tuesday, June 26, 2018

[v2.0] Ok Google, Open my curtains!

This post is a follow-up to my previous post http://vignesh.foamsnet.com/2018/06/ok-google-open-my-curtains.html.

Note: I've created a github repository which contains the code and some more details. I intend to keep that up to date with newer ideas, etc. https://github.com/vickyg3/curtain-automation

When i posted the previous set-up on reddit, one of them suggested a better way to do this that will overcome the cons of the previous method (noise and lack of manual control).

In a nutshell, these are the replacements i made:
  • Use a stepper motor instead of a servo.
  • Use a timing belt pulley and timing belts instead of a pulley and rope.

Here are the updated list of parts (with links to the cheapest ones i could find online to keep the cost minimum - although i didn't necessarily buy it from these links):

* Mounting bracket for the pulley on the non-motor end - I used a servo mounting bracket with a long screw. I am sure there are better alternatives for this one - $12.99
* Super glue - $4
* Vibration dampener for stepper motor (optional but highly recommended to keep the noise down) - $2.98
* 12V DC adapter - $8.99

Total Cost - $67.69 (some of it can probably be gotten for a cheaper price on ebay/gearbest/aliexpress).

Step 1 - Screw in the mounting bracket

This is quite straightforward. I drilled in a couple of drywall anchors and screwed in the mounting bracket to the wall.

Step 2 - Install the motor and the vibration dampener

Place the vibration dampener on the motor. Make sure that the non-threaded holes on the dampener are touching the motor and use two M3 screws to attach the motor and the dampener. Attach the pulley wheel to the motor's shaft using the screws on the side of the pulley.

Now the motor can be mounted on to the mounting bracket using 2 M3 screws which connect to the dampener's threaded holes.
Motor attached to the mounting bracket (shown without the vibration dampener).

Step 3 - Install the pulley mounting bracket on the other end

I drilled a drywall anchor on the other end and screwed the pulley mounting bracket in. I then used a long screw with a couple of plastic fillers to hold the other pulley roughly in the center.

Step 4 - Loop the timing belt around the pulleys

I had bought an open ended timing belt. I looped it around either pulleys and tightened them as much as i could by hand and cut off the rest of the belt leaving about an inch of overlap. I then used super glue on the extra inch of belt to stick to them together with as much tension as possible. You could also use a clamp like this with a screw to close the loop on the belt.

At this point, you should be able to move the belt manually by hand by pulling it gently in either direction. If so, there is enough tension on the belt to move the curtains.

Step 5 - Attach the curtains to the timing belt

Just as before, i placed the curtains in the completely closed state and attached each curtain to either side of the timing belt using a safety pin.

Here's a sketch from before about how the pulleys and the curtains move:

Step 6 - Program the microcontroller

I used the same NodeMCU ESP8266 controller as before. Here's the gist that contains the Arduino sketch: https://gist.github.com/vickyg3/623ca535b565ed43c8b617a6f7c7c06f (it is a crude version and has a lot of room for improvement, but i left it for another day).

Step 7 - Microcontroller and Motor Driver setup

Here's the wiring:
* DIR+ to D2
* PUL+ to D5
* ENA+ to D8
* DIR-, PUL- and ENA- to GND (can either be bundled together or connected separately to individual GND pins on the NodeMCU)
* A+, A-, B+ and B- need to be connected to the motor (refer to the motor's spec for the wiring colors for your motor).
* The switches on the driver need to be set to ON, ON, OFF, ON, ON, OFF (S3 and S6 should be off).

Connect the DC power supply to the driver. I cut the ends of an old DC adapter and identified the positive and negative wires using a multimeter.

I then glued the driver and the NodeMCU board to the wall behind the curtain using small command strips. Any double sided tape should work as they aren't that heavy.

Step 8 - Home Assistant Configuration


That is pretty much it. For more details on how you can control it from Google Home/Alexa, please see my previous post.

The noise level of the old servo based system was around 60 decibels (as measured by an app on my phone). The new system with vibration dampeners works at 30-35 decibels and is barely audible. Most of the noise is from the curtains actually moving on the rod.

Here's how it works (The video is noisy because the roomba was running when i recorded the clip):


Here's a video without much of external noise:



Saturday, June 16, 2018

Ok Google, Open my curtains!

Finally I've found a worthy enough reason to write a blog post.

I've been wanting to make the curtains in my home "smart" for a while now. I have what is called "grommet curtains"  and there are apparently no off the shelf solutions to automate this. There is this kickstarter project called Slide which retrofits to any curtain type, but that is still in its early stages and a bit pricey (~$150).

I ran into a tutorial which spoke about automating grommet curtains. But they used a 3d-printer to print custom designed components which wasn't an option for me (I don't have a 3d printer and i don't have any knowledge of how to design components for a 3d printer).

I borrowed the basic idea from that video. Two pulleys at either end with a rope running around them. One of the pulleys is attached to a servo which is controlled by a microcontroller. Here's an awful sketch of the idea:

Here are some of the challenges faced/things i did:
  • There is no cheap off the shelf servo that has a pulley attached to it. So i had to tweak around to figure out a way to mount a pulley to the servo.
  • The load on the servo to pull the rope along with the curtains is pretty high. So the servo has to be mounted securely to the wall. I first tried a heavy duty double sided tape, but that wasn't enough to withstand the tension of the rope. I then tried out various things and found a mount that could be screwed into the wall.
  • The wall mount for the servo held it too close to the wall and there was no room for the pulley (whose diameter is larger than the breadth of the servo) to fit in and rotate smoothly. So i used a couple of washers behind each mounting screw to give enough room for the pulley.
  • To tie the other pulley (which has no motor), i simply used a rope to tie the pulley on to the curtain rod's mounting bracket.
  • The servo had to have metal gears in order to have enough torque to pull the curtains. But such servos need a minimum of 4.8 volts of power. I found a NodeMCU board which had a 5V pin to supply enough power to the servo.


Here are the list of parts with links to where i bought them:

* NodeMCU (ESP8266) microcontroller (model with 5V pin) - Amazon - $5.98
* Jumper wire (to connect to the 5V pin) - Amazon - $5.24
* MG995 Servo (360 degree, metal gear, digital model) - Amazon - $10.99
* Servo wall mount - Amazon - $12.99
* Washers - I just used a couple of old washers lying around. Equivalent link: Home Depot - $2
* Pulley (for attaching with servo) - Servocity - $3.49
* Pulley (for the other end) - Home Depot -  $2.47
* Rope - Home Depot - $3.98
* Safety pins - Amazon - $3.15

Total Cost - $50.33 (some of it can probably be gotten for a cheaper price on ebay/gearbest/aliexpress).

Ok, with all that out of the way, let me explain how exactly i built and programmed this.

Step 1 - Attach pulley to the servo

Attaching the winch pulley to the servo is quite straight-forward. I screwed in the 4 pieces of the pulley with 2 bolts (on diagonally opposite ends) and small hex nuts. I then attached one of the servo horns to the other two holes of the pulley with two small screws (that came with the servo).

Now, the servo horn can merely be screwed into the servo until it's fairly tight.

Step 2 - Install the mounting bracket

After marking two spots with the mounting bracket's holes, i drilled in two drywall anchors on those spots. Then use two screws to screw the mounting bracket into the wall placing two washers in between the mounting bracket and the wall. This makes sure there is enough room to mount the servo along with the pulley.
This is the bracket i used to mount the servo to the wall
Step 3 - Attach servo to the mounting bracket

This is very straight-forward. The only catch is i used two nuts instead of 4 to attach the servo on to the mounting bracket.
Servo mount with washer behind. Pulley attached to the servo.
Step 4 - Mount the pulley on the other end

I used a small rope to tie the pulley on to the curtain rod's mounting bracket on the other end. A nut and bolt can also be used but since the rope worked for me i didn't look further.

Step 5 - Tie the rope on to the pulleys

Loop the rope around the pulley without the servo once. In the servo end, loop the rope around the pulley at least twice and then tie a really stiff knot. Make sure that the rope is really tight. Cut off any extra rope since it could cause friction when the rope is moving.
Rope tied to the pulleys and attached to the curtains.
Step 6 - Attach the curtains to the rope

I used a couple of safety pins to attach the curtains to the rope. I set the curtains in fully closed positions and then attached each half to one of the ropes. When the pulley spins, both the ropes will move in opposite directions thereby opening each curtain outward. The same process is reversed to close it.
Curtains attached to the rope with safety pins.
Step 7 - Program the microcontroller

This is my first foray into programming a microcontroller and surprisingly enough it was really simple. The NodeMCU ESP8266 board is a $5 wifi enabled board. Wifi means that you can send commands to it through simple HTTP requests.

Here's the arduino sketch i used to make a simple HTTP server that supports 3 commands: left, right and off (which spins the servo left, right and turns off respectively): https://gist.github.com/vickyg3/94b80435fa10a58691f563f643aaf807

Once this is flashed into the board, controlling the servo is simply a matter of "curl http://<ip>/left".

Step 8 - Mount the microcontroller

I mounted the microcontroller near the servo (using a small double side tape on the wifi chip) and just attached the servo wires to the appropriate pins (i used a jumper wire to connect the power wire to the 5 volt pin). I then ran a long micro-usb cable that i had lying around to power the microcontroller.


Step 9 - Home Assistant configuration

I added this to home assistant as a command line cover that used curl. Here's a sample configuration:

Where curtains.sh contains the following:

I determined the time to sleep between rotating the pulley and turning it off by trial and error. It usually took more time to close than to open because the set up struggled a bit to pull the curtains in that direction. It now shows up in home assistant, like so:


That's it. You can now include this in your automations, etc. I have set up automations like close the curtains after sunset, when we are away and so on.

If you have your home assistant tied to google assistant, you can control the curtain by saying "Ok Google, Turn the <curtain name> on/off". If you want custom commands, you can also try ifttt with google assistant to have commands like "Ok Google, open my curtains!".

Here's the Eureka moment

Some cons of this system:
  • The servo is a bit noisy. This is probably ok given that curtain control is not too frequent. It is probably bearable for 10 seconds or so once in a while.
  • Hooking up the curtains this way makes it impossible to control the curtains manually (since the curtains are tied to the rope). I've worked around this by sticking a button next to the curtain by the wall for those scenarios where we don't want to use voice control. Pressing the button will open/close the curtain.
    Button to control the curtains in lieu of voice/phone control.

Comments and suggestions about improving this in any way are welcome!

Friday, June 27, 2014

Use your Chromecast/Roku on a Hotel WiFi

Chromecast and Roku are really wonderful devices which allow you to take all your media with you where ever you go. Especially, if you travel a lot, it's definitely way better to watch something on your Netflix subscription rather than paying exorbitant rates on the hotel's pay-per-view.

But there's a problem. Hotel WiFi's usually use web based authentication (i.e.) their wireless network is usually open and anyone can connect to it. Only when you try and open a webpage, they send you to an authentication page that asks for a username/password (which the hotel will provide you) and/or asks you to accept the terms and conditions.

The problem is that Chromecast and Roku do not have native support for such authentication. But fear not, in this post, i am going to write about a few ways in which you can work around this limitation to enjoy Roku/Chromecast on the hotel's WiFi network.

Find out your device's MAC Address

2 of the 3 workarounds that i mention requires you to know the MAC Address of your Chromecast/Roku device. Here's how you figure it out:

Roku
  • Switch it on
  • Navigate to Settings->Network->Wireless
  • On the bottom right, you can see the MAC Address of the Roku
Chromecast
  • Switch it on
  • Connect your phone to the hotel WiFi and authenticate it
  • Open the Chromecast Setup app on your android phone
  • Tap on devices and wait for it to scan
  • Tap on your Chromecast device in the list
  • Tap "Set Up"
  • Tap "I see the code"
  • Tap "Set Name"
  • The MAC Address of your chromecast will be displayed on the screen now. 
Workaround 1 - Call the Tech Support

Most hotels give you a small sheet of paper with your WiFi username and password. That sheet usually also has a "tech support" phone number. Here is what you can do: Call the tech support number and tell them exactly this: "I would like to use the roku media player device over the hotel WiFi. I wanted to check if you could whitelist the MAC Address of my device to by-pass the authentication page".

Depending on the mood and knowledge of the tech support person, he/she might say okay. But nevertheless, it's gonna take some time before the whitelist happens. And once the whitelist happens, you can enjoy Chromecast/Roku over the hotel WiFi.

Workaround 2 - Spoof your MAC and authenticate from your laptop

The whole web authentication system works around MAC addresses. Once you enter your username and password, your MAC and IP addresses are going to be whitelisted for a certain amount of time (about 24 hours) and your device will be allowed to access the internet in that time period.

One key weakness about this authentication mechanism is that MAC address is easily spoof'able. So we are going to to assign your Roku/Chromecast's MAC address to your laptop and perform the authentication like usual and then make use of that whitelist to access the internet from your Roku/Chromecast. Here are the steps (follow them precisely to the word):
  • Find the MAC address of your Roku/Chromecast using the steps above. Note it down.
  • Open the terminal (assumes linux).
  • Run "ifconfig" and note down the MAC Address of the laptop. [1]
  • Run this command: "sudo ifconfig wlan0 down".
  • Disconnect from the WiFi network on the laptop.
  • Run this command: "sudo ifconfig wlan0 hw ether <mac address of roku>".
  • IMPORTANT: Turn off the Roku/Chromecast by unplugging it.
  • Run this command: "sudo ifconfig wlan0 up".
  • Connect to the Hotel's WiFi network on the laptop.
  • Open the browser and navigate to google.com (or any other website).
  • It will ask for authentication, provide username/password that the hotel gave you.
  • Type google.com again and verify that you can access Google.
  • Run this command: "sudo ifconfig wlan0 down".
  • Disconnect from the WiFi network on the laptop.
  • Run this command: "sudo ifconfig wlan0 hw ether <mac address of your laptop from step [1] above>".
  • Run this command: "sudo ifconfig wlan0 up".
  • Now you can plug your Chromecast/Roku back in and connect to the Hotel's WiFi network on that. It should now be connected to the internet!
You will have to repeat these steps after the whitelist expires (usually about once a day).

Note: The above two work arounds will connect your Chromecast/Roku directly to the hotel's WiFi 

Workaround 3 - Set up your own WiFi network

Buy a portable WiFi adapter and use that to share your Hotel's WiFi through your own access point.

Hope this helps!

-Vignesh

Monday, November 4, 2013

Introducing Super Secure File - One File, Completely Secure, Access Anywhere!

Super Secure File gets you a really secure password protected file that you can access anywhere with an internet connection. Smartphone, Tablet, Laptop, SmartTV, anything!

To cut to the chase and create your Super Secure File, go to: http://secure.foamsnet.com.

How does it work?

Super Secure File basically uses Google Drive to store your encrypted file and does all the encryption and decryption locally in Javascript. The key never ever leaves your computer. Once you close the tab, boom, the key is gone. Nobody knows the key but you (and probably your spouse if you are married).

Motivation

This is not a big feat or anything, this is merely a mashup of a few libraries to prove a point to myself. The motive behind this app is to build a secure mechanism to store my passwords and credit card numbers on the cloud so that I can access it anywhere. I do not trust anyone who links me up to a server when it comes to information like this. Which is why i wanted a completely static HTML page with no server access whatsoever to provide me with this functionality.

Feel free to examine the source code here (and please let me know if you find anything utterly stupid): https://github.com/vickyg3/super-secure-file

Hosting and Links

Since this is a static page, I have not hosted this on my server. This is merely hosted as a github page (if you look at the repo, you'll see the default branch to be gh-pages and not master). Hosting it as a github page also proves that it has no server interaction whatsoever and cannot steal your key by any mean.

So, all you need is to remember your password and one of these URLs (they all redirect to the same Github Page): http://bit.ly/securefile or http://bit.ly/supersecurefile or http://secure.foamsnet.com or http://vickyg3.github.io/super-secure-file/super_secure_file.html

Get your Super Secure File and make your life a little easier! :-)


-Vignesh

Wednesday, October 23, 2013

Open sourcing Social Photos

I have been working on a lot of open source projects lately (chromium, AOSP, ffmpeg, etc.) and I have had this tremendous change in the way i look at software projects now. I am all the more convinced that open source is the only right way of doing software.

With that in mind, I've made a pledge to myself that no matter what I do, I am going to put the source out there. As a first step, i'm open sourcing the one big project of mine, Social Photos.

The source can be found here: https://github.com/vickyg3/social-photos

It is a snapshot of the one that's currently powering the live site: http://socialphotos.net (with API keys redacted). Feel free to fork and use as you please. Although i'd appreciate a link back, it's not mandatory. Also, i'll be more than happy to look at Pull Requests.

One of the main reasons that developers (including myself) don't post our code out there is that we are ashamed of our code. I was really ashamed by the number of hacks i did in this project that i couldn't even think of making it public. I'm over it. I'm ready to accept people fixing my mistakes.

Happy Coding!



-Vignesh

Wednesday, September 11, 2013

VLC Media Player: Automatically Skip Songs in Indian Movies!


I watch a lot of movies. Really a lot. And VLC Media Player is my (and many others') favorite. Indian movies are plagued with songs in irrelevant times and most of the time it just interrupts the pace/flow of the movie. No offense to music lovers/music makers, I like listening to songs in general. But I don't like them in the middle of an important scene in the movie.

The Problem

Whenever a song starts, inevitably I try to use the seek bar (using the seek bar is really one of the big pain points of any media player as it almost never takes you to where you want) and seek to the end of the song. Most of the time I end up seeking either just after the song (thereby missing something important) or to some portion in between the song (thereby having to wait for some more time for the song to end).

As an engineer, I naturally wondered, Wouldn't it be wonderful to have an automated way (preferably a keyboard shortcut) to just skip the song and move to the more important stuff?

This is exactly what I sat down to solve. Based on this xkcd, it seemed like it would be worth the time.And I (sort of) have a perfect solution that helps me skip songs automatically in the press of a button in VLC Media Player.

The Solution

As hard as the problem might seem, I ended up using a very simple heuristic. Start analyzing the audio stream, and whenever there is a silence for about a second or so, it's likely that the song ends there. I just came up with this heuristic based on the fact that most Indian movie songs are continuous (either lyric or the music goes on throughout the song without any breaks) and when the song ends, there is usually a small interval of silence before the next scene starts. And if there is a silence somewhere in between the song, just do the analysis again and it will take you to the next silence which is most likely the end of the song.

Is it perfect? Absolutely not. It's not even a solution, it's more of a heuristic (aka hack) which exploits some pattern in the Indian movie songs. And in my observation (I have been using this for quite a while now), It seems to be working correctly 99% of the time.

Implementation Details

Note: This section has technical jibber-jabber. If all you care about is how to use the script in your VLC media player, skip ahead to the "Usage" section.

First things first, I chose VLC media player, because that's the one I use. If you aren't using it, then you should start using it too. To begin with, we need to query VLC Media Player.

The overall flow goes something like this:
  1. Get the name of the file that VLC is currently playing
  2. Get the time point of the current playback from VLC
  3. Analyze the audio stream of the file and detect the next silence beginning from the time point of current playback
  4. Seek VLC to the determined duration where silence was detected (this is likely the end point of our song)
As complex as these steps might seem, they are fairly trivial to accomplish. To perform steps 1, 2 and 4 all we need to do is enable the HTTP interface in VLC. Once that's done, it is straightforward to get details of playback and control the player through a simple HTTP interface. The 2nd step is a little more tricky as it involves analysis of the audio stream of a file. Fortunately, we have a swiss army knife in our hands which will not only analyze the audio stream, but pin point us to the exact location of silence that we are looking for. The tool is none other than FFmpeg. The silence detect filter in ffmpeg has been used to accomplish this.

Here is a rough sketch of the ffmpeg command that I use:

ffmpeg -ss <start_time> -i <input_file> -t 600 -vn -af silencedetect=noise=0.1 -f null -

Let me break that up:
  • -ss <start_time> :- seeks to the specified time in the input file. this value for this is obtained from VLC's HTTP interface
  • -i <input_file> :- absolute path of the file that VLC is currently playing. this value is obtained from VLC's HTTP interface
  • -t 600 :- analyzes only 600 seconds (10 minutes) of audio to detect for silence (as Indian movie songs are hardly longer than 10 minutes).
  • -vn :- ignore the video
  • -af silencedetect=noise=0.1 :- enable the silence detection filter with a threshold of 0.1dB. this value was picked by trial and error.
  • -f null - :- just print the output of the filter in stdout rather than a file.

We then grep for the exact duration and then seek VLC based on this output.

Code

Look into the variables on top of the file and change them as per your environment if required.

Usage

To use this script, you need to install the following (fairly straightforward if you are tech-savy, but doable even if you are not).


Once you do the above steps, all you need to do is to bind a keyboard shortcut such that the script will execute. For Mac, I used Keyboard Maestro to set up a global keyboard shortcut which will invoke the script. There should be an equivalent program for Windows/Linux too. So that whenever a song starts, I merely use the keyboard shortcut to skip it.

Hope you enjoy it.


-Vignesh


Education is a cure for all problems. Donate for the cause of Educating kids: Computer Kindness Foundation is helping schools to build Libraries. Follow the link to contribute.

Sunday, July 14, 2013

Announcing Social Photos v2!

I have been working on this side project for quite a while now and I am happy to announce that it is launch ready now!

Visit http://socialphotos.net to manage all your digital photos across Social Networks in one roof using a simple intuitive user interface.

Features Include:

  • Transfer Photos
  • Transfer Albums
  • Download selective albums as a zip file
  • View Slideshow of your albums
  • Monitor progress in a simple pane
  • And much more!

Please do feel free to give feedbacks/suggestions. Use it and Share it!


-Vignesh

Tuesday, April 23, 2013

Solving Boggle (Scramble with Friends) with a Bot!

Headnote

I am always fascinated by Android games, especially puzzle games. This is how it usually works with me and a puzzle game. I start playing them with random friends. They beat me and I beat them on and off. Then I sit and think, this is so monotonic and algorithmic that a human being shouldn't be sitting and doing it. Then I sit with the computer (with my favorite monkeyrunner Jython in it) and try to come up with a simple algorithm for it. Then i plug in the standard monkeyrunner code to actually feed the output of the program back to the device. Then I usually become #1 among my friends in the leaderboard (often even in the global leaderboard) ;-)

This is one such scenario. Zynga's Scramble with Friends has been really popular among my friends off late. So i hit this routine cycle and ended up with a beautiful bot which usually scores a centum (like the one TamBrahm parents force their kids to get in Mathematics).

With that out of the way, let's begin.

Objective of the Game

The game consists of a 4x4 grid of letters. You have to form as many words you can by starting from a letter and by moving to one of the (upto) 8 adjacent letters. Dead simple, but really interesting and addictive.

The first thing needed to solve this is a dictionary of words. I went on the internet and downloaded a plain text dictionary file which had about 170k words in it. Good enough to start with.

Algorithm - Breadth First Search

The number of valid words is usually very limited. In most games, the total number of valid words is usually < 400. So, a simple Breadth First Search (BFS) will do starting with single letter elements and then add the neighbors recursively. One key insight is, if you come across a prefix that never occurs in the dictionary, you can discard that prefix at that point instead of adding it to the traversal queue.

A rough sketch of the algorithm is as follows:
  • queue = [all 16 characters]
  • while queue is not empty:
    • word = head of queue
    • if word is in dictionary output it [1]
    • for all neighbors adjacent to the last character of word
      • new_word = word + neighbor
      • if dictionary has words with prefix new_word, add new_word to the queue [2]
That's it. Straightforward implementation of a BFS-like algorithm.

Choice of Data Structure

The key to solving this problem efficiently lies in choosing a good data structure for implementing the dictionary. The dictionary needs to support two major operations. One is looking up if a word exists. This is used for step [1] in the above algorithm. The other operation is, given a prefix, check if there is atleast one word containing that prefix in the dictionary. This is used for step [2] in the algorithm mentioned above.

Array ?

One good looking candidate is using a simple array (note that the dictionary is already sorted for us). Look up can be performed using simple binary search. Prefix checking can also be performed using a modified binary search (if search succeeds, then prefix exists. if search fails, prefix existence can be determined by looking at the bounds in which the search failed). Also, note that the dictionary has ~173k words. So, searching is gonna take log(173k) which is approximately 18 hits in the worst case. This is a totally fair deal.

Trie ?

Another possibility is using the Trie, whose raison-d'etre (very reason for existence) is to implement such dictionaries. The Trie implementation is also fairly trivial (since we require only two major operations apart from Trie construction). In the Trie, both the operations are gonna take as many hits as the length of the word or the prefix being looked up. So asymptotically, both these data structures are more or less similar and we don't have a big advantage in using either one over the other since our output is always gonna be < 400 words.

I decided to go with the Trie. After reading this article about Trie implementations in Python, I decided to quickly write my own implementation of Trie. Also, this made life simpler as I couldn't quickly find any good resources about using external libraries within monkeyrunner.

Implementation Quirks

Since I had already used monkeyrunner a few times before, implementation turned out to be pretty straightforward. The following are a few implementation quirks and nuances that the script deals with:
  • Input is manually entered as a raw row-major string of length 16.
  • If the same word can be formed by two different combinations, only one combination is actually considered valid. This is overcome by storing a list of already found words in another Trie.
  • Even though the script finds smaller words first (because of BFS), it actually starts outputting words of length >= 5 first and then after it has exhausted all the lengthier words, it then outputs the smaller words in the reverse order of length (4,3,2). This is to maximize points in case we don't find time to output all the words.
  • The game offers three lifelines. I found the freeze option to be useful to the bot (as each freeze gives you 15 additional seconds of game time). So, the script automatically taps on the freeze lifeline every 30 seconds.
  • We also need to store the co-ordinate of each letter in the queue along with the letters themselves in order to simulate the output in the device.
  • The co-ordinates are hard-coded for Nexus 7 portrait mode.

Code

The whole implementation can be found here: https://github.com/vickyg3/scripts/tree/master/scramble_bot

Sample Video

Here is the exciting part. This is how it looks like when my bot plays the game:



It's always a very nice feelings to watch you script do such beautiful things.

-Vignesh

Wanna do some good deed? Visit http://www.computerkindness.org (Or look for the banner in the top-right of this page).

Saturday, April 20, 2013

C++ COW Craziness

Note: This isn't one of those Linus'ish articles that bitches about C++. I like C++ and I would just like to point out one of the many nuances in the language that could affect the performance of your program without your knowledge.


C++ STL's string class promises Copy-on-write. What that means is that, you can make as many copies of the string, but the actual memory duplication will happen only when one of the strings are actually written to (i.e.) no memory duplication will be made for copies that are made for pure reads. Or atleast that's what I thought, until I discovered today that, if you use the [ ] operator on the string, you rig the COW functionality of it forever. It is something that you normally don't do, but doing so could cost you a lot of performance. Let's run through an example.
string s1(1024 * 1024 * 16, 'g');
for(int i = 0; i < 1000; i++) {
  string s2 = s1;
}
This runs in 19 milliseconds. That's because (obviously) there are no actual copies made. Just 1000 pointers being created to the existing 16 megabytes of data. Now, lets try modifiying the copied string.
string s1(1024 * 1024 * 16, 'g');
for(int i = 0; i < 1000; i++) {
  string s2 = s1;
  s2[0] = 'v';
}
This runs in 4.3 seconds. That's right, from 19 milliseconds to 4.3 seconds for making 1000 actual copies of 16 MB of data. This is the expected behavior, a copy is done when you try to write to it. Next comes the weird part, consider the following code:
string s1(1024 * 1024 * 16, 'g');
for(int i = 0; i < 1000; i++) {
  string s2 = s1;
  s2[0];
}
Guess how much time this should take? Intuitively it seems like this should hit the COW fast path (i.e.) no actual copies, because there is no "write" here. This takes 4.3 seconds too! The problem behind the [ ] operator is that, you can easily stash away a pointer to some portion of the string and modify it later thereby screwing up the state. So, it is impossible to perform COW once you use the [ ] operator on a string. The following snippet illustrates this:
string s1("hello");
char *p = &s1[2];
string s2 = s1;
*p = 'v';
You see what happened there? You stashed away a pointer to the middle of the string and then tried to change it later after the copy. This is sort of an indirect write, and there is no way for the compiler to determine this. So, the moment is sees the [ ] operator, it removes the COW functionality for that string. One way to do such a read without rigging the COW functionality is to do a crazy cast like this:
string s1(1024 * 1024 * 16, 'g');
const_cast<const string &>(s1)[0];
for(int i = 0; i < 1000; i++) {
  string s2 = s1;
}
This snippet takes the fast COW path and runs in 20 milliseconds. The takeaway from this article is that, do not use the [ ] (or the .at()) operator on strings, especially large string that could be copied later on. Even though you think you're doing an harmless read, you are rigging the COW functionality of that string forever. You are paying the price for that pointer you stashed away (or may be even released long back) without knowing.

 -Vignesh

Saturday, June 23, 2012

Convert your keyboard into an Android game controller!

I have been gifted with a new android phone. It's the big G branded Galaxy Nexus. Its blazingly fast and awesome to use (especially after years of HTC Wildfire usage). Right from day one, i have been really addicted to this game called Temple Runner which wasn't compatible with my old phone.

The game is very straightforward to play and it involves only 4 different operations. Swipe up, left, right and down. Coming from a strong keyboard background, I was never 100% comfortable with touch interfaces as i was with keyboard. And these 4 operations sounded analogous to the accelerate, brake and turn operations while playing a racing game in the computer keyboard.

That got me thinking, is there a way to make the computer keyboard into a game controller for my Android phone? Turns out its fairly straightforward. In this post i'll explain exactly how to do that.

Ingredients
  • Android phone (obviously)
  • USB cable connected in debugging mode
  • Android SDK installed
  • Very very basic python english
There's a tool named monkeyrunner which enables us to send operations from the computer to the phone via a very simple Python API (monkeyrunner tool is a part of Android SDK). A sample code for a controller would look like this:

Code until line 7 is fairly straightforward to understand. The only thing that i would like to explain here is the device object. It is an object of the MonkeyDevice class. This class has all the API methods that you need to use in order to simulate the operations. For example, device.touch(100, 200, MonkeyDevice.DOWN_AND_UP) will simulate a touch event at co-ordinate 100, 200 (with the origin being top left). As simple as that!

You can find the detailed documentation of the monkey device class to know about other methods like drag, type, etc.

The full code which i used for playing Temple Run game is given below:


One point to note is that, the sys.stdin.read(1) line will read one character and wait for the enter key to be pressed. This could be annoying given that you are writing a game controller. In order to avoid the enter key press, if you are on linux run "stty raw" before running this script and if on windows use the getch function in msvcrt module.

-Vignesh

Friday, May 25, 2012

I'm Feeling Lucky!

I have completed my college life. No more exams, no more results, no more bunking first half and sleeping and lots of other things will be no more. At this point, I want to take some time out, share the experience of my amazing roller coaster ride and thank the people who mattered and have helped me get where I am today (and where I will be in a few months :-P).

The Dream

Just like every computer science student, I had a dream too. My dream started along a bit early. Right from my school days, I had two role models. I had only one dream. I found a few 6 year old messages in my gtalk log where i was cribbing to my friends about my dream of working at my dream company at its headquarters.

The Start

I got through a really good job during my on-campus placements. It is at this point most people get carried away, but somehow i managed to not fall into that trap and thereby miss my dream. I chose to do my final semester internship in another company so that I will have bandwidth to explore other options. Btw, the workplace where I am doing my internship is awesome (this place is so awesome that I just can't stop boasting about it whenever I talk of internships).


Ok coming back to the topic, naturally the first step was to prepare for other companies' interviews. I started doing that and decided to apply to a company by end of March. Thankfully, one of my friends knew a person there who could refer me and get me an interview (btw, my friend happens to be a really wonderful human being who has helped me whole heartedly whenever i needed any help. He also happens to be my college senior and i am heavily indebted to him!). Off went my resume into the company and i got an automated "thank you for your interest in us" email.

The Phone Call

Then the recruiter called me and was ready to set me up with interviews beginning with a phone screening. I was told I would get a call by 11 AM. The interviewer had some issues in dialing in my number so it got delayed by 10 minutes. One of the worst 600 seconds of my life where I was tensed to the core. Once the interviewer called me, time flew off. Einstein was right.

I felt quite confident. Eventhough i didn't nail the interview, I felt it was far away from being tagged along a tweet as #pathetic. Few days later, I got an email from my recruiter stating that I have cleared the phone screening and will have to visit their office in Hyderabad for on site interviews.

The Visit

I was plagued with sickness and was in a severe low health for a few days before the interview. They flew me from Chennai to Hyderabad on the evening before the interview. I have been informed that I would be picked up by a cab as soon as I landed at Hyderabad. That was the first "awe" moment of the trip. The cab driver was standing at the arrival lounge with a placard that had my name.


I couldn't have dinner that night, couldn't have breakfast on the day of the interview. Somehow i reached the office. The first thing I noticed was the sheer enormity of the Hyderabad office. It was just too good.

Thankfully Air India was flying that day!
Once I reached the office, I had to have a sticker with my name printed on it (a temporary id card sorta thing). Since it wouldn't stick to my t shirt, i had to stick it around my arm like a watch!



And then there were 6!

Then started the interview process. There were 6 rounds each comprising of 45 minutes to one hour. I had a lunch break in between for half hour and eventhough i couldn't eat much (because of my illness), i was totally mesmerized by the food court that they had. The interviews were over around 6 o clock in the evening and I came back to Chennai the same night. It was a long day and i was totally down with illness at the night.

The Wait

Next came the worst part, waiting for the results. I don't know what to write in this column, but there a few things and people that helped me overcome this strenuous period. My work at internship gave me some distractions but night times were a nightmare where I barely slept for 2 or 3 hours.

The Surprise

Then came the call on 17th May, stating that I have gotten through and that I will be intimated about the work location in a day or two. I was wonderstuck, I had no words to describe what it meant to me. I mean, it was my dream ever since from when I was at school. Fortunately, I was with the people I love when the call came and I could not have been more happier.

As it turns out, the call on May 17th wasn't the happiest moment in my life. That came a few days after, when I received my offer letter. It was a totally unexpected freaking surprise. My salary was mentioned in US dollars. I was searching the letter to know my work location (as I was most eager to know whether the work location would be Bangalore or Hyderabad). When I found it, my heart just froze, I mean, it just froze. It was my dream location. It was what I dreamed about in my school days. It was whose pictures I posted in Orkut years back when it was my dream.

It was a DREAM COME TRUE !

The People

None of this would have happened if not for the really supportive people around me. I have an amazing set of F.R.I.E.N.D.S from college and school. I really owe them for all their support over the past howmanyever years I have known them.

Another bunch of people whom I really owe a lot are my friends in twitter. It was one of the main reasons why I was able to achieve my dreams. Every discussion (the technical ones) I had in twitter had been a value addition to me. When I think of it, few people come to my mind immediately. Thanks a lot guys, eventhough we've hardly met in person, you are a vital part of my life.

Thanks are due to my parents who have been alongside me for every single decision I took in my life. They trusted me totally and I hope I have justified that trust to a certain extent now.

Apart from them, I sincerely thank all of you who have been a part of my life over the past 22 years. Without you people, I will not be where I am today.

Conclusion

I am joining my first full time job in a few months. I am living in dreams when i think of the fact that i am going to be working in the same place where people like Prabhakar Raghavan, Matt CuttsGuido van RossumJoshua BlochRobert Love (and not to mention Larry Page and Sergey Brin) work. My life cannot be more close to perfect than it is now. Once again, I sincerely thank each and every one of you!


I'm Feeling Lucky!

-Vignesh

P.S.: I have not mentioned about one very important person in this post. That is completely intentional and the reason for that being lack of words to describe what that person means to me. :-)

Saturday, May 7, 2011

Orkut Deja Vu - The Technical Side!


Its been almost two months now since I first launched "Orkut Deja Vu" - A series of web applications and a chrome extension that helps you move your memories from orkut to facebook. Personally, I think the application was a good hit. In this article i will try and explain the technical side of it and the various hurdles faced on the due course of development.


Note: This article is for the technically inclined and if you don't want the technical details and just want to use the application, visit http://orkutdejavu.foamsnet.com!


Java and My server!


To begin with it, my server is a VPS running linux with a humble 700MB RAM and a shared processor. My search for an Orkut API ended with orkut os client - An official API provided by Google. This is more of a library than an API and only the java implementation of the library was very sophisticated (though there were php implementations, they weren't that good). Ever since i started learning computer science, if there was one thing i hated, it was java (now don't even get me started about perl).


So there lied the first problem in front of my eyes: Running java in my server. I didn't want to take up the pain of setting up JSP for this sake and decided to just call the java program that does the orkut calls from PHP using shell_exec. I know it isn't a safe option, but since there is no user passed data and the calls are hard-coded, i was sure that there was no injection vulnerabilities. Yet this approach isn't very efficient as it spawns a separate java vm for every exec call, but it was a compromise that i had to make for not setting up a java based server.


OAuth - The headache!


The orkut library's OAuth implementation was really messy. Fortunately, it had a method to explicitly set an OAuth access token obtained from elsewhere. That said, I used Zend OAuth library in PHP to perform the 3 legged OAuth and use that access token in the java programs. There were totally four java programs: one each to fetch the user's orkut name, albums list, photos and scraps. The java programs printed the output as JSON if it was successful or nothing if there was an exception. PHP then parses that JSON. I used JSON so that all the escaping will be taken care by the JSON libraries and thereby ensuring safety of data transmission.


Photo Album Migrator


The photo album migration was quite straight forward without much hurdles. All i had to do was integrate the following: Image gallery, Facebook API, Orkut API and write some simple javascript that made AJAX calls to transfer the photos. This was quite a cakewalk as i was already very familiar with the Facebook graph API.



Scrapbook Downloader


Again, the programming side of this was quite straight forward. But there was one major challenge involved in designing this. The java program generates a html file containing the scraps which is then converted to PDF. HTML to PDF conversion is CPU intensive and hence needs to be done with care. I could have used a resource manager like Sun Grid Engine, but i did not want to make things complex for a simple job to be done. Also, the conversion is not done programatically by a library as all the PHP PDF libraries were memory-wise very expensive (a file with ~100 scraps always exceeded PHP's memory limit of 64MB). So, I used a external command line utility (wkhtmltopdf) to accomplish this conversion. Again it was a simple shell_exec with hard-coded arguments.




Testimonials Migrator


This was the really challenging part. There was no Orkut API that gave access to users' testimonials. But i didn't want to give up. I really wanted to pull off a tool that can migrate testimonials to facebook. So I thought of attacking this problem from the heart of orkut - the orkut website. Obviously, the first thing that came to my mind was a Google Chrome extension. The extension will inject a javascript into orkut.com website and add a "Post to Facebook" button beneath eacch of your testimonials.


The first hurdle in accomplishing this was that there were two versions of orkut (old and new) with different page structures. I didn't want to write two different scripts to handle the versions. Instead i wrote another script that detects the version and if it is new, it prompted the user to redirect to the older version in order to use the extension. The next job was to understand orkut's DOM so that I can place the buttons. This ended up being quite an easy job too.


Another glitch in chrome extensions is that we cannot specify images directly in CSS for content scripts(for e.g.: background: url(a.jpg); is not possible), as the CSS will run in the scope of the website. So, it has to be either done programatically using javascript or encode the image in base64 and hard code it in the CSS. I chose the first option. From this point, it was fairly straight forward. When the user clicks on the post button, store the corresponding testimonial using HTML5's local storage and create a new tab where the user can choose the posting options. Again, the facebook authentication and API usage here were simple as i had enough exposure already.


Epilogue


Though it seems like a simple app, huge amount of thoughts are put into every single aspect in design of the application and the entire development process was a fun journey with a great learning curve. This application has made me feel my web presence. Web is really a great platform for amateur developers like me. I have got around 20 new followers in twitter and a person from brazil appreciating me for this application. I have really been motivated a lot by this and hope to continue the same stride in creating usable applications as this one!


This post will not be complete without a heartfelt thanks to all those who supported me on due course of development and all those who used and shared this with your friends!


-Vignesh

Tuesday, April 19, 2011

The Social Network - Build it Google, We will Come!

I recently read an article about Larry Page taking over as the CEO of Google and sending an internal memo to googlers about 25% cut in their bonuses if Google didn’t do well in social arena this year. I was disturbed a lot ever since I read that and wanted to pour out my thoughts about a dream social network from Google. Yes, I frankly think Google can still do much better than Facebook.

A headnote, this article is totally how i view a Google social network shall be made possible. I have tried to think of it as practically as possible. Some of it may sound silly/stupid for expert readers, so kindly bear with me.

Orkut was the trend setter! - What went wrong?

Orkut was the first and most famous "social network" of all time. It came during the period where the term "social network" was not really defined. Orkut gave that term a definition. And it was doing really well especially in places like India and Brazil. Ever since Facebook came in, Orkut started to lose.

I, personally, would say that the reason why Orkut never caught on was because Google tried to remain professional. They probably wanted to stick to the Google style of doing things and in the process forgot that people just wanted to have fun and party on in the social network unlike other Google services where professionalism kept people happy. The best example i would like to quote is, Orkut did not have scrap threading for a long time and that was available even for SMS by the time Orkut added that. Naturally, we don’t want to roam around in a blazer/suit 365x24x7. Facebook realized it and they just let people do whatever they wanted to do, literally no restrictions whatsoever.

Sign of Innovation - Google Wave

Google then launched wave and claimed that "it is simply going to change the way people communicate". Well, we know how true it is from the fact that wave has been axed by Google few months back and is now residing in its open source home of Apache.


Build it Google - We will come!

Again, the problem with Google Wave has been that it was difficult for a layman to understand and use it on a day-to-day basis. Even when wave was axed, not a single layman cared about it, only computer professionals cared since the underlying technology and protocols were really well built. Yet again, Google had failed to capitalize the wonderful technology they built by coping it up to what everyone actually wanted. In short, Google tried to remain professional with wave too.

Sign of Desperation - Google Buzz

Then came Google Buzz, supposedly the "Twitter killer". One major factor that i feel Google doesn’t realize when building social products is that, You cannot force people down their throats to go Social. Yes, I love Twitter and can’t live without it but at the same time I don’t want to read my tweets in my Gmail inbox.


Build it Google - We will come!

Similarly, Google Reader is one of the most wonderful software ever built. But with literally no connection whatsoever, Google decided to tie Buzz with Reader. This tie up lead to nothing but junk in both Reader and Buzz. And when people wanted to opt out of Buzz, it resulted in loss all their Reader follow list too. Making it opt-in is a really good vision by Google and at the same time they should also make sure that the opt-out is cleanly done.

What next? Social + Google = ??

So can Google ever surpass the mountain, that is Facebook, and succeed in social like they did in search? My answer is, yes they surely can. Sure Facebook has some 600 million users but Google is no poor lad when it comes to userbase too. Infact, Google is still a more prominent part of our life than Facebook is. Conduct a poll asking "Which of the following can’t we live without - Facebook or Google?" and i bet the winner will be Google.

Imagine a social network that revolves around all of Google’s services. Imagine a service that aggregates all of gmail, youtube, reader, maps, picasa, talk, news, voice and even orkut. Google, if you can build a rock solid service that does this and add your typical magical touch to it, then definitely you can climb the mount everest that is Facebook. Add to this the crazy, yet possible, thought of Google acquiring Twitter and integrating Buzz with it seamlessly. By recitifying all the mistakes that it did in the social arena in the past and building such a clean and fun service, it can surely overpower Facebook.

Google’s userbase is much more loyal when compared to that of Facebook. Google, as a company, with its policies is much closer to our hearts than Facebook is. Identify Facebook’s problems and fix it. Facebook’s main concerns today are spam and privacy. I can’t think of a product other than Gmail that can handle spam so near to perfection. Also, Google Talk has been an integral part of Gmail and Orkut for so many years now and not once we have seen any spam in it that can even be compared with the Facebook chat spam we have these days. Though Google have had their own share of controversies regarding privacy, they have somehow held on and been in the good books of their users when it came to privacy.


Build it Google - We will come!


Of course all this is not going to be an overnight affair, it is going to take lots of effort and time. Given that Google is investing so keenly on getting that top spot in the social arena, proper focus, being unprofessional and learning from the past are the key factors that will decide the fate of Google in the social arena. They can’t afford to flop anymore. This may be Google’s last chance to make an impact. By heart, i sincerely hope that Google can just snatch that number one spot in the social arena!

So, my message is short and simple: "Build it Google - We will come!".

-Vignesh

Wednesday, March 23, 2011

Scripting vs Programming - Mastering the art of arts!

Why this post?

The line of difference between a script and a program has become very blurry these days to the extent that these terms are used interchangeably. Though there is no hard and tight way to theoretically define what a script is and say how it is different from a program, if you have done a lot of programming and if you are a person who loves to automate things, then you can definitely realize the clear line of difference between scripting and programming. In this article, I try to give my views on what scripting is, how it differs from programming, etc. (Whole of this article just represents my view and there is a good chance that some of it may be wrong).

What is a script?

A script is just a small piece of code, usually written in a non-traditional programming language (like bash or perl) that is used to get a job done. Well, sure you can’t see much of how it differs from the definition of a "program". That is what i try to explain on the due course of this article.

How does it differ from a program?
As i said earlier, there is no concrete set of rules to distinguish a script and a program. The main deciding factors are:
  • the purpose with which its developed
  • the design mechanism underwent on due course of development, and
  • the person who uses it

Scripts are generally very specific to their task. They just do what is to be done, nothing more or nothing less. Whereas programs generally have a broad scope. They are more sophisticated and usually do much more than what they are supposed to do. This is the difference with respect to the first point.

Scripts generally don’t follow any design. Scripts are usually just written, with no design in mind whatsoever. Even if they are complex, they aren’t designed with care and concern. Whereas programs on the other hand are designed to work with a proper flow and fault tolerance. Scripts are usually used by programmers themselves internally, whereas programs are full fledged tools that are used by everyone from geeks to laymen. To state an example, Facebook is a "program" and if you build something that will scrape data off facebook in the format you want, then that could be a "script".

Scripting is usually considered as programming as a part of developing an actual program. For example, the recent android patent issue says Google used a "script" to clean up all the comments and other stuff from the kernel header files. So, scripts can be generally categorized as utility functions that helps you making your "program" development easier.

What’s a scripting language?

Again, a scripting language is a programming language that is generally non-traditional. Scripting language usually provides constructs for doing things in the quickest way possible rather than in the most efficient way possible (For e.g. most of the scripting languages usually have a sort() function to sort the data. Though they may not be the most efficient implementation of sorting data, it gets the job done without fuss). Another aspect is that scripting languages are usually interpreted and not compiled. This gives the assurance that the script dies if anything goes wrong, the script starts over all again, taking advantage of the fact that scripts need not provide any atomicity over what they do.

Uses of scripting

I love automating things i do and hence scripting is a very essential part of my online life. Scripts can help your online life get much easier and better. For example, i have various little chrome content scripts (google chrome’s equivalent of greasemonkey scripts) that helps me make my day-to-day browsing easier and more productive. Also, i extensively use sed and awk scripts to browse through log files generated by the programs i develop. I even have scripts that help me check if there are new episodes of my favorite TV Serials (BBT, HIMYM) available for download and alert me.

When it comes to automating day to day online tasks, scripting is your swiss army knife. You can accomplish things quickly and in the way you want them to be.

Scripting as an art

We all know that programming is more of an art than a science. Developing a perfect program is close to impossible. But scripting too is an art that can aid you in making your programming life much better. Learning a scripting language at the beginning may seem weird, but once you get used to the constructs, it will really be a cake walk and you will find it a lot useful to have it as one of your assets.

To sum up..

Scripting and programming always go together. Scripting aids in automating things that will make a program better than what it is now. Though only a beginner, my humble piece of advice to every programmer out there is "Never hesitate to automate things. You learn a lot while automating silly things! So next time when you come across a silly problem in your work or in your project, try to tackle it with a quick utility script rather trying to fix it manually!"

-Vignesh

Wednesday, March 16, 2011

Introducing Orkut Déjà Vu! - Orkut to Facebook Photo Album Migrator!

As we all know, Orkut was the trend setter of the modern "Social Networks". Few years back, Facebook took over that top spot in social networks from Orkut. Yet we all have lots of sweet memories stuck with Orkut in the form of Scraps, Photo Albums, Testimonials, etc. This website helps you pull out your old memories from Orkut and make them brand new by moving them over to Facebook!



This is just a night time project that i have been working on for almost a month now!

I don't want to bore you with stories. Try out the app straight away here: http://orkut.foamsnet.com or http://orkutdejavu.foamsnet.com

I am sure there are plenty of bugs. Please email me at vig..@gmail.com(click to expand) for any comments/feedbacks!

-Vignesh

Saturday, February 26, 2011

Why Plagiarism Hurts?

I recently attended a so called "online programming contest" of one of the premier institutions in the state (not mentioning the name to not stir any arguments over it - I tweeted it here and here though). I have been attending this contest since the past 3 years and was highly disappointed about this year's event.

The reason is, as the title suggests, it was nothing but a blatant ramp of plagiarism. There were totally 8 questions to be solved out of which 4 questions were mere "copy-paste" jobs from spoj. Such events need not be perfect, but when you conduct an event of such stature you are atleast expected to make sure that google doesn’t give an exact match for the questions you give. As i mentioned in the tweet, the other 4 questions were very poorly worded and more or less dumb. Anyways, i am not going to ramble about the contest in this post. But it got me thinking, plagiarism can really hurt. It can hurt both the ends of users badly.

First things first, what is plagiarism? Sounding like a fancy GRE word, it has a simple meaning: Copying someone else’s content without their consent. I know spoj doesn’t mind if their questions are being copied, but it should either be altered so that it doesn’t look like the original question or (even and) spoj should have been properly cited.

When someone writes something on the internet these days, it has become like they have lost complete ownership over it. Plagiarism is a very big problem these days. It exists on all levels. Starting from a simple online programming contest to industry definers like Microsoft. Google even launched an algorithm change to their core search engine algorithm this week that ranks plagiarised pages lower than pages with original content.

My point is, when you plagiarise something without consent and citations, its not just a matter of two keystrokes in your computer. You hurt people’s feelings. And you will never understand those feelings unless you start writing something on your own and someone else copies and pastes it without your consent. It takes very little effort to cite the original source of any content you use, but that gesture will make your users respect you more than they did before.

There are even licensing policies that helps you prevent plagiarism and at the same time lets you use others content (one such license is Creative Commons License).Always place appropriate citations. If an author is writing content on the internet, then he’d sure respond to you via email/twitter if you want to use pieces from his article. Be gentle and place the credit to the work where the credit actually belongs to rather than stealing it. You will definitely be insulted when the plagiarism is spotted. So why not place credit and not screw up your reputation? You may have loads of original content. But even a small piece of plagiarised content is capable of bringing you under the spotlight (the recent Ankit Fadia scam for example - Fadia may have saved a war or billions of rupees for the indian government, but now he’s been registered in my mind as the guy who copied a book in the name of authoring it).

To sum up things, The world has evolved, Internet has become commonplace but what will always remain is the human values that we possess. If you copy content without consent, you are violating the human values that morally governs the internet.

Take a stand, Say no to plagiarism, Innovate the planet together!

-Vignesh