<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;DkAFR34zeSp7ImA9WhRUF04.&quot;"><id>tag:blogger.com,1999:blog-7520738</id><updated>2012-01-28T12:41:56.081+05:30</updated><category term="logging" /><category term="bitwise" /><category term="class_diagrams" /><category term="video stanford compsci" /><category term="design_patterns" /><category term="kay" /><category term="singleton" /><category term="junit" /><category term="ranges" /><category term="mock_objects" /><category term="competition" /><category term="design_principles" /><category term="exceptions" /><category term="java applets 64-bit linux" /><category term="grails" /><category term="inheritance" /><category term="translating" /><category term="git" /><category term="grep" /><category term="android api" /><category term="video" /><category term="performance" /><category term="unicode" /><category term="polyglot_programming" /><category term="eclipse" /><category term="interactions" /><category term="strings" /><category term="newline" /><category term="closures" /><category term="training" /><category term="DockingFrames" /><category term="interpolation" /><category term="android_architecture video" /><category term="earning" /><category term="control_structures" /><category term="djano serialization python json" /><category term="linux eeepc" /><category term="xml" /><category term="helloworld" /><category term="CSS" /><category term="refactoring" /><category term="reference_types" /><category term="git partial_add" /><category term="teaching internet blogs podcasts new_media" /><category term="CVS" /><category term="faq" /><category term="learning_jsf" /><category term="gant" /><category term="misc" /><category term="stallman" /><category term="online" /><category term="vnc gnome" /><category term="timeboxing" /><category term="dojo" /><category term="hsqldb" /><category term="android application_lifecycle" /><category term="custom_component" /><category term="groovy" /><category term="software" /><category term="coding" /><category term="templating" /><category term="design" /><category term="final" /><category term="podcasting" /><category term="methods" /><category term="requirements" /><category term="blogging" /><category term="erasure" /><category term="object_oriented" /><category term="simplicity" /><category term="blogcamppune" /><category term="education" /><category term="podcast" /><category term="public" /><category term="test_driven development" /><category term="slashy_string" /><category term="DRY" /><category term="lists" /><category term="gc" /><category term="map" /><category term="types" /><category term="microisv" /><category term="android webview" /><category term="iAccelerator" /><category term="classloader" /><category term="unconference" /><category term="feedback" /><category term="agile" /><category term="screencasts" /><category term="python" /><category term="browser" /><category term="android apps_are_equal" /><category term="DWR" /><category term="jsf_intro" /><category term="polymorphism" /><category term="learning" /><category term="encapsulation" /><category term="alan" /><category term="comments" /><category term="javacvs" /><category term="teaching" /><category term="sharing" /><category term="coupling" /><category term="math" /><category term="python design_patterns" /><category term="static" /><category term="programming" /><category term="itvidya" /><category term="android parrallel" /><category term="metaprogramming" /><category term="goals" /><category term="website" /><category term="Java" /><category term="book" /><category term="quiz" /><category term="Boolean" /><category term="thread" /><category term="high_cohesion" /><category term="JDBC" /><category term="jquery" /><category term="beans" /><category term="certification" /><category term="inner_classes" /><category term="generics" /><category term="abstraction" /><category term="composition" /><category term="groovy grails unittest" /><category term="android apps_without_borders" /><category term="software_design" /><category term="double_checked_locking" /><category term="iptables" /><category term="numbers" /><category term="conventions" /><title>CODING INSIGHTS</title><subtitle type="html">Parag Shah's notes on stuff he learns while coding</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>244</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/adaptivesoftware" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="adaptivesoftware" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">adaptivesoftware</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;Dk8CRHg9eCp7ImA9WhZUE0g.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7610876492027781737</id><published>2011-06-06T13:45:00.004+05:30</published><updated>2011-06-06T15:37:45.660+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-06T15:37:45.660+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="microisv" /><title>Running your own one person company</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TxT0PqInFULKA57oGHBZY9ohIbc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TxT0PqInFULKA57oGHBZY9ohIbc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TxT0PqInFULKA57oGHBZY9ohIbc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TxT0PqInFULKA57oGHBZY9ohIbc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Recently there was a post on PuneTech on mom's re-entering the IT work force after a break. Two of the biggest concerns mentioned were :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Coping with vast advances (changes) in the IT landscape&lt;/li&gt;&lt;li&gt;Balancing work and family responsibilities&lt;/li&gt;&lt;/ul&gt;Since I have been running a one person company for a good amount of time, I suggested that as an option. In this post I will discuss various aspects of running a one person company.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Advantages:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;You have full control of your time. You can choose to spend as much or as little time as you would like. There is also a good chance that you will be able to decide when you want to spend that time. &lt;/li&gt;&lt;li&gt;You get to work on something that you enjoy doing. Tremendous work satisfaction.&lt;/li&gt;&lt;li&gt;You have the option of working from home.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;b&gt;Disadvantages:&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;It can take a little while for the work to get set, so you may not be able to see revenues for some time.&lt;/li&gt;&lt;li&gt;It takes a huge amount of discipline to work without a boss, and without deadlines.&lt;/li&gt;&lt;li&gt;You will not get the benefits (insurance, etc) that a company would give you.&lt;/li&gt;&lt;li&gt;Your finances may or may not show a constant graph.&lt;/li&gt;&lt;li&gt;You may have a hard time getting home loans, since most banks (especially in India) feel that employed people are more stable (whatever that means :-) )&lt;/li&gt;&lt;li&gt;People may think you are not doing &lt;b&gt;&lt;i&gt;real work&lt;/i&gt;&lt;/b&gt; (most people have a very skewed notion of what real work means)&lt;/li&gt;&lt;li&gt;You will have to deal with distractions, if you are working from home.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Even though the disadvantages outnumber the advantages, qualitatively I think the advantages are vast. I may be a bit biased, but I really think that a 9 - 5 job in a large organization, totally sucks the soul out of a person.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Legal&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I will restrict this advise to India, whose laws I am accustomed with. You do &lt;b&gt;not&lt;/b&gt; need to register any legal entity to run  a one person business. You can run it on your own name, you can raise invoices on your own name, and you can file your taxes on your personal PAN number.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some people may create a sole proprietorship, but that is purely to have a business name and to be able to invoice clients on a business name, rather than your personal name. Besides this, having a sole proprietorship has the advantage of being able to easily separate personal and business accounts. The latter can be achieved simply by keeping a separate savings account for work related transactions. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some people may also choose to create an LLP. Besides the points mentioned for sole proprietorship,an LLP will shield your personal finances against business losses, lawsuits, etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will not get into the legalities of creating a sole proprietorship, or LLP. My suggestion is to start work on your personal name, and create a legal entity later, if required. You should consult your CA for details of creating a business entity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Types of work&lt;/b&gt;&lt;/div&gt;&lt;div&gt;There are many types of work that can be done as a one person business. I will focus on IT related fields in this post. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Freelancing:&lt;/b&gt; &lt;/div&gt;&lt;div&gt;Many people make a living by doing freelance projects. You can either get projects directly from clients, or you can work on one of many freelancing websites. These websites publish projects that people want completed. If you feel that you can do the project, then you can bid for it. If you get the project, you will have to complete it in the stipulated time, and with the required features. The payment usually comes once the client is satisfied with the work. Most of these websites allow the client as well as the developer to rate each other. These ratings go a long way in determining whether a client will give you projects.  Typically a freelancing website have work related to coding, documentation, website design, etc. Some such websites are: &lt;a href="elance.com/"&gt;Elance&lt;/a&gt;, &lt;a href="http://www.vworker.com/?txtFromURL=AId_7889766"&gt;vWorker.com&lt;/a&gt;, &lt;a href="http://freelanceswitch.com/"&gt;FreelanceSwitch&lt;/a&gt;,  &lt;a href="https://www.odesk.com/"&gt;ODesk&lt;/a&gt;, and &lt;a href="http://www.freelancer.com/affiliates/adaptives/"&gt;freelancer.com&lt;/a&gt;. &lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;(Disclosure: I will get a small commission if you register on some of these websites, following the provided link)&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Regardless, of whether you get projects from a freelancing website, or on you own, you should always have your own website, and a blog. I cannot stress how important it is for a freelancer to have a blog. Your blog is the place where potential clients and friends get a glimpse of the real you. It is also your showcase for projects completed, and an online portfolio.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;Contract programming:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you have been in the software industry for a long while, then you probably already have a lot of contacts who would like to give you some contract programming work. This can also be lucrative and fun. In contract programming you typically make a commitment (such as 20 hours per week), and charge on an hourly rate.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Teaching:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If have passion for sharing your knowledge with others, then teaching is a wonderful way to do satisfying work and earn a livelihood. There are various avenues for teaching. You can teach in a local college, you can teach at companies, or you can teach on the Internet. You can also do all of these if you desire. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some places you can create courses and teach on the web are, &lt;a href="http://edufire.com/"&gt;edufire.com&lt;/a&gt;, and &lt;a href="http://wiziq.com/"&gt;wiziq.com&lt;/a&gt;. You can also create your own website for teaching using &lt;a href="http://www.moodle.org/"&gt;Moodle&lt;/a&gt;, or a similar open source software. I have created my own &lt;a href="http://diycomputerscience.com/"&gt;website for teaching computer science&lt;/a&gt;, but I am not yet making any significant revenue from it, so beware before you take it as a role model :-) However, you can check out this website of a &lt;a href="http://use-the-index-luke.com/"&gt;database expert&lt;/a&gt; who maintains a learning community on his website.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can also create and sell screencasts like the people at &lt;a href="http://peepcode.com/screencasts"&gt;Peepcode&lt;/a&gt;, and &lt;a href="http://destroyallsoftware.com/"&gt;Destroy all software&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; I think there is a lot to be said about teaching, and it probably warrants a separate blog post.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Creating mobile applications:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Many people make a living by creating mobile applications, for Android, iPhone, etc. The amounts vary, but it is very much do-able. Several people give helpful tips and also post there monthly incomes on their blogs. You might find them useful. This is &lt;a href="http://www.kreci.net/"&gt;one example website&lt;/a&gt; of an independent developer who posts monthly incomes and also gives helpful tips.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Creating stock photos, and designs:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you are the arty type, you can create stock photos, images, or icons, and put them up for sale on stock photo websites. There are many such websites, and some people are able to make a good continuous stream of income from them. &lt;a href="http://www.istockphoto.com/"&gt;iStockPhoto&lt;/a&gt; is one such website. You can also create designs for clients on sites like &lt;a href="http://99designs.com/"&gt;99designs.com&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Selling websites:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you enjoy making and selling websites, you can make and auction your websites on &lt;a href="https://flippa.com/"&gt;Fippa.com&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Niche websites:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you are really passionate about something, and also have a lot of knowledge in that field, then you can share your knowledge on a niche website, and earn revenues from advertisements, affiliate sales, subscriptions, etc. See &lt;a href="http://www.smartpassiveincome.com/nichesiteduel/"&gt;this blog post&lt;/a&gt; on information about building niche websites.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;E-Commerce:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you have something to sell, you can also set up shop using a hosted e-commerce solution. However, keep in mind that managing logistics, shipping, handling, and customer care may be more than what one person can handle.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I hope you found this post useful. This is a brief list of things that can be done as a one person entity, and some pointers on how to go about doing it. I think plenty more can be said on this topic. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will try and write further blog posts talking about each of these points in greater detail. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7610876492027781737?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7610876492027781737/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7610876492027781737" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7610876492027781737?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7610876492027781737?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2011/06/running-your-own-one-person-company.html" title="Running your own one person company" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>4</thr:total></entry><entry gd:etag="W/&quot;D0cARHg8cCp7ImA9WhZQGU0.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7678593585766294222</id><published>2011-04-27T17:17:00.001+05:30</published><updated>2011-04-27T17:20:45.678+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T17:20:45.678+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="hsqldb" /><title>My HSQLDB schema inspection story</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/fHCxa1cJsOUhI6TaGyUt_qGsA6c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fHCxa1cJsOUhI6TaGyUt_qGsA6c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/fHCxa1cJsOUhI6TaGyUt_qGsA6c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fHCxa1cJsOUhI6TaGyUt_qGsA6c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This is a simple story of my need to inspect the schema of an HSQLDB database for a participar FOREIGN KEY, and the interesting things I had to do to actually inspect it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I am using an &lt;a href="http://hsqldb.org/"&gt;HSQLDB 1.8&lt;/a&gt; database in one of my web applications. The application has been developed using the &lt;a href="http://www.playframework.org/"&gt;Play framework&lt;/a&gt;, which by default uses &lt;a href="http://www.oracle.com/technetwork/articles/javaee/jpa-137156.html"&gt;JPA&lt;/a&gt; and &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt;. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;A few days back, I wanted to inspect the schema which Hibernate had created for one of my model objects. I started the HSQLDB database on my local machine, and then started the database manager with the following command&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;java -cp ./hsqldb-1.8.0.7.jar org.hsqldb.util.DatabaseManagerSwing&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;When I tried the view the schema of my table, it showed me the columns and column types on that table, but it did not show me columns were FOREIGN KEYs.&lt;br /&gt;&lt;a href="http://tinypic.com?ref=2rgm353" target="_blank"&gt;&lt;img src="http://i52.tinypic.com/2rgm353.jpg" border="0" alt="Image and video hosting by TinyPic"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;i&gt;Image 1: Table schema as shown by HSQLDB's database manager&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I decided to search on &lt;a href="http://www.stackoverflow.com"&gt;StackOverflow&lt;/a&gt; and find out how I could view the full schema of the table in question. I got a few hints, and they all pointed to the system tables, so I decided to turn on the "show system tables" option from HSQLDB's view menu.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The first table that caught my eye was &lt;strong&gt;information_schema.system_tables&lt;/strong&gt;, so I fired the query:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select * from information_schema.system_tables;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;This gave me all the system as well as application tables, but did not give me the detail I was looking for, which was the FOREIGN KEY contstraints on the 'USERREGISTRATIONDATE' table.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The next table that caught my eye was &lt;strong&gt;information_schema.system_table_constraints&lt;/strong&gt;, so I fired the following query:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;select * from information_schema.system_table_constraints where table_name = 'USERREGISTRATIONDATE';&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;This helped a bit further. It told me that the &lt;strong&gt;USERREGISTRATIONDATE&lt;/strong&gt; table had a FOREIGN KEY and the constraint name was 'FK98DCB61247140EFE'.&lt;br /&gt;&lt;a href="http://tinypic.com?ref=15gjlc" target="_blank"&gt;&lt;img src="http://i55.tinypic.com/15gjlc.png" border="0" alt="Image and video hosting by TinyPic"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;i&gt;Image 2: Result from table INFORMATION_SCHEMA.SYSTEM_TABLE_CONSTRAINTS&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Nice, but it still did not tell me which column the constraint refered to.&lt;/div&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The next table I came across was &lt;strong&gt;information_schema.system_crossreference&lt;/strong&gt;. This seemed to have a column called 'FK_NAME'. Good, I fired the query:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;select * from information_schema.system_crossreference where FK_NAME='FK98DCB61247140EFE';&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Here is what this table showed me...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;a href="http://tinypic.com?ref=675b1f" target="_blank"&gt;&lt;img src="http://i56.tinypic.com/675b1f.png" border="0" alt="Image and video hosting by TinyPic"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;i&gt;Image 3: Result from table INFORMATION_SCHEMA.SYSTEM_CROSSREFEREBCE&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Awesome, this time it showed me the name of the the FOREIGN KEY 'FK98DCB61247140EFE' references the 'ID' column of table 'USER'&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I finally had my answer, but before ending this post, let me mention just one more thing. I realized that I did not need the information_schema.system_table_constraints table at all. I only needed the information_schema.crossreference table with the following query:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;select PKTABLE_NAME, PKCOLUMN_NAME, FKTABLE_NAME, FKCOLUMN_NAME &lt;br /&gt;from information_schema.system_crossreference &lt;br /&gt;where FKTABLE_NAME='USERREGISTRATIONDATE' and FKCOLUMN_NAME='USER_ID';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tinypic.com?ref=25hhjq1" target="_blank"&gt;&lt;img src="http://i53.tinypic.com/25hhjq1.jpg" border="0" alt="Image and video hosting by TinyPic"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;i&gt;Image 4: Finally the query that clearly showed me the FOREIGN KEY&lt;/i&gt;&lt;/div&gt;&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Now all this should not have been so time consuimng. The GUI tool should have given me this information right away.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7678593585766294222?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7678593585766294222/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7678593585766294222" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7678593585766294222?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7678593585766294222?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2011/04/my-hsqldb-schema-inspection-story.html" title="My HSQLDB schema inspection story" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://i52.tinypic.com/2rgm353_th.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEECQ384cCp7ImA9Wx5UEUs.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-2439163575941477024</id><published>2010-10-15T15:49:00.007+05:30</published><updated>2010-10-15T22:41:02.138+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-15T22:41:02.138+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="singleton" /><category scheme="http://www.blogger.com/atom/ns#" term="double_checked_locking" /><title>Double Checked Locking And Java Singletons</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/OYyPQJHwFM4LqIoHB8KWlKOoBO8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OYyPQJHwFM4LqIoHB8KWlKOoBO8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/OYyPQJHwFM4LqIoHB8KWlKOoBO8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OYyPQJHwFM4LqIoHB8KWlKOoBO8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I read this &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html"&gt;article&lt;/a&gt; by &lt;a href="http://www.cs.umd.edu/~pugh/"&gt;Bill Pugh&lt;/a&gt; on why the &lt;cite&gt;double checked locking&lt;/cite&gt; idiom does not guarantee thread safety in Java Singletons. That article taught me a lot of new things, and to be honest, I had to re-read that article at least a couple of times to partially understand it :-)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I recently created a presentation to make at DevCamp on this topic. What follows are my slides and an explanation of each slide. I hope you enjoy this presentation and find it useful.&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px" id="__ss_5450422"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/parag/double-checkedlockingjavasingletons" title="Double checkedlockingjavasingletons"&gt;Double checkedlockingjavasingletons&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse5450422" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=doublecheckedlockingjavasingletons-101015051343-phpapp02&amp;amp;stripped_title=double-checkedlockingjavasingletons&amp;amp;userName=parag"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed name="__sse5450422" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=doublecheckedlockingjavasingletons-101015051343-phpapp02&amp;amp;stripped_title=double-checkedlockingjavasingletons&amp;amp;userName=parag" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/parag"&gt;parag&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;slide 1:&lt;/b&gt; &lt;/div&gt;&lt;div&gt;In this presentation I will discuss the &lt;cite&gt;double checked locking&lt;/cite&gt; idiom, and explain why it does not work to provide thread safety to Java Singletons. I will also talk about how using volatile fields will fix the problem in JDK 1.5 onwards.&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 2 (Singleton):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Many of you might already have used the &lt;a href="http://sourcemaking.com/design_patterns/singleton"&gt;Singleton design pattern&lt;/a&gt;. In case you have not, here is a brief description of what Singletons are. The Singleton pattern is used when we want to ensure that there is only one instance of a class per something. In most cases, the something is 'JVM - Classloader' combination. So, in such cases we want to ensure that there is only one instance of the Singleton class in the JVM-Classloader. But we are not restricted to this. We may need only one instance of the Singleton per Session, or per Request, or per anything else that makes sense in the software you are making. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is clear that we want to control the instantiation process of the Singleton class. To do this, the first thing we do as shown in the example is to make the constructor private. With the constructor private, no other class can create an instance of this class. OK, so how will we create &lt;b&gt;&lt;i&gt;any&lt;/i&gt;&lt;/b&gt; instance of this class? We provide a public static method called &lt;code&gt;getInstance()&lt;/code&gt; which will return an instance of this class. We will also use a private static field called instance to hold the one and only instance of this class. Since we control the &lt;code&gt;getInstance()&lt;/code&gt; method, every time it is invoked we will return instance. The first time however, &lt;code&gt;instance&lt;/code&gt; will not be initialized, so we put a null check in &lt;code&gt;getInstance()&lt;/code&gt; and instantiate &lt;code&gt;instance&lt;/code&gt; if it has not already been instantiated. Hence forth we will always return a reference to &lt;code&gt;instance&lt;/code&gt;. This way we ensure that only one instance of our Singleton will be ever created (the one we save in the field called &lt;code&gt;instance&lt;/code&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 3 (Is This A Safe Singleton?):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Look at the class carefully and ask yourself "Is this Singleton safe?"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 4 (The Singleton is not Threadsafe):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you have looked at the class carefully, you will realize that the Singleton is not thread safe. This slide shows why it is not thread safe. Imagine that a thread T1 invokes &lt;code&gt;getInstance()&lt;/code&gt;. If an instance of the Singleton has not been created till now, then &lt;code&gt;instance&lt;/code&gt; will be null, and T1 will enter the if block. Now imagine that T1 gets pre-empted, and thread T2 also calls &lt;code&gt;getInstance()&lt;/code&gt;. Since T1 got pre-empted before it got a chance to create &lt;code&gt;instance&lt;/code&gt;, the reference in &lt;code&gt;instance&lt;/code&gt; is still null. So T2 will also enter the if block. Now if T2 does not get pre-empted then it will go ahead all the way where it will create an instance of Singleton, and probably even use it. Now when T1 is resumed, unfortunately it does not know that the Singleton has already been created, since it has already gone past the null check. T1 will also happily create an instance of our Singleton, thus breaking the Singleton pattern. We have 2 instances of the Singleton which is simply not allowed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 5 (Let;s Make It Threadsafe):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Alright so we need to make the &lt;code&gt;getInstance()&lt;/code&gt; method thread safe. The simplest way to do this is by making it synchronized. Once it is synchronzied, only one thread will be allowed to enter the method at a time, and we will never get into an issue where we end up having multiple instances of the Singleton.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 6 (That Was Expensive):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Making a method synchronized is expensive. A thread executing a synchronized method must acquire a monitor before it can invoke the method, and release the monitor after executing the method. This takes time and CPU cycles. In early JVM's (I have read somewhere), the time to invoke (not execute) a synchronized method was as much as 100x the time taken to invoke a non synchronized method. I think this was improved in later JVM's where it was about 15x. I recently did a quick test on JDK 1.6, and the number I got was 2x. Regardless of how much slower it is, it is definitely slower, and programmers always want to make their code fast.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 7 (Let's Use Double Checked Locking):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Some very smart programmers came up with the "double checked locking" idiom to relieve the code of this expensive operation. What we really should have done, is only synchronize the code which instantiates the Singleton, and not the entire method. That way we incur the expense of the synchronized block only once, when the Singleton needs to be created, and all subsequent times (instance == null) will always be false, and the instance will be returned to the calling code.  We put a second check inside the synchronized block, because it is possible that a thread could get pre-empted just after the first null check, but before it enters the synchronized block. In such a case, if another thread enters this method, and goes all the way to creating the instance then the first thread will not know of it and will create a second instance. To prevent this, we put another check in the synchronized block. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So this is a pretty smart solution. We eliminate the synchronization on the method, thus eliminating synchronization on the main path.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 8 (Will It Work?):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The solution described in the previous slide (double checked locking) is a pretty smart solution. But it does not work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 9 (Why?):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;There are two reasons why it does not work. The compiler as well as the processor (as well as the JVM) may reorder instructions if they feel it might be more optimal. Off course they cannot randomly reorder instructions but they could if they can prove that the reordering will maintain as-if-serial semantics. However, this is not the only reason. On a multi-processor system, each processor has it's own memory cache. The cache is not always synchronized with main memory immediately. This can cause a write to a memory location to happen in the local cache, which will not be visible to other threads which could be running on other processors. Even if the writing thread does flush it's local cache, it is still possible that another thread which reads that value, may not have pulled in most recent values from the main memory into it's local cache. This can cause a situation very similar to reordering where the effect of a write is not visible to another thread that is reading that variable's value.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 10 (instance = new LoneRanger(””)  !=  Atomic operation):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;If you look at the example in slide 7, you might think that the statement below is an atomic statement.&lt;/div&gt;&lt;div&gt;instance = new LoneRanger();&lt;/div&gt;&lt;div&gt;But that is not the case. For the sake of simplicity this slide shows the statement above broken into 2 operations. In the first part, an instance of the class is constructed, and in the second part a reference to that instance is assigned to the variable instance.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 11 (Compiler Reordering):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Now what if the compiler reorders the instructions in such a way that the field instance is assigned an uninitialized block of memory (created for the class LoneRanger), and then the constructor of LoneRanger is invoked in the second step. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 12 (Compiler Reordering Pseudocode):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This slides shows pseudocode to understand the effect of compiler reordering on the &lt;cite&gt;double checked locking&lt;/cite&gt; code. The code in the synchronzied block which instantiates our Singleton is broken into two steps: assignment, and initialization, where the assignment happens before the initialization.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now imagine thread T1 enters the &lt;code&gt;getInstance()&lt;/code&gt; method, enters the synchronized block and executes the statement which assigns the block of memory allocated for LoneRanger to the variable called instance. If T1 gets preempted and thread T2 enters &lt;code&gt;getInstance()&lt;/code&gt; then T2 may see a non null value for instance. Thus T2 will actually be returned an initialized object of LoneRanger. This could cause all sorts of bugs in the software.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So in the first problem described a few slides back, we ran into the issue of having multiple instances of our Singleton, which we attempted to fix with the &lt;cite&gt;double checked locking&lt;/cite&gt; idiom. However, this introduced the issue where a thread might be given a reference to an uninitialized instance of the Singleton.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 13 (Can We Prevent reordering):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Programmers never give up :-) When an even smarter programmer was explained this problem, he remarked "so let us prevent reordering and our problem will be solved !". Ok let's try that, but how do we prevent reordering? Well there is something called a memory barrier, which may help us. Instructions cannot be reordered across memory barriers (although they may be reordered within a memory barrier). Let's see if we can introduce memory barriers to prevent the reordering that's been giving us such a hard time till now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 14 (Memory Barrier):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;A memory barrier is a low level (at the level of the processor) construct which is used to create a fence around instructions. Instructions which are fenced inside a memory barrier cannot be moved out of the fence, and memory caches are also synched with main memory when a memory barrier is encountered.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 15 (Memory Barrier):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This slide explains memory barriers with an illustration. In this slide notice that instructions (instr2, instr3, &amp;amp; instr3) are fenced with the memory barrier. Because of the semantics of a memory barrier these instructions can never be moved out of the barrier, but they may be re-ordered within the memory barrier. We can also see when the memory barrier is entered the local processor cache is invalidated and latest values are read from the main memory, and when the memory barrier is exited then the local cached is flushed and the main memory is updated with the latest values.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;slide 16 (Memory Barrier):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Because memory barrier is a low level construct, there is no way to explicitly create one in a high level language like Java. However, the synchronized keyword in Java implicitly creates a memory barrier. Before I read this, I had no clue that synchronization in Java is anything more than a mutex. But I read somewhere that when a monitor is obtained an memory barrier is also created and when a monitor is released the memory barrier ends (this is my understanding, please correct me if this is wrong).&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 17 (Double Checked Locking With Memory Barrier):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The fact that assignment and construction of our Singleton could be reordered created the issue of potentially having an uninitialized Singleton. We want to ensure that the reordering does not happen. For that let us separate the construction and assignment with a memory barrier and put the assignment after the construction. We do this with 2 synchronized blocks and a temporary variable. In the inner synchronized block we will initialize the Singleton and assign it to a temporary variable. We don't care if this is reordered, because the class variable instance will still be null which will prevent another thread from getting an initialized instance of the Singleton. Then we assign the reference to the temporary variable to the class variable instance. This happens outside the memory barrier. So by employing a memory barrier we are hoping to maintain program order in the execution of instructions. Again a very smart solution, but unfortunately this does not work either.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 18 (Monitor Exit Semantics):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The semantics of monitor exit specify that everything that happened before the monitor exit should happen before it, which means that nothing from the inner synchronized block (where we instantiate the Singleton) will be moved out of the inner synchronized block, however, it does not mean that something will not be moved from outside of the block to within it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 19 (Monitor Exit Semantics):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This slide explains monitor exit semantics with an illustration. As we can see inst2 and inst3 are within the memory barrier. Neither of them will be moved out of the block, but inst4 which is out of the memory barrier may be moved in the barrier.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 20 (Double Checked Locking With Memory Barrier):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This slide shows the code where we tried to use the memory barrier. But this time we show the code with a potential reordering. With the statement instance = tempInstance inside the memory barrier it could be further reordered to the point before the actual construction of the Singleton, bringing us back to the same problem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 21 (OK So What The Hell Will Work ?):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Alright enough of playing around... not I am getting a bit edgy.... just tell me what the hell is going to work. Is this what you are saying to yourself? Java has a special modifier called volatile. We can use these fields to help us with the Singleton.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 22 (Semantics of volatile):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The volatile modifier is used in Java to communicate state changes between threads. This slide explains the semantics of volatile with an illustration.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The code on the left shows a class which has two methods: writer() and reader(). The writer() method writes values of variables x and v to memory, and the reader() method reads values of x and v from memory. Imagine that both these method will be called by different threads T1 and T2, running on different processors P1, and P2. Each processor has a local memory cache and off course there is also the main memory. The variable v is volatile and x is not volatile. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When thread T1 executes writer() we are guaranteed that the instructions will not be reordered because v is volatile. We are also guaranteed that when thread T1 exits the method, processor P1's local cache will be flushed to main memory, which means that the value of x as well as v will be visible to other threads. When thread T2 executes the method reader(), it first reads the value of v, this is going to invalidate the local cache of P1, and fetch the latest values from main memory. This ensures that it sees the latest values (which in this case were the ones written by T1 when it called writer()) of v and x.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So this slide explains the semantics of volatile and how volatile may be used to ensure that instructions are executed in program order and also ensure the visibility of writes by one thread by another thread.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 23 (Double Checked Locking With Volatile):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;This slide shows our old and well known example which uses &lt;cite&gt;double checked locking&lt;/cite&gt;, but this time with a little difference. This time we have made the variable instance a volatile field. Making it volatile will ensure that the write to initialize the LoneRanger object and the assignment of that instance to the field instance will not be reordered. This elimitaes the problem of seeing an uninitialized Singleton object.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 24 (Singleton With Static Initializer):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;After doing all these coding gymnastics, in this slide we show a solution which is probably the simplest solution for creating a thread safe Singleton. Instead of instantiating the Singleton in &lt;code&gt;getInstance()&lt;/code&gt;, we use a static initializer, which will instantiate the Singleton when the class is loaded. Java semantics ensure us that all static fields of a class will be completely initialized before the class is available for use. This means that the field instance will be properly initialized before anyone makes use of the class to get an instance of the Singleton.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 25 (Singleton With Static Initializer):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;In this slide we understand the pros and cons of using a static initializer. Even though using a static initializer is the simplest solution, it is possible that everything the Singleton needs to initialize itself may not be available when the class is loaded (which causes the static initializer to be invoked). It is also possible that the Singleton may be eagerly loaded, which may result in greater loading time for our application, something that may be undesirable if instantiating the Singleton is an expensive operation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slides 26, 27, 28 (Summary):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;In these slides we summarize the main points covered in the presentation till now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 29 (Resources):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Links to some very good and relevant articles, including my &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html"&gt;favorite article&lt;/a&gt; by Bill Pugh.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;slide 30 (Thank You):&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Thank you for your patience. I hope you found this presentation useful. One more thing before signing of - many people (&lt;a href="http://www.c2.com/cgi/wiki?SingletonsAreEvil"&gt;here&lt;/a&gt; and &lt;a href="http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/"&gt;here&lt;/a&gt;, but &lt;a href="http://mattberther.com/2004/05/27/singletons-are-not-evil"&gt;someone&lt;/a&gt; also disagrees) consider Singletons to be evil...&lt;/div&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-2439163575941477024?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/2439163575941477024/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=2439163575941477024" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/2439163575941477024?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/2439163575941477024?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/10/double-checked-locking-and-java.html" title="Double Checked Locking And Java Singletons" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;A0MFSH84eyp7ImA9WxFaGUo.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-147812032376159188</id><published>2010-07-24T15:44:00.007+05:30</published><updated>2010-07-24T19:20:19.133+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-24T19:20:19.133+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="learning" /><title>DIY Masters in Computer Science</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HCmYBaI1pSWxkUf7iOlDAFV10C0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HCmYBaI1pSWxkUf7iOlDAFV10C0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HCmYBaI1pSWxkUf7iOlDAFV10C0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HCmYBaI1pSWxkUf7iOlDAFV10C0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Since my formal education, a lot of advances have taken place in software development. I have been able to keep up with a few with regular reading and practice. But a lot of this learning has been a bit random, and as a result a bit dissipated as well. I feel like I want to engage in continuous learning, in a more organized manner.&lt;br /&gt;&lt;br /&gt;Over the years there are several core concepts which I have forgotten because I have not been able to use them in my regular work. I feel like relearning those concepts.&lt;br /&gt;&lt;br /&gt;I think the volume and content of both these can constitute a masters course in Computer Science. But I do not want to go back to school. Not because there is anything wrong with school - I had a great time in grad school. But here's why...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I don't want to go back to school because I want to define the courses I want to learn, and not pick up from what's offered.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I don't want to go back to school because I want to be able to learn at my own pace, which at times may be slower than 1 course per semester.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I don't want to go back to school because I do not want to spend a fortune learning stuff which I can learn myself using free resources.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I don't want to go back to school because I would rather create online/social credentials than get a school certificate.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;I don't want to go back to school because I want to demonstrate that a person can not only get knowledge but also credentials if they engage in disciplined self-study and leave learning trails on the Internet.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;So this time I am doing a DIY (Do-It-Yourself) masters in Computer Science. so I can refresh things I have forgotten and learn new technologies and concepts which have gained importance in recent times, in an organized way.&lt;br /&gt;&lt;br /&gt;I did a Masters in Computer Science more than a decade back. Since then, Internet, communication technologies, and social networking, have made it possible for someone to do a similar program all by themselves, using open courseware, and social learning.&lt;br /&gt;&lt;br /&gt;By doing this program, I am not only planning to enhance my own knowledge, but am also hoping to show how one can get a Master's education worth of knowledge, and credentials, by self learning, and without spending a fortune. Here's a very brief &lt;a href="http://opencs.wikidot.com/statementofpurpose"&gt;statement of purpose&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My DIY Learning Process:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have created a &lt;a href="http://opencs.wikidot.com/learningplan"&gt;learning plan&lt;/a&gt; which outlines at a high level the topics I want to learn. I will study one or two topics at a time, and at a manageable pace, given other work commitments.&lt;br /&gt;&lt;br /&gt;Once the topics to learn have been identified, I will identify learning resources, forums, and mentors for that topic.&lt;br /&gt;&lt;br /&gt;A very basic study plan is to study the material, and make notes of my understanding, as well as questions and thoughts, I get in my mind as I am learning. I will make these notes available on a &lt;a href="http://opencs.posterous.com/"&gt;special blog&lt;/a&gt;. This &lt;a href="http://opencs.posterous.com/"&gt;blog&lt;/a&gt; will serve as a personal knowledge base (I can refer to it in the future), as well as a learning trail (for proof of study and understanding).&lt;br /&gt;&lt;br /&gt;All the homework I do while I am taking a course will be made available in the public domain. I will either post it on my &lt;a href="http://opencs.posterous.com/"&gt;blog&lt;/a&gt;, or if the homework involves coding, on a public open source repository such as Github. I will also do one or more projects to practice the entire body of knowledge as a whole and publish that too in the public domain.&lt;br /&gt;&lt;br /&gt;I will also create presentations of what I learn, and make them available in the public domain.&lt;br /&gt;&lt;br /&gt;I will connect with mentors who are experts in the topic I am learning. Depending on their time availability I will request them to help me identify gaps in my understanding, and validate my knowledge.&lt;br /&gt;&lt;br /&gt;When I have doubts, I will ask questions on Internet forums. If my questions are not answered satisfactorily on the forums, I will refer them to my mentors.&lt;br /&gt;&lt;br /&gt;Please visit my &lt;a href="http://opencs.wikidot.com/learningplan"&gt;learning plan&lt;/a&gt; for further details.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Establishing Credentials:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A person can have several reasons for learning. One is for the knowledge (either for the joy of knowing something, or for more practical application of the knowledge), and another for establishing credentials, so someone else may entrust us with work which requires such knowledge. A self learned person may have the knowledge, but may lack credentials to prove it. It is also possible for a person studying in a silo to think he has grokked what he just learned, when in reality he may not have understood the matter properly. To be able to provide proof of knowledge as well as to validate my learning with other practitioners, I plan to engage in what can be loosely classified as social learning.&lt;br /&gt;&lt;br /&gt;I will do the following to document my learning and to engage with the community of practitioners, in the hope of validating my knowledge and establishing credentials for what I learn:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Answer questions on forums&lt;/li&gt;&lt;li&gt;Blog my study notes, and clearly articulate my takeaway from all the lectures I view, or text I read&lt;/li&gt;&lt;li&gt;Create presentations and post them on YOUTube, or other video sharing services&lt;/li&gt;&lt;li&gt;Publish homework on open source code repositories such as GitHub, etc&lt;/li&gt;&lt;li&gt;Request my mentors to quiz me to help me find gaps in my understanding of a topic. I will publish the quiz as audio/video and request the mentor to post their feedback in the public domain&lt;/li&gt;&lt;li&gt;Take quizzes and tests wherever possible and economical&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;So I am leaving these learning crumbs on various places on the Internet, but I need something to bring everything together. Something which can serve as the focal point, or a lens into all my learning. I created a &lt;a href="http://opencs.wikidot.com/"&gt;wiki&lt;/a&gt; site to serve as the focal point.&lt;br /&gt;&lt;br /&gt;Have you been meaning to learn something yourself? Perhaps you can do your own DIY course in whatever interests you. Here is a lens into my &lt;a href="http://opencs.wikidot.com/"&gt;DIY experiment&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-147812032376159188?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/147812032376159188/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=147812032376159188" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/147812032376159188?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/147812032376159188?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/07/diy-masters-in-computer-science.html" title="DIY Masters in Computer Science" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DkEAQX0zfip7ImA9WxFQFks.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7159727745765852184</id><published>2010-05-12T17:14:00.000+05:30</published><updated>2010-05-12T17:14:00.386+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-12T17:14:00.386+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android parrallel" /><title>Android apps can run in parrallel (video)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7RA_O_G5KIXbAEYXs4YidBizy0I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7RA_O_G5KIXbAEYXs4YidBizy0I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7RA_O_G5KIXbAEYXs4YidBizy0I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7RA_O_G5KIXbAEYXs4YidBizy0I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This is the seventh in a series of videos published by Google on Android programming.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7lScgyXGxwo&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/7lScgyXGxwo&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;In this video the speaker starts an app to track photos his buddy publishes on Flickr. He can keep this application running in the background, so while he is browsing or checking his email, this application will constantly track the photos and notify him if a new photo has been uploaded.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7159727745765852184?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7159727745765852184/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7159727745765852184" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7159727745765852184?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7159727745765852184?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/android-apps-can-run-in-parrallel-video.html" title="Android apps can run in parrallel (video)" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEMAQXYzeSp7ImA9WxFQFUo.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7774555708831553283</id><published>2010-05-11T16:44:00.001+05:30</published><updated>2010-05-11T16:44:00.881+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-11T16:44:00.881+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android apps_without_borders" /><title>Adndroid apps don't have any borders (video)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EAMl7s0UAobb_cWgD3UtGyHbjPs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EAMl7s0UAobb_cWgD3UtGyHbjPs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EAMl7s0UAobb_cWgD3UtGyHbjPs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EAMl7s0UAobb_cWgD3UtGyHbjPs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This is the sixth in a series of videos provided by Google on Android programming.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/3LkNlTNHZzE&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/3LkNlTNHZzE&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Index:&lt;br /&gt;00:00 Introduction&lt;br /&gt;00:32 Zebra crossing application&lt;br /&gt;01:35 Library app&lt;br /&gt;02:14 A GeoSocial app which combines user GPS, user created photos, and Compass&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;My Takeaway:&lt;/span&gt;&lt;br /&gt;Android applications do not have any borders. They can use data from other applicatiosns, they can use hardware available on the device such as camera, compass, GPS, accelerometer, etc, and they can also use content from the web API's.&lt;br /&gt;&lt;br /&gt;The first application called Zebra Crossing is an application which can pull information from bar codes and QR codes. So if you photograph a product's bar code and give it to the application, it will pull up information about the book from the web. If on the other hand you give it a QR code from the back of a business card, it can extract contact information about that person which you can use to call or send email. The Zebra Crossing app also publishes intents, to allow other applications to communicate with it.&lt;br /&gt;&lt;br /&gt;The second application is a library application which uses the "Zebra Crossing" app to add books to your personal library.&lt;br /&gt;&lt;br /&gt;The third application, which I found to e really cool is an application which mashes together GPS, photographs, and the Compass to create a GeoSocial application. So here's what it does. Imagine you are on a vacation and want to locate cool things around where you are. You can use this application to find out all the photographs people have taken around that locality. If you find something you like, you can actually locate that thing (which was photographed) on a map and also use the Compass to get there. Cool isn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7774555708831553283?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7774555708831553283/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7774555708831553283" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7774555708831553283?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7774555708831553283?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/adndroid-apps-dont-have-any-borders.html" title="Adndroid apps don't have any borders (video)" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEYEQX8-eyp7ImA9WxFQFEs.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-5658718801732610051</id><published>2010-05-10T10:05:00.001+05:30</published><updated>2010-05-10T10:05:00.153+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-10T10:05:00.153+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android webview" /><title>How to embed the web in Android apps (video)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zuF3aMcapgB0HjoqkPnkIvOZO2c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zuF3aMcapgB0HjoqkPnkIvOZO2c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zuF3aMcapgB0HjoqkPnkIvOZO2c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zuF3aMcapgB0HjoqkPnkIvOZO2c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This is the fifth in a series of videos provided by Google on Android programming.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Ex7YsQ_YH2U&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Ex7YsQ_YH2U&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;This video shows how we can use the WebView to create applications that render HTML pages. Along with being able to embed HTML and Javascript web pages in apps, the most exciting thing I found in this view was the fact that the Javascript in a webpage can communicate with Java code and Java code can communicate with javascript. This is really cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-5658718801732610051?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/5658718801732610051/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=5658718801732610051" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/5658718801732610051?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/5658718801732610051?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/how-to-embed-web-in-android-apps-video.html" title="How to embed the web in Android apps (video)" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkEEQ3oyeyp7ImA9WxFQE0Q.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-2950706542645664969</id><published>2010-05-09T13:06:00.000+05:30</published><updated>2010-05-09T13:06:42.493+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-09T13:06:42.493+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android apps_are_equal" /><title>Android programming - All applications are created equal (video)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/fIHE9Jz5MfdCVGLAPLV6FPWDHTI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fIHE9Jz5MfdCVGLAPLV6FPWDHTI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/fIHE9Jz5MfdCVGLAPLV6FPWDHTI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/fIHE9Jz5MfdCVGLAPLV6FPWDHTI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This is the fourth video in the series of videos provided by Google on Android programming.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/3aUjukCdPyQ&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/3aUjukCdPyQ&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Index:&lt;/span&gt;&lt;br /&gt;00:25 Dianes ringtone app&lt;br /&gt;01:08 App to create a shortcut to anything on the system&lt;br /&gt;01:36 Replacing the home screen (End at 02:17)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My Takeaway:&lt;/span&gt;&lt;br /&gt;This video shows that all applications created on the Android platform are equal. Even though I have not done any iPhone development, I believe applications written for iPhone do not have access to everything the way Android applications do. So this is a positive for Android development.&lt;br /&gt;&lt;br /&gt;In this video we see how to a custom application can change the ringtone on an Android phone, how another application can create shortcuts to anything on the phone, and how we can also change the 'Home' application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-2950706542645664969?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/2950706542645664969/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=2950706542645664969" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/2950706542645664969?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/2950706542645664969?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/android-programming-all-applications.html" title="Android programming - All applications are created equal (video)" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CU8NRnY9fSp7ImA9WxFQE0w.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-4710639378464485471</id><published>2010-05-08T12:45:00.003+05:30</published><updated>2010-05-08T15:48:17.865+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-08T15:48:17.865+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android api" /><title>Android Programming - API's (Video)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6JqNNcNq7FrkY9je-zoosqbOxi4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6JqNNcNq7FrkY9je-zoosqbOxi4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6JqNNcNq7FrkY9je-zoosqbOxi4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6JqNNcNq7FrkY9je-zoosqbOxi4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This is the third video in the series of videos provided by Google on Android programming.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/MPukbH6D-lY&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/MPukbH6D-lY&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Index:&lt;/span&gt;&lt;br /&gt;00:00 Introduction&lt;br /&gt;00:16 Android API's&lt;br /&gt;00:24 Location Manager&lt;br /&gt;01:25 XMPP&lt;br /&gt;02:42 Notification Manager&lt;br /&gt;04:08 View System&lt;br /&gt;06:00 Conclusion (Ends at 07:05)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;My Takeaway:&lt;/span&gt;&lt;br /&gt;In this video the speaker talks about API's provided on the Android platform to developers.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;LocationManager&lt;/span&gt; API allows an application to get the location of the device it is running on. This information can be used to register intents, which will inform the user if they are close to an interesting location such as a Ice Cream shop. I can also think of another use. If traffic information is available, then we can also use the location manager to inform us if we are getting close to a high traffic area. Interestingly this API uses whatever information it has to determine the location. If GPS information is available then it will use that, otherwise it will use cell tower information.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;XMPP Service&lt;/span&gt; is used to send messages to a device. It can be used to send device to device messages, or server to device messages. I think this API can have very interesting uses. It can be used for multiplayer games, and it can probably also be used by trekkers to track each other.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;Notification Manager&lt;/span&gt; API provides applications the ability to send notifications to the user on the status bar. My impression is that this API is very well designed. The notification appears on the status bar, such that if a user selects it (using whatever input method available... touch, etc), it will display a preview about the application and notification. If the user is interested, they can further select the notification to go to the application which send it.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;View system&lt;/span&gt; provides several view controls help developers make their applications. Interesting controls include a Map control to embed location information in applications, and an HTML control to embed web pages in applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-4710639378464485471?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/4710639378464485471/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=4710639378464485471" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4710639378464485471?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4710639378464485471?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/android-programming-apis-video.html" title="Android Programming - API's (Video)" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D08BQHc-cCp7ImA9WxFXEUw.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-6318261106635876126</id><published>2010-05-05T20:41:00.004+05:30</published><updated>2010-05-17T22:34:11.958+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-17T22:34:11.958+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android application_lifecycle" /><title>Android programming - Application lifecycle (Video)</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/otOW4mQ9ESpbbJ1QGEPleQGESj0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/otOW4mQ9ESpbbJ1QGEPleQGESj0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/otOW4mQ9ESpbbJ1QGEPleQGESj0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/otOW4mQ9ESpbbJ1QGEPleQGESj0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This is the second video in the series of videos provided by Google on Android programming.&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fL6gSd4ugSI&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/fL6gSd4ugSI&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="385" width="480"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Index&lt;/span&gt;&lt;br /&gt;00:00 - Introduction&lt;br /&gt;01:00 - How Android integrates apps written by different authors.&lt;br /&gt;07:50 - Conclusion (Ends at 08:16)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This video walks us through a hypothetical use case, where a user opens their email, reads a message which contains a link to some location. The user then clicks on the link, opens the browser and views the location on Google Maps.&lt;br /&gt;&lt;br /&gt;While engaging in these activities, the user starts various applications (processes) and also navigates back and forth among them. The video explains how Android manages resources and the application stack so the user can navigate across their apps seamlessly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My Takeaway&lt;/span&gt;&lt;br /&gt;From the video it seems like Android supports a maximum of 4 running processes. One of those processes is the System process, so a user can have at most 3 applications running simultaneously. However, this does not mean that a user cannot open more applications. When the user opens the 4th application, Android will automatically terminate an application, and will also revive it in a known state if the user were to go to it again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://ram.redanyway.com/"&gt;Ram&lt;/a&gt; pointed out that "4 running processes" is purely a number they used in this example. He is absolutely correct. 4 is just an example (perhaps they assumed 64 MB RAM on the phone...). The real number depends on the amount of memory (RAM) available on the phone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-6318261106635876126?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/6318261106635876126/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=6318261106635876126" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/6318261106635876126?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/6318261106635876126?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/android-programming-application.html" title="Android programming - Application lifecycle (Video)" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;AkMDQ3k7fyp7ImA9WxFRGEQ.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7684738909494121326</id><published>2010-05-02T12:20:00.007+05:30</published><updated>2010-05-03T20:24:32.707+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-03T20:24:32.707+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="android_architecture video" /><title>Android programming - architecture video</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J8S6CS5mCEU5Xyqi7QYXnsk1Ir8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J8S6CS5mCEU5Xyqi7QYXnsk1Ir8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J8S6CS5mCEU5Xyqi7QYXnsk1Ir8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J8S6CS5mCEU5Xyqi7QYXnsk1Ir8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I have been getting interested in Android programming, so I went over to their website and found some introductory videos.&lt;br /&gt;&lt;br /&gt;Here's the first one with a little index of what is discussed and my take away from the video.&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/QBGfUs9mQYY&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/QBGfUs9mQYY&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="385" width="480"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Video Index:&lt;/span&gt;&lt;br /&gt;00:0 Introduction&lt;br /&gt;00:40 Linux Kernel&lt;br /&gt;01:09 Native Libraries&lt;br /&gt;03:09 Android runtime&lt;br /&gt;04:13 Core libraries&lt;br /&gt;04:31 Application framework&lt;br /&gt;07:00 Applications&lt;br /&gt;07:25 Application building blocks&lt;br /&gt;09:37 Example of re-using components in Android&lt;br /&gt;12:18 Conclusion and resources&lt;br /&gt;12:48 End&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My Takeaway:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Architecture wise the Android platform has several layers:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Linux Kernel&lt;/li&gt;&lt;li&gt;Native Libraries&lt;/li&gt;&lt;li&gt;Android Runtime&lt;/li&gt;&lt;li&gt;Core Libraries&lt;/li&gt;&lt;li&gt;Application Framework&lt;/li&gt;&lt;/ol&gt;The applications that we make are build on top of the "application framework" layer.&lt;br /&gt;&lt;br /&gt;The Linux Kernel was chosen because of it's stability, services, security, and presence of several device drivers.&lt;br /&gt;&lt;br /&gt;Native Libraries consist of various components for rendering graphics and fonts (Surface Manager, OpenGL, SGL, Freetype), a lightweight database engine (SQLLite), a browser engine (WebKit), and others.&lt;br /&gt;&lt;br /&gt;The Android Runtime consists of Dalvik the Java Virtual Machine created by Google, which is optimized for running on embedded devices which have low resources. Dalvik runs *.dex files which are created by converting *.jar and *.class files. On top of Dalvik are the core Java libraries consisting of things like the Collections, IO API, etc.&lt;br /&gt;&lt;br /&gt;Then the Core libraries layer consists of components such as Activity Manager, Resource Manager, Package Manager, Content Provider, Telephony Manager, XMPP, etc.&lt;br /&gt;&lt;br /&gt;Android applications typically have 4 building blocks, which applications mayor may not use. These are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Activities&lt;/li&gt;&lt;li&gt;Intent Receivers&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Services&lt;/li&gt;&lt;li&gt;Content Providers&lt;/li&gt;&lt;/ol&gt;The video ends with an example of how various applications can re-use a photo picker component. So, we may have multiple applications like email, Blooger, etc which may need to select a photo. These applications do not have to write their own photo picker. They just show an "Intent" to pick a photo, and the component which fulfills that intent will be chosen. This binding is done pretty late, so we can actually change the component that fulfills the intent, and then henceforth that component will be used for that intent.&lt;br /&gt;&lt;br /&gt;In the next few blog posts I will be embedding more Android videos along with my learnings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7684738909494121326?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7684738909494121326/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7684738909494121326" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7684738909494121326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7684738909494121326?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/05/android-programming-architecture-video.html" title="Android programming - architecture video" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DEUCRnYzfip7ImA9WxFRFk8.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-8052830513684312824</id><published>2010-04-30T16:32:00.002+05:30</published><updated>2010-04-30T16:47:47.886+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-30T16:47:47.886+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="vnc gnome" /><title>tightvnc with gnome messes up the keyboard mapping</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bc4dH9IfbWAsw16hxkeQ-rJzseM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bc4dH9IfbWAsw16hxkeQ-rJzseM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bc4dH9IfbWAsw16hxkeQ-rJzseM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bc4dH9IfbWAsw16hxkeQ-rJzseM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Everytime I run our unit tests, I get Java Swing windows flying across my screen making it impossible to work. A friend suggested that if I ran the tests in a vncclient session, the windows will be contained within vncviewers window.&lt;br /&gt;&lt;br /&gt;So I installed tightvncserver and client on my Ubuntu 9.10 machine. When I started vncviewer I realized that the keyboard mapping as messed up, making it impossible to type anything sensibly in the vnc session.&lt;br /&gt;&lt;br /&gt;Some searching seems to suggest that Gnome is causing this problem. &lt;a href="http://https://bugs.launchpad.net/ubuntu/+source/vino/+bug/112955"&gt;This page&lt;/a&gt; offered a solution of changing VNC's startup file to not fully start Gnome, and it worked for me.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Workaround:  I modified my ~/.vnc/xstartup to be:&lt;/p&gt; &lt;p&gt;#!/bin/sh&lt;/p&gt; &lt;p&gt;xrdb $HOME/.Xresources&lt;br /&gt;gnome-wm &amp;amp;&lt;br /&gt;gnome-panel &amp;amp;&lt;br /&gt;nautilus --no-default-window &amp;amp;&lt;br /&gt;gnome-cups-icon &amp;amp;&lt;br /&gt;gnome-volume-&lt;wbr&gt;manager &amp;amp;&lt;br /&gt;xterm &amp;amp;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-8052830513684312824?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/8052830513684312824/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=8052830513684312824" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/8052830513684312824?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/8052830513684312824?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/04/tightvnc-with-gnome-messes-up-keyboard.html" title="tightvnc with gnome messes up the keyboard mapping" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEcBRHYzcCp7ImA9WxFRE0k.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-3984736072066275084</id><published>2010-04-27T10:47:00.003+05:30</published><updated>2010-04-27T10:57:35.888+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-27T10:57:35.888+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java applets 64-bit linux" /><title>Java Applet on 64 bit Linux</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0PjROcm4i__wmD3be-4yodrJBb4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0PjROcm4i__wmD3be-4yodrJBb4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0PjROcm4i__wmD3be-4yodrJBb4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0PjROcm4i__wmD3be-4yodrJBb4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I have been working on an Ubuntu 9.10 (64 bit system) from some time. I had read some stories of problems running 64 bit Java Applets on 64 bit Firefox, so when I needed to use Applets I did some googling to figure out how to do it.&lt;br /&gt;&lt;br /&gt;I came across a couple of posts. Some had different solutions for different versions (3.5, 3.6) of Firefox, and they also wanted me to use IcedTea. The solution I used is outlined &lt;a href="http://ubuntuforums.org/showthread.php?t=1013658"&gt;here&lt;/a&gt;, and it worked perfectly well for me.&lt;br /&gt;&lt;br /&gt;Note: You may not have libnpj2.so in the same place mentioned below.&lt;br /&gt;&lt;br /&gt;&lt;pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 50px; text-align: left;"&gt;mkdir ~/.mozilla/plugins/&lt;br /&gt;ln -s /usr/lib/jvm/jre1.6.0_12/lib/amd64/libnpjp2.so ~/.mozilla/plugins/&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-3984736072066275084?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/3984736072066275084/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=3984736072066275084" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/3984736072066275084?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/3984736072066275084?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/04/java-applet-on-64-bit-linux.html" title="Java Applet on 64 bit Linux" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU8DQns9eSp7ImA9WxFSFE0.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-4628373194244995949</id><published>2010-04-06T22:07:00.007+05:30</published><updated>2010-04-16T14:21:13.561+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-16T14:21:13.561+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grep" /><title>Showing lines before and after a grep match</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QLRQhfEKkcZGnOsx-4IbGj5_cY4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QLRQhfEKkcZGnOsx-4IbGj5_cY4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QLRQhfEKkcZGnOsx-4IbGj5_cY4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QLRQhfEKkcZGnOsx-4IbGj5_cY4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Today I ran running grep on the output of &lt;code&gt;hg log&lt;/code&gt;, but only to realize that I wanted a couple of lines before and after the line which matched as well.&lt;br /&gt;&lt;br /&gt;I am sure this is common knowledge, but I did not know how to do it, so am sharing it in the hope that someone finds it useful.&lt;br /&gt;&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;hg log | grep --before-context=2 --after-context=2 username&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Running the above showed me changeset number, comments etc for all the mercurial changesets committed by the specified user.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-4628373194244995949?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/4628373194244995949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=4628373194244995949" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4628373194244995949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4628373194244995949?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2010/04/showing-lines-before-nad-after-grep.html" title="Showing lines before and after a grep match" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CUEDQ3o5fSp7ImA9WxNWFEw.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-5850957275496924284</id><published>2009-10-04T09:55:00.004+05:30</published><updated>2009-10-13T11:31:12.425+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-13T11:31:12.425+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="education" /><title>Some thoughts on redesigning education</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AqRdqVknVOYR1EDb3OPVwRX48vs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AqRdqVknVOYR1EDb3OPVwRX48vs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AqRdqVknVOYR1EDb3OPVwRX48vs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AqRdqVknVOYR1EDb3OPVwRX48vs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Some time back I read a &lt;a href="http://www.geekybusiness.com/redesigning-education"&gt;blog post&lt;/a&gt; on redesigning education. It asked some very good questions. Stuff which I had been thinking of myself. I left my thoughts on the blog, but I would also like to start a conversation around these ideas with those who read this blog as well.&lt;br /&gt;&lt;br /&gt;I would like to know what other people think of the issue of redesigning (college) education.&lt;br /&gt;&lt;p&gt;I have often thought about how college education can be improved. To answer this question, we first have to ask a very basic question. What is the purpose of education?&lt;/p&gt;&lt;p&gt;To me, we need education for 3 things:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;To learn more about the world around us&lt;/li&gt;&lt;li&gt;To lead positive constructive lives&lt;/li&gt;&lt;li&gt;To earn a good living / fulfill our ambitions&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I think education has to a large extent evolved to fulfill #3 (with a bias towards earning a comfortable living). The semester system, along with multiple choice tests, and grading, has made our education system into an assembly line. Students are pushed into the assembly line, given classes, administered tests, branded with a grade and pushed out of the assembly line, into the workforce.&lt;/p&gt;&lt;p&gt;Even though this is not the best way to teach, this system has for the most part worked till now. I think there are several reasons.&lt;/p&gt;&lt;p&gt;1. For many of students, getting an education is simply a means to gain employable skills (I do not say this in a negative way).&lt;br /&gt;2. A university has to provide these skills in a time and cost efficient way to the students. It has to provide some branding which will be valuable to students, and make it easy for employers to spot the talent they want to recruit.&lt;/p&gt;&lt;p&gt;In the last few years I have taught programming classes at a local college. In one semester, I tried to move away from the regular grading mechanism. I wanted to focus on deep learning of programming skills, sharing and brainstorming ideas, code reviews, collaborating with the community of practice, etc. However, students still needed to be graded, so I had to come up with a way to fulfill that requirement also. Without going into details I will simply say, in that semester, I put in an effort which was orders of magnitude greater than the regular effort (because I had to fulfill the grading requirement). Students learned a lot in that semester, and I too enjoyed running that course, but towards the end of the semester, I was tremendously stressed out managing the course, and my regular programming work.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So even though the current education system is sub-optimal, I do not think it is because of evil intentions. It is possibly the most practical mechanism that has emerged over time.&lt;/p&gt;&lt;p&gt;However, many things have changed in the past few decades. The shelf life of knowledge has greatly reduced. The Internet has made it possible to share information, and collaborate with people at a distance. Many businesses have started valuing knowledge over degrees (this is at least true in software, and probably in media, advertising, etc as well). The read-write web has made it possible for students to easily create a digital portfolio, and to establish alternate credentials. So all the things a student needs for learning (information, interactions, guidance, review and feedback, and credentials) can be put together in a non traditional way. I stress so much on non traditional because the traditional education system excludes many learners, and this I feel can be changed.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So here is the ideal education system according to me:&lt;/p&gt;&lt;p&gt;A student enters the education system with some goals, and connects with mentors who will help her in fulfilling those goals. These mentors may be traditional teachers who work for a university, or may be employees of an organization, senior practitioners who choose to help on the Internet, friends, family, or people who have retired from the workforce, but would like to share their wisdom and help others. &lt;/p&gt;&lt;p&gt;With the help of mentors, the student defines learning goals, and identifies resources. These resources could be traditional classes, books, or digital material (videos, text, audio...). &lt;/p&gt;&lt;p&gt;With these materials and a micro mentor network, the student begins her learning process. When they have questions, there are a several resources from their mentor network they can turn to. These students may be part of a traditional classroom in some cases, whereas in other cases they may be part of a local or virtual study group. Think of it as being part of an appropriate group for every course they want to take.  There are several tools, both real world as well as digital to enable this.&lt;/p&gt;&lt;p&gt;As the student learns, they leave a digital learning trail. One possible way is using blogs, audio recordings, wikis, contributions on forums, and other digital artifacts. So students blog their assignments and problem sets. They participate on Internet forums asking and answering questions. They may create a podcast (or screencasts) of their assignments and presentations. Maybe some students will be able to do practical work which is similar in nature to the assignments and problem sets.&lt;/p&gt;&lt;p&gt;Senior practitioners, traditional teachers, mentors from the community, help the student understand the strengths and weaknesses in their knowledge. The student subsequently fills in the holes by seeking help from their mentor network, and by revisiting those concepts. Community members endorse a students' understanding of their topic of study. Maybe tests still have a place... I don't know...&lt;/p&gt;&lt;p&gt;When a student knows enough, they can enter the workforce. Proof of their knowledge already exists on the Internet. Some organizations may accept them purely based on their digital portfolio and an interview, while others may expect them to take some tests. Students can prepare for these tests, if they wish to work for that organization.&lt;/p&gt;&lt;p&gt;Students however, do not stop their education after getting employed. The process outlined above continues, but perhaps at a slower pace. Thus even after starting work a person continues to accumulate (non credit) credentials. These credentials may either be continuing education certificates from a university or Internet endorsements from the community of practice.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This to me is the ideal educational scenario. But it will not be without problems. &lt;/p&gt;&lt;p&gt;There will always be the issue of credibility of an online portfolio, and endorsements from random mentors. Is there a process using which we can streamline online credentials and validate the credibility???&lt;br /&gt;&lt;/p&gt;&lt;p&gt;There will be issues with self-discipline. College gives a certain structure. Doing it by oneself needs a lot of will-power and discipline. One can easily while away time, thinking they are learning something. Maybe the &lt;a href="http://www.pomodorotechnique.com/"&gt;Pomodoro technique&lt;/a&gt; can help here.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;But I think this scenario is workable. I like it because it allows students to learn at their own pace (without excluding students who do not have resources to attend traditional colleges), from many mentors, thus gaining knowledge and wisdom from many sources. But most importantly, it allows students to take control of their education, and seek out the best, albeit disparate sources for knowledge.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Here's my own humble effort towards contributing towards this goal - &lt;a href="http://www.adaptivelearningonline.net/" rel="nofollow"&gt;http://www.adaptivelearningonline.net&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-5850957275496924284?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/5850957275496924284/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=5850957275496924284" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/5850957275496924284?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/5850957275496924284?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/10/some-thoughts-on-redesigning-education.html" title="Some thoughts on redesigning education" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>7</thr:total></entry><entry gd:etag="W/&quot;DkMGRng-eSp7ImA9WxNSEU4.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7326051699525102682</id><published>2009-08-24T22:38:00.003+05:30</published><updated>2009-08-24T22:50:27.651+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-24T22:50:27.651+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><title>Fixing a mistake after commiting in Git</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ukkCzrakyrWhr3iHhfCH_Ibpqvk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ukkCzrakyrWhr3iHhfCH_Ibpqvk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ukkCzrakyrWhr3iHhfCH_Ibpqvk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ukkCzrakyrWhr3iHhfCH_Ibpqvk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;So, I ran into an interesting issue while coding today. I made a lot of changes and committed code to my Git repository. Just after committing, I realized that I still had to make some changes to a file and those changes should also have gone in with the previous commit.&lt;br /&gt;&lt;br /&gt;Fixing a commit mistake can be done in two ways. Revert the commit, make the changes and then recommit them. This is the preferred way if we have already made the changes public (and thus someone may already have pulled them). However, in my case I am the only one working on this project right now and I had not pushed the changes to GitHub, so I could try the other method.&lt;br /&gt;&lt;br /&gt;So here's what I did. I made changes to the file, added it to the index, and committed it thus:&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;$git commit --amend&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Committing code with the --amend switch will cause the index to be committed as part of the previous commit. Git also brings up the editor window, in case we want to change the commit message. This method can also be used to change the commit message without adding any files to the commit.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Reference: &lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#reverting-a-commit"&gt;Git documentation on kernel.org&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7326051699525102682?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7326051699525102682/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7326051699525102682" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7326051699525102682?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7326051699525102682?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/08/fixing-mistake-after-commiting-in-git.html" title="Fixing a mistake after commiting in Git" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;AkMDQXY-cSp7ImA9WxNSEEk.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-57106153852054194</id><published>2009-08-23T17:56:00.006+05:30</published><updated>2009-08-23T22:57:50.859+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-23T22:57:50.859+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python design_patterns" /><title>Lack of design patterns in Python</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WsSCU3S5f70wRbrbjCtE5vIt3t8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WsSCU3S5f70wRbrbjCtE5vIt3t8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WsSCU3S5f70wRbrbjCtE5vIt3t8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WsSCU3S5f70wRbrbjCtE5vIt3t8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;While searching for PyCon videos, I came across &lt;a href="http://bitworking.org/news/"&gt;Joe Gregorio's&lt;/a&gt; very good video on (lack of) design patterns in Python. I  have also added the video timeline along with some notes I made for myself and my takeaway. Enjoy the video.&lt;br /&gt;&lt;br /&gt;&lt;embed src="http://blip.tv/play/g4Vi_9ZkAg" type="application/x-shockwave-flash" width="480" height="350" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt; &lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Timeline:&lt;/strong&gt;&lt;br /&gt;[00:00] - Start&lt;br /&gt;[00:15] - People pick tools based on a mythology and not necessarily facts&lt;br /&gt;[02:35] - Python isn't just Java without the compiler&lt;br /&gt;[03:34] - Design patterns are also a sign of weakness in a language&lt;br /&gt;[04:06] - Lack of design patterns in Python (proof of lack)&lt;br /&gt;[06:10] - Patterns are built into Python&lt;br /&gt;[07:00] - Strategy pattern in Python the wrong and right way&lt;br /&gt;[07:36] - The strategy pattern is invisible in languages with first-class functions&lt;br /&gt;[08:07] - Some other language features in Python (first class functions, metaprogramming, iterators, closures)&lt;br /&gt;[09:17] - The iterator pattern (iterators) is also built into Python&lt;br /&gt;[09:36] - The observer pattern is also built into Python&lt;br /&gt;[10:17] - Factory method pattern in Python (&lt;br /&gt;[10:34] - Abstract Factory Pattern&lt;br /&gt;[10:40] - Strategy pattern goes away becaise of first class functions&lt;br /&gt;[11:08] - Drawing some useful conslusions&lt;br /&gt;[12:20] - Drawing light on Python from the perspective of patterns&lt;br /&gt;[12:31] - Thread Pool and Concurrency patterns (should we be talking about language features in Python for concurrency patterns???)&lt;br /&gt;[13:49] - Channels (a model for concurrent processes)&lt;br /&gt;[15:12] - PyCSP (implmentation of csp on top of Python)&lt;br /&gt;[18:42] - Conclusions, summary, and questions&lt;br /&gt;[19:17] - end (video goes on for a few more seconds waiting for questions)&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;br /&gt;There are very few references to design patterns in Python mailing lists and discussions around Python... design patterns could be a sign of weakness in a language... patterns are built into Python (hence very little discussion)...strategy pattern is invisible in languages with first class functions...&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt;&lt;br /&gt;If you have to implement a design pattern, first look at language features and try to determine if any can be used instead of the pattern or at least assist in the implementation of the pattern while programming in that language.&lt;br /&gt;&lt;br /&gt;Ask yourself if a language feature would make that pattern part of the language itself.&lt;br /&gt;&lt;br /&gt;Concurrency patterns are a rich area to look at.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://bitworking.org/news/Python_isnt_Java_without_the_compile"&gt;Python isn’t just Java without the compile&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://norvig.com/design-patterns/"&gt;Design patterns in dynamic programming&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=""&gt;Advanced topics in programming languages: Concurrency and message passing in Newspeak (Rob Pike)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://home.comcast.net/~refilman/text/dpl/csp.pdf"&gt;Channels (pdf)&lt;/a&gt; C.A.R.Hoare&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-57106153852054194?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/57106153852054194/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=57106153852054194" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/57106153852054194?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/57106153852054194?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/08/lack-of-design-patterns-in-python.html" title="Lack of design patterns in Python" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;AkEHRno6fCp7ImA9WxNTFU8.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-170687461636379949</id><published>2009-08-17T22:32:00.001+05:30</published><updated>2009-08-17T22:33:57.414+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-17T22:33:57.414+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iAccelerator" /><title>iAccelerator</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KQLiwVDxDi170iTyBGc2VnmDzyE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KQLiwVDxDi170iTyBGc2VnmDzyE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KQLiwVDxDi170iTyBGc2VnmDzyE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KQLiwVDxDi170iTyBGc2VnmDzyE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;iAccelerator&lt;br /&gt;&lt;br /&gt;I took a sabbatical from my consulting work this summer to participate in the &lt;a href="http://www.iaccelerator.org/"&gt;iAccelerator&lt;/a&gt; program. This is a program for early stage software startups, similar to &lt;a href="http://www.ycombinator.com/"&gt;YCombinator&lt;/a&gt;, but the first of it's kind (I believe) in India.&lt;br /&gt;&lt;br /&gt;I enjoy teaching programming, I have taught programming classes at a &lt;a href="http://www.scit.edu/"&gt;college&lt;/a&gt;, done corporate workshops, and more recently have been working on a &lt;a href="http://www.adaptivelearningonline.net/"&gt;website for participatory learning&lt;/a&gt;. This time I was looking for a different kind of mentoring experience, something which would be free form and fun. After a discussion with &lt;a href="http://wheresfreeman.blogspot.com/"&gt;Freeman&lt;/a&gt;, I decided to go spend the summer at iAccelerator.&lt;br /&gt;&lt;br /&gt;In the first few days of the program we had introductions by all the teams where they spoke about their product and vision. This was followed by a session on team building and thinking out of the box, a few legal sessions, sessions on accounting and company law, and several other mentoring sessions. All this is very useful for early stage software stratups, especially when they are founded by techies who are excelent hackers but need some help with legal and business stuff.&lt;br /&gt;&lt;br /&gt;iAccelerator had ten very motivated and talented teams. I split my time helping them with technical stuff and working on my participatory learning project.&lt;br /&gt;&lt;br /&gt;We worked out of a large hall, converted very tastefully into a working area. Each team had their own space towards the walls, and the centre was furnished with couches, projector, a large whiteboard (where we had presentations and brainstorming sessions) and a wii for fun and entertainment.&lt;br /&gt;&lt;br /&gt;Even though everyone had their own work areas, many people chose to work on the couches. Working from the couches was a lot more fun and it gave opportunities for discussions, knowledge exchange, and friendly bantering. The couch culture (as I call this) in retrospect has been a very important part of the cameredierie and the excellent environment we had among us.&lt;br /&gt;&lt;br /&gt;A good, positive, and helpful environment is one of the best things in such a program. Whenever anyone was stuck with a problem, or needed help with something new, they would always find someone who had that knowledge and was willing to share it. Everyone had their unique strengths, and collectively we all had a lot of talent which flowed freely. Entrepreneurship is also often a journey of highs and lows. There are times when you feel like your product will take over the world, and then there are times which can be described as not so pleasant. Being in a good environment with friends, means that you are not in this alone. If someone is down he can be sure that his buddies will pull him up.&lt;br /&gt;&lt;br /&gt;One team found their first few customers within the group itself, and another team made a kick-ass software for internal communication which had passionate users from day one.&lt;br /&gt;&lt;br /&gt;Ever so often we would have mentors, and successful entrepreneurs come talk to us about various things related to business and startups. Many guests spoke about their journey as entrepreneurs, their successes, failures, and lessons learned. Besides these sessions, we were also invited for many talks given by various mentors to the IIM students. This was a benefit of being on the IIM-A campus. Several mentors also worked one on one with the teams to help them with their vision and business plans.&lt;br /&gt;&lt;br /&gt;Since we all had technical skills, internally we did several TechTalks on topics such as security, Amazon EC2 &amp;amp; cloud computing, designing with GIMP, JQuery, version control with SVN and Git, and many more. Sometimes we played tech videos from the Internet and had discussions around them. These sessions were a lot of fun and we all learned from them.&lt;br /&gt;&lt;br /&gt;Since Freeman has successfully created and exited a startup in the past, he had many insights about how to run a startup. He shared his  knowledge and insights with everyone, helping with business plans, vision, fund raising pitches, and many other nitty gritties of creating startups.&lt;br /&gt;&lt;br /&gt;However, it was not just work all the time. We had a great time watching MTV while eating breakfast in the college mess. I can now tell you that watching MTV is far better than reading the morning newspaper. We played ping pong (Freeman and me had some really fun and intense ping pong sessions) ... we played cricket... on weekends we watched movies on the office projector. We also had a lot of diverse talent in the group. &lt;a title="Jeevan Ram" href="http://twitter.com/jeevanram" id="j7hv"&gt;Jeevan Ram&lt;/a&gt; rocked everyone with his dancing and &lt;a href="http://www.twitter.com/ghazalravi"&gt;Ghazal&lt;/a&gt; made us laugh with his mimicry.&lt;br /&gt;&lt;br /&gt;It's amazing how well we all got to know each other in just a few months. Thinking back, this was the best time I have had after graduating. Most importantly, I cannot stress enough the fact that I made really good friends, and I am very grateful for the wonderful time we all spent together.&lt;br /&gt;&lt;br /&gt;This year's iA program will end in a few weeks. I wish all the teams lot of success and good luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-170687461636379949?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/170687461636379949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=170687461636379949" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/170687461636379949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/170687461636379949?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/08/iaccelerator.html" title="iAccelerator" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total></entry><entry gd:etag="W/&quot;D0MFQ3s8fip7ImA9WxJaFks.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-7630176711517139435</id><published>2009-08-07T22:00:00.002+05:30</published><updated>2009-08-07T22:46:52.576+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-07T22:46:52.576+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="djano serialization python json" /><title>Custom JSON Encoder in Django</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aVyGlvlfAtDMcFvHOCsCHUPjypc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aVyGlvlfAtDMcFvHOCsCHUPjypc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aVyGlvlfAtDMcFvHOCsCHUPjypc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aVyGlvlfAtDMcFvHOCsCHUPjypc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I have been messing around with how to display date formats (in questions and answers) for my &lt;a href="http://www.adaptivelearningonline.net"&gt;web based learning site&lt;/a&gt; from the past couple days. After trying various things, I settled for what seems to be a web 2.0 standard for displaying dates - displaying dates as &lt;span style="font-style: italic;"&gt;'2 days 4 hours ago'&lt;/span&gt; instead of the actual date and time &lt;span style="font-style: italic;"&gt;'4th August, 2009 5:50 PM'&lt;/span&gt;. I like this because I do not have to deal with any browser localization issues. Everything is a delta between the &lt;a href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time"&gt;UTC&lt;/a&gt; time a question was asked and the current UTC time (btw if you are working with &lt;a href="http://docs.python.org/library/datetime.html"&gt;datetime&lt;/a&gt; in Python, do read &lt;a href="http://simonwillison.net/2009/Jul/6/datetime/"&gt;this blog post&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;In my &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; based application, I use &lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt; to get questions and answers for forums on every topic page. The application sends back &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; to the Javascript functions which display the questions and answers from the JSON objects.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://code.djangoproject.com/browser/django/trunk/django/core/serializers/json.py"&gt;DjangoJSONEncoder&lt;/a&gt; (scroll to the end of this module) provided by Django serializes dates in a specific format. I wanted to change this so that a date would be serialized as &lt;span style="font-style: italic;"&gt;'2 days ago'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A bit of Googling bought me to &lt;a href="http://blog.quaternio.net/2009/07/16/json-encoding-and-decoding-with-custom-objects-in-python/"&gt;Jessy's very nice blog post&lt;/a&gt;, which explained very nicely how to create a custom Encoder to be used for serializing objects in Python. This seemed like a good idea, so I wrote my custom encoder to change the way dates are displayed;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="python"&gt;&lt;br /&gt;class Web20DatesEncoder(DjangoJSONEncoder):&lt;br /&gt;  SECONDS_IN_HR = 60 * 60&lt;br /&gt;  SECONDS_IN_MIN = 60&lt;br /&gt;  def default(self, object):&lt;br /&gt;    if isinstance(object, datetime.datetime):&lt;br /&gt;      delta = datetime.datetime.now() - object&lt;br /&gt;      return self.get_delta_as_string(delta)&lt;br /&gt;    else:&lt;br /&gt;      return super(Web20DatesEncoder, self).default(object)&lt;br /&gt;&lt;br /&gt;  def get_delta_as_string(self, delta):&lt;br /&gt;    days = delta.days&lt;br /&gt;    seconds = delta.seconds&lt;br /&gt;    hours = 0&lt;br /&gt;    minutes = 0&lt;br /&gt;    hours = seconds / self.SECONDS_IN_HR&lt;br /&gt;    seconds = seconds % self.SECONDS_IN_HR&lt;br /&gt;    minutes = seconds / self.SECONDS_IN_MIN&lt;br /&gt;    seconds = seconds % self.SECONDS_IN_MIN&lt;br /&gt;    delta_str = ''&lt;br /&gt;    if days &gt; 0:&lt;br /&gt;      delta_str += str(days) + ' days, '&lt;br /&gt;    if hours &gt; 0:&lt;br /&gt;      delta_str += str(hours) + ' hours, '&lt;br /&gt;    if days &lt;= 0 and seconds &gt; 0:&lt;br /&gt;      delta_str += str(seconds) + ' secs, '&lt;br /&gt;    return delta_str&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, I could not figure out how to hook this class into the call chain so that it is used when my QuerySet is serialized as such;&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="python"&gt;&lt;br /&gt;res = serializers.serialize(”json”, questions)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One solution which came up was to use the 'cls' parameter in the call to serialize.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="python"&gt;&lt;br /&gt;res = serializers.serialize(”json”, questions, cls=Web20DatesEncoder)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, when I ran my code, there was an error:&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;dump() got multiple values for keyword argument ‘cls’&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Why do we get this error? Maybe (I still do understand Python well enough to be sure) because, the end_serialization method in &lt;a href="http://code.djangoproject.com/browser/django/trunk/django/core/serializers/json.py"&gt;django.core.Serializers.json.Serializer&lt;/a&gt; has the following line:&lt;br /&gt;&lt;pre class="prettyprint" code="python"&gt;&lt;br /&gt;simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see it specifically passes &lt;code&gt;cls=DjangoJSONEncoder&lt;/code&gt; to &lt;code&gt;simplejson.dump(...)&lt;/code&gt;, and this is the reason why we get the above error message.&lt;br /&gt;&lt;br /&gt;Now I do not know what is the right way to resolve this issue, but here's how I did it. I created a subclass of JSONSerializer, such that my subclass used my custom encoder.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="python"&gt;&lt;br /&gt;from django.core.serializers.json import Serializer as JSONSerializer&lt;br /&gt;&lt;br /&gt;class DateModifyingJSONSerializer(JSONSerializer):&lt;br /&gt;  def end_serialization(self):&lt;br /&gt;    self.options.pop('stream', None)&lt;br /&gt;    self.options.pop('fields', None)&lt;br /&gt;    simplejson.dump(self.objects, self.stream, cls=Web20DatesEncoder, **self.options)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and the client code which earlier instantiated JSONSerializer now uses DateModifyingJSONSerializer.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="python"&gt;&lt;br /&gt;#Here is the code snippet which uses the above class&lt;br /&gt;json_serializer = DateModifyingJSONSerializer()&lt;br /&gt;res = json_serializer.serialize(query_set)&lt;br /&gt;&lt;br /&gt;#instead of old code shown below&lt;br /&gt;#serializers.get_serializer("json")()&lt;br /&gt;#res = json_serializer.serialize(query_set)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I hope you find this solution useful. Please leave a comment if it helped you, or if you know a better way to perform this task.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-7630176711517139435?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/7630176711517139435/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=7630176711517139435" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7630176711517139435?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/7630176711517139435?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/08/custom-json-encoder-in-django.html" title="Custom JSON Encoder in Django" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DkEBQnYzfip7ImA9WxJbE0k.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-8204675158897302375</id><published>2009-07-23T15:38:00.004+05:30</published><updated>2009-07-23T15:54:13.886+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-23T15:54:13.886+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git partial_add" /><title>Git supports commiting specific parts of a file</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xYOBdvKq5TyIgM_6Izx0RpJ1uTQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xYOBdvKq5TyIgM_6Izx0RpJ1uTQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xYOBdvKq5TyIgM_6Izx0RpJ1uTQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xYOBdvKq5TyIgM_6Izx0RpJ1uTQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;While working on my web based learning project, I made a lot of changes to a Django view file without committing them. When I actually decided to commit, I realized that the changes in my view file should go into separate commits. I knew it was possible to commit parts of a file in Git, but I was not sure exactly how it could be done.&lt;br /&gt;&lt;br /&gt;I asked the &lt;a href="http://stackoverflow.com/questions/1170660/commiting-specific-parts-of-a-file-in-git"&gt;question on StackOverflow&lt;/a&gt; and got an answer within minutes :-)&lt;br /&gt;&lt;br /&gt;Anyways here's how I did it. I had 3 files in my index:&lt;br /&gt;&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;urls.py&lt;br /&gt;app/courses/templates/course/show.html&lt;br /&gt;app/courses/view.py&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first 2 files were fine, but I did not want to commit the entire view file with the first two, I wanted only one change in that file to go in this commit.&lt;br /&gt;&lt;br /&gt;Since I had already added the view file to the index, I first had to unstage it with:&lt;br /&gt;&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;git reset app/courses/view.py&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I did an interactive add to add only one hunk from the view file:&lt;br /&gt;&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;git add --patch apps/courses/view.py&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Running this command showed me the first hunk from the file and an option asking me if I wanted ti stage that hunk. I decided I did not want the first hunk, then it showed me the second hunk. This was the change I wanted, so I entered 'y' at the option and proceeded to enter 'n' for all the remaining hunks.&lt;br /&gt;&lt;br /&gt;After this I wanted to ensure that the right hunk from the file was staged to be committed, so I typed:&lt;br /&gt;&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;git diff --color --cached apps/courses/view.py&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This showed me all the changed that were staged. After ensuring that the changes I wanted were the ones staged, I commited them with:&lt;br /&gt;&lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;&lt;br /&gt;git commit&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-8204675158897302375?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/8204675158897302375/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=8204675158897302375" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/8204675158897302375?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/8204675158897302375?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/07/git-supports-commiting-specific-parts.html" title="Git supports commiting specific parts of a file" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0UBRXc6cSp7ImA9WxJUE0w.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-2581247630723394668</id><published>2009-07-11T14:33:00.008+05:30</published><updated>2009-07-11T16:50:54.919+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-11T16:50:54.919+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><title>JQuery selectors and future elements</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/i21ZC5VZWa_Elp0QcoEOBn46sxI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i21ZC5VZWa_Elp0QcoEOBn46sxI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/i21ZC5VZWa_Elp0QcoEOBn46sxI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i21ZC5VZWa_Elp0QcoEOBn46sxI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I am using &lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt; for the AJAX and dynamic aspects of my web based learning platform.&lt;br /&gt;&lt;br /&gt;I like the fact that JQuery allows us to use &lt;a href="http://en.wikipedia.org/wiki/Cascading_Style_Sheets"&gt;CSS&lt;/a&gt; type selectors to select elements on the page to either manipulate them, add event handlers, or a host of other things.&lt;br /&gt;&lt;br /&gt;So, the code below intercepts clicks on all links and dynamically adds a new link when a link is clicked.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;lt;link rel="stylesheet" type="text/css" href="/site-media/al/style.css" /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;lt;script type="text/javascript" src="./jquery-1.3.2.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;  &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;    $(document).ready(function() {&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;      $("a").click(function() {&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;        $("ul#questions").append("&amp;lt;li&amp;gt;&amp;lt;a href='#'&amp;gt;click me&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;");&lt;br /&gt;     &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;});&lt;br /&gt;   &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;});&lt;br /&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;lt;/script&amp;gt;&lt;br /&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;    &amp;lt;ul id="questions"&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;      &amp;lt;li&amp;gt;&amp;lt;a href="#"&amp;gt;Click Me: 0&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;    &amp;lt;/ul&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt; &lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;    &amp;lt;textarea style="Width: 400px; Height: 200px" name="textarea" cols=20&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There is a problem with this code. Everytime you click on the link called "Click Me: 0" a new link is added, but if you click on the new link, then nothing happens. So, why does JQuery not work with dynamically added elements?&lt;br /&gt;&lt;br /&gt;The reason is because the following call&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="javascript"&gt;&lt;br /&gt;$("a").click(function() {&lt;br /&gt;//...&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;only binds to the anchor elements present on the webpage when the $(document).ready() function is called. It will not bind to future elements. To bind to future elements as well, we have to use the &lt;a href="http://docs.jquery.com/Events/live"&gt;live()&lt;/a&gt; function.&lt;br /&gt;&lt;br /&gt;Try using this code to bind to the "a" elements and it will work.&lt;br /&gt;&lt;pre class="prettyprint" code="javascript"&gt;&lt;br /&gt;$("a").live("click", function() {&lt;br /&gt; $("div#questions").append("&lt;a href="http://www.blogger.com/post-edit.g?blogID=7520738&amp;amp;postID=2581247630723394668#"&gt;click me&lt;/a&gt;");&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-2581247630723394668?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/2581247630723394668/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=2581247630723394668" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/2581247630723394668?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/2581247630723394668?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/07/jquery-selectors-and-future-elements.html" title="JQuery selectors and future elements" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;AkEBQXk5eSp7ImA9WxJVFU4.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-3677458748466885718</id><published>2009-07-02T17:46:00.003+05:30</published><updated>2009-07-02T18:14:10.721+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-02T18:14:10.721+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iptables" /><title>Refreshing iptables</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yuQSRauzZ5bjXKO_Om55r8RTCjE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yuQSRauzZ5bjXKO_Om55r8RTCjE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yuQSRauzZ5bjXKO_Om55r8RTCjE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yuQSRauzZ5bjXKO_Om55r8RTCjE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;The last time I played around with IPTables was about 6 - 7 years back. I have been working with a Linux box again from the last few months and I am absolutely thrilled about it. Nevertheless, I have also been meaning to set up a simple IPTables firewall on my machine.&lt;br /&gt;&lt;br /&gt;Since I had forgotten all my IPTables concepts, I decided to hunt the Internet for some good articles. I found some really nice resources to refresh my memory as well as learn new things.&lt;br /&gt;&lt;br /&gt;Here is a nice 3 part video series from &lt;a href="http://www.linuxjournal.com/"&gt;Linux Journal&lt;/a&gt;.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.linuxjournal.com/video/mastering-iptables-part-i"&gt;iptables part 1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.linuxjournal.com/video/mastering-iptables-part-2"&gt;iptables part 2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.linuxjournal.com/video/mastering-iptables-final-installment"&gt;iptables part 3&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;The entire series takes less than a half hour and is a good refresher or introduction to IPTables.&lt;br /&gt;&lt;br /&gt;Here is a &lt;a href="http://jengelh.medozas.de/images/nf-packet-flow.png"&gt;nice picture&lt;/a&gt; which explains how a packet is routed through various chains in the ip tables. If you are looking for a quick refresher, this might help you out.&lt;br /&gt;&lt;br /&gt;If you want more details, here is a &lt;a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables"&gt;tutoria&lt;/a&gt;l, and yet &lt;a href="http://iptables-tutorial.frozentux.net/"&gt;another tutorial&lt;/a&gt;, and &lt;a href="http://www.netfilter.org/"&gt;Netfilter's&lt;/a&gt; excellent &lt;a href="http://www.netfilter.org/documentation/index.html"&gt;documentation&lt;/a&gt; on IPTables.&lt;br /&gt;&lt;br /&gt;So now there is no excuse for not setting up a little firewall on your Linux box.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-3677458748466885718?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/3677458748466885718/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=3677458748466885718" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/3677458748466885718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/3677458748466885718?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/07/refreshing-iptables.html" title="Refreshing iptables" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEUNRXo6cCp7ImA9WxJWFkQ.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-3224751927408103524</id><published>2009-06-22T22:46:00.002+05:30</published><updated>2009-06-22T23:08:14.418+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-22T23:08:14.418+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="inheritance" /><category scheme="http://www.blogger.com/atom/ns#" term="composition" /><title>Inheritance vs. composition depending on how much is same and how much differs</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Nxw5i7zIMZzcFsRRyVLi1AulKRc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Nxw5i7zIMZzcFsRRyVLi1AulKRc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Nxw5i7zIMZzcFsRRyVLi1AulKRc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Nxw5i7zIMZzcFsRRyVLi1AulKRc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I am reading the excellent &lt;a href="http://www.djangobook.com"&gt;Django book&lt;/a&gt; right now. In the 4th chapter on &lt;a href="http://www.djangobook.com/en/2.0/chapter04/"&gt;Django templates&lt;/a&gt;, there is an example of includes and inheritance in Django templates.&lt;br /&gt;&lt;br /&gt;Without going into details about Django templates, the include is very similar to composition where we can include the text of another template for evaluation. Inheritance in Django templates works in a way similar to object inheritance. Django templates can specify certain blocks which can be redefined in subtemplates. The subtemplates use the rest of the parent template as is.&lt;br /&gt;&lt;br /&gt;Now we have all learned that inheritance is used when we have a is-a relationship between classes, and composition is used when we have a contains-a relationship. This is absolutely right, but while reading about Django templates, I just realized another pattern in these relationships. This is really simple and perhaps many of you may have already have had this insight...&lt;br /&gt;&lt;br /&gt;We use inheritance when we want to allow reuse of the bulk of one object in other objects such that it can change a few things as per it's requirements. So in a way we have a template which we want to allow reuse of in the greater part and modification of in the smaller part. On the other hand we use composition when we want to reuse another object in this object. So we have a template in which we want to plug some holes in functionality.&lt;br /&gt;&lt;br /&gt;Does this make sense?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-3224751927408103524?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/3224751927408103524/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=3224751927408103524" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/3224751927408103524?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/3224751927408103524?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/06/inheritance-vs-composition-depending-on.html" title="Inheritance vs. composition depending on how much is same and how much differs" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;DkMBRn0-fyp7ImA9WxJWEEs.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-4698590796154664774</id><published>2009-06-15T15:49:00.005+05:30</published><updated>2009-06-15T16:44:17.357+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-15T16:44:17.357+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="slashy_string" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>Slashy strings in Groovy</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cvaQuR2DcqrVfXOFEQyNi8Tzyok/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cvaQuR2DcqrVfXOFEQyNi8Tzyok/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cvaQuR2DcqrVfXOFEQyNi8Tzyok/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cvaQuR2DcqrVfXOFEQyNi8Tzyok/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Groovy has done a great job of enhancing Java Strings. It offers a lot of features like String interpolation with GStrings, triple quoted Strings, multi-line Strings, and slashy Strings.&lt;br /&gt;&lt;br /&gt;In this post I will talk about slashy Strings in Groovy. But before doing that let us see how we represent a regular expression in Java. Let's say I have a list of fully qualified file names and I want to match all files in my 'c:\tmp' directory.&lt;br /&gt;&lt;br /&gt;I would create a String to represent my regex in Java like this:&lt;br /&gt;String exp = "C:\\\\tmp\\\\.*"&lt;br /&gt;&lt;br /&gt;The four '\' are needed because '\' is a meta character in regular expressions, so we need to represent a '\' as a '\\'. Because a '\' is used for escaping special characters in Java, we need to represent '\\' as '\\\\'. Wow doesn't this look cumbersome. Well, this is not just one case. Regular expressions make use of the '\' character for special classes. Everytime we want to use a '\w' or a '\d' or something like that we will have to use '\\w' and '\\d' instead. &lt;br /&gt;&lt;br /&gt;Slashy Strings in Groovy give us a way around this by allowing us to represent regular expressions just like they would be represented without having to escape the '\' in Java.&lt;br /&gt;&lt;br /&gt;Using them we can write &lt;br /&gt;&lt;br /&gt;def file = /C:\\tmp\\.*/&lt;br /&gt;&lt;br /&gt;Notice that slashy Strings have to be surrounded by forward slashes, and are mostly used when Strings need to represent regular expressions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-4698590796154664774?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/4698590796154664774/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=4698590796154664774" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4698590796154664774?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4698590796154664774?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/06/slashy-strings-in-groovy.html" title="Slashy strings in Groovy" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkQAQn8yfyp7ImA9WxJQF0o.&quot;"><id>tag:blogger.com,1999:blog-7520738.post-4673147444312432858</id><published>2009-05-30T23:09:00.005+05:30</published><updated>2009-05-31T19:29:03.197+05:30</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-31T19:29:03.197+05:30</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="groovy grails unittest" /><title>Testing Groovy domain classes</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yvW_zyxUApTjxC2OZpYmeR5Z73Y/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yvW_zyxUApTjxC2OZpYmeR5Z73Y/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yvW_zyxUApTjxC2OZpYmeR5Z73Y/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yvW_zyxUApTjxC2OZpYmeR5Z73Y/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;If you are trying to test Grails domain class constraints by putting your unit test cases in the  'test/unit' directory, then your tests will fail because the domain objects will not have the 'valdate' method. This can be resolved in two ways:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Place the test cases inside test/integration (which will slow things down)&lt;/li&gt;&lt;li&gt;Use the method 'mockForConstraintsTests(Trail)' to create mock method in your domain class and continue writing your test cases in 'test/unit'&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;What follows is some example code around this finding.&lt;br /&gt;&lt;br /&gt;I am working on a Groovy on Grails project for a website to help programmers keep up and refresh their skills.&lt;br /&gt;&lt;br /&gt;I started with some &lt;a href="http://www.grails.org/GORM"&gt;domain classes&lt;/a&gt; and then moved on to write some unit tests. When we create a Grails project using &lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;grails create-app&lt;/pre&gt;, &lt;br /&gt;it creates several directories, one of which is a directory called 'test' for holding unit tests. This directory contains two directories, 'unit', and 'integration' for unit and integration tests respectively.&lt;br /&gt;&lt;br /&gt;Now begins an interesting journey with writing unit tests in Groovy. I wanted to write tests for my domain classes. A simple domain class like the one I have below can contain only properties and constraints for those properties. This is what Trail.groovy looks like.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="groovy"&gt;&lt;br /&gt;class Trail {&lt;br /&gt; String shortName&lt;br /&gt; String name&lt;br /&gt; String description&lt;br /&gt;&lt;br /&gt; def hasMany = [learningObjects:LearningObject]&lt;br /&gt;&lt;br /&gt; static constraints = {&lt;br /&gt;   shortName(maxSize:6, blank:false)&lt;br /&gt;   name(maxSize:75, blank:false)&lt;br /&gt;   description(maxSize:2048, blank:false)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I wanted to start writing unit tests to test the constraints. When Grails creates a domain class, it injects several methods in it at runtime , one of which is a method called 'validate'. This method is called before the domain object is saved and it will return a false if the domain object has violated any constraints. So, I created a simple unit test to test the constraints of Trail.groovy&lt;br /&gt;&lt;br /&gt;This is what my initial test case looked like.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="groovy"&gt;&lt;br /&gt;import grails.test.*&lt;br /&gt;&lt;br /&gt;class TrailTests extends GrailsUnitTestCase {&lt;br /&gt;&lt;br /&gt;  def trail&lt;br /&gt;&lt;br /&gt;  protected void setUp() {&lt;br /&gt;    super.setUp()&lt;br /&gt;    trail = new Trail(shortName:'sname',&lt;br /&gt;                            name:'Java 101',&lt;br /&gt;                            description:'This is a basic Java course')&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void tearDown() {&lt;br /&gt;    super.tearDown()&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  void testShortNameConstraints() {&lt;br /&gt;    assertTrue(trail.validate())&lt;br /&gt;    trail.shortName = 'thisisaverylongname'&lt;br /&gt;    assertFalse(trail.validate())&lt;br /&gt;    trail.shortName = ''&lt;br /&gt;    assertFalse(trail.validate())&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  //... further methods not shown&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When I ran my tests using &lt;br /&gt;&lt;pre class="adaptiveconsole"&gt;grails test-app&lt;/pre&gt; &lt;br /&gt;(See how well Grails integrated testing), I got a bunch of errors that told me that the 'validate' method was not found. If you enjoy looking at stack traces... feast your eyes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Testcase: testShortNameConstraints took 0.159 sec&lt;br /&gt; Caused an ERROR&lt;br /&gt;No signature of method: Trail.validate() is applicable for argument types: () values: []&lt;br /&gt;groovy.lang.MissingMethodException: No signature of method: Trail.validate() is applicable for argument types: () values: []&lt;br /&gt; at TrailTests.testShortNameConstraints(TrailTests.groovy:20)&lt;br /&gt; at _GrailsTest_groovy$_run_closure4.doCall(_GrailsTest_groovy:203)&lt;br /&gt; at _GrailsTest_groovy$_run_closure4.call(_GrailsTest_groovy)&lt;br /&gt; at _GrailsTest_groovy$_run_closure2.doCall(_GrailsTest_groovy:147)&lt;br /&gt; at _GrailsTest_groovy$_run_closure1_closure19.doCall(_GrailsTest_groovy:113)&lt;br /&gt; at _GrailsTest_groovy$_run_closure1.doCall(_GrailsTest_groovy:96)&lt;br /&gt; at TestApp$_run_closure1.doCall(TestApp.groovy:66)&lt;br /&gt; at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:324)&lt;br /&gt; at gant.Gant$_dispatch_closure6.doCall(Gant.groovy:334)&lt;br /&gt; at gant.Gant$_dispatch_closure6.doCall(Gant.groovy)&lt;br /&gt; at gant.Gant.withBuildListeners(Gant.groovy:344)&lt;br /&gt; at gant.Gant.this$2$withBuildListeners(Gant.groovy)&lt;br /&gt; at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)&lt;br /&gt; at gant.Gant.dispatch(Gant.groovy:334)&lt;br /&gt; at gant.Gant.this$2$dispatch(Gant.groovy)&lt;br /&gt; at gant.Gant.invokeMethod(Gant.groovy)&lt;br /&gt; at gant.Gant.processTargets(Gant.groovy:495)&lt;br /&gt; at gant.Gant.processTargets(Gant.groovy:480)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After some Googling I realized that the 'validate' method is injected into domain objects by the Grails framework, and therefore it does not exist when we instantiate the domain object from test code. I later found that if a test is placed inside 'test/integration' then the test cases are created as the objects would have been created by the Grails framework. So the domain objects would have the 'validate' method. But I also read in another place (I cannot remember where), that if possible it is k better to mock these special methods instead of putting tests in the integration directory, since these tests take longer to instantiate and can slow down the overral running time. And I found in yet another place that there exists a method called 'mockForConstraintsTests(Trail)' which will inject the 'validate' method along with some other methods. So, I added this mock method to my setup after which I was able to run my tests successfully.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint" code="groovy"&gt;&lt;br /&gt;  protected void setUp() {&lt;br /&gt;    super.setUp()&lt;br /&gt;    mockForConstraintsTests(Trail)&lt;br /&gt;    trail = new Trail(shortName:'sname',&lt;br /&gt;                            name:'Java 101',&lt;br /&gt;                            description:'This is a basic Java course')&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The rest of the class is the same.&lt;br /&gt;&lt;br /&gt;So to summarize, if you are trying to test constraints in Grails domain classes, you have two options:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Place the test cases inside test/integration (which will slow things down)&lt;/li&gt;&lt;li&gt;Use the method 'mockForConstraintsTests(Trail)' to create mock method in your domain class and continue writing your test cases in 'test/unit'&lt;/li&gt;&lt;/ol&gt;I will post more such episodes of how Google helped me resolve issues I faced while developing :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7520738-4673147444312432858?l=blog.adaptivesoftware.biz' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.adaptivesoftware.biz/feeds/4673147444312432858/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7520738&amp;postID=4673147444312432858" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4673147444312432858?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7520738/posts/default/4673147444312432858?v=2" /><link rel="alternate" type="text/html" href="http://blog.adaptivesoftware.biz/2009/05/testing-groovy-domain-classes.html" title="Testing Groovy domain classes" /><author><name>Parag</name><uri>http://www.blogger.com/profile/16885449156962300704</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>9</thr:total></entry></feed>

