tag:blogger.com,1999:blog-220442262024-03-05T15:43:52.464+05:30Tech BitsSujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.comBlogger57125tag:blogger.com,1999:blog-22044226.post-26248311766359374712023-12-13T15:21:00.003+05:302023-12-13T15:39:53.765+05:30Test Driven Development -- An Example<div style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">This post is written as a model answer to an exam question. As I have clarified earlier, this is way too long to be written in the exam. But, it suffices as an example.</span></div><div style="text-align: justify;"><br /></div><div style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">The main philosophy of test-driven development is:</span></div><div style="text-align: left;"><ul style="text-align: left;"><li style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">Use test cases as specifications.</span></li><li style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">Test cases should be written preferably before the part of the implementation they test. Hence, a newly introduced test would typically fail. Then the code should be modified to make it pass, possibly followed by some refactoring to improve the design.</span></li><li style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">We stop coding as soon as we get all test cases to pass.</span></li><li style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">If we are thinking of a new feature, or cases within the new feature, we should first write a test case corresponding to that.</span></li></ul></div><div style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">These tests become part of the project assets, and can be used later at any point in time. </span><span style="font-family: georgia; font-size: large;">TDD is aligned with agile methodology as it focuses on creating work code as opposed to separate documentation.</span></div><div style="text-align: justify;"><span style="font-family: georgia; font-size: medium;"><br /></span></div><div style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">First set up the testing environment. For simplicity and self-sufficiency, I have </span><span style="font-family: georgia; font-size: medium;">created my own TestResult class</span><span style="font-family: georgia; font-size: large;">.</span></div><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #557799;">#include <iostream></span>
<span style="color: #008800; font-weight: bold;">using</span> <span style="color: #008800; font-weight: bold;">namespace</span> std;
<span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">TestResult</span> {
<span style="color: #997700; font-weight: bold;">public:</span>
<span style="color: #008800; font-weight: bold;">const</span> <span style="color: #333399; font-weight: bold;">bool</span> result;
<span style="color: #008800; font-weight: bold;">const</span> string message;
TestResult(<span style="color: #333399; font-weight: bold;">bool</span> r, string m) <span style="color: #333333;">:</span> result(r), message(m) {}
};
</pre></div>
<p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">The algorithm for palindrome detection that I want to use is the following:</span></p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p style="text-align: justify;"><span style="color: #274e13; font-family: helvetica; font-size: medium;">match S with:</span></p></blockquote><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p style="text-align: justify;"><span style="color: #274e13; font-family: helvetica; font-size: medium;">case "" --> raise exception</span></p></blockquote><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p style="text-align: justify;"><span style="color: #274e13; font-family: helvetica; font-size: medium;">case "x" --> true</span></p></blockquote><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p style="text-align: justify;"><span style="color: #274e13; font-family: helvetica; font-size: medium;">case "xy" --> x = y</span></p></blockquote><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p style="text-align: justify;"><span style="color: #274e13; font-family: helvetica; font-size: medium;">case "xS'y" --> x = y /\ pal(S')</span></p></blockquote></blockquote><div style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">This is not the most efficient implementation. But that is not the point here. We </span><span style="font-family: georgia; font-size: medium;">intend this to be an illustration of the test-driven methodology.</span></div><p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">Going by the above algorithm, the first case we would like to test is that if </span><span style="font-size: medium;"><span style="font-family: georgia;">an empty string is given, the function should throw an exception. The test case </span><span style="font-family: georgia;">for checking this is as follows:</span></span></p><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 16.25px; margin-bottom: 0px; margin-top: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t1</span>() {
try {
isPalindrome(<span style="background-color: #fff0f0;">""</span>);
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception not thrown"</span>);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">true</span>, e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}</pre></div><p><span style="font-family: georgia; font-size: medium;">The main function or the driver for now is as follows:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">main</span>() {
TestResult r1 <span style="color: #333333;">=</span> t1();
cout <span style="color: #333333;"><<</span> r1.result <span style="color: #333333;"><<</span> <span style="background-color: #fff0f0;">", "</span> <span style="color: #333333;"><<</span> r1.message <span style="color: #333333;"><<</span> endl;
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #0000dd; font-weight: bold;">0</span>;
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">The first cut implementation of the isPalindrome function is as follows:</span></p>
<span style="font-size: medium;"><!--HTML generated using hilite.me--></span><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333399; font-weight: bold;">bool</span> <span style="color: #0066bb; font-weight: bold;">isPalindrome</span>(string s) {
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #007020;">true</span>;
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">As you can see, it's designed to fail t1. And when we run it, it indeed </span><span style="font-family: georgia; font-size: medium;">does:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">0, Exception not thrown
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">Next we modify the function to make t1 pass.</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333399; font-weight: bold;">bool</span> <span style="color: #0066bb; font-weight: bold;">isPalindrome</span>(string s) {
<span style="color: #008800; font-weight: bold;">if</span>(s <span style="color: #333333;">==</span> <span style="background-color: #fff0f0;">""</span>) {
<span style="color: #008800; font-weight: bold;">throw</span> string(<span style="background-color: #fff0f0;">"Empty string provided"</span>);
}
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #007020;">true</span>;
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">t1 passes:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">Now, we wish to handle the next case.</span></p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;"><p style="text-align: left;"><span style="color: #274e13; font-family: helvetica; font-size: medium;">case "x" --> true</span></p></blockquote>
<span style="color: #274e13; font-family: helvetica;"><!--HTML generated using hilite.me--></span><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t2</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"a"</span>);
TestResult r(ans <span style="color: #333333;">==</span> <span style="color: #007020;">true</span>, <span style="background-color: #fff0f0;">""</span>);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">This test passes without any need of change to the code.</span></p><p><span style="font-family: georgia; font-size: medium;">So, we move over to the next case:</span></p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;"><p style="text-align: left;"><span style="white-space: normal;"><span style="font-size: medium;"><span style="font-family: georgia; white-space: pre;"> </span><span style="color: #274e13; font-family: helvetica;">case "xy" --> x = y</span></span></span></p></blockquote><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t3</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"aa"</span>);
TestResult r(ans <span style="color: #333333;">==</span> <span style="color: #007020;">true</span>, <span style="background-color: #fff0f0;">"Correct!"</span>);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">This passes:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
</pre></div>
<p><span style="font-size: medium;"><span style="font-family: georgia;">But we need to test this case more, for the subcase when we are </span><span style="font-family: georgia;">expecting a negative answer:</span></span></p>
<span style="font-size: medium;"><!--HTML generated using hilite.me--></span><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t4</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"ab"</span>);
<span style="color: #333399; font-weight: bold;">bool</span> result <span style="color: #333333;">=</span> ans <span style="color: #333333;">==</span> <span style="color: #007020;">false</span>;
string message <span style="color: #333333;">=</span> result <span style="color: #333333;">?</span> <span style="background-color: #fff0f0;">"Correct"</span> <span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">"Wrong answer"</span>;
TestResult r(ans <span style="color: #333333;">==</span> <span style="color: #007020;">false</span>, message);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">As expected, this test case fails:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
0, Wrong answer
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">The palindrome function needs to be modified appropriately to make this </span><span style="font-family: georgia; font-size: medium;">test case pass:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333399; font-weight: bold;">bool</span> <span style="color: #0066bb; font-weight: bold;">isPalindrome</span>(string s) {
<span style="color: #008800; font-weight: bold;">if</span>(s <span style="color: #333333;">==</span> <span style="background-color: #fff0f0;">""</span>) {
<span style="color: #008800; font-weight: bold;">throw</span> string(<span style="background-color: #fff0f0;">"Empty string provided"</span>);
}
<span style="color: #008800; font-weight: bold;">if</span>(s.size() <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">1</span>) {
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #007020;">true</span>;
}
<span style="color: #008800; font-weight: bold;">if</span>(s.size() <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">2</span>) {
<span style="color: #008800; font-weight: bold;">return</span> s[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #333333;">==</span> s[<span style="color: #0000dd; font-weight: bold;">1</span>];
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">Now, t4 passes:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">Now that we have tested the third case to our satisfaction, we move </span><span style="font-family: georgia; font-size: medium;">over to the final case:</span></p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;"><div style="text-align: left;"><span style="white-space: normal;"><span style="font-size: medium;"><span style="font-family: georgia; white-space: pre;"> </span><span style="color: #274e13; font-family: helvetica;">case "xS'y" --> x = y and pal(S')</span></span></span></div></blockquote><p><span style="font-family: georgia; font-size: medium;">We first add a test case for testing the final case:</span></p>
<span style="font-size: medium;"><!--HTML generated using hilite.me--></span><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t5</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"aba"</span>);
<span style="color: #333399; font-weight: bold;">bool</span> result <span style="color: #333333;">=</span> ans <span style="color: #333333;">==</span> <span style="color: #007020;">true</span>;
string message <span style="color: #333333;">=</span> result <span style="color: #333333;">?</span> <span style="background-color: #fff0f0;">"Correct"</span> <span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">"Wrong answer"</span>;
TestResult r(result, message);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">t5 passes without any need of code change.</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
1, Correct
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">Let's add t6 to check the negative case:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t6</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"abb"</span>);
<span style="color: #333399; font-weight: bold;">bool</span> result <span style="color: #333333;">=</span> ans <span style="color: #333333;">==</span> <span style="color: #007020;">false</span>;
string message <span style="color: #333333;">=</span> result <span style="color: #333333;">?</span> <span style="background-color: #fff0f0;">"Correct"</span> <span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">"Wrong answer"</span>;
TestResult r(result, message);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">This fails:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
1, Correct
0, Wrong answer
</pre></div>
<p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">This requires us to implement another function, say 'sub', which gives </span><span style="font-size: medium;"><span style="font-family: georgia;">us a copy of the passed string with the first and the last character </span><span style="font-family: georgia;">omitted. Formally:</span></span></p><p style="text-align: justify;"><span style="white-space: normal;"><span style="font-size: medium;"><span style="font-family: georgia; white-space: pre;"> </span><span style="color: #274e13; font-family: helvetica;">"xS'y" --> raise exception if S' = ""</span></span></span></p><p style="text-align: justify;"><span style="white-space: normal;"><span style="color: #274e13; font-family: helvetica; font-size: medium;"><span style="white-space: pre;"> </span>--> S' if S' != ""</span></span></p><p style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: georgia;">This should be used on strings with length greater than or equal to 2. </span><span style="font-family: georgia;">We make some code changes to make place for the sub function. We begin </span><span style="font-family: georgia;">with a dummy implementation of sub as follows:</span></span></p>
<span style="font-size: medium;"><!--HTML generated using hilite.me--></span><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">string <span style="color: #0066bb; font-weight: bold;">sub</span>(string s) {
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">"Hello"</span>;
}
<span style="color: #333399; font-weight: bold;">bool</span> <span style="color: #0066bb; font-weight: bold;">isPalindrome</span>(string s) {
<span style="color: #008800; font-weight: bold;">if</span>(s <span style="color: #333333;">==</span> <span style="background-color: #fff0f0;">""</span>) {
<span style="color: #008800; font-weight: bold;">throw</span> string(<span style="background-color: #fff0f0;">"Empty string provided"</span>);
}
<span style="color: #008800; font-weight: bold;">if</span>(s.size() <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">1</span>) {
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #007020;">true</span>;
}
<span style="color: #008800; font-weight: bold;">if</span>(s.size() <span style="color: #333333;">==</span> <span style="color: #0000dd; font-weight: bold;">2</span>) {
<span style="color: #008800; font-weight: bold;">return</span> s[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #333333;">==</span> s[<span style="color: #0000dd; font-weight: bold;">1</span>];
}
<span style="color: #008800; font-weight: bold;">return</span> s[<span style="color: #0000dd; font-weight: bold;">0</span>] <span style="color: #333333;">==</span> s[s.size() <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span>] <span style="color: #333333;">&&</span> isPalindrome(sub(s));
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">The above causes t6 to pass, but breaks t5.</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
0, Wrong answer
1, Correct
</pre></div>
<p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">We understand that this is because of the erroneous implementation of </span><span style="font-family: georgia; font-size: medium;">sub function. So, we turn our attention to sub.</span></p><p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">We start with a test case to check its first case:</span></p><div style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: georgia; white-space: pre;"> </span><span><span style="color: #274e13; font-family: helvetica;">"xS'y" --> raise exception if S' = ""</span></span></span></div><div style="text-align: justify;"><span style="font-size: large;"><span style="color: #274e13; font-family: helvetica;"><br /></span></span></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">TestResult <span style="color: #0066bb; font-weight: bold;">t7</span>() {
try {
string ans <span style="color: #333333;">=</span> sub(<span style="background-color: #fff0f0;">"a"</span>);
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception not thrown"</span>);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">true</span>, e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">t7 fails. And we make the requisite code modification to get it to pass.</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">string <span style="color: #0066bb; font-weight: bold;">sub</span>(string s) {
<span style="color: #008800; font-weight: bold;">if</span>(s.size() <span style="color: #333333;"><</span> <span style="color: #0000dd; font-weight: bold;">2</span>) {
<span style="color: #008800; font-weight: bold;">throw</span> string(<span style="background-color: #fff0f0;">"Insufficient size."</span>);
}
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">"Hello"</span>;
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">For sure, t7 passes:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
0, Wrong answer
1, Correct
1, Insufficient size.
</pre></div>
<p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">But t5 is still failing. Clearly, all is not well with sub. Anyway, </span><span style="font-family: georgia; font-size: medium;">let's proceed to handle the other case in sub:</span></p><div style="text-align: justify;"><span style="color: #274e13; font-family: helvetica; font-size: medium;"><span style="white-space: pre;"> </span><span>--> S' if S' != ""</span></span></div><p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">We jump any ceremony and make the following change to sub:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">string <span style="color: #0066bb; font-weight: bold;">sub</span>(string s) {
<span style="color: #008800; font-weight: bold;">if</span>(s.size() <span style="color: #333333;"><</span> <span style="color: #0000dd; font-weight: bold;">2</span>) {
<span style="color: #008800; font-weight: bold;">throw</span> string(<span style="background-color: #fff0f0;">"Insufficient size."</span>);
}
string new_s <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span>;
<span style="color: #008800; font-weight: bold;">for</span>(<span style="color: #333399; font-weight: bold;">unsigned</span> <span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span>; i <span style="color: #333333;"><</span> s.size() <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span>; i<span style="color: #333333;">++</span>) {
new_s <span style="color: #333333;">+=</span> s[i];
}
<span style="color: #008800; font-weight: bold;">return</span> new_s;
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">t5 passes:</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
1, Correct
1, Correct
1, Insufficient size.
</pre></div>
<p style="text-align: justify;"><span style="font-family: georgia; font-size: medium;">This has presumably completed our development of the code. However, </span><span style="font-size: medium;"><span style="font-family: georgia;">we need to run it through some more tests before we can call it </span><span style="font-family: georgia;">complete.</span></span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><div style="text-align: justify;">TestResult <span style="color: #0066bb; font-weight: bold;">t8</span>() {</div> try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"aba"</span>);
<span style="color: #333399; font-weight: bold;">bool</span> result <span style="color: #333333;">=</span> ans <span style="color: #333333;">==</span> <span style="color: #007020;">true</span>;
string message <span style="color: #333333;">=</span> result <span style="color: #333333;">?</span> <span style="background-color: #fff0f0;">"Correct"</span> <span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">"Wrong answer"</span>;
TestResult r(result, message);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
TestResult <span style="color: #0066bb; font-weight: bold;">t9</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"abba"</span>);
<span style="color: #333399; font-weight: bold;">bool</span> result <span style="color: #333333;">=</span> ans <span style="color: #333333;">==</span> <span style="color: #007020;">true</span>;
string message <span style="color: #333333;">=</span> result <span style="color: #333333;">?</span> <span style="background-color: #fff0f0;">"Correct"</span> <span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">"Wrong answer"</span>;
TestResult r(result, message);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
TestResult <span style="color: #0066bb; font-weight: bold;">t10</span>() {
try {
<span style="color: #333399; font-weight: bold;">bool</span> ans <span style="color: #333333;">=</span> isPalindrome(<span style="background-color: #fff0f0;">"aaba"</span>);
<span style="color: #333399; font-weight: bold;">bool</span> result <span style="color: #333333;">=</span> ans <span style="color: #333333;">==</span> <span style="color: #007020;">false</span>;
string message <span style="color: #333333;">=</span> result <span style="color: #333333;">?</span> <span style="background-color: #fff0f0;">"Correct"</span> <span style="color: #333333;">:</span> <span style="background-color: #fff0f0;">"Wrong answer"</span>;
TestResult r(result, message);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
<span style="color: #008800; font-weight: bold;">catch</span> (string e) {
TestResult r(<span style="color: #007020;">false</span>, <span style="background-color: #fff0f0;">"Exception: "</span> <span style="color: #333333;">+</span> e);
<span style="color: #008800; font-weight: bold;">return</span> r;
}
}
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">To our pleasure, all these new test cases pass in one shot!</span></p>
<!--HTML generated using hilite.me--><div style="background: rgb(240, 240, 240); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">1, Empty string provided
1,
1, Correct!
1, Correct
1, Correct
1, Correct
1, Insufficient size.
1, Correct
1, Correct
1, Correct
</pre></div>
<p><span style="font-family: georgia; font-size: medium;">This completes the test driven development of the isPalindrome function.</span></p>Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-50861526904792390622021-03-03T18:14:00.000+05:302021-03-03T18:14:18.715+05:30Automating Your Build with Makefiles<p style="text-align: justify;">I know I am getting into a well-known topic. What more, make is a pretty old technology. We have so many other cooler build automation technologies out there. IDEs like Eclipse and Visual Studio make it unnecessary to write your old build system in the first place.</p><p style="text-align: justify;">After the above negative marketing, let me tell you why then I am writing this post: because understanding how dependencies work between the various modules of your software is fundamentally connected to your design thinking. In fact, understanding how make's algorithm works at a high level is worth the effort. I present a prototype implementation of the same below, all of ~30 lines of OCaml code.</p><h3 style="text-align: left;">A Running Example</h3><p>(Adapted from a illustrative project by my student Anirudh C.) <br /></p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; border-color: gray; border-image: none 100% / 1 / 0 stretch; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: medium solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><table><tbody><tr><td><pre style="line-height: 125%; margin: 0px;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30</pre></td><td><pre style="line-height: 125%; margin: 0px;"><span style="color: #888888;">(* arith.ml -- begin *)</span>
<span style="color: #008800; font-weight: bold;">let</span> inc x <span style="color: #333333;">=</span> x <span style="color: #333333;">+</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #008800; font-weight: bold;">let</span> dec x <span style="color: #333333;">=</span> x <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #008800; font-weight: bold;">let</span> add x y <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> loop x y <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">if</span> y <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span> <span style="color: #008800; font-weight: bold;">then</span> x <span style="color: #008800; font-weight: bold;">else</span> loop <span style="color: #333333;">(</span>inc x<span style="color: #333333;">)</span> <span style="color: #333333;">(</span>dec y<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">in</span> loop x y
<span style="color: #008800; font-weight: bold;">let</span> sub x y <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> loop x y <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">if</span> y <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span> <span style="color: #008800; font-weight: bold;">then</span> x <span style="color: #008800; font-weight: bold;">else</span> loop <span style="color: #333333;">(</span>dec x<span style="color: #333333;">)</span> <span style="color: #333333;">(</span>dec y<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">in</span> loop x y
<span style="color: #888888;">(* arith.ml -- end *)</span>
<span style="color: #888888;">(* circle.ml -- begin*)</span>
<span style="color: #008800; font-weight: bold;">let</span> pi <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">.</span><span style="color: #0000dd; font-weight: bold;">141</span>
<span style="color: #008800; font-weight: bold;">let</span> area r <span style="color: #333333;">=</span> pi <span style="color: #333333;">*.</span> r <span style="color: #333333;">*.</span> r
<span style="color: #008800; font-weight: bold;">let</span> circumference r <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">.</span> <span style="color: #333333;">*.</span> pi <span style="color: #333333;">*.</span> r
<span style="color: #888888;">(* circle.ml - end *)</span>
<span style="color: #888888;">(* main.ml -- begin *)</span>
<span style="color: #008800; font-weight: bold;">let</span> main <span style="color: #007020;">()</span> <span style="color: #333333;">=</span>
print_endline <span style="color: #333333;">(</span>string_of_int <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">Arith</span>.add <span style="color: #0000dd; font-weight: bold;">1</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">));</span>
print_endline <span style="color: #333333;">(</span>string_of_int <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">Arith</span>.sub <span style="color: #0000dd; font-weight: bold;">3</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">));</span>
print_endline <span style="color: #333333;">(</span>string_of_float <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">Circle</span>.area <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">.))</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #333333;">_</span> <span style="color: #333333;">=</span> main <span style="color: #007020;">()</span>
<span style="color: #888888;">(* main.ml -- end *)</span>
</pre></td></tr></tbody></table></div>
<p style="text-align: justify;">In the code shown above, we have three modules, arith (arith.ml, arith.mli), circle (circle.ml, circle.mli) and main (main.ml, main.mli). main uses both arith and circle which are self contained modules. The OCaml implementation of the above idea, therefore, has the following additional files:</p><p>arith.cmi: The object code for the interface of arith module<br /></p><p>arith.cmo: The object code for the implementation of arith module</p><p>circle.cmi: The object code for the interface of circle module</p><p>circle.cmo: The object code for the implementation of circle module</p><p>main.cmi: The object code for the interface of main module</p><p>main.cmo: The object code for the implementation of main module</p><p>app: The final executable.</p><p> Here are the listings of the interface files:</p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; border-color: gray; border-image: none 100% / 1 / 0 stretch; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: medium solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><table><tbody><tr><td><pre style="line-height: 125%; margin: 0px;"> 1
2
3
4
5
6
7
8
9
10
11
12
13</pre></td><td><pre style="line-height: 125%; margin: 0px;"><span style="color: #888888;">(* arith.mli -- begin *)</span>
<span style="color: #008800; font-weight: bold;">val</span> add <span style="color: #333333;">:</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">int</span>
<span style="color: #008800; font-weight: bold;">val</span> sub <span style="color: #333333;">:</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">int</span>
<span style="color: #888888;">(* arith.mli -- end *)</span>
<span style="color: #888888;">(* circle.mli -- begin*)</span>
<span style="color: #008800; font-weight: bold;">val</span> area <span style="color: #333333;">:</span> <span style="color: #333399; font-weight: bold;">float</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">float</span>
<span style="color: #008800; font-weight: bold;">val</span> circumference <span style="color: #333333;">:</span> <span style="color: #333399; font-weight: bold;">float</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">float</span>
<span style="color: #888888;">(* circle.mli - end *)</span>
<span style="color: #888888;">(* main.mli -- begin *)</span>
<span style="color: #008800; font-weight: bold;">val</span> main<span style="color: #333333;">:</span> <span style="color: #333399; font-weight: bold;">unit</span> <span style="color: #333333;">-></span> <span style="color: #333399; font-weight: bold;">unit</span>
<span style="color: #888888;">(* main.mli -- end *)</span>
</pre></td></tr></tbody></table></div>
<p> <br /></p><p>The dependencies between the various files is shown by the following directed acyclic graph:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY9RNL0UVxYj30WmiSP2HjQlhLjyf02EtKOgCoFQqQ5Rq5EWEGVWRQogtn5QoG3jr1Zlon6LC0BDFMbjiXuNnrOvVDppjsyAzdD4yREXcVSk2-dEhY5AlGqZFkAaFZKCejlz3J/s1023/arirudh.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="469" data-original-width="1023" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiY9RNL0UVxYj30WmiSP2HjQlhLjyf02EtKOgCoFQqQ5Rq5EWEGVWRQogtn5QoG3jr1Zlon6LC0BDFMbjiXuNnrOvVDppjsyAzdD4yREXcVSk2-dEhY5AlGqZFkAaFZKCejlz3J/w400-h184/arirudh.png" width="400" /></a></div><br /><p style="text-align: justify;">As you can see, the dependencies look a bit complicated, if not a lot. Part of why it's this way has to do with the particular programming language that you are using. For example, OCaml has this idea of object code being generated from the interface files by compiling the .mli file. However, the most important aspect of this structure is agnostic to the programming language. That aspect of the dependencies is its directed acyclic nature. In the dependency graph above, you will find no cycles or loops.</p><p style="text-align: justify;">What impact do the above dependency relations have on build automation process. Here is the exhaustive sequence of build steps:</p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; border-color: gray; border-image: none 100% / 1 / 0 stretch; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: medium solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><table><tbody><tr><td><pre style="line-height: 125%; margin: 0px;">1
2
3
4
5
6
7</pre></td><td><pre style="line-height: 125%; margin: 0px;">ocamlc -c arith.mli <span style="color: #888888;"># builds arith.cmi</span>
ocamlc -c arith.ml <span style="color: #888888;"># builds arith.cmo</span>
ocamlc -c circle.mli <span style="color: #888888;"># builds circle.cmi</span>
ocamlc -c circle.ml <span style="color: #888888;"># builds circle.cmo</span>
ocamlc -c main.mli <span style="color: #888888;"># builds main.cmi</span>
ocamlc -c main.ml <span style="color: #888888;"># builds main.cmo</span>
ocamlc -o app arith.cmo circle.cmo main.cmo <span style="color: #888888;"># builds app</span>
</pre></td></tr></tbody></table></div>
<p><br /></p><p style="text-align: justify;">The first influence is the following: The dependee must always be compiled after all its dependencies have been compiled. The sequence in which the above steps are written respects this order.</p><p style="text-align: justify;">The second one is an opportunity of optimisation: <i>When you are building the application,
you compile only that part of the application which is depends on any
part which has been modified since the last build.</i> For example, if we make a modification in the circle.ml file, which parts of the build process need to be repeated? Looking at the dependency graph we can say that its circle.cmo, and app, because these are only two nodes in the graph from which you can reach circle.ml by following the directed edges of the dependence graph.</p><h3 style="text-align: justify;"> The make Algorithm</h3><p style="text-align: justify;">The make algorithm allows us to implement the above optimisation. We specify the dependency graph in a makefile. Here's the Makefile for the above application:</p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; border-color: gray; border-image: none 100% / 1 / 0 stretch; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: medium solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><table><tbody><tr><td><pre style="line-height: 125%; margin: 0px;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20</pre></td><td><pre style="line-height: 125%; margin: 0px;"><span style="color: #0066bb; font-weight: bold;">app </span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">arith.cmo circle.cmo main.cmo</span>
ocamlc -o app arith.cmo circle.cmo main.cmo
<span style="color: #0066bb; font-weight: bold;">arith.cmo</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">arith.ml arith.cmi</span>
ocamlc -c arith.ml
<span style="color: #0066bb; font-weight: bold;">circle.cmo</span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">circle.ml circle.cmi</span>
ocamlc -c circle.ml
<span style="color: #0066bb; font-weight: bold;">arith.cmi </span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">arith.mli</span>
ocamlc -c arith.mli
<span style="color: #0066bb; font-weight: bold;">circle.cmi </span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">circle.mli</span>
ocamlc -c circle.mli
<span style="color: #0066bb; font-weight: bold;">main.cmo </span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">main.ml main.cmi arith.cmi circle.cmi</span>
ocamlc -c main.ml
<span style="color: #0066bb; font-weight: bold;">main.cmi </span><span style="color: #333333;">:</span> <span style="color: #6600ee; font-weight: bold;">main.mli</span>
ocamlc -c main.mli
</pre></td></tr></tbody></table></div>
<p><br /></p><p><br /></p><p> </p><p> </p><p> </p><p style="text-align: justify;">make algorithm takes this graph as an input, studies the modification timestamps of all the targets and does just what is necessary (and useful) in the build process of the application. What's the rule to be followed here? Whenever any of the dependencies, say <i>d</i>, of a dependee/target file <i>f</i> was modified after <i>f</i> was modified, <i>f</i> needs to be rebuilt. However, one more bit. The timestamp of <i>f</i> and <i>d</i> is checked only after this rule is applied on <i>d</i>. And recursively. While an untrained human mind may find this a bit mind-bending, it's really a very very simple algorithm.</p><p></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; border-color: gray; border-image: none 100% / 1 / 0 stretch; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: medium solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><table><tbody><tr><td><pre style="line-height: 125%; margin: 0px;"> 1
2
3
4
5
6
7
8
9
10</pre></td><td><pre style="line-height: 125%; margin: 0px;">function process_node(n)
<span style="color: #008800; font-weight: bold;">if</span>(n<span style="color: #333333;">.</span>deps <span style="color: #333333;">!=</span> {}) then
process_node(n<span style="background-color: #fff0f0;">') for all n'</span> <span style="color: black; font-weight: bold;">in</span> n<span style="color: #333333;">.</span>deps
maxdepts <span style="color: #333333;">=</span> <span style="color: #007020;">max</span>(timestamps(n<span style="color: #333333;">.</span>deps))
<span style="color: #008800; font-weight: bold;">if</span>(timestamp(n) <span style="color: #333333;"><</span> maxdepts) then
execute(n<span style="color: #333333;">.</span>action)
update_timestamp(n, now)
endif
endif
end
</pre></td></tr></tbody></table></div>
<p style="text-align: justify;"><br /></p><p style="text-align: justify;">The algorithm above does a depth first traversal starting with the target which we are building. After having processed all the dependencies, it compares the timestamp of the current target with those of all its dependencies. If any one of them is more recently modified than the target, the target is rebuilt by executing its build command.</p><p style="text-align: justify;">To round up the article, here's the OCaml implementation of the above algorithm. Even though the code has a good 170 LOC, note that the core algorithm is just 33 lines (L42 to L72). Rest of it is all plumbing and testing code.<br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; border-color: gray; border-image: none 100% / 1 / 0 stretch; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><table><tbody><tr><td><pre style="line-height: 125%; margin: 0px;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170</pre></td><td><pre style="line-height: 125%; margin: 0px;"><span style="color: #008800; font-weight: bold;">type</span> node <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">:</span> bytes<span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">:</span> node <span style="color: #333399; font-weight: bold;">list</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">:</span> bytes<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">type</span> timestamp <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
n <span style="color: #333333;">:</span> node<span style="color: #333333;">;</span>
t <span style="color: #333333;">:</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> string_of_timestamp ts <span style="color: #333333;">=</span>
<span style="background-color: #fff0f0;">"</span><span style="background-color: #fff0f0; color: #666666; font-weight: bold;">\t</span><span style="background-color: #fff0f0;">("</span> <span style="color: #333333;">^</span> ts<span style="color: #333333;">.</span>n<span style="color: #333333;">.</span>name <span style="color: #333333;">^</span> <span style="background-color: #fff0f0;">", "</span> <span style="color: #333333;">^</span> <span style="color: #333333;">(</span>string_of_int ts<span style="color: #333333;">.</span>t<span style="color: #333333;">)</span> <span style="color: #333333;">^</span> <span style="background-color: #fff0f0;">")"</span>
<span style="color: #008800; font-weight: bold;">let</span> string_of_timestamps tslist <span style="color: #333333;">=</span>
<span style="background-color: #fff0f0;">"["</span> <span style="color: #333333;">^</span>
<span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">let</span> strtss <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.map string_of_timestamp tslist <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.fold_left <span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">fun</span> x y <span style="color: #333333;">-></span> x <span style="color: #333333;">^</span> y <span style="color: #333333;">^</span> <span style="background-color: #fff0f0;">"</span><span style="background-color: #fff0f0; color: #666666; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">"</span><span style="color: #333333;">)</span> <span style="background-color: #fff0f0;">""</span> strtss<span style="color: #333333;">))</span> <span style="color: #333333;">^</span>
<span style="background-color: #fff0f0;">"]"</span>
<span style="color: #008800; font-weight: bold;">exception</span> <span style="color: #bb0066; font-weight: bold;">My_exception</span> <span style="color: #008800; font-weight: bold;">of</span> <span style="color: #333399; font-weight: bold;">string</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> get_timestamp timestamps n' <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">match</span> timestamps <span style="color: #008800; font-weight: bold;">with</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> <span style="color: #008800; font-weight: bold;">raise</span> <span style="color: #333333;">(</span><span style="color: #bb0066; font-weight: bold;">My_exception</span> n'<span style="color: #333333;">.</span>name<span style="color: #333333;">)</span>
<span style="color: #333333;">|</span> <span style="color: #333333;">{</span> n<span style="color: #333333;">;</span> t <span style="color: #333333;">}</span> <span style="color: #333333;">::</span> tl <span style="color: #333333;">-></span>
<span style="color: #008800; font-weight: bold;">if</span> n <span style="color: #333333;">=</span> n' <span style="color: #008800; font-weight: bold;">then</span> t
<span style="color: #008800; font-weight: bold;">else</span> <span style="color: #333333;">(</span>get_timestamp tl n'<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> update_timestamp timestamps n' t' <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">match</span> timestamps <span style="color: #008800; font-weight: bold;">with</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> <span style="color: #007020;">[]</span>
<span style="color: #333333;">|</span> <span style="color: #333333;">{</span> n <span style="color: #333333;">=</span> n<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> t <span style="color: #333333;">}</span> <span style="color: #333333;">::</span> tl <span style="color: #333333;">-></span>
<span style="color: #008800; font-weight: bold;">if</span> n <span style="color: #333333;">=</span> n' <span style="color: #008800; font-weight: bold;">then</span> <span style="color: #333333;">{</span> n <span style="color: #333333;">=</span> n'<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> t'<span style="color: #333333;">}</span> <span style="color: #333333;">::</span> tl
<span style="color: #008800; font-weight: bold;">else</span> <span style="color: #333333;">{</span> n <span style="color: #333333;">;</span> t <span style="color: #333333;">}</span> <span style="color: #333333;">::</span> <span style="color: #333333;">(</span>update_timestamp tl n' t'<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> max <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">function</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> <span style="color: #008800; font-weight: bold;">raise</span> <span style="color: #bb0066; font-weight: bold;">Not_found</span>
<span style="color: #333333;">|</span> <span style="color: #333333;">[</span>h<span style="color: #333333;">]</span> <span style="color: #333333;">-></span> h
<span style="color: #333333;">|</span> h <span style="color: #333333;">::</span> t <span style="color: #333333;">-></span> <span style="color: #008800; font-weight: bold;">let</span> maxt <span style="color: #333333;">=</span> max t <span style="color: #008800; font-weight: bold;">in</span> <span style="color: #008800; font-weight: bold;">if</span> h <span style="color: #333333;">></span> maxt <span style="color: #008800; font-weight: bold;">then</span> h <span style="color: #008800; font-weight: bold;">else</span> maxt
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> process_node n ts <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> myt <span style="color: #333333;">=</span> get_timestamp ts n <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.length n<span style="color: #333333;">.</span>dependencies <span style="color: #333333;"><></span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #008800; font-weight: bold;">let</span> depts <span style="color: #333333;">=</span> process_dependencies n<span style="color: #333333;">.</span>dependencies ts <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> maxts <span style="color: #333333;">=</span> max <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.map <span style="color: #333333;">(</span>get_timestamp depts<span style="color: #333333;">)</span> n<span style="color: #333333;">.</span>dependencies<span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">if</span> myt <span style="color: #333333;"><</span> maxts <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #008800; font-weight: bold;">begin</span>
print_endline <span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"executing "</span> <span style="color: #333333;">^</span> n<span style="color: #333333;">.</span>action<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">let</span> ts' <span style="color: #333333;">=</span> update_timestamp depts n <span style="color: #333333;">(</span>maxts <span style="color: #333333;">+</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">begin</span>
print_endline <span style="color: #333333;">(</span>string_of_timestamps ts'<span style="color: #333333;">);</span>
ts'
<span style="color: #008800; font-weight: bold;">end</span>
<span style="color: #008800; font-weight: bold;">end</span>
<span style="color: #008800; font-weight: bold;">else</span>
<span style="color: #008800; font-weight: bold;">begin</span>
print_endline <span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Nothing to be done for "</span> <span style="color: #333333;">^</span> n<span style="color: #333333;">.</span>name<span style="color: #333333;">);</span>
ts
<span style="color: #008800; font-weight: bold;">end</span>
<span style="color: #008800; font-weight: bold;">else</span>
<span style="color: #008800; font-weight: bold;">begin</span>
print_endline <span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Nothing to be done for "</span> <span style="color: #333333;">^</span> n<span style="color: #333333;">.</span>name<span style="color: #333333;">);</span>
ts
<span style="color: #008800; font-weight: bold;">end</span>
<span style="color: black; font-weight: bold;">and</span> process_dependencies deps ts <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> loop deps ts <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">match</span> deps <span style="color: #008800; font-weight: bold;">with</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> ts
<span style="color: #333333;">|</span> d <span style="color: #333333;">::</span> deps' <span style="color: #333333;">-></span>
<span style="color: #008800; font-weight: bold;">let</span> ts' <span style="color: #333333;">=</span> process_node d ts <span style="color: #008800; font-weight: bold;">in</span> loop deps' ts'
<span style="color: #008800; font-weight: bold;">in</span>
loop deps ts
<span style="color: #008800; font-weight: bold;">let</span> arith_mli <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"arith.mli"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> arith_cmi <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"arith.cmi"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>arith_mli<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -c arith.mli"</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> arith_ml <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"arith.ml"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> arith_cmo <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"arith.cmo"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>arith_ml<span style="color: #333333;">;</span> arith_cmi<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -c arith.ml"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> circle_mli <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"circle.mli"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> circle_cmi <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"circle.cmi"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>circle_mli<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -c circle.mli"</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> circle_ml <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"circle.ml"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> circle_cmo <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"circle.cmo"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>circle_ml<span style="color: #333333;">;</span> circle_cmi<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -c circle.ml"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> main_mli <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"main.mli"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> main_cmi <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"main.cmi"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>main_mli<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -c main.mli"</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> main_ml <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"main.ml"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">""</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> main_cmo <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"main.cmo"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>main_ml<span style="color: #333333;">;</span> main_cmi<span style="color: #333333;">;</span> circle_cmi<span style="color: #333333;">;</span> arith_cmi<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -c main.ml"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> app <span style="color: #333333;">=</span> <span style="color: #333333;">{</span>
name <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"app"</span><span style="color: #333333;">;</span>
dependencies <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>arith_cmo<span style="color: #333333;">;</span> circle_cmo<span style="color: #333333;">;</span> main_cmo<span style="color: #333333;">];</span>
action <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"ocamlc -o app arith.cmo circle.cmo main.cmo"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">let</span> ts <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> arith_mli<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> arith_cmi<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> arith_ml<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> arith_cmo<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> circle_mli<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> circle_cmi<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> circle_ml<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> circle_cmo<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> main_mli<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> main_cmi<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> main_ml<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> main_cmo<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">{</span>n <span style="color: #333333;">=</span> app<span style="color: #333333;">;</span> t <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">};</span>
<span style="color: #333333;">]</span>
<span style="color: #008800; font-weight: bold;">let</span> t1 <span style="color: #007020;">()</span> <span style="color: #333333;">=</span>
process_node app ts
<span style="color: #008800; font-weight: bold;">let</span> t2 <span style="color: #007020;">()</span> <span style="color: #333333;">=</span>
<span style="color: #333333;">(</span>update_timestamp ts main_cmo <span style="color: #0000dd; font-weight: bold;">10</span><span style="color: #333333;">)</span> <span style="color: #333333;">|></span> string_of_timestamps <span style="color: #333333;">|></span> print_endline
<span style="color: #008800; font-weight: bold;">let</span> t3 <span style="color: #007020;">()</span> <span style="color: #333333;">=</span>
<span style="color: #333333;">(</span>get_timestamp ts arith_mli<span style="color: #333333;">)</span> <span style="color: #333333;">|></span> string_of_int <span style="color: #333333;">|></span> print_endline<span style="color: #333333;">;</span>
<span style="color: #333333;">(</span>get_timestamp ts circle_mli<span style="color: #333333;">)</span> <span style="color: #333333;">|></span> string_of_int <span style="color: #333333;">|></span> print_endline
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #333333;">_</span> <span style="color: #333333;">=</span> t2 <span style="color: #007020;">()</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #333333;">_</span> <span style="color: #333333;">=</span> t1 <span style="color: #007020;">()</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #333333;">_</span> <span style="color: #333333;">=</span> t3 <span style="color: #007020;">()</span>
</pre></td></tr></tbody></table></div>
<p><br /></p><p>Hope you found the above useful and interesting!<br /></p>Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-72340434409830861832020-11-18T16:27:00.004+05:302020-12-06T15:50:26.461+05:30The Fascinating Art of Making Notes<div style="text-align: justify;"></div><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">Note-taking is a regular activity anyone wanting to record his reading, thoughts, ideas, etc. does on a regular basis. It could be a student, a teacher, or any expert. Note-taking happens in a variety of situations. One of the most prevalent is the classroom, lectures or meetings. For me, I make notes mostly in the following situations:</span></span></p><ul style="text-align: left;"><li><span style="font-family: georgia;"><span style="font-size: large;">Thinking, e.g. for my research<br /></span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Reading</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Preparing for lectures<br /></span></span></li></ul><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">In this article, I wish to share some of my own methods, practices and observations about making notes. My thoughts around this topic are focused around drawing figures. Most if not all of my understanding must be translated into some visual language (which broadly includes mathematical notations and program code too) to be checked off as per my personal QA standards. This mayn't be a universal method as different people have different styles of comprehending their thoughts. I am a visual thinker. No surprise, I draw lots of pictures to express my thoughts, and to test their clarity.</span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">While we all try to represent our abstract thoughts as viewable artifacts, I am sure most of us pretty much muddle through the process without fully understanding what's going on. One objective of writing this piece is also to unpack this mental process, as I understand it. No rocket science here. But, there's always merit in sharing.</span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;"></span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">All visualisation of our thoughts has two main purposes. One is to help us think, and the other is as a communication tool.</span></span></p><h3 style="text-align: left;"><span style="font-family: georgia;"><span style="font-size: large;"><span style="color: red;">Note-making as a Thinking Tool </span><br /></span></span></h3><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">When we are using writing/drawing as a tool for understanding, flexibility is important. What you write or draw should be malleable enough to move in step with your thoughts. When the artifact you are thinking about appears like a rectangle, an ellipse or a blob with some text in it, you want to go ahead and put that out on paper. It doesn't help searching for an appropriate shape or object in the shapes library of your favourite editor. Doing so has at least the following disadvantages:</span></span></p><ol style="text-align: left;"><li><span style="font-family: georgia;"><span style="font-size: large;">It comes in the way of your thoughts, slowing you down</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">It increases the cognitive load further impending thoughts</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">It tends to influence the way you want to show your thoughts. This may hamper the freedom with which you think.</span></span></li></ol><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">With the current state-of-the-art, computing devices are yet to become portable and lightweight enough to be readily available everywhere.<br /></span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">Hence, I personally prefer handwriting/hand-drawing as the preferred tool for this. I feel that nothing can match a notebook and a pen/pencil when it comes to providing that flexibility.</span></span></p><p style="text-align: left;"><span style="color: #2b00fe;"><span style="font-family: georgia;"><span style="font-size: large;"><b>Traditional -- Pen/pencil + Notebook</b></span></span></span></p><p style="text-align: left;"><span style="color: #2b00fe;"><span style="font-family: georgia;"><span style="font-size: large;"></span></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ_SAc1PN_61xOug0MGstQ5-2n9YwwtANoriTQhL_0vHRSLfULU5J_y08qOFXz36QYZ4yTXTmSwklBFLc42ztQqVQYAw7AMQwC9q7TTMilyhJrGWyoCL-hPQX2z-rtn84wKCOP/s3941/IMG_20201118_140938.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="3941" data-original-width="2848" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ_SAc1PN_61xOug0MGstQ5-2n9YwwtANoriTQhL_0vHRSLfULU5J_y08qOFXz36QYZ4yTXTmSwklBFLc42ztQqVQYAw7AMQwC9q7TTMilyhJrGWyoCL-hPQX2z-rtn84wKCOP/w289-h400/IMG_20201118_140938.jpg" width="289" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Handwritten characters and shapes are closest to our thoughts<br /></td></tr></tbody></table><span style="color: #2b00fe;"><span style="font-family: georgia;"><span style="font-size: large;"><br /><b><br /></b></span></span></span><p></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">Pens are more beautiful and comfortable writing devices. Output, if got right, is of course superior to that of a pencil. Pencils (coupled with erasers) are more forgiving of mistakes as you can correct them.</span></span></p><div style="text-align: left;"><b><span style="font-family: georgia;"><span style="font-size: large;">Advantages of Traditional:</span></span></b><span style="font-family: georgia;"><span style="font-size: large;"> </span></span><span style="font-family: georgia;"><span style="font-size: large;"> </span></span></div><ol style="text-align: left;"><li><span style="font-family: georgia;"><span style="font-size: large;">Flexible</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Handy and available</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Inexpensive</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">No learning required</span></span><b><span style="font-family: georgia;"><span style="font-size: large;"><br /></span></span></b></li></ol><p style="text-align: left;"><br /></p><div style="text-align: left;"><b><span style="font-family: georgia;"><span style="font-size: large;">Disadvantages of Traditional:</span></span></b><span style="font-family: georgia;"><span style="font-size: large;"> </span></span><span style="font-family: georgia;"></span><span style="font-family: georgia;"><span style="font-size: large;"> </span></span></div><ol style="text-align: left;"><li><span style="font-family: georgia;"><span style="font-size: large;">All manual</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Limited</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Messy</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Paper based</span></span><b><span style="font-family: georgia;"><span style="font-size: large;"><br /></span></span></b></li></ol><p style="text-align: left;"><span style="color: #2b00fe;"><span style="font-family: georgia;"><span style="font-size: large;"><br /><br /></span></span></span></p><p style="text-align: left;"><span style="color: #2b00fe;"><span style="font-family: georgia;"></span></span></p><h4 style="text-align: left;"><span style="color: #2b00fe;"><span style="font-family: georgia;"><span style="font-size: large;"> </span></span></span></h4><h4 style="text-align: left;"><span style="color: #2b00fe;"><span style="font-family: georgia;"><span style="font-size: large;">Digital tablets</span></span></span></h4><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">The state-of-the-art has now come close to the point where the best of both the worlds -- digital and traditional -- are now available in digital. You can handwrite, hand-draw to your heart's content if you have a stylus enabled device like a tablet computer or a Wacom tablet like device. There are further advantages which make digital handwriting a very compelling choice for making your first handwritten notes. The most important is flexibility. When it comes to correcting mistakes, even a pencil and an eraser have their limits; while in a digital writing pad, mistakes are easily forgiven and forgotten. You can correct and tweak to an almost infinite extent, preventing the write-ups or figures from getting messy with more edits. The richness and variety of tools that you get in the digital medium can't easily be matched by traditional medium. Pen colours, thickness, shapes, backgrounds, templates ... If all these blend seamlessly with handwriting/drawing, then the flexibility of the digital medium is just irresistible.<br /></span></span></p><p style="text-align: left;"><span style="font-family: georgia;"><span style="font-size: large;"></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIKFHAQBsLEDYVX_6Nng_yp-08hNhB8ZSJvcV_ZF5XV7R_w0uXGA_4sYZ3M7kre2xYdzR9NctyEu8-X1If4wYiPx9Gh-SijX6xAfE02FuZOoNM82mVW8gBSeNJuFGwswnchlV9/s2874/hand-drawn-notebook.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="2874" data-original-width="2799" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIKFHAQBsLEDYVX_6Nng_yp-08hNhB8ZSJvcV_ZF5XV7R_w0uXGA_4sYZ3M7kre2xYdzR9NctyEu8-X1If4wYiPx9Gh-SijX6xAfE02FuZOoNM82mVW8gBSeNJuFGwswnchlV9/w390-h400/hand-drawn-notebook.jpg" width="390" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">While traditional is incomparable in its experience, correcting mistakes gets harder as you go.<br /></td></tr></tbody></table><span style="font-family: georgia;"><span style="font-size: large;"><br /> <table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0B-DmCcpXNB4NIv1Q0ctHQYy_Si8jaQVNMyqcvOIhFzvyS832H77uNoFlUwbGHcCNmPQuPA2ApDWWyGpw4TwFV-l352D5gOV6Djz5eAvpZa4R9CCGiYzZ1QMv7wu3yy-oshy/s711/digital-handwriting.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="484" data-original-width="711" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0B-DmCcpXNB4NIv1Q0ctHQYy_Si8jaQVNMyqcvOIhFzvyS832H77uNoFlUwbGHcCNmPQuPA2ApDWWyGpw4TwFV-l352D5gOV6Djz5eAvpZa4R9CCGiYzZ1QMv7wu3yy-oshy/w400-h272/digital-handwriting.png" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The richness of tools, variety, flexibility of digital medium is incomparable<br /></td></tr></tbody></table><br /></span><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFaQ7vOdDweRwNtwCAa_GVyJLYyz0PXA4HIZDM3FR4wta2moXhDSB0dLb9rCf2lUp_P_JrcYQZFxUw12gALfbBJmhXUw0YPo8wSHe3wIFaRq0nU2NOBeoWsyzUOHO4aiPAIHkg/s744/handdrawn.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="572" data-original-width="744" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFaQ7vOdDweRwNtwCAa_GVyJLYyz0PXA4HIZDM3FR4wta2moXhDSB0dLb9rCf2lUp_P_JrcYQZFxUw12gALfbBJmhXUw0YPo8wSHe3wIFaRq0nU2NOBeoWsyzUOHO4aiPAIHkg/s320/handdrawn.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">For me, first cut digital notes are nearly undistisguishable from their traditional counterpart<br /></td></tr></tbody></table><br /><br /></span><p></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">And to top it all, copy-paste often comes as a boon for re-using your earlier efforts and in maintaining a uniform look and feel. While, this part mayn't be terribly important when you are making personal notes, it's important when you have drawn something very complicated, or when you want your personal notes to evolve into fair notes for sharing with others.</span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;"> </span></span></p><b><span style="font-family: georgia;"><span style="font-size: large;">Advantages of Digital Handwriting/drawing:</span></span></b><span style="font-family: georgia;"><span style="font-size: large;"> </span></span><ol style="text-align: left;"><li><span style="font-family: georgia;"><span style="font-size: large;">Flexible</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Versatile</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Integrates seamlessly with completely digital tools</span></span><b><span style="font-family: georgia;"><span style="font-size: large;"><br /></span></span></b></li></ol><p style="text-align: left;"><br /></p><div style="text-align: left;"><b><span style="font-family: georgia;"><span style="font-size: large;">Disadvantages of </span></span></b><b><span style="font-family: georgia;"><span style="font-size: large;"><b><span style="font-family: georgia;"><span style="font-size: large;">Digital Handwriting/drawing</span></span></b>:</span></span></b><span style="font-family: georgia;"><span style="font-size: large;"> </span></span></div><ol style="text-align: left;"><li><span style="font-family: georgia;"><span style="font-size: large;">Expensive</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">May involve learning</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Not as portable and available as traditional medium</span></span><b><span style="font-family: georgia;"><span style="font-size: large;"><br /></span></span></b></li></ol><span style="font-family: georgia;"></span><span style="color: red;"><span style="font-family: georgia;"></span></span><h3 style="text-align: left;"><span style="color: red;"><span style="font-family: georgia;"><span style="font-size: large;">Note-making as a Communication Tool</span></span></span></h3><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">Once your thoughts are clear enough and the visualisation thereof have attained a respectable look, you may or mayn't be interested to turn them into a fair material. In case you are looking for further enhancement of quality, this is a good point to go completely digital. This part is nothing enigmatic. Here, it's not so much about thinking, but about leveraging the digital tools at hand to achieve the best result. This article is not about that, nor do I profess to be an expert in that topic. Hence, I will be brief here.<br /></span></span></p><p style="text-align: left;"><span style="font-family: georgia;"><span style="font-size: large;"><br /></span></span></p><h3 style="text-align: left;"><span style="color: red;"><span style="font-family: georgia;"><span style="font-size: large;">Stepwise Transformation</span></span></span></h3><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">As mentioned earlier, it would be great if the hand-drawn figures can be evolved into digital figures. This would primarily mean replacing wobbly lines and irregular shapes with smooth and regular digitally created lines and shapes. If your handwriting is not good, that can be replaced by digital text. Also, reshaping, resizing and relocating components of your drawing would give satisfying results.<br /></span></span></p><p style="text-align: left;"><span style="font-family: georgia;"><span style="font-size: large;"></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2omHLsIXbDu1dRyWZTJBmZnWhUER0wAJIhH6tciWHU9ZAxfQoU3YLiYbBIThnZdYtBmgOPrLXftb1B4yB-mQcapeqY1egvfLD47LAXTL7BM3_7gpCMyqVCBCfNWTRQ9Kk2r7O/s810/mixed.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="605" data-original-width="810" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2omHLsIXbDu1dRyWZTJBmZnWhUER0wAJIhH6tciWHU9ZAxfQoU3YLiYbBIThnZdYtBmgOPrLXftb1B4yB-mQcapeqY1egvfLD47LAXTL7BM3_7gpCMyqVCBCfNWTRQ9Kk2r7O/s320/mixed.png" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><span style="font-family: georgia;">Once the basic idea is put down, gradual transformation to a more digital look begins</span></td></tr></tbody></table><span style="font-family: georgia;"><span style="font-size: large;"><br /> </span></span><p></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">Of course, that's possible only when the first drawings are made digitally using an appropriate tool. Otherwise, you would have to put in the effort of creating the first digital equivalent of your hand-drawn figure in a traditional medium. In my understanding, that's a very small part of the overall effort.</span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">My knowledge of Windows and Mac world is limited and dated, as it's been years since I last used them in any significant measure. But, I am very sure that there must be very powerful and flexible tools out there which allow you to gradually and stepwise turn your hand-drawn sketches into digitally rendered ones. May be even Microsoft Word and Powerpoint have these features. In Linux, I have recently been using <a href="https://openboard.ch/" target="_blank">Openboard</a> and <a href="https://github.com/xournalpp/xournalpp">Xournal++</a> for this. Both are extremely stable, user friendly systems with very little learning curve involved. Again, it's not about the tools, but about a bit of ingenuity.</span></span></p><p style="text-align: left;"><span style="font-family: georgia;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJdpQluamaxQfNPGjszkqMwFAvsrCY_FJOvw2XJm1VwYw2gH-5Pqew2NT-7Hr2qheISie1-hhnonrXfpgp59rm-ULdpw6xIWgSvBRONIw9R_hJK89w19jonM8pg7iKUPJfdYIy/s787/wyswyg.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="604" data-original-width="787" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJdpQluamaxQfNPGjszkqMwFAvsrCY_FJOvw2XJm1VwYw2gH-5Pqew2NT-7Hr2qheISie1-hhnonrXfpgp59rm-ULdpw6xIWgSvBRONIw9R_hJK89w19jonM8pg7iKUPJfdYIy/w400-h308/wyswyg.png" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Nearly completely Digitised Figure; notice the seamless intermixing of handwritten characters with digitally drawn shapes<br /></td></tr></tbody></table><span style="font-family: georgia;"><br /><span style="font-size: large;"><br /></span></span><p></p><h4 style="text-align: left;"><span style="font-family: georgia;"><span style="font-size: large;"><span style="color: #2b00fe;">LaTeX and TikZ</span></span></span></h4><h4 style="text-align: left;"><span style="font-family: georgia;"><span style="font-size: large;"><span style="color: #2b00fe;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii_CoffEF-N9Lc0ZrzZ6lh17L1NPWbHHlXBd8j-gGKe1mcZqv60pAvAINQTQ01LH_requ_8kY5oP1TtxWn-gSvy5nJXx1yRmTYA77GA6pFUOULbNFvuZRl1OZc5ksXbVHnq3-6/s544/TikZ.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="198" data-original-width="544" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii_CoffEF-N9Lc0ZrzZ6lh17L1NPWbHHlXBd8j-gGKe1mcZqv60pAvAINQTQ01LH_requ_8kY5oP1TtxWn-gSvy5nJXx1yRmTYA77GA6pFUOULbNFvuZRl1OZc5ksXbVHnq3-6/w400-h145/TikZ.png" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">TikZ typesetting is famously LaTeX Quality -- Unmatchable!<br /></td></tr></tbody></table><br /> </span><br /></span></span></h4><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">As for my personal taste, I do most (probably all) of my documentation in <a href="https://latex.org/forum/" target="_blank">LaTeX</a>. Hence, translating things into that environment works best for me. TikZ is a LaTeX based drawing tool. The advantage of using <a href="https://en.wikipedia.org/wiki/PGF/TikZ">TikZ</a> is that your drawings are a part of your LaTeX document. This helps their maintenance. The output quality is one of the best in my opinion. The figure is really drawn logically using a programming language of sorts, and not visually. This makes the whole thing very robust. Moving and resizing never messes up your figures. And staying within the LaTeX ecosystem has plenty of advantages which any seasoned LaTeX user will swear by. Some of them are as follows:</span></span></p><ol style="text-align: justify;"><li><span style="font-family: georgia;"><span style="font-size: large;">Powerful. Almost anything can be drawn. <br /></span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Logically/mathematically defined structure which doesn't go wrong easily</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Vector graphics rendering. So no pixellation of figures when zooming in or printing out</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Powerful packages for virtually any kind of drawing use case</span></span></li><li><span style="font-family: georgia;"><span style="font-size: large;">Extremely active online community. So, nearly all questions get readily answered with a single Google search.<br /></span></span></li></ol><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">The only disadvantage of using this tool is the learning curve, which is quite formidable. In fact, without assuming a fair degree of familiarity with LaTeX as a prerequisite, it can be a difficult proposition to opt for TikZ as preferred drawing tool.</span></span></p><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;"><br /></span></span></p><h3 style="text-align: justify;"><span style="color: red;"><span style="font-family: georgia;"><span style="font-size: large;">Conclusion</span></span></span></h3><p style="text-align: justify;"><span style="font-family: georgia;"><span style="font-size: large;">Writing mainly serves two purposes: as a thinking tool and as a communication/documentation/recording/archival tool. The former asks for flexibility. Handwriting is best for this. The latter asks for quality. Digital helps there. In this article, we have presented a process of documentation that begins with predominantly handwriting, and gradually transforming into digital depending on the specific quality requirements and resources available. We have also shared information about some tools which can be used to implement</span></span><span style="font-family: georgia; font-size: x-large;"> <span style="font-size: large;">this process.</span></span></p>Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-33757263348804108112020-02-04T19:58:00.000+05:302020-02-04T19:58:12.606+05:30Higher Order Functions and Tail Recursion<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgow2AFFKOGtHjwEn8frJ4p80_eLkBadscP_hTzHevo5GIyqlRD-55mD2wa58jLZM45o9L1qBoJFJBN6YyCToxtoKNp_0hWoAGWUpecfkjkVSG0Y5ZtDxK3BIa_7AOXqkWdtljB/s1600/p1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="972" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgow2AFFKOGtHjwEn8frJ4p80_eLkBadscP_hTzHevo5GIyqlRD-55mD2wa58jLZM45o9L1qBoJFJBN6YyCToxtoKNp_0hWoAGWUpecfkjkVSG0Y5ZtDxK3BIa_7AOXqkWdtljB/s640/p1.jpg" width="388" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj57LxRDpHcXt825-Jz1oruD7nEkbFBRgfX6SawHpFWJLsB9NOQxY9sq-agFDlUD3kAw2BMnf6KAYfVIDMMjMeVg29TVegLYBBEFsRjmsnBEMJQA9-6vm_bDiVp3obRUwdMPKg/s1600/p2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="949" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj57LxRDpHcXt825-Jz1oruD7nEkbFBRgfX6SawHpFWJLsB9NOQxY9sq-agFDlUD3kAw2BMnf6KAYfVIDMMjMeVg29TVegLYBBEFsRjmsnBEMJQA9-6vm_bDiVp3obRUwdMPKg/s640/p2.jpg" width="378" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrhsjzf2z0FOMOSiDQOAlW2ZFLNTBGOPaAc1AtBuwG5uSOr7cbZluMwGJDGaFCDSfwegDzngwJ5WNSUdHNFAKa19E847YWfzS68PkXuwONdRMozpyh7-GrxMBZfHKy5Fk9AL_n/s1600/p3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1002" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrhsjzf2z0FOMOSiDQOAlW2ZFLNTBGOPaAc1AtBuwG5uSOr7cbZluMwGJDGaFCDSfwegDzngwJ5WNSUdHNFAKa19E847YWfzS68PkXuwONdRMozpyh7-GrxMBZfHKy5Fk9AL_n/s640/p3.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzbe8wFBHZSA1RzBA_HgSp2HPEJsuMC4AX4mXJhCmuP4RnURF2d6nzIdQchzCUqabaaCA6NxCcQdxNY3YYYGztitLXS7Sg0aufAoXS4ZEJfDF90SMZIdGlATI-SlaVD6SyKj9N/s1600/p4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="929" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzbe8wFBHZSA1RzBA_HgSp2HPEJsuMC4AX4mXJhCmuP4RnURF2d6nzIdQchzCUqabaaCA6NxCcQdxNY3YYYGztitLXS7Sg0aufAoXS4ZEJfDF90SMZIdGlATI-SlaVD6SyKj9N/s640/p4.jpg" width="370" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3iQPwPcEQCP4kSHiIuEm_Vbt1DGs-pXwbTKvDIMj3Zv9nVl81smQOY1cxddJJ3TcDLu51Q_iiGoLfjWGZ-TFA3VArZGh_sZk-FBCXfstYGOHRwvMaF5382ZmugYHcS3_ci8cv/s1600/p5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1006" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3iQPwPcEQCP4kSHiIuEm_Vbt1DGs-pXwbTKvDIMj3Zv9nVl81smQOY1cxddJJ3TcDLu51Q_iiGoLfjWGZ-TFA3VArZGh_sZk-FBCXfstYGOHRwvMaF5382ZmugYHcS3_ci8cv/s640/p5.jpg" width="402" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIBZaW1xh8UIhzqH2HM44Nf1Kw2d4kfMIK3dRVFVrUIuHec17yB4iMHJotu31jyTNyHkLeX9hyphenhyphenU3MyPm9COhwfjUHegmoqm2jWKhNfQF1fy_4loVTIoC3O-pa96sk81upHuOFE/s1600/p6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="935" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIBZaW1xh8UIhzqH2HM44Nf1Kw2d4kfMIK3dRVFVrUIuHec17yB4iMHJotu31jyTNyHkLeX9hyphenhyphenU3MyPm9COhwfjUHegmoqm2jWKhNfQF1fy_4loVTIoC3O-pa96sk81upHuOFE/s640/p6.jpg" width="372" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYlCQz2p_w-R3hk85dEVzKrPAfb4mt-zwQ7qWZHAxyfB0llhVYd7trWUUrdi7WcrG1m_rBXDsmNcqo2u2Uyxrw6Q9W1GfDr5h5bSb0FzVlXBlzSU4yQiK5M9-jxem_ybHnqZlf/s1600/p7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="986" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYlCQz2p_w-R3hk85dEVzKrPAfb4mt-zwQ7qWZHAxyfB0llhVYd7trWUUrdi7WcrG1m_rBXDsmNcqo2u2Uyxrw6Q9W1GfDr5h5bSb0FzVlXBlzSU4yQiK5M9-jxem_ybHnqZlf/s640/p7.jpg" width="394" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbxbqKmwmZcEFDVUxZjHxaHOHopx7Gg3tpugA7wfgEKjHrX7IJ650w39US2NoGnqQGK4oEmNvC8rRoFf4Y2fELIz_IO368k1U8hmbrtIAet2VQAo6iHtFOf65NMjEEcvu5Ht_s/s1600/p8.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1273" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbxbqKmwmZcEFDVUxZjHxaHOHopx7Gg3tpugA7wfgEKjHrX7IJ650w39US2NoGnqQGK4oEmNvC8rRoFf4Y2fELIz_IO368k1U8hmbrtIAet2VQAo6iHtFOf65NMjEEcvu5Ht_s/s640/p8.jpg" width="508" /></a></div>
<br /></div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-73733770566443444952018-09-04T09:19:00.000+05:302018-09-04T09:34:23.733+05:30Reversing a Queue<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;">There was a question in the discussion as to how to reverse a queue without a stack.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;"><br /></span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;">Reversing a queue using a stack is quite easy.</span></span></div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">reverseWithStack</span><span style="color: #333333;">(</span>Queue<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span><span style="color: #333333;"></span> queue<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
Stack<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span> stack <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> Stack<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span><span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">while</span><span style="color: #333333;">(</span>queue<span style="color: #333333;">.</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">()</span> <span style="color: #333333;">==</span> <span style="color: #008800; font-weight: bold;">false</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
stack<span style="color: #333333;">.</span><span style="color: #0000cc;">push</span><span style="color: #333333;">(</span>queue<span style="color: #333333;">.</span><span style="color: #0000cc;">remove</span><span style="color: #333333;">());</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">while</span><span style="color: #333333;">(</span>stack<span style="color: #333333;">.</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">()</span> <span style="color: #333333;">==</span> <span style="color: #008800; font-weight: bold;">false</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span>stack<span style="color: #333333;">.</span><span style="color: #0000cc;">pop</span><span style="color: #333333;">());</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
<span style="font-family: Georgia, "Times New Roman", serif;"><span style="font-size: large;">How to do it without a stack. I think, there may be convoluted ways. But here's a simple way using recursion:</span></span></div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">reverseWithoutStack</span><span style="color: #333333;">(</span>Queue<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span><span style="color: #333333;"></span> queue<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">if</span><span style="color: #333333;">(</span>queue<span style="color: #333333;">.</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">())</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333399; font-weight: bold;">int</span> n <span style="color: #333333;">=</span> queue<span style="color: #333333;">.</span><span style="color: #0000cc;">remove</span><span style="color: #333333;">();</span>
reverseWithoutStack<span style="color: #333333;">(</span>queue<span style="color: #333333;">);</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span>n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;">Well, there's no magic happening here. Actually, we are cheating a bit here. How? We have simulated the behaviour of a stack through recursion. In fact, there's still a stack -- an actual stack -- in action which enables us to solve this problem. It's the program stack! Just that it's hidden.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;"><br /></span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;">Many algorithms which could be implemented using a loop and a stack could be rephrased into a simpler one with recursion, simply because recursion hides the stack within itself and allows us to reap its benefits all the same! A classical example is depth first search of trees, which can be implemented using a stack, but a simpler and elegant implementation can be created using recursion.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;"><br /></span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: Georgia, "Times New Roman", serif;">Here's the complete code:</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">java.util.Stack</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">java.util.Queue</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">java.util.LinkedList</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Reverse</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">main</span><span style="color: #333333;">(</span>String<span style="color: #333333;">[]</span> args<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
Queue<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span> queue <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> LinkedList<span style="color: #333333;"><</span>Integer<span style="color: #333333;">>();</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">);</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">);</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span><span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">);</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">println</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Before reversing ..."</span><span style="color: #333333;">);</span>
printQueue<span style="color: #333333;">(</span>queue<span style="color: #333333;">);</span>
<span style="color: #888888;">// reverseWithoutStack(queue);</span>
reverseWithoutStack<span style="color: #333333;">(</span>queue<span style="color: #333333;">);</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">println</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"After reversing ..."</span><span style="color: #333333;">);</span>
printQueue<span style="color: #333333;">(</span>queue<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">reverseWithStack</span><span style="color: #333333;">(</span>Queue<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span> queue<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
Stack<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span> stack <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> Stack<span style="color: #333333;"><</span>Integer<span style="color: #333333;">>();</span>
<span style="color: #008800; font-weight: bold;">while</span><span style="color: #333333;">(</span>queue<span style="color: #333333;">.</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">()</span> <span style="color: #333333;">==</span> <span style="color: #008800; font-weight: bold;">false</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
stack<span style="color: #333333;">.</span><span style="color: #0000cc;">push</span><span style="color: #333333;">(</span>queue<span style="color: #333333;">.</span><span style="color: #0000cc;">remove</span><span style="color: #333333;">());</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">while</span><span style="color: #333333;">(</span>stack<span style="color: #333333;">.</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">()</span> <span style="color: #333333;">==</span> <span style="color: #008800; font-weight: bold;">false</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span>stack<span style="color: #333333;">.</span><span style="color: #0000cc;">pop</span><span style="color: #333333;">());</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">reverseWithoutStack</span><span style="color: #333333;">(</span>Queue<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span> queue<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">if</span><span style="color: #333333;">(</span>queue<span style="color: #333333;">.</span><span style="color: #0000cc;">isEmpty</span><span style="color: #333333;">())</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333399; font-weight: bold;">int</span> n <span style="color: #333333;">=</span> queue<span style="color: #333333;">.</span><span style="color: #0000cc;">remove</span><span style="color: #333333;">();</span>
reverseWithoutStack<span style="color: #333333;">(</span>queue<span style="color: #333333;">);</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span>n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">printQueue</span><span style="color: #333333;">(</span>Queue<span style="color: #333333;"><</span>Integer<span style="color: #333333;">></span> queue<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
String s <span style="color: #333333;">=</span> <span style="background-color: #fff0f0;">"[ "</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> i <span style="color: #333333;"><</span> queue<span style="color: #333333;">.</span><span style="color: #0000cc;">size</span><span style="color: #333333;">();</span> i<span style="color: #333333;">++)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span> n <span style="color: #333333;">=</span> queue<span style="color: #333333;">.</span><span style="color: #0000cc;">remove</span><span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">if</span><span style="color: #333333;">(</span>i <span style="color: #333333;"><=</span> queue<span style="color: #333333;">.</span><span style="color: #0000cc;">size</span><span style="color: #333333;">()</span> <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
s <span style="color: #333333;">+=</span> n <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">", "</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">else</span> <span style="color: #333333;">{</span>
s <span style="color: #333333;">+=</span> n <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">" "</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
queue<span style="color: #333333;">.</span><span style="color: #0000cc;">add</span><span style="color: #333333;">(</span>n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
s <span style="color: #333333;">+=</span> <span style="background-color: #fff0f0;">"]"</span><span style="color: #333333;">;</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">println</span><span style="color: #333333;">(</span>s<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-86076437658363758872018-09-01T10:39:00.005+05:302018-09-01T10:49:42.143+05:30Implementation of Lexical Analyser<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Compiler texts usually provide a detailed treatment to the theoretical aspects of the design of a lexical analyser. In most cases, the issues of putting together all these concepts in a real working lexical analyser are typically never discussed. Probably, there’s good reason for this too, as very good tools exist that automatically generate lexical analysers from lexical specifications provided as regular expression patterns.<br /> </span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Yet, manually implementing a lexical anlyser that embodies all the concepts taught in a compilers text or course is an interesting engineering exercise. Doing this seems to provide some nuanced insights about how such a system can be designed. Experience thus earned is likely to be useful in solving other software design problems sharing technical properties with the lexical analyser. In this article, we show how a lexical analyser can be implemented using C++. We do so using an example discussed in the following section.</span></span></div>
<h3 style="text-align: left;">
<span style="color: #990000;"><span style="font-size: x-large;"><span style="font-family: "georgia" , "times new roman" , serif;">Example</span></span></span></h3>
<h3 style="text-align: left;">
<span style="color: #990000;"><span style="font-size: x-large;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></span></h3>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Here, we design a lexical analyser that recognises the follow token classes:</span></span></div>
<blockquote class="tr_bq">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #351c75;"><b>Assignment.</b></span> (ASSIGN) Represented by the single character ‘=’.</span></span><br />
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Regular expression: =</span></span><br />
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Automaton:</span></span></blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUwB5USQnWR3dsIgNtvFguLPdMIRSp3YKJLcsptTJ2UBu6IM6ALjz5WOSc4dFB9CSOWv17FV5HwR6Ii3gDT8zlG9zlbu1S194Bzt-_k67LnGdcwVD2-fDdQORSH9zrLovpnN58/s1600/assign.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="135" data-original-width="485" height="55" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUwB5USQnWR3dsIgNtvFguLPdMIRSp3YKJLcsptTJ2UBu6IM6ALjz5WOSc4dFB9CSOWv17FV5HwR6Ii3gDT8zlG9zlbu1S194Bzt-_k67LnGdcwVD2-fDdQORSH9zrLovpnN58/s200/assign.png" width="200" /></a></div>
<br />
<blockquote>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #351c75;"><b>Equals.</b></span> (EQ) Represented by the string ‘==’.<br />Regular expression: ==<br />Automaton:</span></span></div>
</blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS9W9InLW4IgHofsyRKUDmqSRTTVXAxrT60KKXFkChUh4H_nDhV_AbMMKtFz8d4xX9OhZhUzzZxwJ0SfMB5U0F4dUIuxFrxfqnY3kM-MKo4CzY_byfeXSsDsozctaxLrvHauJ0/s1600/eq.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="139" data-original-width="795" height="55" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS9W9InLW4IgHofsyRKUDmqSRTTVXAxrT60KKXFkChUh4H_nDhV_AbMMKtFz8d4xX9OhZhUzzZxwJ0SfMB5U0F4dUIuxFrxfqnY3kM-MKo4CzY_byfeXSsDsozctaxLrvHauJ0/s320/eq.png" width="320" /></a></div>
<br />
<blockquote>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #351c75;"><b>Identifiers.</b></span> (ID) Represented by any string that starts with an alphabetic character and is followed by zero or more alphanumeric characters.<br />Regular expression: α[α|N ]?<br />Automaton:</span></span></div>
</blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZn6Sq67dI3YJAQZNJbZxzLoSUhZpQtQKR-dI5WvJ7bwgI_nkuOvnmphDKwXsaaOnawGEZa3W_TK0RGJBGdoaZOySddA800A55wIMqbsNzSohqf5alrzpSpD3XpliI59dSVM1t/s1600/id.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="159" data-original-width="785" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZn6Sq67dI3YJAQZNJbZxzLoSUhZpQtQKR-dI5WvJ7bwgI_nkuOvnmphDKwXsaaOnawGEZa3W_TK0RGJBGdoaZOySddA800A55wIMqbsNzSohqf5alrzpSpD3XpliI59dSVM1t/s320/id.png" width="320" /></a></div>
<br />
<blockquote>
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #351c75;"><b>Whitespace.</b></span> (WS) Represented by a non-empty string of spaces or tabs.</span></span><br />
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Regular expression: [SP ACE|T AB]+</span></span><br />
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Automaton:</span></span></blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5NI4HpzuMqxUib8hGstjJNvJ1TiUQreeE1kKK6kQOakhtk6mxIl3zlr2Cov6q4wdlcJNyiMbYzR8SzD4y6gsZV9-ZzkU8pWALjWTwiSVGfwWQZlhp42furzKrjMJ7qm6S3J37/s1600/ws.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="123" data-original-width="927" height="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5NI4HpzuMqxUib8hGstjJNvJ1TiUQreeE1kKK6kQOakhtk6mxIl3zlr2Cov6q4wdlcJNyiMbYzR8SzD4y6gsZV9-ZzkU8pWALjWTwiSVGfwWQZlhp42furzKrjMJ7qm6S3J37/s400/ws.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">A practical recogniser would try to consume as much of the input string as possible returning a token. For instance, if the input in "ab", and the input pointer has just consume ’a’, it has a choice of returning the ID token with lexeme "a". However, the lexer must hang on before hurrying to do that. It must look ahead of where it currently is and decide on its next move based on what it sees. Here, for example, it would see that the next character to be consumed is ’b’. This, if eaten, would help construct a longer lexeme, and result in further progress of the lexical analysis process before a token is returned. Hence, the lexical analyser, instead of returning rightaway will go ahead and consume ’b’. Thereafter, it will find that either the input string is over, or the next unconsumed chanracter is a non-alphanumeric one. Thus, the<br />lexical analyser will return ID token class "ab" being the lexeme.</span></span></div>
<h3 style="text-align: left;">
<span style="font-size: x-large;"><span style="color: #990000;"><span style="font-family: "georgia" , "times new roman" , serif;">Combining the Automata</span></span></span></h3>
<h3 style="text-align: left;">
<span style="font-size: x-large;"><span style="color: #990000;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></span></h3>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">There are multiple approaches possible in designing the combined recogniser. The conceptually simplest is to merge all the automata corresponding to each token class into one. This is the approach we take here. The combined automaton for the token classes is as shown in the following figure:</span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEGURXvjUHJ8_MT84VruY_Eda9hruf_MMlYGdCsJBzF_MeuRaQ14LIw8MEjIXmJQrwxMlnYwPTzqgzvKlD_41djOQ2Abuoge3qmI2acQTuGNJfugNJAVxeB5nOWG-F3gNrqEEO/s1600/combined.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="567" data-original-width="653" height="277" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEGURXvjUHJ8_MT84VruY_Eda9hruf_MMlYGdCsJBzF_MeuRaQ14LIw8MEjIXmJQrwxMlnYwPTzqgzvKlD_41djOQ2Abuoge3qmI2acQTuGNJfugNJAVxeB5nOWG-F3gNrqEEO/s320/combined.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The Combined Automaton</td></tr>
</tbody></table>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></span></div>
<h3 style="text-align: left;">
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Recognising the Next Token</span></span></span></h3>
<h3>
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></span></h3>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">The central function in lexical analysis is the stateful procedure that begins consuming character upon character until it can consume no other. At that point it has to make a decision as to whether it has been able to recognise a valid token. If yes, that token is returned; otherwise, an error is announced. So, at the high level, the algorithm goes like this:</span></span></div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgupvwIlBrPkYMNRSiHvWPqUp2pkicj56LukvHpOOruFBA_ifAec8WXtDbOIh-Ee1dWduLtZyhws7PWlKAVMSLFOVr7gz-oY7eMwUqLqSo_9-3UIfN4r4LwU9mld0tr_JHLEFPD/s1600/algo.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="354" data-original-width="922" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgupvwIlBrPkYMNRSiHvWPqUp2pkicj56LukvHpOOruFBA_ifAec8WXtDbOIh-Ee1dWduLtZyhws7PWlKAVMSLFOVr7gz-oY7eMwUqLqSo_9-3UIfN4r4LwU9mld0tr_JHLEFPD/s640/algo.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pseudocode for the procedure that gets the next token</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: left;">
<span style="color: #990000;"><span style="font-size: x-large;"><span style="font-family: "georgia" , "times new roman" , serif;">Architecture and Implementation</span></span></span></h3>
<h3 style="text-align: left;">
<span style="font-size: x-large;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></h3>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Now, let’s take a look at the implementation that we have done. The system has been designed within a Scanner class, which encapsulates an instance of DFA class.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG_K-X71m6hspEPEfWnBQb6TrwpAdorq0YAl18pScy9pvytsnsQwDjLtQZtPIzH6pSQvW1FamBX32lw-Ur8SRSte5lXqWhyYqE48ob8fPQGNGmaNQcikTCwDIxNvSf7c32Lmti/s1600/arch.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="557" data-original-width="668" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG_K-X71m6hspEPEfWnBQb6TrwpAdorq0YAl18pScy9pvytsnsQwDjLtQZtPIzH6pSQvW1FamBX32lw-Ur8SRSte5lXqWhyYqE48ob8fPQGNGmaNQcikTCwDIxNvSf7c32Lmti/s400/arch.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Architecture of the Lexical Analyser</td></tr>
</tbody></table>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></span></div>
<h4 style="text-align: left;">
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Class DFA</span></span></span></h4>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">DFA class provides the basic API for creating a deterministic finite state automaton. An instance is created by specifying the list of state IDs (which are integers), the initial state ID, and the list of final states ID. The transitions are later added to the DFA using the add transition method in a very user-friendly manner. Internally, the DFA has been designed like a directed graph using adjacency list style connections.</span></span></div>
<h4 style="text-align: left;">
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Class Scanner</span></span></span></h4>
<h4>
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></span></h4>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">The Scanner class implements the functionalities of the lexical analyser. It keeps account of the input string, and the progress of the lexical analysis through this string. It actuates the DFA by feeding it one character at a time, and makes the decision regarding acceptance or rejection of the input string at appropriate<br />times. the next token method returns the next token beginning at the current position on the input string. scan method returns all the tokens contained in the input string, by making repeated calls to next token.</span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></span></div>
<h3 style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #990000;"><span style="font-size: x-large;">Code</span></span></span></span></h3>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #990000;"><span style="font-size: x-large;"><span style="color: black; font-size: large;">The code for the lexical analyser can be found in <a href="https://gitlab.com/sujitkc/compilers/tree/68958fc8958a69b721d7494f28becb58409e0aa5/code/la/ex1" target="_blank">this link</a>. In fact, as of the current date, the code contains a slight enhancement to the lexical analyser described here, in that it is also able to distinguish between identifiers and keywords. The scanner is implemented in <span style="color: #274e13;"><span style="font-family: "Courier New", Courier, monospace;">KWScanner</span></span> class which simply extends the <span style="font-family: "Courier New", Courier, monospace;"><span style="color: #274e13;">Scanner</span></span> class with the required capability.</span></span></span></span></span><br />
<br />
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><span style="color: #990000;"><span style="font-size: x-large;"><span style="color: black; font-size: large;">This code is likely to keep evolving beyond what is described here. The latest version of the code can be found in <a href="https://gitlab.com/sujitkc/compilers/tree/master/code/la/ex1" target="_blank">this link</a>. </span> </span></span></span></span></div>
<h3 style="text-align: left;">
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">User Instructions</span></span></span></h3>
<h3>
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></h3>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">The executable <span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #274e13;">la</span></span> is created by running <span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #274e13;">make</span></span>. <span style="color: #274e13;"><span style="font-family: "courier new" , "courier" , monospace;">la</span></span> can be run simply without provided any command line arguments.</span></span></div>
<h4 style="text-align: left;">
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">Navigating the Code</span></span></span></h4>
<h4>
<span style="color: purple;"><span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"></span></span></span></h4>
<div style="text-align: justify;">
<span style="font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;">The main function is in the file <span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #274e13;">la.cpp</span></span>. The above example is implemented in the test case function <span style="color: #274e13;"><span style="font-family: "courier new" , "courier" , monospace;">t3</span></span>. In <span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #274e13;">t3</span></span>, we create an object dfa of type DFA. We construct it to resemble the DFA shown in figure above.</span></span></div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-29768020218433698792018-07-23T21:14:00.001+05:302018-07-23T21:14:14.649+05:30Simulating Higher Order Functions using Strategy Design Pattern<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
We wish to implement a function that takes an integer array as an input and returns an integer array of the same length but each of its elements double the corresponding element in the input array. One possibly reasonable implementation is shown below.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div dir="ltr" style="text-align: justify;" trbidi="on">
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Hof</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">main</span><span style="color: #333333;">(</span>String<span style="color: #333333;">[]</span> args<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> a <span style="color: #333333;">=</span> <span style="color: #333333;">{</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">};</span>
printArray<span style="color: #333333;">(</span>doubleArray<span style="color: #333333;">(</span>a<span style="color: #333333;">));</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">dbl</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> n <span style="color: #333333;">*</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">print</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">print</span><span style="color: #333333;">(</span>n <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">" "</span><span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> <span style="color: #0066bb; font-weight: bold;">doubleArray</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> array<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> ans <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[</span>array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">];</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> i <span style="color: #333333;"><</span> array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">;</span> i<span style="color: #333333;">++)</span> <span style="color: #333333;">{</span>
ans<span style="color: #333333;">[</span>i<span style="color: #333333;">]</span> <span style="color: #333333;">=</span> dbl<span style="color: #333333;">(</span>array<span style="color: #333333;">[</span>i<span style="color: #333333;">]);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> ans<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> <span style="color: #0066bb; font-weight: bold;">printArray</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> array<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> ans <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[</span>array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">];</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> i <span style="color: #333333;"><</span> array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">;</span> i<span style="color: #333333;">++)</span> <span style="color: #333333;">{</span>
ans<span style="color: #333333;">[</span>i<span style="color: #333333;">]</span> <span style="color: #333333;">=</span> print<span style="color: #333333;">(</span>array<span style="color: #333333;">[</span>i<span style="color: #333333;">]);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> ans<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<br />
On running this program, we get the following output:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">2 4 6</span>
</pre>
</div>
<br />
<br />
Now, we additionally wish to implement a function that squares an integer array, we may have to insert the pieces below.<br />
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Hof</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">main</span><span style="color: #333333;">(</span>String<span style="color: #333333;">[]</span> args<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> a <span style="color: #333333;">=</span> <span style="color: #333333;">{</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">};</span>
printArray<span style="color: #333333;">(</span>doubleArray<span style="color: #333333;">(</span>a<span style="color: #333333;">));</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">dbl</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> n <span style="color: #333333;">*</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">print</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">print</span><span style="color: #333333;">(</span>n <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">" "</span><span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> <span style="color: #0066bb; font-weight: bold;">doubleArray</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> array<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> ans <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[</span>array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">];</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> i <span style="color: #333333;"><</span> array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">;</span> i<span style="color: #333333;">++)</span> <span style="color: #333333;">{</span>
ans<span style="color: #333333;">[</span>i<span style="color: #333333;">]</span> <span style="color: #333333;">=</span> dbl<span style="color: #333333;">(</span>array<span style="color: #333333;">[</span>i<span style="color: #333333;">]);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> ans<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> <span style="color: #0066bb; font-weight: bold;">printArray</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> array<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> ans <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[</span>array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">];</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> i <span style="color: #333333;"><</span> array<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">;</span> i<span style="color: #333333;">++)</span> <span style="color: #333333;">{</span>
ans<span style="color: #333333;">[</span>i<span style="color: #333333;">]</span> <span style="color: #333333;">=</span> print<span style="color: #333333;">(</span>array<span style="color: #333333;">[</span>i<span style="color: #333333;">]);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> ans<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<br />
<br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">2 4 6</span>
<span style="color: #cccccc;">1 4 9 </span>
</pre>
</div>
<br />
<br />
<div style="text-align: justify;">
However, Java does badly when it comes to economy of expression. </div>
<div style="text-align: justify;">
Let's just look at how the same code would look in another programming language, Python, shown below. </div>
<div style="text-align: justify;">
<!-- HTML generated using hilite.me --><br /></div>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">print</span> <span style="color: #007020;">map</span>(<span style="color: #008800; font-weight: bold;">lambda</span> x: <span style="color: #0000dd; font-weight: bold;">2</span> <span style="color: #333333;">*</span> x, [<span style="color: #0000dd; font-weight: bold;">1</span>, <span style="color: #0000dd; font-weight: bold;">2</span>, <span style="color: #0000dd; font-weight: bold;">3</span>])
<span style="color: #008800; font-weight: bold;">print</span> <span style="color: #007020;">map</span>(<span style="color: #008800; font-weight: bold;">lambda</span> x: x <span style="color: #333333;">*</span> x, [<span style="color: #0000dd; font-weight: bold;">1</span>, <span style="color: #0000dd; font-weight: bold;">2</span>, <span style="color: #0000dd; font-weight: bold;">3</span>])
</pre>
</div>
<br />
On running this program, we get the following output:<br />
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">[2, 4, 6]</span>
<span style="color: #cccccc;">[1, 4, 9]</span>
</pre>
</div>
<br />
<br />
<br />
<div style="text-align: justify;">
One of the reasons for this enormous of economy of syntax is a <i>higher order function</i> called <b><span style="font-family: "Courier New", Courier, monospace;">map</span></b>. A higher order function is a function that takes other functions as inputs (and possibly computes functions as output). <b><span style="font-family: "Courier New", Courier, monospace;">map</span></b> is one such function that takes a function, say \lstinline$f$, and a list, say <b><span style="font-family: "Courier New", Courier, monospace;">l</span></b>, and returns a list each of whose elements is <b><span style="font-family: "Courier New", Courier, monospace;">f</span></b> applied to the corresponding element in <b><span style="font-family: "Courier New", Courier, monospace;">l</span></b>. HOFs are a common feature of functional programming. In fact, what inheritance and polymorphism is to object-oriented programming, HOFs are the same to functional programming: the main abstraction mechanism for code reuse and modularisation.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Unfortunately, Java (until Java 8) doesn't have higher order functions. But the case for higher order functions is strong enough that we wish to implement something similar in Java. How do we do it?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
With our knowledge of object-oriented programming, we can come out with a fairly close approximation to the idea of higher order functions. The central idea is: in OOP, we can't pass functions to functions, but we can pass objects which have functions in them. Thus, all we need to do is pack the function that we want to pass to a HOF in a class, and pass an object of that class to the HOF.</div>
<div style="text-align: justify;">
The solution for the problem is presented below.</div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Hof</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">main</span><span style="color: #333333;">(</span>String<span style="color: #333333;">[]</span> a<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> ar <span style="color: #333333;">=</span> <span style="color: #333333;">{</span><span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">};</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> newarray <span style="color: #333333;">=</span> Hof<span style="color: #333333;">.</span><span style="color: #0000cc;">map</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> Dbl<span style="color: #333333;">(),</span> ar<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n <span style="color: #333333;">:</span> newarray<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">println</span><span style="color: #333333;">(</span>n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span></pre>
<pre style="line-height: 125%; margin: 0;"><span style="color: #333333;"> </span>
newarray <span style="color: #333333;">=</span> Hof<span style="color: #333333;">.</span><span style="color: #0000cc;">map</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> Dbl<span style="color: #333333;">(),</span> ar<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n <span style="color: #333333;">:</span> newarray<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">println</span><span style="color: #333333;">(</span>n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #333333;">[]</span> map<span style="color: #333333;">(</span>Function f<span style="color: #333333;">,</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #333333;">[]</span> a<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> newarray <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[</span>a<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">];</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> i <span style="color: #333333;">&</span>lt<span style="color: #333333;">;</span> a<span style="color: #333333;">.</span><span style="color: #0000cc;">length</span><span style="color: #333333;">;</span> i<span style="color: #333333;">++)</span> <span style="color: #333333;">{</span>
newarray<span style="color: #333333;">[</span>i<span style="color: #333333;">]</span> <span style="color: #333333;">=</span> f<span style="color: #333333;">.</span><span style="color: #0000cc;">execute</span><span style="color: #333333;">(</span>a<span style="color: #333333;">[</span>i<span style="color: #333333;">]);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">return</span> newarray<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">interface</span> <span style="color: #bb0066; font-weight: bold;">Function</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">execute</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Dbl</span> <span style="color: #008800; font-weight: bold;">implements</span> Function <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">execute</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #0000dd; font-weight: bold;">2</span> <span style="color: #333333;">*</span> n<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">Sqr</span> <span style="color: #008800; font-weight: bold;">implements</span> Function <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">execute</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> n <span style="color: #333333;">*</span> n<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
which gives us the following output:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">2</span>
<span style="color: #cccccc;">4</span>
<span style="color: #cccccc;">6</span>
<span style="color: #cccccc;">1</span>
<span style="color: #cccccc;">4</span>
<span style="color: #cccccc;">9</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
Just in case it's not clear already, let me help you walk through the code.</div>
<div style="text-align: justify;">
<br /></div>
<ol style="text-align: justify;">
<li>The first thing to notice is the interface <b><span style="font-family: "Courier New", Courier, monospace;">Function</span></b>. It has a method declaration <b><span style="font-family: "Courier New", Courier, monospace;">execute</span></b> that takes an integer and returns an integer. This represents the function that would be passed to the higher order function map and would be applied to each element of the integer array.</li>
<li>The next thing to observe is the <b><span style="font-family: "Courier New", Courier, monospace;">map</span></b> method which takes two parameters: the first is <b><span style="font-family: "Courier New", Courier, monospace;">f</span></b>, an instance of <b><span style="font-family: "Courier New", Courier, monospace;">Function</span></b>; and the other is the array of <b><span style="font-family: "Courier New", Courier, monospace;">int</span></b>s <b><span style="font-family: "Courier New", Courier, monospace;">a</span></b>. It returns the resultant array after applying <b><span style="font-family: "Courier New", Courier, monospace;">f</span></b> on each element of <b><span style="font-family: "Courier New", Courier, monospace;">a</span></b> as shown.</li>
<li>Finally, an instance of <b><span style="font-family: "Courier New", Courier, monospace;">Dbl</span></b> and <b><span style="font-family: "Courier New", Courier, monospace;">Sqr</span></b> are passed in turn to <b><span style="font-family: "Courier New", Courier, monospace;">Hof.map</span></b> in the \lstinline@main@ method to be applied to <b><span style="font-family: "Courier New", Courier, monospace;">array</span></b>.</li>
</ol>
<div style="text-align: justify;">
<br />
This application is to demonstrate how object-oriented principles can be used to create highly reusable code. The <b><span style="font-family: "Courier New", Courier, monospace;">map</span></b> method here is a boiler-plate code that can be used wherever there's a need to apply a function on all elements of an integer array to create a new one. What that function to applied should be is a parameter to the method, and hence is flexible.</div>
<h3 style="text-align: left;">
Anonymous Classes</h3>
<div style="text-align: justify;">
The next question we ask is: In Java, is there something equivalent to lambda expressions as seen in Python. Lambda expressions are like anonymous functions which are typically created for a one time use as a parameter to a higher order function. This avoids creation of extra named functions and saves the namespace (variable environment) from unnecessary clutter. Here, the classes <b><span style="font-family: "Courier New", Courier, monospace;">Dbl</span></b> and <b><span style="font-family: "Courier New", Courier, monospace;">Sqr</span></b> are similar classes: to be instantiated once to be passed to <b><span style="font-family: "Courier New", Courier, monospace;">Hof.map</span></b>, and then to be forgotten. Why do we need to create a named class which will ever be implemented only once? Like anonymous functions (lambda) in Python, do we have something like anonymous classes? Indeed, yes!<br />
<br />
We replace the earlier <b><span style="font-family: "Courier New", Courier, monospace;">Hof.main</span></b> method with the lines shown below. </div>
<div style="text-align: justify;">
<!-- HTML generated using hilite.me --><br /></div>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">main</span><span style="color: #333333;">(</span>String<span style="color: #333333;">[]</span> a<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333399; font-weight: bold;">int</span><span style="color: #333333;">[]</span> ar <span style="color: #333333;">=</span> <span style="color: #333333;">{</span><span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">};</span>
Function triple <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> Function<span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">int</span> <span style="color: #0066bb; font-weight: bold;">execute</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="color: #0000dd; font-weight: bold;">3</span> <span style="color: #333333;">*</span> n<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">};</span>
newarray <span style="color: #333333;">=</span> Hof<span style="color: #333333;">.</span><span style="color: #0000cc;">map</span><span style="color: #333333;">(</span>triple<span style="color: #333333;">,</span> ar<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">for</span><span style="color: #333333;">(</span><span style="color: #333399; font-weight: bold;">int</span> n <span style="color: #333333;">:</span> newarray<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
System<span style="color: #333333;">.</span><span style="color: #0000cc;">out</span><span style="color: #333333;">.</span><span style="color: #0000cc;">println</span><span style="color: #333333;">(</span>n<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<div style="text-align: left;">
<br />
Here's the output:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #202020; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #cccccc;">3</span>
<span style="color: #cccccc;">6</span>
<span style="color: #cccccc;">9</span>
</pre>
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br />
<div style="text-align: justify;">
Here, we used the <b><span style="font-family: "Courier New", Courier, monospace;">map</span></b> method to triple the <b><span style="font-family: "Courier New", Courier, monospace;">array</span></b>. The <b><span style="font-family: "Courier New", Courier, monospace;">Function</span></b> interface is implemented through an anonymous class (a class with no name) set to <b><span style="font-family: "Courier New", Courier, monospace;">Function triple</span></b>. All we need to do to make it a concrete class is to provide its own implementation of the <b><span style="font-family: "Courier New", Courier, monospace;">execute</span></b> method. We do so. And it just works smoothly. No need to create another class named <b><span style="font-family: "Courier New", Courier, monospace;">Triple</span></b> or something. No too many unused class names. No namespace clutter!</div>
</div>
</div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-48665860322359859352018-06-25T09:01:00.002+05:302018-06-25T09:03:43.271+05:30Taking Interest in FIFA 2018<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
As a father of a growing pre-teen boy, I am supposed to take at least some interest in sports. Particularly when the whole world is afire about FIFA world cup.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, yesterday, I sat beside my son watching the match between Japan and Senegal, picking Senegal as the team I supported (as my son supported Japan). Thank God! The match ended in a draw!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It was a nice experience. I did find the match interesting. But, it would have been too much to expect me to concentrate on the game all the while. While the match on, I fiddled with my laptop, and did a little program to calculate the importance of the remaining matches in the opening round.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I have pasted the output (with some edits to include the dates and times) at the end of the source code within comments.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The program has some simple illustration of how the library higher order functions List.map and List.sort can be used. There's also a higher order function rate_match implemented.<br />
<br />
Hope you find it helpful in deciding which matches in the opening round you would like to watch, and in the process get a bit familiar with functional programming with OCaml. </div>
<br />
<br />
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">let</span> teams <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>
<span style="background-color: #fff0f0;">"Germany"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Brazil"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Belgium"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Portugal"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Argentina"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Switzerland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"France"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Poland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Chile"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Spain"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Peru"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Denmark"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"England"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Uruguay"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Mexico"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Colombia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Netherlands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Wales"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Italy"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Croatia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Tunisia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Iceland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Costa Rica"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Sweden"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"United States"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Austria"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Senegal"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Slovakia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Northern Ireland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Romania"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Republic of Ireland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Paraguay"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Venezuela"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Serbia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Ukraine"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Australia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Iran"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Turkey"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Congo DR"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bosnia-Herzegovina"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Morocco"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Scotland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Montenegro"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Greece"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Egypt"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Czech Republic"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Ghana"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Nigeria"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bulgaria"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cameroon"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Hungary"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Burkina Faso"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Norway"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Jamaica"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Panama"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Slovenia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Korea Republic"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Albania"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bolivia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Ecuador"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Japan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Honduras"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Finland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Mali"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cape Verde Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Algeria"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Saudi Arabia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Côte d'Ivoire"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Guinea"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Russia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"FYR Macedonia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"El Salvador"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Syria"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"South Africa"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"China PR"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Zambia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"UAE"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Belarus"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Lebanon"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Canada"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Curaçao"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Uganda"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Congo"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Oman"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Gabon"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Luxembourg"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cyprus"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Benin"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Iraq"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Faroe Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Trinidad and Tobago"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Kyrgyzstan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Israel"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Estonia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Uzbekistan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Georgia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"India"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Qatar"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Palestine"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Armenia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Libya"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Vietnam"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Niger"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Haiti"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Azerbaijan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Madagascar"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Mauritania"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Korea DPR"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Central African Republic"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Jordan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Sierra Leone"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Kenya"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bahrain"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Mozambique"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Philippines"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Namibia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Kazakhstan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Zimbabwe"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Tajikistan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"New Zealand"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Guinea-Bissau"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Thailand"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Malawi"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Chinese Taipei"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Togo"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Lithuania"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Antigua and Barbuda"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Sudan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Latvia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Turkmenistan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Andorra"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Nicaragua"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Yemen"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Swaziland"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"St. Kitts and Nevis"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Rwanda"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Angola"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Myanmar"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Botswana"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Tanzania"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Kosovo"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Hong Kong"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Equatorial Guinea"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Solomon Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Afghanistan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Guatemala"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Lesotho"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Burundi"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Comoros"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Maldives"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Ethiopia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Dominican Republic"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Suriname"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"New Caledonia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Mauritius"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"South Sudan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Tahiti"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Liberia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Kuwait"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Barbados"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Nepal"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Vanuatu"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Belize"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Indonesia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Fiji"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cambodia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Papua New Guinea"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Grenada"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Singapore"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"St. Lucia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Malaysia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Gambia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"St. Vincent / Grenadines"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Puerto Rico"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Chad"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Moldova"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Dominica"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bermuda"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Laos"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Liechtenstein"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cuba"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Guyana"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bhutan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Malta"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Macao"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Mongolia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"São Tomé e Príncipe"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Seychelles"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Aruba"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Guam"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Timor-Leste"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"American Samoa"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cook Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bangladesh"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Gibraltar"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Brunei"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Djibouti"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Samoa"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"US Virgin Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Sri Lanka"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Pakistan"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Cayman Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"San Marino"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"British Virgin Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Montserrat"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Turks and Caicos Islands"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Anguilla"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Bahamas"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Eritrea"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Somalia"</span><span style="color: #333333;">;</span>
<span style="background-color: #fff0f0;">"Tonga"</span><span style="color: #333333;">;</span>
<span style="color: #333333;">]</span>
<span style="color: #008800; font-weight: bold;">let</span> matches <span style="color: #333333;">=</span> <span style="color: #333333;">[</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Japan"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Senegal"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Poland"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Colombia"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Uruguay"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Russia"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Saudi Arabia"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Egypt"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Spain"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Morocco"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Iran"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Portugal"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Australia"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Peru"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Denmark"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"France"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Nigeria"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Argentina"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Iceland"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Croatia"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Korea Republic"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Germany"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Mexico"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Sweden"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Serbia"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Brazil"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Switzerland"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Costa Rica"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Japan"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Poland"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Senegal"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Colombia"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"Panama"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Tunisia"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"England"</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Belgium"</span><span style="color: #333333;">);</span>
<span style="color: #333333;">]</span>
<span style="color: #008800; font-weight: bold;">exception</span> <span style="color: #bb0066; font-weight: bold;">My_Not_found</span> <span style="color: #008800; font-weight: bold;">of</span> <span style="color: #333399; font-weight: bold;">string</span>
<span style="color: #008800; font-weight: bold;">let</span> find x l <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> iter i <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">function</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> <span style="color: #008800; font-weight: bold;">raise</span> <span style="color: #333333;">(</span><span style="color: #bb0066; font-weight: bold;">My_Not_found</span> x<span style="color: #333333;">)</span>
<span style="color: #333333;">|</span> h <span style="color: #333333;">::</span> t <span style="color: #333333;">-></span> <span style="color: #008800; font-weight: bold;">if</span> h <span style="color: #333333;">=</span> x <span style="color: #008800; font-weight: bold;">then</span> i <span style="color: #008800; font-weight: bold;">else</span> iter <span style="color: #333333;">(</span>i <span style="color: #333333;">+</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> t
<span style="color: #008800; font-weight: bold;">in</span>
iter <span style="color: #0000dd; font-weight: bold;">1</span> l
<span style="color: #008800; font-weight: bold;">let</span> rate_match <span style="color: #333333;">(</span>t1<span style="color: #333333;">,</span> t2<span style="color: #333333;">)</span> imp <span style="color: #333333;">=</span>
imp <span style="color: #333333;">(</span>find t1 teams<span style="color: #333333;">)</span> <span style="color: #333333;">(</span>find t2 teams<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">let</span> rate_matches ms <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> rates <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.map <span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">fun</span> m <span style="color: #333333;">-></span> <span style="color: #333333;">(</span>m<span style="color: #333333;">,</span> rate_match m <span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">fun</span> x y <span style="color: #333333;">-></span> x <span style="color: #333333;">*</span> y<span style="color: #333333;">)))</span> ms <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #0e84b5; font-weight: bold;">List</span>.sort <span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">fun</span> <span style="color: #333333;">(_,</span> r1<span style="color: #333333;">)</span> <span style="color: #333333;">(_,</span> r2<span style="color: #333333;">)</span> <span style="color: #333333;">-></span> <span style="color: #008800; font-weight: bold;">if</span> r1 <span style="color: #333333;"><</span> r2 <span style="color: #008800; font-weight: bold;">then</span> <span style="color: #333333;">-</span><span style="color: #0000dd; font-weight: bold;">1</span> <span style="color: #008800; font-weight: bold;">else</span> <span style="color: #008800; font-weight: bold;">if</span> r1 <span style="color: #333333;">=</span> r2 <span style="color: #008800; font-weight: bold;">then</span> <span style="color: #0000dd; font-weight: bold;">0</span> <span style="color: #008800; font-weight: bold;">else</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> rates
<span style="color: #888888;">(*</span>
<span style="color: #888888;">By using 'addition' as the joining function</span>
<span style="color: #888888;">[</span>
<span style="color: #888888;"> (("England", "Belgium"), 14); June 28 11.30 PM</span>
<span style="color: #888888;"> (("Denmark", "France"), 17); June 26 7.30 PM</span>
<span style="color: #888888;"> (("Poland", "Colombia"), 22); June 24 11.30 PM</span>
<span style="color: #888888;"> (("Switzerland", "Costa Rica"), 27); June 27 11.30 PM</span>
<span style="color: #888888;"> (("Serbia", "Brazil"), 34); June 27 11.30 PM</span>
<span style="color: #888888;"> (("Mexico", "Sweden"), 37); June 27 7.30 PM</span>
<span style="color: #888888;"> (("Iran", "Portugal"), 39); June 25 7.30 PM</span>
<span style="color: #888888;"> (("Iceland", "Croatia"), 40); June 26 11.30 PM</span>
<span style="color: #888888;"> (("Senegal", "Colombia"), 41); June 28 7.30 PM</span>
<span style="color: #888888;"> (("Australia", "Peru"), 45); June 26 7.30 PM</span>
<span style="color: #888888;"> (("Spain", "Morocco"), 49); June 25 11.30 PM</span>
<span style="color: #888888;"> (("Nigeria", "Argentina"), 51); June 26 11.30 PM</span>
<span style="color: #888888;"> (("Korea Republic", "Germany"), 56); June 27 7.30 PM</span>
<span style="color: #888888;"> (("Japan", "Poland"), 67); June 28 7.30 PM</span>
<span style="color: #888888;"> (("Panama", "Tunisia"), 74); June 28 11.30 PM</span>
<span style="color: #888888;"> (("Uruguay", "Russia"), 82); June 25 7.30 PM</span>
<span style="color: #888888;"> (("Japan", "Senegal"), 86); June 24 8.30 PM</span>
<span style="color: #888888;"> (("Saudi Arabia", "Egypt"), 110) June 25 7.30 PM</span>
<span style="color: #888888;">]</span>
<span style="color: #888888;">By using 'multiplication' as the joining function</span>
<span style="color: #888888;">[</span>
<span style="color: #888888;"> (("England", "Belgium"), 39);</span>
<span style="color: #888888;"> (("Korea Republic", "Germany"), 57);</span>
<span style="color: #888888;"> (("Serbia", "Brazil"), 68);</span>
<span style="color: #888888;"> (("Denmark", "France"), 84);</span>
<span style="color: #888888;"> (("Poland", "Colombia"), 128);</span>
<span style="color: #888888;"> (("Switzerland", "Costa Rica"), 138);</span>
<span style="color: #888888;"> (("Iran", "Portugal"), 148);</span>
<span style="color: #888888;"> (("Nigeria", "Argentina"), 240);</span>
<span style="color: #888888;"> (("Mexico", "Sweden"), 360);</span>
<span style="color: #888888;"> (("Australia", "Peru"), 396);</span>
<span style="color: #888888;"> (("Spain", "Morocco"), 410);</span>
<span style="color: #888888;"> (("Senegal", "Colombia"), 432);</span>
<span style="color: #888888;"> (("Iceland", "Croatia"), 440);</span>
<span style="color: #888888;"> (("Japan", "Poland"), 488);</span>
<span style="color: #888888;"> (("Uruguay", "Russia"), 980);</span>
<span style="color: #888888;"> (("Panama", "Tunisia"), 1155);</span>
<span style="color: #888888;"> (("Japan", "Senegal"), 1647);</span>
<span style="color: #888888;"> (("Saudi Arabia", "Egypt"), 3015)</span>
<span style="color: #888888;">]</span>
<span style="color: #888888;">*)</span>
</pre>
</td></tr>
</tbody></table>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-65028023401276668502017-05-04T16:05:00.005+05:302017-05-04T16:43:29.725+05:30Calculating PI using Monte Carlo Simulation<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZj-FoOdgQL0tSiBQjy04eZzrpcWV5FwkPPR07lyH_xuT5MyiwCRS2UBk5jq_2F1UOwgnLfvdSjfHDgGrwjU_QG6aBXigu45O4HssLJRIC1ltwCHkQT5Yl8h1ReflaugSJiG6m/s1600/uc.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="372" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZj-FoOdgQL0tSiBQjy04eZzrpcWV5FwkPPR07lyH_xuT5MyiwCRS2UBk5jq_2F1UOwgnLfvdSjfHDgGrwjU_QG6aBXigu45O4HssLJRIC1ltwCHkQT5Yl8h1ReflaugSJiG6m/s400/uc.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Monte Carlo Simulation to Compute PI</td></tr>
</tbody></table>
<span style="color: #cc0000;">
Equations</span></h3>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_VNVXWUFN25IBf8WS9ixGK0PLviXQli2z9P3TwStbCT77XttRW7RISbeO1JwaysA54LuVFFNbM9uDxBL4I34vPVz6r6ptlABh3YxX_t4mIKhrJUXfw_Kp6dVjCnWuUL1dFHVI/s1600/equations.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="342" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_VNVXWUFN25IBf8WS9ixGK0PLviXQli2z9P3TwStbCT77XttRW7RISbeO1JwaysA54LuVFFNbM9uDxBL4I34vPVz6r6ptlABh3YxX_t4mIKhrJUXfw_Kp6dVjCnWuUL1dFHVI/s400/equations.png" width="400" /></a></div>
<br /></div>
<div style="text-align: left;">
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3>
<span style="color: #cc0000;">
Code</span></h3>
<!-- HTML generated using hilite.me -->Follows a sample OCaml code to implement the above idea.<br />
<br />
<br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">let</span> one_point <span style="color: #aa22ff;">()</span> <span style="color: #666666;">=</span> <span style="color: #666666;">(</span><span style="color: blue; font-weight: bold;">Random</span>.float <span style="color: #666666;">(2.)</span> <span style="color: #666666;">-.</span> <span style="color: #666666;">1.,</span> <span style="color: blue; font-weight: bold;">Random</span>.float <span style="color: #666666;">(2.)</span> <span style="color: #666666;">-.</span> <span style="color: #666666;">1.)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> n_points n <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #aa22ff; font-weight: bold;">rec</span> iter acc <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">function</span>
<span style="color: #666666;">0</span> <span style="color: #666666;">-></span> acc
<span style="color: #666666;">|</span> n <span style="color: #666666;">-></span> iter <span style="color: #666666;">((</span>one_point <span style="color: #aa22ff;">()</span><span style="color: #666666;">)</span> <span style="color: #666666;">::</span> acc<span style="color: #666666;">)</span> <span style="color: #666666;">(</span>n <span style="color: #666666;">-</span> <span style="color: #666666;">1)</span>
<span style="color: #aa22ff; font-weight: bold;">in</span>
iter <span style="color: #aa22ff;">[]</span> n
<span style="color: #008800; font-style: italic;">(* tail-recursive implementation of map to prevent stack-overflow. *)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> mymap f l <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #aa22ff; font-weight: bold;">rec</span> iter f acc <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">function</span>
<span style="color: #aa22ff;">[]</span> <span style="color: #666666;">-></span> acc
<span style="color: #666666;">|</span> h <span style="color: #666666;">::</span> t <span style="color: #666666;">-></span> iter f <span style="color: #666666;">((</span>f h<span style="color: #666666;">)</span> <span style="color: #666666;">::</span> acc<span style="color: #666666;">)</span> t
<span style="color: #aa22ff; font-weight: bold;">in</span>
iter f <span style="color: #aa22ff;">[]</span> l
<span style="color: #008800; font-style: italic;">(* tail-recursive implementation of filter to prevent stack-overflow. *)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> myfilter f l <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #aa22ff; font-weight: bold;">rec</span> iter f acc <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">function</span>
<span style="color: #aa22ff;">[]</span> <span style="color: #666666;">-></span> acc
<span style="color: #666666;">|</span> h <span style="color: #666666;">::</span> t <span style="color: #666666;">-></span> <span style="color: #aa22ff; font-weight: bold;">if</span> <span style="color: #666666;">(</span>f h<span style="color: #666666;">)</span> <span style="color: #aa22ff; font-weight: bold;">then</span> <span style="color: #666666;">(</span>iter f <span style="color: #666666;">((</span>f h<span style="color: #666666;">)</span> <span style="color: #666666;">::</span> acc<span style="color: #666666;">)</span> t<span style="color: #666666;">)</span>
<span style="color: #aa22ff; font-weight: bold;">else</span> <span style="color: #666666;">(</span>iter f acc t<span style="color: #666666;">)</span>
<span style="color: #aa22ff; font-weight: bold;">in</span>
iter f <span style="color: #aa22ff;">[]</span> l
<span style="color: #aa22ff; font-weight: bold;">let</span> pi <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> total <span style="color: #666666;">=</span> <span style="color: #666666;">10000000</span> <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #008800; font-style: italic;">(* number of times the dart is thrown *)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> points <span style="color: #666666;">=</span> n_points total <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #008800; font-style: italic;">(* list of points all the darts hit *)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> rs <span style="color: #666666;">=</span> mymap <span style="color: #666666;">(</span><span style="color: #aa22ff; font-weight: bold;">fun</span> <span style="color: #666666;">(</span>x<span style="color: #666666;">,</span> y<span style="color: #666666;">)</span> <span style="color: #666666;">-></span> x <span style="color: #666666;">*.</span> x <span style="color: #666666;">+.</span> y <span style="color: #666666;">*.</span> y<span style="color: #666666;">)</span> points <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #008800; font-style: italic;">(* the distance from origin of all points *)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> inner_points <span style="color: #666666;">=</span> myfilter <span style="color: #666666;">(</span><span style="color: #aa22ff; font-weight: bold;">fun</span> r <span style="color: #666666;">-></span> r <span style="color: #666666;"><=</span> <span style="color: #666666;">1.)</span> rs <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #008800; font-style: italic;">(* list of all points inside or on the unit circle *)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> num_inner_points <span style="color: #666666;">=</span> <span style="color: blue; font-weight: bold;">List</span>.length inner_points <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #008800; font-style: italic;">(* number of points inside or on the unit circle *)</span>
<span style="color: #666666;">4.</span> <span style="color: #666666;">*.</span> <span style="color: #666666;">((</span>float_of_int num_inner_points<span style="color: #666666;">)</span> <span style="color: #666666;">/.</span> <span style="color: #666666;">(</span>float_of_int total<span style="color: #666666;">))</span> <span style="color: #008800; font-style: italic;">(* value of PI. *)</span>
</pre>
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<h3 style="text-align: left;">
<span style="color: #cc0000;">
OCaml Interpretor Interaction</span></h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: left;"><tbody>
<tr><td style="text-align: center;"><br /></td></tr>
</tbody></table>
<h3 style="clear: both; text-align: left;">
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: navy; font-weight: bold;">#</span> <span style="color: #008800; font-style: italic;">#use "pi.ml";;</span>
<span style="color: #888888;">val one_point : unit -> float * float = <fun></span>
<span style="color: #888888;">val n_points : int -> (float * float) list = <fun></span>
<span style="color: #888888;">val mymap : ('a -> 'b) -> 'a list -> 'b list = <fun></span>
<span style="color: #888888;">val myfilter : ('a -> bool) -> 'a list -> bool list = <fun></span>
<span style="color: #888888;">val pi : float = 3.1419352</span>
</pre>
</div>
</h3>
<h3 style="clear: both; text-align: left;">
</h3>
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
<span style="color: #cc0000;">
Notes</span></h3>
<div style="text-align: justify;">
A large number of points are generated within the bounding square. The probability distribution for the points over this area is uniform, which means that the probability of occurrence of a dot at all points in the given square is equal. With large values of <i>N</i>, the ratio of the number of points inside the unit circle to <i>N</i> starts approaching the ratio of the areas of the unit circle and the square. This idea is used to compute a close approximate to Pi.<br />
<br />
As we use OCaml's library module Random to generate the points, the value of Pi computed in every simulation is non-deterministic and is different from the other by a small amount. The time needed to do the above computation was about 10 seconds on my laptop.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Most of the lines in the above code are really there to either enhance the readability or scalability of the program. As List.map and List.filter are non-tail recursive implementations, they lead to stack overflow for very large values of total (>= 1000000). The tail-recursive implementations of map and filter are provided only to prevent stack overflow for very large values of total (>= 1000000).</div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-68044508281943897852016-10-02T18:09:00.000+05:302016-10-02T18:13:00.682+05:30Higher Order Functions in Python<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: left;">
<span style="color: purple; font-family: Georgia, Times New Roman, serif; font-size: large;"><i>Pardon the hand-written notes. Will try and type out the whole thing in some future point.</i></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Georgia, Times New Roman, serif; font-size: large;"><i><br /></i></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Georgia, Times New Roman, serif; font-size: large;"><i><br /></i></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq83hkHzp6RbVV6wxc1X9MXpZ9KR2KJiM0yvAqnFXRsOsk0MNR_A-TVIMUP4-VAKjSXAFF-hAKBt6ltf9q-xppvcd6TaHJ5yvpVWtQl5MaA2SF6W3cNe7F0fi5Lt6lg2SZi2ks/s1600/hof1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiq83hkHzp6RbVV6wxc1X9MXpZ9KR2KJiM0yvAqnFXRsOsk0MNR_A-TVIMUP4-VAKjSXAFF-hAKBt6ltf9q-xppvcd6TaHJ5yvpVWtQl5MaA2SF6W3cNe7F0fi5Lt6lg2SZi2ks/s400/hof1.jpg" width="251" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCp0yQgKAdZukyMLWFbuA_chyphenhyphenRM3WtEHfA8YZazRH66fHWN3z58lxLrOr1j4UEvpkTgDFXbVYOZMTmJl7qg-HSdR-FKFdNDRQxDkqp5X10wFC8hO7kYHGeLmNTGfG1_HMFvyRu/s1600/hof2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCp0yQgKAdZukyMLWFbuA_chyphenhyphenRM3WtEHfA8YZazRH66fHWN3z58lxLrOr1j4UEvpkTgDFXbVYOZMTmJl7qg-HSdR-FKFdNDRQxDkqp5X10wFC8hO7kYHGeLmNTGfG1_HMFvyRu/s400/hof2.jpg" width="287" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieT4a9ayf1AnAoOnvfJbmKZkSHuVaL78ncFkDdZsD3O8ois0l_Npw7Eece2u3XOOl_dsZKqWqZWLFc37tdgvaddAJjHt8nGCDrGf0F3nuYZ-zF6ogEol9gOkNGbGR5Z-1-bA7-/s1600/hof3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieT4a9ayf1AnAoOnvfJbmKZkSHuVaL78ncFkDdZsD3O8ois0l_Npw7Eece2u3XOOl_dsZKqWqZWLFc37tdgvaddAJjHt8nGCDrGf0F3nuYZ-zF6ogEol9gOkNGbGR5Z-1-bA7-/s400/hof3.jpg" width="276" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKUPHUGlZ3tZDnbrIUv_8BCEqiaFqFsFEAGQRhHdhu5p1mp3TJ_5hbHkic2b5hX7gNZfIzDW7fL5xlgpiviJrHy9tI5Xxg_a3b_kE5nGLV9iP-dJdsMeJ1IxOhFNRdd1AfQKKW/s1600/hof4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKUPHUGlZ3tZDnbrIUv_8BCEqiaFqFsFEAGQRhHdhu5p1mp3TJ_5hbHkic2b5hX7gNZfIzDW7fL5xlgpiviJrHy9tI5Xxg_a3b_kE5nGLV9iP-dJdsMeJ1IxOhFNRdd1AfQKKW/s400/hof4.jpg" width="281" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhradjLGSqtnX8aZjqd1_mOnAukREGRrgtoIg_ePsA9ydNIuHgmA87WEiXol00N42MjRDzCHq4DCV6RHQx_ceaZdOuMDiLNh8_Xav4ahsnJa7qMrjCkyz9TwEnoQzvGSktjLpg/s1600/hof5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhradjLGSqtnX8aZjqd1_mOnAukREGRrgtoIg_ePsA9ydNIuHgmA87WEiXol00N42MjRDzCHq4DCV6RHQx_ceaZdOuMDiLNh8_Xav4ahsnJa7qMrjCkyz9TwEnoQzvGSktjLpg/s400/hof5.jpg" width="277" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1CBYVLXu0umHaq6hYa2ibM5RXzpQVb5M-MrIZ0ivZEGww-EQGHxEN59LUYX7hxylqOFV3EjZXJMtoCebx5GBgRDwnT5s5cc4j4LT_4ORYYuHeo8BgnTZaFGx632gdHsJ0GHTY/s1600/hof6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1CBYVLXu0umHaq6hYa2ibM5RXzpQVb5M-MrIZ0ivZEGww-EQGHxEN59LUYX7hxylqOFV3EjZXJMtoCebx5GBgRDwnT5s5cc4j4LT_4ORYYuHeo8BgnTZaFGx632gdHsJ0GHTY/s400/hof6.jpg" width="276" /></a></div>
<br /></div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-35380926730576317732016-09-21T10:04:00.003+05:302016-09-21T11:31:58.911+05:30Computing Unions and Differences for Sets of Time Durations<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2jT1qulomp-1UqW3AUcHKj0GyezfthfADSVo9Py0P9I4X12sgd-XK2F_gumYUZiEBb090IQYkbizj2IAnvMlljsr99fVMly9DGDz2KMWGRDEO7XVHrm3jwJrGxPXa3bjuJbc2/s1600/timeline.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2jT1qulomp-1UqW3AUcHKj0GyezfthfADSVo9Py0P9I4X12sgd-XK2F_gumYUZiEBb090IQYkbizj2IAnvMlljsr99fVMly9DGDz2KMWGRDEO7XVHrm3jwJrGxPXa3bjuJbc2/s400/timeline.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: "arial" , "helvetica" , sans-serif;">Timeline</span></td></tr>
</tbody></table>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQg07fQF-p-tgICT9LQjxBziVbb7z8OAA13E5_TCTQ43lTWeOf4p1C9lFU0N53pRIcmgsv6tzyR6P556fOV01qUe9zowCMZH-PQwbIEhv31tm3U63h2FWjSnk_1WQX3OisF2Yp/s1600/legend.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQg07fQF-p-tgICT9LQjxBziVbb7z8OAA13E5_TCTQ43lTWeOf4p1C9lFU0N53pRIcmgsv6tzyR6P556fOV01qUe9zowCMZH-PQwbIEhv31tm3U63h2FWjSnk_1WQX3OisF2Yp/s200/legend.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">This article presents an algorithm to compute set union and set minus in a specific context. Each set is a set of contiguous stretches on a real line.</span></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Problem Description</span></h3>
<h4 style="text-align: justify;">
<span style="color: red; font-family: "arial" , "helvetica" , sans-serif;">Union</span></h4>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Consider a scenario where two people are teamed up to contribute to a particular task, say attending to an infant child. As long as any one of them is available to look after the child, it's fine. For other times, they probably would have to look for an alternative arrangement. The time any one person is available can be represented as a set of durations. The time for which at least one of the two persons is available is nothing but the union of the sets of durations during which each one of them is available.</span></div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
<span style="color: red; font-family: "arial" , "helvetica" , sans-serif;">Set Minus</span></h4>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Consider a scenario when two people are looking for a slot wherein both are available for a discussion. This can be thought of a difference between the the available time of one person and the busy time of the other.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></div>
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Solution Approach</span></h3>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The solution approach makes use of a variable <i>level</i> which keeps track of the starts and ends of durations. After placing all the important time instants on a time line, we scan the time line from left to right.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">While computing union, we use the following strategy to set the <i>level</i> during our scan of the timeline:</span></div>
<div>
<ol style="text-align: left;">
<li style="text-align: justify;"><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Each time any of the duration begins, we increment <i>level</i> by 1.</span></li>
<li style="text-align: justify;"><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Each time any of the durations ends, we decrement <i>level</i> by 1.</span></li>
</ol>
</div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">As per the above, the stretches of the timeline with <i>level</i> = 0 indicate stretches when none of the two sets is present.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The rest of the timeline will have positive values of <i>level</i> indicating that at least one of the two sets is present there.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">In another pass of the timeline, we now collect all the continuous stretches of the timeline where <i>level</i> is not zero. This gives us the set of durations corresponding to the union of the two sets.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">While computing set minus, we employ the following strategy for maintaining <i>level</i>.</span></div>
<div style="text-align: justify;">
<ol>
<li><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The starting point of a duration in the first set and end of a duration in the second set cause <i>level</i> to be incremented by 1.</span></li>
<li><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The end point of a duration in the first set and start of a duration in the second set cause <i>level</i> to be decremented by 1.</span></li>
</ol>
</div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">As per the above, the stretches of the timeline with <i>level = 1</i> indicates stretches in the difference between the first set and the second.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">In another pass, we collect the set of contiguous portions of the timeline where <i>level = 1</i>. This is our answer of set minus.</span></div>
<div style="text-align: justify;">
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Extensions</span></h3>
<div>
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">The</span><span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"> <span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>union</b></span> </span><span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">and</span><span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"> <span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>setminus</b></span> </span><span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">functions can be used to implement other useful set operations on the above kind of sets, <i>viz</i>.</span><span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"> </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>complement</b></span><span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><b style="color: blue;"><span style="color: #274e13; font-family: "times" , "times new roman" , serif;">intersection</span></b><span style="color: blue; font-family: "georgia" , "times new roman" , serif;">.</span></span></div>
</div>
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Implementation</span></h3>
<div style="text-align: justify;">
<span style="color: red; font-family: "arial" , "helvetica" , sans-serif;"><b>Representation of the sets</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">We represent the sets of durations as lists of pairs. s1 and s2 in the above figure (Timeline) have been represented as follows:</span><br />
<span style="font-size: large;"><br /></span>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> s1 <span style="color: #666666;">=</span> [(<span style="color: #666666;">1</span>, <span style="color: #666666;">5</span>), (<span style="color: #666666;">8</span>, <span style="color: #666666;">10</span>), (<span style="color: #666666;">15</span>, <span style="color: #666666;">20</span>)]
s2 <span style="color: #666666;">=</span> [(<span style="color: #666666;">2</span>, <span style="color: #666666;">4</span>), (<span style="color: #666666;">6</span>, <span style="color: #666666;">12</span>), (<span style="color: #666666;">16</span>, <span style="color: #666666;">21</span>)]
</pre>
</div>
<span style="font-size: large;"><br /></span>
<span style="font-size: large;"></span><br />
<h4>
<span style="font-size: large;"><span style="font-size: small;"><span style="color: red; font-family: "arial" , "helvetica" , sans-serif;">Code Design</span></span></span></h4>
<span style="font-family: "georgia" , "times new roman" , serif;"><span style="font-size: large;">When we implement the above two algorithms as two completely separate functions <span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>union</b></span> and <span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>setminus</b></span>, we realise that they have a very common structure. This gives us the motivation to try and capture this commonality between the two functions in a piece of re-usable code. We do so by designing a higher-order function <span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>make_function</b></span>, which is parameterised by another function which captures the specific elements of the two functions. </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>f1</b></span><span style="font-size: large;"> and <span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>f2</b></span> are the two functions capturing these specificities of union and set minus.</span></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif;"><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The </span><span style="font-size: large;"><b style="color: #274e13; font-family: georgia, 'times new roman', serif;">make_function</b><span style="font-family: "georgia" , "times new roman" , serif;"> function prepares a function and returns it as a result. the two functions </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>union</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>setminus</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> are created by calling </span><b style="color: #274e13; font-family: georgia, 'times new roman', serif;">make_function</b><span style="font-family: "georgia" , "times new roman" , serif;"> with </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>f1</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><b style="font-family: georgia, 'times new roman', serif;"><span style="color: #274e13; font-family: "times" , "times new roman" , serif;">f2</span></b><span style="font-family: "georgia" , "times new roman" , serif;"> as arguments respectively. Note that this could have been implemented alternatively by embedding a call to </span><b style="color: #274e13; font-family: georgia, 'times new roman', serif;">make_function</b><span style="font-family: "georgia" , "times new roman" , serif;"> in </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>union</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>setminus</b></span><span style="font-family: "georgia" , "times new roman" , serif;">. This is a perfectly good option when </span></span><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>union</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"> and </span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><span style="color: #274e13; font-weight: bold;">setminus</span><span style="font-family: "georgia" , "times new roman" , serif;"> get used only once</span></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">. However, considering a scenario where </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>union</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"> and </span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><span style="color: #274e13; font-weight: bold;">setminus</span></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"> may get called several times in a larger program, the strategy used here will lead to a slightly improved speed, not to mention improved readability (arguable).</span></span></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Code</span></h3>
<div style="text-align: justify;">
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-style: italic;"># utility function for the implementation of union</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">f1</span>(s1, s2):
START <span style="color: #666666;">=</span> <span style="color: #666666;">1</span>
END <span style="color: #666666;">=</span> <span style="color: #666666;">-1</span>
l <span style="color: #666666;">=</span> []
<span style="color: #aa22ff; font-weight: bold;">for</span> (s, e) <span style="color: #aa22ff; font-weight: bold;">in</span> s1:
l<span style="color: #666666;">.</span>append((s, START))
l<span style="color: #666666;">.</span>append((e, END))
<span style="color: #aa22ff; font-weight: bold;">for</span> (s, e) <span style="color: #aa22ff; font-weight: bold;">in</span> s2:
l<span style="color: #666666;">.</span>append((s, START))
l<span style="color: #666666;">.</span>append((e, END))
<span style="color: #aa22ff; font-weight: bold;">return</span> <span style="color: #aa22ff;">sorted</span>(l, key <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">lambda</span> (x, y): x)
<span style="color: #008800; font-style: italic;">#utility function for implementation of setminus</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">f2</span>(s1, s2):
START1 <span style="color: #666666;">=</span> <span style="color: #666666;">1</span>
END1 <span style="color: #666666;">=</span> <span style="color: #666666;">-1</span>
START2 <span style="color: #666666;">=</span> <span style="color: #666666;">-1</span>
END2 <span style="color: #666666;">=</span> <span style="color: #666666;">1</span>
l <span style="color: #666666;">=</span> []
<span style="color: #aa22ff; font-weight: bold;">for</span> (s, e) <span style="color: #aa22ff; font-weight: bold;">in</span> s1:
l<span style="color: #666666;">.</span>append((s, START1))
l<span style="color: #666666;">.</span>append((e, END1))
<span style="color: #aa22ff; font-weight: bold;">for</span> (s, e) <span style="color: #aa22ff; font-weight: bold;">in</span> s2:
l<span style="color: #666666;">.</span>append((s, START2))
l<span style="color: #666666;">.</span>append((e, END2))
<span style="color: #aa22ff; font-weight: bold;">return</span> <span style="color: #aa22ff;">sorted</span>(l, key <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">lambda</span> (x, y): x)
<span style="color: #008800; font-style: italic;"># Higher order function to create union and setminus functions</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">make_function</span>(f):
<span style="color: #008800; font-style: italic;"># boilerplate function to be returned from make_function after being plugged with f.</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">g</span>(s1, s2):
level <span style="color: #666666;">=</span> <span style="color: #666666;">0</span>
result <span style="color: #666666;">=</span> []
l <span style="color: #666666;">=</span> f(s1, s2)
<span style="color: #aa22ff; font-weight: bold;">for</span> (t, SE) <span style="color: #aa22ff; font-weight: bold;">in</span> l:
<span style="color: #aa22ff; font-weight: bold;">print</span> (t, level)
last <span style="color: #666666;">=</span> level
level <span style="color: #666666;">+=</span> SE
<span style="color: #aa22ff; font-weight: bold;">if</span> level <span style="color: #666666;">==</span> <span style="color: #666666;">1</span> <span style="color: #aa22ff; font-weight: bold;">and</span> last <span style="color: #666666;">==</span> <span style="color: #666666;">0</span>:
start <span style="color: #666666;">=</span> t
<span style="color: #aa22ff; font-weight: bold;">if</span> level <span style="color: #666666;">==</span> <span style="color: #666666;">0</span> <span style="color: #aa22ff; font-weight: bold;">and</span> last <span style="color: #666666;">==</span> <span style="color: #666666;">1</span>:
end <span style="color: #666666;">=</span> t
result<span style="color: #666666;">.</span>append((start, end))
<span style="color: #aa22ff; font-weight: bold;">return</span> result
<span style="color: #aa22ff; font-weight: bold;">return</span> g
union <span style="color: #666666;">=</span> make_function(f1)
setminus <span style="color: #666666;">=</span> make_function(f2)
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">t1</span>():
s1 <span style="color: #666666;">=</span> [(<span style="color: #666666;">1</span>, <span style="color: #666666;">5</span>), (<span style="color: #666666;">8</span>, <span style="color: #666666;">10</span>), (<span style="color: #666666;">15</span>, <span style="color: #666666;">20</span>)]
s2 <span style="color: #666666;">=</span> [(<span style="color: #666666;">2</span>, <span style="color: #666666;">4</span>), (<span style="color: #666666;">6</span>, <span style="color: #666666;">12</span>), (<span style="color: #666666;">16</span>, <span style="color: #666666;">21</span>)]
<span style="color: #aa22ff; font-weight: bold;">print</span> union(s1, s2)
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">t2</span>():
s1 <span style="color: #666666;">=</span> [(<span style="color: #666666;">1</span>, <span style="color: #666666;">5</span>), (<span style="color: #666666;">8</span>, <span style="color: #666666;">10</span>), (<span style="color: #666666;">15</span>, <span style="color: #666666;">20</span>)]
s2 <span style="color: #666666;">=</span> [(<span style="color: #666666;">2</span>, <span style="color: #666666;">4</span>), (<span style="color: #666666;">6</span>, <span style="color: #666666;">12</span>), (<span style="color: #666666;">16</span>, <span style="color: #666666;">21</span>)]
<span style="color: #aa22ff; font-weight: bold;">print</span> setminus(s1, s2)
<span style="color: #aa22ff; font-weight: bold;">if</span> __name__ <span style="color: #666666;">==</span> <span style="color: #bb4444;">"__main__"</span>:
t1()
t2()
</pre>
</td></tr>
</tbody></table>
</div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><a href="https://drive.google.com/open?id=0B1WZgxQ3CbErQWpKM2Y5SE5uQjA">set.py</a></span></div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-52442265218782279842016-09-13T18:48:00.000+05:302016-09-15T11:46:37.056+05:30APIs with Functions<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">This post introduces the concept of application programming interfaces (APIs) and what they are good for. As an example, we continue to use the <a href="http://sujitkc-techbits.blogspot.in/2016/09/a-program-to-simplify-transactions.html" target="_blank"><i>Hisaab</i></a> program.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">As we have seen, functions are a very powerful abstraction mechanism to wrap around pieces of computation which can then be used and re-used as needed. This leads to a code which is more compact, readable, modifiable and flexible.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">In <i>Hisaab</i>, the implementation we first created uses a particular representation of the graph data-structure called the <i>edge list</i>. For example, the following graph will be represented by the code right below that:</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguQ-Ocw5vrD_171hrZnJmtDQcjMwhIWhG-AcOApbuKVymi_5OxlZ_dAk5bslT_Yy1nlrM-WLshvfXPhkLYyvmysqpCrVDo7OFJvQLZOjThhkgjCdjJFCKMPhTE2zbMR5T0i31G/s1600/e2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="301" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguQ-Ocw5vrD_171hrZnJmtDQcjMwhIWhG-AcOApbuKVymi_5OxlZ_dAk5bslT_Yy1nlrM-WLshvfXPhkLYyvmysqpCrVDo7OFJvQLZOjThhkgjCdjJFCKMPhTE2zbMR5T0i31G/s320/e2.png" width="320" /></a></div>
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">[
(<span style="color: #bb4444;">"A"</span>, <span style="color: #666666;">15</span>, <span style="color: #bb4444;">"F"</span>),
(<span style="color: #bb4444;">"A"</span>, <span style="color: #666666;">20</span>, <span style="color: #bb4444;">"B"</span>),
(<span style="color: #bb4444;">"B"</span>, <span style="color: #666666;">10</span>, <span style="color: #bb4444;">"D"</span>),
(<span style="color: #bb4444;">"B"</span>, <span style="color: #666666;">10</span>, <span style="color: #bb4444;">"C"</span>),
(<span style="color: #bb4444;">"D"</span>, <span style="color: #666666;">30</span>, <span style="color: #bb4444;">"C"</span>),
(<span style="color: #bb4444;">"C"</span>, <span style="color: #666666;">30</span>, <span style="color: #bb4444;">"G"</span>),
(<span style="color: #bb4444;">"G"</span>, <span style="color: #666666;">25</span>, <span style="color: #bb4444;">"E"</span>),
(<span style="color: #bb4444;">"F"</span>, <span style="color: #666666;">100</span>, <span style="color: #bb4444;">"E"</span>),
(<span style="color: #bb4444;">"E"</span>, <span style="color: #666666;">150</span>, <span style="color: #bb4444;">"D"</span>),
(<span style="color: #bb4444;">"G"</span>, <span style="color: #666666;">90</span>, <span style="color: #bb4444;">"D"</span>)
]
</pre>
</div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The code of the algorithm is reproduced below:</span></div>
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">reroute</span>((n1, w, n2), n):
<span style="color: #aa22ff; font-weight: bold;">if</span>(n1 <span style="color: #666666;">==</span> n): <span style="color: #aa22ff; font-weight: bold;">return</span> [(n2, <span style="color: #666666;">-</span>w, n1)]
<span style="color: #aa22ff; font-weight: bold;">elif</span>(n1 <span style="color: #666666;">!=</span> n) <span style="color: #aa22ff; font-weight: bold;">and</span> (n2 <span style="color: #666666;">!=</span> n): <span style="color: #aa22ff; font-weight: bold;">return</span> [(n1, w, n), (n2, <span style="color: #666666;">-</span>w, n)]
<span style="color: #aa22ff; font-weight: bold;">else</span>: <span style="color: #aa22ff; font-weight: bold;">return</span> [(n1, w, n2)]
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">starify_graph</span>(g, n):
new_g <span style="color: #666666;">=</span> []
<span style="color: #aa22ff; font-weight: bold;">for</span> e <span style="color: #aa22ff; font-weight: bold;">in</span> g:
new_edge <span style="color: #666666;">=</span> reroute(e, n)
new_g<span style="color: #666666;">.</span>extend(new_edge)
<span style="color: #aa22ff; font-weight: bold;">return</span> new_g
<span style="color: #008800; font-style: italic;"># assumption: g is not a multigraph.</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">merge</span>((n1, w, n2), g):
<span style="color: #aa22ff; font-weight: bold;">for</span> i <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #aa22ff;">range</span>(<span style="color: #aa22ff;">len</span>(g)):
(m1, w1, m2) <span style="color: #666666;">=</span> g[i]
<span style="color: #aa22ff; font-weight: bold;">if</span>(m1 <span style="color: #666666;">==</span> n1 <span style="color: #aa22ff; font-weight: bold;">and</span> m2 <span style="color: #666666;">==</span> n2):
g[i] <span style="color: #666666;">=</span> (n1, w <span style="color: #666666;">+</span> w1, n2)
<span style="color: #aa22ff; font-weight: bold;">return</span> g
g<span style="color: #666666;">.</span>append((n1, w, n2))
<span style="color: #aa22ff; font-weight: bold;">return</span> g
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">graph_of_mgraph</span>(mg):
g <span style="color: #666666;">=</span> []
<span style="color: #aa22ff; font-weight: bold;">for</span> e <span style="color: #aa22ff; font-weight: bold;">in</span> mg:
g <span style="color: #666666;">=</span> merge(e, g)
<span style="color: #aa22ff; font-weight: bold;">return</span> g
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<br />
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The above code depends on the way we have implemented the graph data-structure. There are several examples in the above code which demonstrate the fact that the above code has been written with the knowledge about the internal implementation of the graph data-structure.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<ul style="text-align: left;">
<li style="text-align: justify;"><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Line 1, 14: assumes that edges are triples.</span></li>
<li style="text-align: justify;"><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Line 8, 10, 16, 18, 20, 24: graph is assumed to be an edge list.</span></li>
</ul>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The disadvantage with the above implementation of the algorithm is that it is strictly dependent on the way the graph data-structure is implemented. If the implementation of graph changes, the algorithm would have to be pretty much completely re-implemented.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Let's see how the above graph represented as an adjacency list would look like:</span></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">{
<span style="color: #bb4444;">'A'</span>: [(<span style="color: #bb4444;">'F'</span>, <span style="color: #666666;">15</span>), (<span style="color: #bb4444;">'B'</span>, <span style="color: #666666;">20</span>)],
<span style="color: #bb4444;">'C'</span>: [(<span style="color: #bb4444;">'G'</span>, <span style="color: #666666;">30</span>)],
<span style="color: #bb4444;">'B'</span>: [(<span style="color: #bb4444;">'D'</span>, <span style="color: #666666;">10</span>), (<span style="color: #bb4444;">'C'</span>, <span style="color: #666666;">10</span>)],
<span style="color: #bb4444;">'E'</span>: [(<span style="color: #bb4444;">'D'</span>, <span style="color: #666666;">150</span>)],
<span style="color: #bb4444;">'D'</span>: [(<span style="color: #bb4444;">'C'</span>, <span style="color: #666666;">30</span>)],
<span style="color: #bb4444;">'G'</span>: [(<span style="color: #bb4444;">'E'</span>, <span style="color: #666666;">25</span>), (<span style="color: #bb4444;">'D'</span>, <span style="color: #666666;">90</span>)],
<span style="color: #bb4444;">'F'</span>: [(<span style="color: #bb4444;">'E'</span>, <span style="color: #666666;">100</span>)]
}
</pre>
</div>
<br />
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Below, we should the implementation of the algorithm when the graph is implemented as an adjacency list.</span></div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">starify_graph</span>(g, n):
new_g <span style="color: #666666;">=</span> {} <span style="color: #008800; font-style: italic;"># instantiating a dictionary</span>
<span style="color: #aa22ff; font-weight: bold;">for</span> n1 <span style="color: #aa22ff; font-weight: bold;">in</span> g: <span style="color: #008800; font-style: italic;">#initialising the empty graph</span>
new_g[n1] <span style="color: #666666;">=</span> []
<span style="color: #aa22ff; font-weight: bold;">for</span> n1 <span style="color: #aa22ff; font-weight: bold;">in</span> g:
<span style="color: #008800; font-style: italic;"># invert and add every node starting with n.</span>
<span style="color: #aa22ff; font-weight: bold;">if</span>(n1 <span style="color: #666666;">==</span> n):
<span style="color: #aa22ff; font-weight: bold;">for</span> (n2, w) <span style="color: #aa22ff; font-weight: bold;">in</span> g[n1]:
add_edge(new_g[n2], (n1, <span style="color: #666666;">-</span>w))
<span style="color: #aa22ff; font-weight: bold;">else</span>:
<span style="color: #aa22ff; font-weight: bold;">for</span> (n2, w) <span style="color: #aa22ff; font-weight: bold;">in</span> g[n1]:
<span style="color: #008800; font-style: italic;"># add every node ending at n.</span>
<span style="color: #aa22ff; font-weight: bold;">if</span>(n2 <span style="color: #666666;">==</span> n):
add_edge(new_g[n1], (n2, w))
<span style="color: #008800; font-style: italic;"># reroute all other nodes.</span>
<span style="color: #aa22ff; font-weight: bold;">else</span>:
add_edge(new_g[n1], (n, w))
add_edge(new_g[n2], (n, <span style="color: #666666;">-</span>w))
<span style="color: #aa22ff; font-weight: bold;">return</span> new_g
</pre>
</td></tr>
</tbody></table>
</div>
<br />
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">As is evident, this implementation is significantly different from the previous implementation. Again, there are several evidences in this code to show that it strictly assumes an adjacency list implementation of the graph data-structure.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Line 2: Graph is a dictionary.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Line 4: The elements of the graph dictionary are lists.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Line 8, 9, 11: The elements of the graph dictionary are pairs.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Modularity</span></h3>
<div style="text-align: justify;">
<span style="color: #351c75; font-family: "georgia" , "times new roman" , serif; font-size: large;"><i>Can we implement the above hisaab algorithm in a way so that it is independent of the internal details of the graph data-structure?</i></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">If we could do so, there would be the following advantages:</span></div>
<div style="text-align: justify;">
</div>
<ul>
<li><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The <i>hisaab</i> algorithm would work fine irrespective of which implementation of graph we use.</span></li>
<li><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The graph data-structure implementation can be modified subsequently without a risk of breaking the <i>hisaab</i> code.</span></li>
</ul>
<div>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The answer to the above question is <i>Yes</i>. By defining a set of functions which define a uniform way by which the rest of the code interacts with the graph code, we can ensure that there is separation between the view of the graph that the rest of the code sees, and its internal implementation. We do so, using a group of functions as follows:</span></div>
<div>
<ol>
<li><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>empty_graph</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">: Returns a new empty graph with no nodes or edges</span></li>
<li><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>make_graph</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">: Returns a new graph having the edges which are provided in a list</span></li>
<li><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>get_edges</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">: Returns the list of edges in the graph</span></li>
<li><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>add_edge</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">: Adds an edge to a graph</span></li>
</ol>
<div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The implementation of the above functions is specific to the specific implementation of the graph, but how they are used is not. Hence, the code which uses a graph only through the above functions is also independent of the specific implementation of the graph data-structure. The above set of functions can be termed as an <i>application programming interface (API)</i>. This is because, this set defines the way one part of the program (called <i>the client</i>) interacts with another part of the program (called <i>the server</i>). Further functions like </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif; font-size: large;"><b>empty_graph</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>make_graph</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> are called </span><i style="font-family: georgia, 'times new roman', serif;">constructors</i><span style="font-family: "georgia" , "times new roman" , serif;"> (because they create new instances of the data-structure)</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>get_edges</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> are called </span><i style="font-family: georgia, 'times new roman', serif;">extractors</i><span style="font-family: "georgia" , "times new roman" , serif;"> (because they reveal information about the data-structure without modifying it) and </span><span style="color: #274e13; font-family: "times" , "times new roman" , serif;"><b>add_edge</b></span><span style="font-family: "georgia" , "times new roman" , serif;"> are called </span><i style="font-family: georgia, 'times new roman', serif;">modifiers</i><span style="font-family: "georgia" , "times new roman" , serif;"> (because they modify the underlying data-structure)</span><span style="font-family: "georgia" , "times new roman" , serif;">. One way to look at the entire scenario would be as follows:</span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgabva6AnEuELCO1pD4uYjGadjfVXzSXcJino9I-wVDsli-vEB9mJxQdTWAwNY80prArqvNwwc-uUaN_teUN9F86XhJtaDpmV2f_87LILkWGGydTXz9iQxOuP3T0szZVd4OlXhF/s1600/api.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgabva6AnEuELCO1pD4uYjGadjfVXzSXcJino9I-wVDsli-vEB9mJxQdTWAwNY80prArqvNwwc-uUaN_teUN9F86XhJtaDpmV2f_87LILkWGGydTXz9iQxOuP3T0szZVd4OlXhF/s400/api.jpg" width="400" /></a></div>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></span></div>
</div>
</div>
<div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The <i>client</i> code (or <i>user</i> code) makes use of the facilities provided by the <i>server</i> code (or <i>back-end</i> code). In <i>hisaab</i>, the algorithm (implemented through the functions </span><span style="color: #274e13; font-family: Times, Times New Roman, serif; font-size: large;"><b>reroute</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"> and </span><span style="color: #274e13; font-family: Times, Times New Roman, serif; font-size: large;"><b>starify_graph</b></span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">) can be considered as the client code, while the graph data-structure can be viewed as the server code. As shown above, the API consisting of the four functions listed above form the interface through which the client talks to the server. Note that it is possible to freely change which of the two implementations the interface uses as the server without affecting the client. This gives us the flexibility of independently implementing the client without concerning ourselves about the internal details of the server.</span></div>
</div>
<div>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">reroute</span>(e, n):
n1 <span style="color: #666666;">=</span> get_start_node(e)
w <span style="color: #666666;">=</span> get_weight(e)
n2 <span style="color: #666666;">=</span> get_end_node(e)
<span style="color: #aa22ff; font-weight: bold;">if</span>(get_start_node(e) <span style="color: #666666;">==</span> n):
<span style="color: #aa22ff; font-weight: bold;">return</span> [make_edge(n1 <span style="color: #666666;">=</span> n2, w <span style="color: #666666;">=</span> <span style="color: #666666;">-</span>w, n2 <span style="color: #666666;">=</span> n1)]
<span style="color: #aa22ff; font-weight: bold;">elif</span>(n1 <span style="color: #666666;">!=</span> n) <span style="color: #aa22ff; font-weight: bold;">and</span> (n2 <span style="color: #666666;">!=</span> n):
<span style="color: #aa22ff; font-weight: bold;">return</span> [make_edge(n1 <span style="color: #666666;">=</span> n1, w <span style="color: #666666;">=</span> w, n2 <span style="color: #666666;">=</span> n), make_edge(n1 <span style="color: #666666;">=</span> n2, w <span style="color: #666666;">=</span> <span style="color: #666666;">-</span>w, n2 <span style="color: #666666;">=</span> n)]
<span style="color: #aa22ff; font-weight: bold;">else</span>:
<span style="color: #aa22ff; font-weight: bold;">return</span> [e]
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">starify_graph</span>(g, n):
new_g <span style="color: #666666;">=</span> empty_graph()
edges <span style="color: #666666;">=</span> get_edges(g)
<span style="color: #aa22ff; font-weight: bold;">for</span> e <span style="color: #aa22ff; font-weight: bold;">in</span> edges:
new_edges <span style="color: #666666;">=</span> reroute(e, n)
<span style="color: #aa22ff; font-weight: bold;">for</span> e <span style="color: #aa22ff; font-weight: bold;">in</span> new_edges:
add_edge(g <span style="color: #666666;">=</span> new_g, e <span style="color: #666666;">=</span> e)
<span style="color: #aa22ff; font-weight: bold;">return</span> new_g
</pre>
</td></tr>
</tbody></table>
</div>
<div>
<br />
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The above code shows the <i>hisaab</i> algorithm re-implemented using the above API.</span> <span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The best way to get convinced this code is independent of any of the internal implementation details of graph data-structure is to look for a dependence. <i>You will not find one!</i></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><i><br /></i></span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The API allows us to implement <i>hisaab</i> as a re-usable algorithm independent of the implementation of the graph.</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span>
<h3>
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Large Scale Software Development and Software Design</span></h3>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">In large scale software development scenario, software systems are developed by teams of multiple software developers. It would be too inefficient to develop each part of the system sequentially. It's important to ensure that all teams are kept busy throughout the project duration. All sub-teams in a project work in parallel to ensure an early completion of the project.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">The way the above is achieved is by dividing the work into several modules which interact with each other to create the complete system. This process is called <i>software design</i>. The division is worked out in a way that there is comparable distribution of work between the various modules. More importantly, each module defines an interface (or API) through which the rest of the system interacts with that module. A good design will ensure that the interfaces are enough to allow powerful interaction between modules but doesn't expose unnecessary details of a module to the rest of the system. While the internal implementation of a module is likely to change rapidly over the execution of a project, the module interfaces must be decided early and frozen. This is important to ensure that all other parts of the system can proceed assuming this interface about the given module. Hence, every sub-team, working on an individual module, can proceed in parallel.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span>
<h3>
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Prototypes and Improvisations</span></h3>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">As mentioned above, API enable independent development of interacting modules. Suppose, one team is developing the client <i>C</i>, and another is developing the server <i>S</i>. A typical way this piece of software would be developed in practice is as follows: An API for <i>S</i> is defined first. As <i>C</i> is dependent on <i>S</i>, a quick-and-dirty implement of <i>S</i> -- say <i>S1</i> -- is created and handed over to the client team so that <i>C</i>'s development can proceed. While <i>C</i>'s development proceeds, the server team continues working on a better-engineered version of <i>S</i> -- say <i>S2</i> -- in parallel. <i>S2</i> would follow the same API of <i>S</i>, however may score better than <i>S1</i> in certain parameters like performance, security etc. By the time <i>C</i>'s development gets over, <i>S2</i> is also ready. The version of the product which gets shipped to the customer uses <i>C</i> as client <i>S2</i> as the server.</span><br />
<br /></div>
<h3 style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Code:</span></h3>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><a href="https://drive.google.com/open?id=0B1WZgxQ3CbErcXNJVDFzUUthZ3M">hisaab1.py</a>: Implements hisaab using a edge-list implementation</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><a href="https://drive.google.com/open?id=0B1WZgxQ3CbErS3N2Q3R4c1ExSGc">hisaab2.py</a>: Implements hisaab using an adjacency-list implementation</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><a href="https://drive.google.com/open?id=0B1WZgxQ3CbErTFNsWTJvb2pBc1k">hisaab3.py</a>: Implements hisaab as a re-usable code by using a graph API</span></div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-27657533123364979772016-09-02T16:39:00.002+05:302016-09-13T15:45:51.584+05:30Hisaab -- A Program to Simplify Transactions among Friends<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="clear: both; text-align: left;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">It's always fun when your technical knowledge comes in handy while to trying to solve some day-to-day problem. you get a kick in being able to describe a problem in its core mathematical essence, and in creating an algorithm to solve the problem. The size of the kick is independent of the size and complexity of the problem.</span></div>
<div style="clear: both; text-align: left;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="clear: both; text-align: left;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Follows a cute example of the above.</span></div>
<h3 style="clear: both; text-align: left;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Problem Description</span></h3>
<div class="separator" style="clear: both; text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Often, a group of people may transact money between each other. A situation may arise when each person </span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">may have taken some money from someone else, thus owing the other person that much amount. To settle the accounts, there might be needed a very large number of transactions needed, requiring everyone to meet everyone else.</span></div>
<h3 style="clear: both;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Solution Approach</span></h3>
<div class="separator" style="clear: both; text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">A </span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">good way to simplify the settlement process would be to make one of the people involved as the </span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><i>bank</i>, or the <i>star</i>. Everyone makes a transaction with this person only, only the net amount she </span><span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">owes to anyone.</span></div>
<div class="separator" style="clear: both; text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<h3 style="clear: both;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Mathematical Model</span></h3>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNPLxpktoJJNSi0KsxTLjWSbdUGU6XAOYObXPfbo5oFd4oRmSM1aiyFDa5_rL3YB4-1CrboHQP1TZgu4XI33Pm74eLUVWhRqCCC5BM3mjQK7CnbQBmMSXk9B_fwX3QpxoH-stu/s1600/e1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNPLxpktoJJNSi0KsxTLjWSbdUGU6XAOYObXPfbo5oFd4oRmSM1aiyFDa5_rL3YB4-1CrboHQP1TZgu4XI33Pm74eLUVWhRqCCC5BM3mjQK7CnbQBmMSXk9B_fwX3QpxoH-stu/s400/e1.png" width="400" /></a></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: left;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"></span></h3>
<h3 style="text-align: left;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large; font-weight: normal; text-align: justify;">The original situation can be represented as a directed graph as shown above in the left side graph. Each node represents a person, and each directed edge indicates a transaction. For example, the edge with weight 15 between A and F means that A owes Rs. 15 to F.</span></h3>
<div style="text-align: left;">
<div style="text-align: justify;">
<div style="text-align: left;">
<div style="text-align: left;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large; text-align: justify;">The solution is shown in the right side graph above. Note that all edges now involve node D. Thus every node needs to make at most one transaction with node D, which is huge simplification of the process. The accounts will now be settled with only 5 transactions as opposed to 9 in the original graph. As an added benefit, nodes which need not transact at all also get identified. For example, node B gets isolated in the right side graph, meaning that it doesn't need to transact anything with node D.</span></div>
</div>
</div>
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large; font-weight: normal;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large; font-weight: normal;"></span></div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="text-align: justify;">
</div>
</div>
<br />
<h3 style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Transforms</span></h3>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large; font-weight: normal;">The solution is achieving through the following two simple graph transformations.</span></div>
<h4 style="text-align: left;">
<span style="color: purple; font-family: "georgia" , "times new roman" , serif; font-size: large; font-weight: normal;">Rerouting</span></h4>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6mSVegaI94xgfPMV279GSQgyu7cMFctDrDgzjDO5dxi7LenwES3Bv3oRhmZSlBsNo08-lBOzr1lo21tDoVyjbUD3FvjV8Ac3lxZJoZ9tno1OZWvCTNCsDq7Ayd3EVso_hYI8Q/s1600/transform.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6mSVegaI94xgfPMV279GSQgyu7cMFctDrDgzjDO5dxi7LenwES3Bv3oRhmZSlBsNo08-lBOzr1lo21tDoVyjbUD3FvjV8Ac3lxZJoZ9tno1OZWvCTNCsDq7Ayd3EVso_hYI8Q/s320/transform.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Suppose we wish to make node 1 the star node. This means that we want all transactions between any pair not involving node 1 should be routed through node 1, as shown above.</span></div>
<br />
<h4 style="text-align: left;">
<span style="color: purple; font-family: "georgia" , "times new roman" , serif; font-size: large; font-weight: normal;">Multigraph to Graph</span></h4>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZSkudVpt5Ctmvfchho8uCyzJ8vNpaqJonBKELKOY0G56FmHnKjRG36LmlRDXYPKw96Nv72Ce_cuegGleVMjLzY_rELd1Sgv6HtiMy-uMNHrqH7gYkzxpSpmr93GB7OCJm7I3/s1600/merge.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZSkudVpt5Ctmvfchho8uCyzJ8vNpaqJonBKELKOY0G56FmHnKjRG36LmlRDXYPKw96Nv72Ce_cuegGleVMjLzY_rELd1Sgv6HtiMy-uMNHrqH7gYkzxpSpmr93GB7OCJm7I3/s320/merge.png" width="320" /></a></div>
<br />
<!-- HTML generated using hilite.me --><br />
<h3 style="text-align: left;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Implementation</span></h3>
<div style="text-align: justify;">
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;">Follows an implementation of the above idea in OCaml. We use a purely functional style (i.e. by using a completely side-effect free style of programming). If you remove the profuse amount in-line documentation, you will notice that the code is remarkably concise (just about 25 lines of code)!</span><br />
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif; font-size: large;">Find an OCaml and Python implementation <a href="https://drive.google.com/folderview?id=0B1WZgxQ3CbErZUlQTUtoNE84eG8&usp=sharing" target="_blank">here</a>.</span></div>
<div>
<span style="color: blue; font-family: "georgia" , "times new roman" , serif; font-size: large;"><br /></span></div>
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;">The following program is useful to simplify the transactions amongst a group of people.</span>
<span style="color: #008800; font-style: italic;">Problem Description: Often, a group of people may transact money between each other. A situation may arise when each person</span>
<span style="color: #008800; font-style: italic;">may have taken some money from someone else, thus owing the other person that much amount. A</span>
<span style="color: #008800; font-style: italic;">good way to simplify the settlement process would be to make one of the people involved as the</span>
<span style="color: #008800; font-style: italic;">bank, or the star. Everyone makes a transaction with this person only, only the net amount she</span>
<span style="color: #008800; font-style: italic;">owes to anyone.</span>
<span style="color: #008800; font-style: italic;">User Instruction:</span>
<span style="color: #008800; font-style: italic;">1. Open the file in a editor.</span>
<span style="color: #008800; font-style: italic;">2. Edit the variable g to reflect what each person owes any other.</span>
<span style="color: #008800; font-style: italic;">3. Save the file</span>
<span style="color: #008800; font-style: italic;">4. Open the OCaml REPL</span>
<span style="color: #008800; font-style: italic;">5. enter the command: #use "hisaab.ml";;</span>
<span style="color: #008800; font-style: italic;">The answer will appear on the standard output.</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Description: Takes an edge e = (n1, w, n2) and a node n, and returns a list of edges, to</span>
<span style="color: #008800; font-style: italic;"> apply starification transform on e.</span>
<span style="color: #008800; font-style: italic;"> Signature: 'a * int * 'a -> 'a -> ('a * int * 'a) list</span>
<span style="color: #008800; font-style: italic;"> Example:</span>
<span style="color: #008800; font-style: italic;"> 1)</span>
<span style="color: #008800; font-style: italic;"># reroute (1, 10, 2) 1;;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list = [(2, -10, 1)]</span>
<span style="color: #008800; font-style: italic;"># reroute (2, 10, 1) 1;;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list = [(2, 10, 1)]</span>
<span style="color: #008800; font-style: italic;"># reroute (2, 10, 3) 1;;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list = [(2, 10, 1); (3, -10, 1)]</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> reroute <span style="color: #666666;">(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)</span> n <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">if</span> n1 <span style="color: #666666;">=</span> n <span style="color: #aa22ff; font-weight: bold;">then</span> <span style="color: #666666;">[(</span>n2<span style="color: #666666;">,</span> <span style="color: #666666;">-</span>w<span style="color: #666666;">,</span> n1<span style="color: #666666;">)]</span>
<span style="color: #aa22ff; font-weight: bold;">else</span> <span style="color: #aa22ff; font-weight: bold;">if</span> n2 <span style="color: #666666;">=</span> n <span style="color: #aa22ff; font-weight: bold;">then</span> <span style="color: #666666;">[(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)]</span>
<span style="color: #aa22ff; font-weight: bold;">else</span> <span style="color: #666666;">[(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n<span style="color: #666666;">);</span> <span style="color: #666666;">(</span>n2<span style="color: #666666;">,</span> <span style="color: #666666;">-</span>w<span style="color: #666666;">,</span> n<span style="color: #666666;">)]</span>
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Description: Takes a list of lists and returns the corresponding list</span>
<span style="color: #008800; font-style: italic;"> Signature: 'a list list -> 'a list</span>
<span style="color: #008800; font-style: italic;"> Example:</span>
<span style="color: #008800; font-style: italic;"># flatten_list [[1;2]; [3;4;5];[6]];;</span>
<span style="color: #008800; font-style: italic;">- : int list = [1; 2; 3; 4; 5; 6]</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #aa22ff; font-weight: bold;">rec</span> flatten_list <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">function</span>
<span style="color: #aa22ff;">[]</span> <span style="color: #666666;">-></span> <span style="color: #aa22ff;">[]</span>
<span style="color: #666666;">|</span> h <span style="color: #666666;">::</span> t <span style="color: #666666;">-></span> <span style="color: blue; font-weight: bold;">List</span>.append h <span style="color: #666666;">(</span>flatten_list t<span style="color: #666666;">)</span>
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Description: Takes a graph (could be multigraph) g and and a node n and returns</span>
<span style="color: #008800; font-style: italic;"> and equivalent graph g' which is starred at n, and preserves the net input/output</span>
<span style="color: #008800; font-style: italic;"> at each node of g.</span>
<span style="color: #008800; font-style: italic;"> Signature: ('a * int * 'a) list -> 'a -> ('a * int * 'a) list</span>
<span style="color: #008800; font-style: italic;"> Example:</span>
<span style="color: #008800; font-style: italic;"># starify_graph [(1, 160, 2); (2, 440, 1); (1, 300, 3); (3, 160, 2)] 1;;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list =</span>
<span style="color: #008800; font-style: italic;">[(3, 160, 1); (2, -160, 1); (3, -300, 1); (2, 440, 1); (2, -160, 1)]</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> starify_graph g n <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> list_of_lists <span style="color: #666666;">=</span> <span style="color: blue; font-weight: bold;">List</span>.map <span style="color: #666666;">(</span><span style="color: #aa22ff; font-weight: bold;">fun</span> g <span style="color: #666666;">-></span> reroute g n<span style="color: #666666;">)</span> g <span style="color: #aa22ff; font-weight: bold;">in</span>
flatten_list list_of_lists
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Description: Takes an edge e = (n1, w, n2) and a graph g, and returns a </span>
<span style="color: #008800; font-style: italic;"> new graph g' such that g' is same as g except that if g contains an edge</span>
<span style="color: #008800; font-style: italic;"> e' with same source and target nodes as e, then e and e' are merged by</span>
<span style="color: #008800; font-style: italic;"> adding their weights.</span>
<span style="color: #008800; font-style: italic;"> Signature: 'a * int * 'b -> ('a * int * 'b) list -> ('a * int * 'b) list</span>
<span style="color: #008800; font-style: italic;"> Assumption: g is not a multi-graph.</span>
<span style="color: #008800; font-style: italic;"> Example:</span>
<span style="color: #008800; font-style: italic;"># let g2 = [(3, -140, 1); (2, 120, 1)];;</span>
<span style="color: #008800; font-style: italic;">val g2 : (int * int * int) list = [(3, -140, 1); (2, 120, 1)]</span>
<span style="color: #008800; font-style: italic;"># merge (3, 140, 1) g2;;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list = [(3, 0, 1); (2, 120, 1)]</span>
<span style="color: #008800; font-style: italic;"># merge (3, 140, 2) g2;; </span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list = [(3, -140, 1); (2, 120, 1); (3, 140, 2)]</span>
<span style="color: #008800; font-style: italic;"># merge (3, 140, 2) [];;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list = [(3, 140, 2)]</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #aa22ff; font-weight: bold;">rec</span> merge <span style="color: #666666;">(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)</span> <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">function</span>
<span style="color: #aa22ff;">[]</span> <span style="color: #666666;">-></span> <span style="color: #666666;">[(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)]</span>
<span style="color: #666666;">|</span> <span style="color: #666666;">(</span>n1'<span style="color: #666666;">,</span> w'<span style="color: #666666;">,</span> n2'<span style="color: #666666;">)</span> <span style="color: #666666;">::</span> t <span style="color: #666666;">-></span>
<span style="color: #aa22ff; font-weight: bold;">if</span> n1 <span style="color: #666666;">=</span> n1' <span style="color: #666666;">&&</span> n2 <span style="color: #666666;">=</span> n2' <span style="color: #aa22ff; font-weight: bold;">then</span> <span style="color: #666666;">((</span>n1<span style="color: #666666;">,</span> w <span style="color: #666666;">+</span> w'<span style="color: #666666;">,</span> n2<span style="color: #666666;">)</span> <span style="color: #666666;">::</span> t<span style="color: #666666;">)</span>
<span style="color: #aa22ff; font-weight: bold;">else</span> <span style="color: #666666;">(</span>n1'<span style="color: #666666;">,</span> w'<span style="color: #666666;">,</span> n2'<span style="color: #666666;">)</span> <span style="color: #666666;">::</span> <span style="color: #666666;">(</span>merge <span style="color: #666666;">(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)</span> t<span style="color: #666666;">)</span>
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Description: Takes a multigraph mg and returns its corresponding graph g by merging</span>
<span style="color: #008800; font-style: italic;"> all edges between common pairs of nodes.</span>
<span style="color: #008800; font-style: italic;"> Signature: ('a * int * 'b) list -> ('a * int * 'b) list</span>
<span style="color: #008800; font-style: italic;"> Example:</span>
<span style="color: #008800; font-style: italic;"># graph_of_mgraph [(1, 160, 2); (2, 300, 1); (2, 140, 1); (1, 300, 3); (3, 160, 2)];;</span>
<span style="color: #008800; font-style: italic;">- : (int * int * int) list =</span>
<span style="color: #008800; font-style: italic;">[(1, 160, 2); (2, 440, 1); (1, 300, 3); (3, 160, 2)]</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> graph_of_mgraph mg <span style="color: #666666;">=</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #aa22ff; font-weight: bold;">rec</span> iter g <span style="color: #666666;">=</span> <span style="color: #aa22ff; font-weight: bold;">function</span>
<span style="color: #aa22ff;">[]</span> <span style="color: #666666;">-></span> g
<span style="color: #666666;">|</span> e <span style="color: #666666;">::</span> t <span style="color: #666666;">-></span> iter <span style="color: #666666;">(</span>merge e g<span style="color: #666666;">)</span> t
<span style="color: #aa22ff; font-weight: bold;">in</span>
iter <span style="color: #aa22ff;">[]</span> mg
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Description: Turns the weight of every edge of a given graph to positive value by inverting the direction of the edge if its weight is negative.</span>
<span style="color: #008800; font-style: italic;"> Signature: ('a * int * 'a) list -> ('a * int * 'a) list</span>
<span style="color: #008800; font-style: italic;"> </span>
<span style="color: #008800; font-style: italic;"> Example:</span>
<span style="color: #008800; font-style: italic;"># abs_weight [("Taru", -140, "Shraddha"); ("Shilpi", 20, "Shraddha")];;</span>
<span style="color: #008800; font-style: italic;">- : (string * int * string) list =</span>
<span style="color: #008800; font-style: italic;">[("Shraddha", 140, "Taru"); ("Shilpi", 20, "Shraddha")] </span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> abs_weight g <span style="color: #666666;">=</span>
<span style="color: blue; font-weight: bold;">List</span>.map <span style="color: #666666;">(</span>
<span style="color: #aa22ff; font-weight: bold;">fun</span> <span style="color: #666666;">(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)</span> <span style="color: #666666;">-></span> <span style="color: #aa22ff; font-weight: bold;">if</span> w <span style="color: #666666;">>=</span> <span style="color: #666666;">0</span> <span style="color: #aa22ff; font-weight: bold;">then</span> <span style="color: #666666;">(</span>n1<span style="color: #666666;">,</span> w<span style="color: #666666;">,</span> n2<span style="color: #666666;">)</span> <span style="color: #aa22ff; font-weight: bold;">else</span> <span style="color: #666666;">(</span>n2<span style="color: #666666;">,</span> <span style="color: #666666;">-</span>w<span style="color: #666666;">,</span> n1<span style="color: #666666;">)</span>
<span style="color: #666666;">)</span> g
<span style="color: #aa22ff; font-weight: bold;">let</span> remove_empty_edges g <span style="color: #666666;">=</span>
<span style="color: blue; font-weight: bold;">List</span>.filter <span style="color: #666666;">(</span><span style="color: #aa22ff; font-weight: bold;">fun</span> <span style="color: #666666;">(_,</span> w<span style="color: #666666;">,</span> <span style="color: #666666;">_)</span> <span style="color: #666666;">-></span> w <span style="color: #666666;"><></span> <span style="color: #666666;">0)</span> g
<span style="color: #008800; font-style: italic;">(*</span>
<span style="color: #008800; font-style: italic;"> Example graph (Provided by Shilpi)</span>
<span style="color: #008800; font-style: italic;"> node 1 -> Shilpi</span>
<span style="color: #008800; font-style: italic;"> node 2 -> Shraddha</span>
<span style="color: #008800; font-style: italic;"> node 3 -> Taru</span>
<span style="color: #008800; font-style: italic;"> (1, 160, 2) -> Shilpi owes Rs. 160 to Shraddha</span>
<span style="color: #008800; font-style: italic;">*)</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> g <span style="color: #666666;">=</span> <span style="color: #666666;">[(</span><span style="color: #bb4444;">"Shilpi"</span><span style="color: #666666;">,</span> <span style="color: #666666;">160,</span> <span style="color: #bb4444;">"Shraddha"</span><span style="color: #666666;">);</span> <span style="color: #666666;">(</span><span style="color: #bb4444;">"Shraddha"</span><span style="color: #666666;">,</span> <span style="color: #666666;">300,</span> <span style="color: #bb4444;">"Shilpi"</span><span style="color: #666666;">);</span> <span style="color: #666666;">(</span><span style="color: #bb4444;">"Shraddha"</span><span style="color: #666666;">,</span> <span style="color: #666666;">140,</span> <span style="color: #bb4444;">"Shilpi"</span><span style="color: #666666;">);</span> <span style="color: #666666;">(</span><span style="color: #bb4444;">"Shilpi"</span><span style="color: #666666;">,</span> <span style="color: #666666;">300,</span> <span style="color: #bb4444;">"Taru"</span><span style="color: #666666;">);</span> <span style="color: #666666;">(</span><span style="color: #bb4444;">"Taru"</span><span style="color: #666666;">,</span> <span style="color: #666666;">160,</span> <span style="color: #bb4444;">"Shraddha"</span><span style="color: #666666;">)]</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> star_node <span style="color: #666666;">=</span> <span style="color: #bb4444;">"Shraddha"</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #666666;">_</span> <span style="color: #666666;">=</span> remove_empty_edges <span style="color: #666666;">(</span>
abs_weight <span style="color: #666666;">(</span>
graph_of_mgraph <span style="color: #666666;">(</span>
starify_graph g star_node<span style="color: #666666;">)))</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> e1 <span style="color: #666666;">=</span> <span style="color: #666666;">[</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r2"</span><span style="color: #666666;">,</span> <span style="color: #666666;">10,</span> <span style="color: #bb4444;">"r3"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r1"</span><span style="color: #666666;">,</span> <span style="color: #666666;">20,</span> <span style="color: #bb4444;">"r2"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r2"</span><span style="color: #666666;">,</span> <span style="color: #666666;">10,</span> <span style="color: #bb4444;">"r4"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r4"</span><span style="color: #666666;">,</span> <span style="color: #666666;">30,</span> <span style="color: #bb4444;">"r3"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r1"</span><span style="color: #666666;">,</span> <span style="color: #666666;">15,</span> <span style="color: #bb4444;">"r6"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r6"</span><span style="color: #666666;">,</span> <span style="color: #666666;">100,</span><span style="color: #bb4444;">"r5"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r7"</span><span style="color: #666666;">,</span> <span style="color: #666666;">25,</span> <span style="color: #bb4444;">"r5"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r5"</span><span style="color: #666666;">,</span> <span style="color: #666666;">150,</span><span style="color: #bb4444;">"r4"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r3"</span><span style="color: #666666;">,</span> <span style="color: #666666;">30,</span> <span style="color: #bb4444;">"r7"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">(</span><span style="color: #bb4444;">"r7"</span><span style="color: #666666;">,</span> <span style="color: #666666;">90,</span> <span style="color: #bb4444;">"r4"</span><span style="color: #666666;">);</span>
<span style="color: #666666;">]</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> star_node <span style="color: #666666;">=</span> <span style="color: #bb4444;">"r4"</span>
<span style="color: #aa22ff; font-weight: bold;">let</span> <span style="color: #666666;">_</span> <span style="color: #666666;">=</span> remove_empty_edges <span style="color: #666666;">(</span>
abs_weight <span style="color: #666666;">(</span>
graph_of_mgraph <span style="color: #666666;">(</span>
starify_graph e1 star_node<span style="color: #666666;">)))</span>
</pre>
</td></tr>
</tbody></table>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com1tag:blogger.com,1999:blog-22044226.post-45547519609723173232014-06-13T22:11:00.002+05:302014-07-02T14:47:33.363+05:30A Battleship Game<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Arial, Helvetica, sans-serif;">Presenting for your entertainment a simple <a href="https://sourceforge.net/projects/cursedbattle/" target="_blank">battleship game</a>. The biggest testimonial for it was that my 5 year old son played it, finished playing, and liked it. Since the first time, he has often requested to be allowed to play it.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">My objective of building this game has been primarily educational. </span><br />
<br />
<ol style="text-align: left;">
<li><span style="font-family: Arial, Helvetica, sans-serif;">to get back to C++</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">to create a practical example of software design of what could be a term-project</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">to use OO best practices with design patterns like singleton, template etc.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">to approximate a model-view-architecture</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">to implement the Smart CPU using a finite state machine</span></li>
</ol>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Additionally, the design has flavours of functional design.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">But, those are secondary. If you get to play the game, and 5 minutes of your time go in a lightweight tussle with the machine, the real objective of this project is achieved.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Would be thankful for feedback and bugs.</span></div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-2563789972224464422014-03-20T13:13:00.002+05:302014-03-20T13:13:33.095+05:30Now LaTeX is a 'Turing Complete' Language<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif; font-size: large;">If you are a LaTeX user, today's a day for you to rejoice. TeX --
the underlying typesetting engine -- was designed by Don Knuth, who won
the highest computer science honour way back in 1974. Now, with Lamport
-- who enriched the software significantly,
and to whom the 'La' part of LaTeX is credited -- getting the Turing
award, we can say that <span style="color: red;">LaTeX now is 'Turing Complete'! :)</span></span></div>
<div style="margin-bottom: 14pt; margin-top: 14pt; text-align: justify;">
<span style="color: black; font-family: Georgia, Times New Roman, serif; font-size: large;">Of
course, Lamport's contributions to Computer Science go far deeper than
just LaTeX. He has made fundamental contributions to distributed and
concurrent computing. To appreciate this, you
needn't have read his papers, or done a course of distributed computing.
If you as much as have made one call with your cell-phone, or have used
the Internet, you have already allowed Lamport's work to touch your
life in a profound way.</span></div>
<div style="margin-bottom: 14pt; margin-top: 14pt; text-align: justify;">
<span style="color: black; font-family: Georgia, Times New Roman, serif; font-size: large;">Let's cheer Leslie for this much deserved, and probably long delayed, honour!</span></div>
<div style="margin-bottom: 14pt; margin-top: 14pt; text-align: justify;">
<a href="http://www.acm.org/news/featured/awards/turing-award-2013" target="_blank"><span style="font-family: Georgia, Times New Roman, serif; font-size: large;">http://www.acm.org/news/featured/awards/turing-award-2013</span></a></div>
<br />
<div>
<span style="font-family: Georgia, Times New Roman, serif; font-size: large;"><a href="http://lms.iiitb.ac.in/moodle/mod/forum/post.php?reply=1325" target="_blank"></a></span></div>
<br />
<div style="margin-bottom: 14pt; margin-top: 14pt; text-align: justify;">
<a href="http://channel9.msdn.com/Series/Microsoft-Research-Luminaries/Leslie-Lamport-Selected-as-2013-ACM-A-M-Turing-Award-Winner" target="_blank"><span style="font-family: Georgia, Times New Roman, serif; font-size: large;">http://channel9.msdn.com/Series/Microsoft-Research-Luminaries/Leslie-Lamport-Selected-as-2013-ACM-A-M-Turing-Award-Winner</span></a></div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-74631888085800363102013-09-27T17:15:00.001+05:302013-09-27T17:15:50.865+05:308-Queens Puzzle using Functional Programming<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Following is the OCaml code I wrote yesterday to solve the 8-queen puzzle. I have presented a solution in Python in an earlier post for the same purpose. However, there's a key difference. This solution is purely functional programming. This means that we do a completely side-effect free computing here. Therefore, we don't have assignments, mutable types, and of course, no loops. Once I got the code in place, I re-implemented the whole thing using loops. For the benefit of those accustomed to a procedural way of programming (me included), I have included that code too here.</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">module</span> <span style="color: #bb0066; font-weight: bold;">EightQueen</span> <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">struct</span>
<span style="color: #008800; font-weight: bold;">let</span> conflict a b diff <span style="color: #333333;">=</span>
<span style="color: #333333;">(</span>a <span style="color: #333333;">=</span> b<span style="color: #333333;">)</span> <span style="color: #333333;">||</span> <span style="color: #333333;">(</span>abs <span style="color: #333333;">(</span>a <span style="color: #333333;">-</span> b<span style="color: #333333;">)</span> <span style="color: #333333;">=</span> diff<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">let</span> emptyList <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> allValues <span style="color: #333333;">=</span> <span style="color: #333333;">[</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">4</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">5</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">6</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">7</span> <span style="color: #333333;">];;</span>
<span style="color: #008800; font-weight: bold;">let</span> maxlength <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.length allValues<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> shuffle d <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> nd <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.map <span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">fun</span> c <span style="color: #333333;">-></span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">Random</span>.bits <span style="color: #007020;">()</span><span style="color: #333333;">,</span> c<span style="color: #333333;">))</span> d <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> sond <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.sort compare nd <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #0e84b5; font-weight: bold;">List</span>.map snd sond
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> checkConflict newList <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> check i <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> c <span style="color: #333333;">=</span> conflict <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.nth newList <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">)</span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.nth newList i<span style="color: #333333;">)</span> i <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">if</span> c <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #007020;">false</span>
<span style="color: #008800; font-weight: bold;">else</span> <span style="color: #008800; font-weight: bold;">if</span> i <span style="color: #333333;">=</span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.length newList <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #007020;">true</span>
<span style="color: #008800; font-weight: bold;">else</span>
check <span style="color: #333333;">(</span>i <span style="color: #333333;">+</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.length newList <span style="color: #333333;"><</span> <span style="color: #0000dd; font-weight: bold;">2</span> <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #007020;">true</span>
<span style="color: #008800; font-weight: bold;">else</span>
check <span style="color: #0000dd; font-weight: bold;">1</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> solve pos <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">if</span> checkConflict pos <span style="color: #333333;">=</span> <span style="color: #007020;">false</span> <span style="color: #008800; font-weight: bold;">then</span>
emptyList
<span style="color: #008800; font-weight: bold;">else</span> <span style="color: #008800; font-weight: bold;">if</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.length pos <span style="color: #333333;">=</span> maxlength <span style="color: #008800; font-weight: bold;">then</span>
pos
<span style="color: #008800; font-weight: bold;">else</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> loop lst allowedValues <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">if</span> allowedValues <span style="color: #333333;">=</span> emptyList <span style="color: #008800; font-weight: bold;">then</span>
emptyList
<span style="color: #008800; font-weight: bold;">else</span>
<span style="color: #008800; font-weight: bold;">let</span> head <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.hd allowedValues
<span style="color: black; font-weight: bold;">and</span> tail <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.tl allowedValues <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> extendedList <span style="color: #333333;">=</span> head<span style="color: #333333;">::</span>pos <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> answer <span style="color: #333333;">=</span> solve extendedList <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">if</span> answer <span style="color: #333333;"><></span> emptyList <span style="color: #008800; font-weight: bold;">then</span>
answer
<span style="color: #008800; font-weight: bold;">else</span>
loop lst tail
<span style="color: #008800; font-weight: bold;">in</span>
loop pos <span style="color: #333333;">(</span>shuffle allValues<span style="color: #333333;">)</span>
<span style="color: #008800; font-weight: bold;">end</span><span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> printList lst <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">match</span> lst <span style="color: #008800; font-weight: bold;">with</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> <span style="color: #007020;">()</span>
<span style="color: #333333;">|</span> e<span style="color: #333333;">::</span>l <span style="color: #333333;">-></span> print_int e <span style="color: #333333;">;</span> print_string <span style="background-color: #fff0f0;">" "</span> <span style="color: #333333;">;</span> printList l
<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> lst <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">EightQueen</span>.solve <span style="color: #0e84b5; font-weight: bold;">EightQueen</span>.emptyList <span style="color: #008800; font-weight: bold;">in</span>
printList lst<span style="color: #333333;">;</span> print_string <span style="background-color: #fff0f0;">"</span><span style="background-color: #fff0f0; color: #666666; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">"</span><span style="color: #333333;">;;</span></pre>
</td></tr>
</tbody></table>
</div>
</div>
<!-- HTML generated using hilite.me --><br />
<br />
And here follows pretty much the same code using imperative style:<br />
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">let</span> conflict a b diff <span style="color: #333333;">=</span>
<span style="color: #333333;">(</span>a <span style="color: #333333;">=</span> b<span style="color: #333333;">)</span> <span style="color: #333333;">||</span> <span style="color: #333333;">(</span>abs <span style="color: #333333;">(</span>a <span style="color: #333333;">-</span> b<span style="color: #333333;">)</span> <span style="color: #333333;">=</span> diff<span style="color: #333333;">)</span>
<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> emptyList <span style="color: #333333;">=</span> <span style="color: #007020;">[]</span><span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> allValues <span style="color: #333333;">=</span> <span style="color: #333333;">[</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">2</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">3</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">4</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">5</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">6</span><span style="color: #333333;">;</span> <span style="color: #0000dd; font-weight: bold;">7</span> <span style="color: #333333;">];;</span>
<span style="color: #008800; font-weight: bold;">let</span> maxlength <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.length allValues<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> print_list <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">function</span>
<span style="color: #007020;">[]</span> <span style="color: #333333;">-></span> <span style="color: #007020;">()</span>
<span style="color: #333333;">|</span> e<span style="color: #333333;">::</span>l <span style="color: #333333;">-></span> print_int e <span style="color: #333333;">;</span> print_string <span style="background-color: #fff0f0;">" "</span> <span style="color: #333333;">;</span> print_list l
<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> shuffle d <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> nd <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.map <span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">fun</span> c <span style="color: #333333;">-></span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">Random</span>.bits <span style="color: #007020;">()</span><span style="color: #333333;">,</span> c<span style="color: #333333;">))</span> d <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> sond <span style="color: #333333;">=</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.sort compare nd <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #0e84b5; font-weight: bold;">List</span>.map snd sond
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> checkConflict newList <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">let</span> result <span style="color: #333333;">=</span> ref <span style="color: #007020;">true</span> <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">for</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1</span> <span style="color: #008800; font-weight: bold;">to</span> <span style="color: #333333;">((</span><span style="color: #0e84b5; font-weight: bold;">List</span>.length newList<span style="color: #333333;">)</span> <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">do</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">!</span>result <span style="color: #333333;">=</span> <span style="color: #007020;">true</span> <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #008800; font-weight: bold;">if</span> conflict <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.nth newList <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">)</span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.nth newList i<span style="color: #333333;">)</span> i <span style="color: #008800; font-weight: bold;">then</span>
result <span style="color: #333333;">:=</span> <span style="color: #007020;">false</span>
<span style="color: #008800; font-weight: bold;">done</span><span style="color: #333333;">;</span>
<span style="color: #333333;">!</span>result
<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">rec</span> solve pos <span style="color: #333333;">=</span>
<span style="color: #008800; font-weight: bold;">if</span> checkConflict pos <span style="color: #333333;">=</span> <span style="color: #007020;">false</span> <span style="color: #008800; font-weight: bold;">then</span>
emptyList
<span style="color: #008800; font-weight: bold;">else</span> <span style="color: #008800; font-weight: bold;">if</span> <span style="color: #0e84b5; font-weight: bold;">List</span>.length pos <span style="color: #333333;">=</span> maxlength <span style="color: #008800; font-weight: bold;">then</span>
pos
<span style="color: #008800; font-weight: bold;">else</span>
<span style="color: #008800; font-weight: bold;">let</span> result <span style="color: #333333;">=</span> ref emptyList <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">for</span> i <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">0</span> <span style="color: #008800; font-weight: bold;">to</span> <span style="color: #333333;">((</span><span style="color: #0e84b5; font-weight: bold;">List</span>.length allValues<span style="color: #333333;">)</span> <span style="color: #333333;">-</span> <span style="color: #0000dd; font-weight: bold;">1</span><span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">do</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">!</span>result <span style="color: #333333;">=</span> emptyList <span style="color: #008800; font-weight: bold;">then</span>
<span style="color: #008800; font-weight: bold;">let</span> <span style="color: #008800; font-weight: bold;">value</span> <span style="color: #333333;">=</span> <span style="color: #333333;">(</span><span style="color: #0e84b5; font-weight: bold;">List</span>.nth allValues i<span style="color: #333333;">)</span> <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> extendedList <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">value</span><span style="color: #333333;">::</span>pos <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">let</span> answer <span style="color: #333333;">=</span> solve extendedList <span style="color: #008800; font-weight: bold;">in</span>
<span style="color: #008800; font-weight: bold;">if</span> answer <span style="color: #333333;"><></span> emptyList <span style="color: #008800; font-weight: bold;">then</span>
result <span style="color: #333333;">:=</span> answer
<span style="color: #008800; font-weight: bold;">done</span><span style="color: #333333;">;</span>
<span style="color: #333333;">!</span>result
<span style="color: #333333;">;;</span>
<span style="color: #008800; font-weight: bold;">let</span> lst <span style="color: #333333;">=</span> solve emptyList <span style="color: #008800; font-weight: bold;">in</span>
print_list lst<span style="color: #333333;">;</span> print_string <span style="background-color: #fff0f0;">"</span><span style="background-color: #fff0f0; color: #666666; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">"</span><span style="color: #333333;">;;</span>
</pre>
</td></tr>
</tbody></table>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-31856485786127222013-05-13T12:11:00.002+05:302013-05-13T15:07:06.438+05:30An Automated Sudoku Generator<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
In <a href="http://sujitkc-techbits.blogspot.in/2013/04/an-automated-sudoku-player.html">a recent post</a>, I presented an automated sudoku player. Given a sudoku puzzle, this little program gives you its solution in a matter of seconds (mostly fractions of a second).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here's an addition to it: An automated Sudoku Generator.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In the earlier one, I had gone into gory details of the algorithm because the beauty lay in the depth first branch and bound design of the algorithm. Here, I don't go into any details, simply because there aren't any! And that's the beauty of the whole thing. It's ridiculously simple.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And it succeeds to completely build on the sudoku solver. Well, almost. I have modified the sudoku solver just slightly to make it <i>randomised</i>. That means that for the same input, two separate runs may (and most probably will) give out two distinct solutions. This was necessary to prevent our sudoku generator from throwing the same puzzle at us every time. Now, every 9 by 9 sudoku puzzle that can be has an equal probability of getting generated by our program!</div>
<br />
The trick is simple: <i>Give sudoku solver a completely empty sudoku
puzzle and let it come back with a valid solved puzzle. Now, just mask
away some of the cells in this grid with blanks. That's your new sudoku
puzzle!</i><br />
Here's the code:<br />
<br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: grey;">#!/usr/bin/python</span>
<span style="color: green; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">sudoku</span> <span style="color: green; font-weight: bold;">import</span> <span style="color: #303030;">*</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">mask</span>(sudoku):
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">generateRandomList</span>(num, lst):
index <span style="color: #303030;">=</span> random<span style="color: #303030;">.</span>randint(<span style="color: #0000d0; font-weight: bold;">0</span>, <span style="color: #007020;">len</span>(lst) <span style="color: #303030;">-</span> <span style="color: #0000d0; font-weight: bold;">1</span>)
result <span style="color: #303030;">=</span> [lst<span style="color: #303030;">.</span>pop(index)]
<span style="color: green; font-weight: bold;">if</span>(num <span style="color: #303030;">></span> <span style="color: #0000d0; font-weight: bold;">1</span>):
result<span style="color: #303030;">.</span>extend(generateRandomList(num <span style="color: #303030;">-</span> <span style="color: #0000d0; font-weight: bold;">1</span>, lst))
<span style="color: green; font-weight: bold;">return</span> result
<span style="color: green; font-weight: bold;">for</span> rowNum <span style="color: black; font-weight: bold;">in</span> <span style="color: #007020;">range</span>(<span style="color: #0000d0; font-weight: bold;">9</span>):
row <span style="color: #303030;">=</span> sudoku[rowNum]
offset <span style="color: #303030;">=</span> random<span style="color: #303030;">.</span>randint(<span style="color: #0000d0; font-weight: bold;">0</span>, <span style="color: #0000d0; font-weight: bold;">1</span>)
maskIndices <span style="color: #303030;">=</span> generateRandomList(<span style="color: #0000d0; font-weight: bold;">5</span> <span style="color: #303030;">+</span> offset, <span style="color: #007020;">range</span>(<span style="color: #0000d0; font-weight: bold;">9</span>))
<span style="color: green; font-weight: bold;">for</span> i <span style="color: black; font-weight: bold;">in</span> maskIndices:
row[i] <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">0</span>
<span style="color: green; font-weight: bold;">return</span> sudoku
</pre>
</div>
<br />
<br />
<div style="text-align: justify;">
In the above almost trivial piece of code, probably the function <b><span style="color: #0b5394;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">generateRandomList</span></span></b> is the only part which merits a second glance. This function takes a list <b>lst</b> and returns a sublist of <b>num</b> randomly chosen elements of it. Again, don't you agree that implementing it recursively has made it simpler to read?</div>
<br />
All the outer <span style="color: blue;"><b><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">mask</span></b></span> function does is to call <b><span style="color: blue;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">generateRandomList</span></span></b> for each of its rows.<br />
<br />
If you wish to test the above, here's the main function:<br />
<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: green; font-weight: bold;">if</span> __name__ <span style="color: #303030;">==</span> <span style="background-color: #fff0f0;">'__main__'</span>:
sudoku <span style="color: #303030;">=</span> [[<span style="color: #0000d0; font-weight: bold;">0</span>] <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">9</span>] <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">9</span>
<span style="color: green; font-weight: bold;">print</span> <span style="background-color: #fff0f0;">'solution:'</span>
solution <span style="color: #303030;">=</span> solve(sudoku)
printSudoku(solution)
<span style="color: green; font-weight: bold;">print</span> <span style="background-color: #fff0f0;">'masked:'</span>
printSudoku(mask(solution))
</pre>
</div>
<br />
<br />
That's all!<br />
<br />
Follows the downloadable file:<br />
<a href="https://docs.google.com/file/d/0B1WZgxQ3CbErWlVRVzBPRElEeTQ/edit">sudoku_maker.py</a> <br />
<br />
Download it at the same place where you have placed your <a href="https://docs.google.com/file/d/0B1WZgxQ3CbErdUhaR2hReFRqdFE/edit">sudoku.py</a>. And make sure to make the sudoku_maker.py an executable:<br />
<span style="color: purple;"><b><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">chmod +x sudoku_maker.py</span></b></span><br />
<br />
Or run it as follows:<br />
<br />
<b><span style="color: purple;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">python sudoku_maker.py</span></span></b><br />
<br />
<h4 style="text-align: left;">
Acknowledgement:</h4>
Thanks <a href="http://www.blogger.com/profile/15753753796044182178">Prahlad</a> for asking me to write the above (or something of this sort).</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com1tag:blogger.com,1999:blog-22044226.post-27473832982219285802013-04-29T16:33:00.000+05:302013-04-29T16:33:18.024+05:30An Automated Sudoku Player<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: justify;">
<a href="http://upload.wikimedia.org/wikipedia/commons/f/ff/Sudoku-by-L2G-20050714.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/f/ff/Sudoku-by-L2G-20050714.svg" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I never played <a href="http://en.wikipedia.org/wiki/Sudoku">Sudoku</a>. And now, it's even more unlikely that I will ever play it again.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
I built a cute little program, all of it probably less than 40 lines, that will solve any damn Sudoku puzzle for me (I think), however hard, while I pay attention to my morning tea and other less brain wracking articles in the newspaper.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The program isn't a trivial piece though. Let me also confess that the algorithm isn't mine. I saw it first in a <a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29">Python</a> course I sat through which <a href="http://www.limberlink.com/team">Dr. Vinay</a> was teaching. After teasing the students in his characteristic style for a couple of hours, he popped out his implementation of it. A 16 line Python code!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The one I present here is pretty much the same algorithm, albeit implemented by a mortal. :)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The algorithm...hm. Well, it's a brute force one, in the same way as the solution to the eight queen puzzle that I presented <a href="http://sujitkc-techbits.blogspot.in/2013/04/showing-lady-her-right-place.html">here</a>. However, it's OK. Sudoku puzzles don't grow larger than 9 by 9. So, a decent implementation comes back with a solution (if it exists) within a second or so on an average. One way to look at it is to treat the puzzle instance as an array of 81 numbers. And you could use that decision cleverly to crunch your program into an ever smaller number of lines). But I am somewhat old fashioned. I have no taste for anything size zero. I decided to represent it in a way similar to how it appears to the eyes: a 9 by 9 matrix. That added some flab to my program. But I like it that way!<br />
<br />
Again, a small bit of notation will help understand the algorithm.</div>
<div style="text-align: justify;">
</div>
<br />
<span style="color: purple;"><i>satisfy(x, Env)</i> =</span><br />
<span style="color: purple;"> <b>if</b> <i>permitted(x, Env) = {}</i> <b>then</b> <i>[]</i></span><br />
<span style="color: purple;"> <b>else</b></span><br />
<span style="color: purple;"> <b>if</b> <i>x = end</i> <b>then</b> <b>let </b><i>val </i>be any value from <i>permitted(x, Env) </i><b>in</b></span><br />
<span style="color: purple;"><b> </b><i>Env U Env[x] = val</i></span><br />
<div style="text-align: justify;">
<span style="color: purple;"> <b>else</b></span><br />
<span style="color: purple;"> <b>if</b> <b>there exists</b> <i>val</i> <b>in</b> <i>permitted(x, Env)</i> <b>such that</b></span><br />
<span style="color: purple;"> <i>satisfy(x + 1, Env U Env[x] = val) != []</i> <b>then</b></span><br />
<span style="color: purple;"> <i>satisfy(x + 1, Env U Env[x] = val)</i></span></div>
<div style="text-align: justify;">
<span style="color: purple;"> <b>else</b> <i>[]</i></span></div>
<div style="text-align: justify;">
<br />
I know, I know. It hasn't remained <i>that</i> simple, this notation. But the attempt underneath to present the same thing in plain English will show you why people (like me) unwillingly resort to mathematical notations (I would agree with you that people who are eager to resort to mathematical notations for no good reason should be sent to the firing squad).<br />
<br />
<blockquote class="tr_bq">
<i>satisfy</i> is recursive. It returns a partially filled sudoku grid (on success) or an empty grid (on failure). For any cell in the grid, if the grid is the last cell in the grid, then, if the set of permitted values for this cell under the given sudoku grid is empty, then it returns an empty grid. Otherwise, it picks any value from that permitted list, sticks that into the cell of the sudoku grid and returns that. In case the cell isn't the last one in the grid, if <i>satisfy</i> receives back a non-empty grid from the subsequent call, it returns the same. Else if it has any untried permitted value left, it uses the same to call satisfy on the next grid cell. If it gets back an empty grid for all permitted values, it returns an empty grid itself, indicating failure in finding a satisfying assignment for the sudoku grid that was passed to it.</blockquote>
<br />
Makes sense? No? To me neither! Let me not therefore belabour the point that math is sometimes not to be avoided for your own benefit.<br />
<br />
One more point. Important one. The above mathematical expression is also a fairly loaded (programmers use the term <i>generic</i>) specification of a depth first backtracking state space
search algorithm. The above structure will pop up in various places if your programming assignments ever take you in the neighbourhood of trees (as in, the data-structures). For example, our eight-queen solver algorithm could also be written very much in the same manner. Only the bells and whistles would be different. More on this sometime later.<br />
<br />
OK. Now take a look back at the expression. Let's try to understand it bit by bit.<br />
<span style="color: purple;"><i>satisfy(x, Env) =</i></span> <br />
Here, we are defining a function satisfy that takes two arguments: <i>x</i>, the grid cell that we are considering currently and <i>Env</i>, which stands for the environment. Environment is again a jazzy word for a set of bindings to things which could be bound. In our case, all the cells in our sudoku grid can be bound to certain values (in the range [1..9]). <i>Env</i> contains one such set of valuations. In it some of the cells have been bound to some values, while some other mayn't yet have been bound to any value. The '=' in the end is the wall between the RHS and LHS. Note that the expression above is actually an equation. So, it's supposed to have an LHS and an RHS separated by an '='. Just to make things further clear, if you have been a lot into programming with C-like languages, the '=' isn't an assignment; it's an equality. Note that the function above is a declarative statement, not an imperative one. Therefore, you don't assign anything to anything; you just declare the condition of equality.<br />
<br />
<span style="color: purple;"><b>if</b> <i>permitted(x, Env) = {}</i> <b>then</b> <i>[]</i></span><br />
<br />
The above means that the set of <i>permitted</i> values for the cell <i>x</i> with the given (partially filled) sudoku grid is empty (i.e. we have no permitted values), then satisfy evaluates to an empty list. This means that with the given inputs this call to the <i>satisfy</i> has failed to come up with satisfying valuations to the empty cells of the sudoku grid.<br />
<br />
But what is a <i>permitted</i> set? The universal set of numbers that can go into a cell is [1..9]. A cell can't have the numbers in this set which have already been taken by the cells with which it <i>conflict</i>s. And which are the cells with which a cell <i>conflict</i>s? The cells in the same row, and those in the same column and those in the same subgrid or region.<br />
<br />
<span style="color: purple;"><i>conflict(x, y) =</i></span><br />
<span style="color: purple;"><i> row(x) = row(y) or column(x) = column(y) or region(x) = region(y)</i></span><br />
<br />
<span style="color: purple;"><i>unpermitted =</i> set of values in all <i>y</i> such that <i>conflict(x, y)</i></span><br />
<span style="color: purple;"><i>permitted = [1..9] \ unpermitted</i></span><br />
<br />
One more question. How to determine the region of a cell? Here's how:<br />
<span style="color: purple;"><i>region(x) = (row(x) / 3, column(x) / 3)</i></span><br />
<br />
That is, it's a pair obtained by dividing both the <i>row</i> and <i>column</i> of <i>x</i> by 3. And remember, this is an integer divide. So, the value computed as the quotient is also an integer, which is the floor of the actual quotient (possibly a rational number). I leave it up to you to convince yourself that this will give you the region indeed. <br />
<br />
Phew! So much for a couple of lines! Are we going to have read a whole
book to understand the complete expression? No. I think, we have dealt with most of the complicated stuff by now. Hereon, things ought to
be straightforward.<br />
<br />
<span style="color: purple;"> <b>else</b></span><br />
<span style="color: purple;"> <b>if</b> <i>x = end</i> <b>then</b> <b>let </b><i>val </i>be any value from <i>permitted(x, Env) </i><b>in</b></span><br />
<span style="color: purple;"><b> </b><i>Env U Env[x] = val</i></span><br />
<span style="color: purple;"></span><br />
<br />
So, we have dealt with the case when there are no permitted values. That corresponds to a failure, and the expression evaluates to an empty set {}. Now, if there <i>are</i> some permitted values, i.e. <i>permitted </i>is not {}, then we check if we are dealing with the last cell in the grid (<i>x = end</i>). If yes, then we have found a solution, and we return the grid as we received it. Else, we continue our journey to the next element in the grid:<br />
<br />
<div style="text-align: justify;">
<span style="color: purple;"> <b>else</b></span><br />
<span style="color: purple;"> <b>if</b> <b>there exists</b> <i>val</i> <b>in</b> <i>permitted(x, Env)</i> <b>such that</b></span><br />
<span style="color: purple;"> <i>satisfy(x + 1, Env U Env[x] = val) != []</i> <b>then</b></span><br />
<span style="color: purple;"> <i>satisfy(x + 1, Env U Env[x] = val)</i></span></div>
<div style="text-align: justify;">
<span style="color: purple;"> <b>else</b> <i>[]</i></span><br />
<br />
<span style="color: purple;"><span style="color: black;">which says that for a given value <i>val</i> in the permitted set, we must get a non-empty set from the call to <i>satisfy </i>on the next cell. If we get an empty set, this <i>val</i> is dud and we have to consider another one. If we aren't left with any before having found success in <i>satisfy</i>ing the next cell, the <i>val</i> being considered in the previous cell is a dud, and we need to tell it to the caller of this <i>satisfy</i>. How? Of course, by returning an empty set.</span></span><br />
<br />
<span style="color: purple;"><span style="color: black;">Also note that in computing the <i>permitted</i> set, we do another clever thing. If it turns out to be an empty set, we have no reason left to proceed further in the same direction, and we <i>backtrack.</i> This saves us from exploring potentially large portions of the state space where searching for a solution would be futile. This clever trick is called <i>pruning</i>. And the family of algorithms which use this technique are called <i>branch and bound</i> algorithms. </span></span><br />
<br />
<span style="color: purple;"><span style="color: black;">Understood? No! Well, I can't make any easier than this. Blame it on my bad writing skills. But as of now, if you haven't yet made it through the above explanation, and you are still keen to, the only way I can think of is to go through it again. Stare at it for a while. And you'll soon see light. It's not very difficult, I can tell you that!</span></span><br />
<br />
<span style="color: purple;"><span style="color: black;">And if understanding the above isn't your cup of tea, well, all is not lost. Here, below, I give out the whole code.</span></span><br />
<br />
<br />
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-style: italic">#!/usr/bin/python</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">conflict</span>((r1, c1), (r2, c2)):
<span style="color: #AA22FF; font-weight: bold">if</span>(r1 <span style="color: #666666">==</span> r2): <span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">True</span>
<span style="color: #AA22FF; font-weight: bold">if</span>(c1 <span style="color: #666666">==</span> c2): <span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">True</span>
<span style="color: #AA22FF; font-weight: bold">if</span>(r1 <span style="color: #666666">/</span> <span style="color: #666666">3</span> <span style="color: #666666">==</span> r2 <span style="color: #666666">/</span> <span style="color: #666666">3</span> <span style="color: #AA22FF; font-weight: bold">and</span> c1 <span style="color: #666666">/</span> <span style="color: #666666">3</span> <span style="color: #666666">==</span> c2 <span style="color: #666666">/</span> <span style="color: #666666">3</span> <span style="color: #AA22FF; font-weight: bold">and</span> (<span style="color: #AA22FF; font-weight: bold">not</span> (r1 <span style="color: #666666">==</span> r2 <span style="color: #AA22FF; font-weight: bold">and</span> c1 <span style="color: #666666">==</span> c2))): <span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">True</span>
<span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">False</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">setminus</span>(lst1, lst2):
<span style="color: #AA22FF; font-weight: bold">return</span> [x <span style="color: #AA22FF; font-weight: bold">for</span> x <span style="color: #AA22FF; font-weight: bold">in</span> lst1 <span style="color: #AA22FF; font-weight: bold">if</span> x <span style="color: #AA22FF; font-weight: bold">not</span> <span style="color: #AA22FF; font-weight: bold">in</span> lst2]
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">nextcell</span>((i, j)):
<span style="color: #AA22FF; font-weight: bold">if</span>(j <span style="color: #666666">==</span> <span style="color: #666666">8</span>):
<span style="color: #AA22FF; font-weight: bold">if</span>(i <span style="color: #666666">==</span> <span style="color: #666666">8</span>): <span style="color: #AA22FF; font-weight: bold">return</span> (<span style="color: #666666">0</span>, <span style="color: #666666">0</span>)
<span style="color: #AA22FF; font-weight: bold">return</span> (i <span style="color: #666666">+</span> <span style="color: #666666">1</span>, <span style="color: #666666">0</span>)
<span style="color: #AA22FF; font-weight: bold">return</span> (i, j <span style="color: #666666">+</span> <span style="color: #666666">1</span>)
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">solve</span>(<span style="color: #AA22FF">input</span>):
empty <span style="color: #666666">=</span> [[<span style="color: #666666">0</span>] <span style="color: #666666">*</span> <span style="color: #666666">9</span>] <span style="color: #666666">*</span> <span style="color: #666666">9</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">satisfy</span>(pos, sudoku):
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">getAllowedValues</span>():
conflicts <span style="color: #666666">=</span> <span style="color: #AA22FF">set</span>([ (r, c) <span style="color: #AA22FF; font-weight: bold">for</span> r <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #AA22FF">range</span>(<span style="color: #666666">9</span>) <span style="color: #AA22FF; font-weight: bold">for</span> c <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #AA22FF">range</span>(<span style="color: #666666">9</span>) <span style="color: #AA22FF; font-weight: bold">if</span>((r, c) <span style="color: #666666">!=</span> pos <span style="color: #AA22FF; font-weight: bold">and</span> conflict(pos, (r, c)))])
notallowed <span style="color: #666666">=</span> <span style="color: #AA22FF">set</span>([sudoku[r][c] <span style="color: #AA22FF; font-weight: bold">for</span> (r, c) <span style="color: #AA22FF; font-weight: bold">in</span> conflicts <span style="color: #AA22FF; font-weight: bold">if</span> sudoku[r][c] <span style="color: #666666">!=</span> <span style="color: #666666">0</span>])
<span style="color: #AA22FF; font-weight: bold">return</span> setminus(<span style="color: #AA22FF">range</span>(<span style="color: #666666">1</span>, <span style="color: #666666">10</span>), notallowed)
<span style="color: #AA22FF; font-weight: bold">if</span>(sudoku[pos[<span style="color: #666666">0</span>]][pos[<span style="color: #666666">1</span>]] <span style="color: #666666">!=</span> <span style="color: #666666">0</span>):
<span style="color: #AA22FF; font-weight: bold">if</span>(pos <span style="color: #666666">!=</span> (<span style="color: #666666">8</span>, <span style="color: #666666">8</span>)): <span style="color: #AA22FF; font-weight: bold">return</span> satisfy(nextcell(pos), sudoku)
<span style="color: #AA22FF; font-weight: bold">else</span>: <span style="color: #AA22FF; font-weight: bold">return</span> sudoku
values <span style="color: #666666">=</span> getAllowedValues()
new <span style="color: #666666">=</span> [r[:] <span style="color: #AA22FF; font-weight: bold">for</span> r <span style="color: #AA22FF; font-weight: bold">in</span> sudoku]
<span style="color: #AA22FF; font-weight: bold">for</span> value <span style="color: #AA22FF; font-weight: bold">in</span> values:
new[pos[<span style="color: #666666">0</span>]][pos[<span style="color: #666666">1</span>]] <span style="color: #666666">=</span> value
filled <span style="color: #666666">=</span> satisfy(nextcell(pos), new)
<span style="color: #AA22FF; font-weight: bold">if</span>(filled <span style="color: #666666">!=</span> empty): <span style="color: #AA22FF; font-weight: bold">return</span> filled
<span style="color: #AA22FF; font-weight: bold">return</span> empty
<span style="color: #AA22FF; font-weight: bold">return</span> satisfy((<span style="color: #666666">1</span>, <span style="color: #666666">0</span>), <span style="color: #AA22FF">input</span>)
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">printSudoku</span>(sudoku):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">'-------------------------'</span>
<span style="color: #AA22FF; font-weight: bold">for</span> i <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #AA22FF">range</span>(<span style="color: #666666">9</span>):
<span style="color: #AA22FF; font-weight: bold">for</span> j <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #AA22FF">range</span>(<span style="color: #666666">9</span>):
<span style="color: #AA22FF; font-weight: bold">if</span>(j <span style="color: #666666">==</span> <span style="color: #666666">8</span>): <span style="color: #AA22FF; font-weight: bold">print</span> sudoku[i][j]
<span style="color: #AA22FF; font-weight: bold">elif</span>(j<span style="color: #666666">%3</span> <span style="color: #666666">==</span> <span style="color: #666666">2</span>): <span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #AA22FF">str</span>(sudoku[i][j]) <span style="color: #666666">+</span> <span style="color: #BB4444">'|'</span>,
<span style="color: #AA22FF; font-weight: bold">else</span>: <span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #AA22FF">str</span>(sudoku[i][j]) <span style="color: #666666">+</span> <span style="color: #BB4444">' '</span>,
<span style="color: #AA22FF; font-weight: bold">if</span>(i<span style="color: #666666">%3</span> <span style="color: #666666">==</span> <span style="color: #666666">2</span>):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">'-------------------------'</span>
<span style="color: #AA22FF; font-weight: bold">print</span>
</pre></div>
<br />
The downloadable algorithm is here:<br />
<a href="https://docs.google.com/file/d/0B1WZgxQ3CbErdUhaR2hReFRqdFE/edit">sudoku.py</a><br />
<br />
The driver is here:<br />
<a href="https://docs.google.com/file/d/0B1WZgxQ3CbErNW5tOGR6aFllTXc/edit">sudoku driver</a><br />
<br />
An couple of examples:<br />
<a href="https://docs.google.com/file/d/0B1WZgxQ3CbErTlo1QzM2SGZXOVE/edit">example input 1</a><br />
<a href="https://docs.google.com/file/d/0B1WZgxQ3CbErN09PVmo0OFN5b3M/edit">example input 2</a><br />
<br /></div>
<div style="text-align: justify;">
Just store the above files someplace (the same place) in your machine and run as follows:<br />
<b><span style="color: #38761d;"><span style="font-family: "Courier New",Courier,monospace;">sudoku_driver input_file</span></span></b><i><br /></i></div>
<i> </i></div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com1tag:blogger.com,1999:blog-22044226.post-70635125008255847102013-04-25T11:56:00.001+05:302013-04-25T13:46:10.730+05:30A Really Open Research Publication Process<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="color: red;"><span style="color: purple;"><span style="color: black;">Follows</span></span><b><span style="color: purple;"> </span></b><span style="color: purple;"><span style="color: black;">a fabricated discussion upon an idea of an alternative research publication system that could bring about several positive changes with respect to how it is done currently:</span></span></span></div>
<ul style="text-align: justify;">
<li><span style="color: red;"><span style="color: purple;"><span style="color: black;">It could drastically reduce the delay between a research and its reporting.</span></span></span></li>
<li><span style="color: red;"><span style="color: purple;"><span style="color: black;">It could significantly bring down the barrier to publication of research in the name of quality which is a very subjective and qualitative parameter as it is measured today.</span></span></span></li>
<li><span style="color: red;"><span style="color: purple;"><span style="color: black;">It will open up the possibility of significantly increasing the activity in authoring, reading, reviewing and ranking research work.</span></span></span></li>
</ul>
<div style="text-align: justify;">
<span style="color: red;"><span style="color: purple;"><span style="color: black;">The below writeup as an approximate transcript of how I was trying to work out the idea in my own mind. So, another side intention of this is to present a new way of reporting research, in the form of dialogues, which doesn't merely presents an idea after it has already taken shape, but also hints towards how it evolved in the head of the researcher. </span></span></span></div>
<div>
<h3 style="text-align: justify;">
<span style="color: red;"><b><span style="color: purple;"> </span></b></span></h3>
<h3 style="text-align: justify;">
<span style="color: red;"><b><span style="color: purple;">The Present System</span> </b></span></h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>How is research publication done today?</b></span></div>
<div style="text-align: justify;">
A researcher writes an article for a specific conference or a journal. The article is reviewed by a group of programme committee members, mostly anonymous, who give their votes, along with review comments, on whether the article should be considered for presentation and publication in conference proceedings (or journal). Depending on that, the fate of the article is decided.</div>
<div style="text-align: justify;">
<b><br /></b></div>
<div style="text-align: justify;">
<span style="color: red;"><b>What happens if the article gets published?</b></span></div>
<div style="text-align: justify;">
A research article getting published is a matter of prestige for a researcher. It is a documented proof of the fact that the researcher has made a contribution to the existing body of knowledge that human race has.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="color: red;">What happens if the article doesn't get published?</span></b></div>
<div style="text-align: justify;">
It's a matter of disappointment for the researcher. But it's not the end of the world. The article rejected from a conference or journal can be improved and resubmitted elsewhere for publication. The comments provided by the peer reviewers are supposed to provide valuable constructive inputs to the researcher to improve his paper.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>What are the advantages of this method?</b></span></div>
<div style="text-align: justify;">
Many. As mentioned above, the very event of publication is a matter of prestige. The fact can be cited in the researcher's resume to assert the point that he has made contributions in the field of knowledge.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>Is that all?</b></span></div>
<div style="text-align: justify;">
Of course not! Publication in a well-recognised journal or conference (together let's call the 'forum') brings it to the view of the entire world. The invention or discovery of the idea thus gets timestamped, and the inventor's (discoverer's) claim to it is also permanently etched in the human history. So, no one else would be able to come up later to stake claim on the same idea.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>Then what happens?</b></span></div>
<div style="text-align: justify;">
So other researchers can't claim the work to be theirs anymore. But the reported work is read by other researchers and gives them more ideas. They can build upon your work to further the knowledge in that field.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="color: red;">You mentioned the word 'well-recognised' somewhere. What's that?</span></b></div>
<div style="text-align: justify;">
There are a large number of fora. Some are more famous -- well recognised -- than the others. That's because they have established a track record of having published research articles of high quality over time. Consequently, users of research ideas (for example, researchers and industries) are likely to refer to these fora more than others when they are looking for scholarly work useful for their purpose. Since the work published in these fora get seen by a large and/or high quality audience, researcher throng at their doorsteps to get their work published there. Competition rises. So does quality. The whole thing turns into a virtuous cycle. On the other hand, those fora who have chosen to let crappy stuff pass through their filters often lose credibility and audience. Eventually this helps weeding out waste stuff.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
<span style="color: purple;">Disadvantages of the Present System</span></h3>
<div style="text-align: justify;">
<span style="color: red;"><b>All this sounds so rosy! Then why are we here talking about an alternative model?</b></span></div>
<div style="text-align: justify;">
That'll be clear if allow to also talk about the negative aspects of the existing publishing model.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>By all means, feel free.</b></span></div>
<div style="text-align: justify;">
OK. One negative thing is the delay between the inception of an idea and its publication. It could be anything between a few months to eternity. But almost never less than a few months.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>Anything else?</b></span></div>
<div style="text-align: justify;">
Yes. And it may be a bit controversial. But all my fellows in research community must have seen this happening. These fora -- conferences and journals -- for obvious reasons tend to get more and more specialised as time passes. Usually papers are written on topics which are very niche. Mostly inaccessible to a large majority of scholars in the world. Often, even though there are millions of scholars in the world, there are almost equally numerous fields of study. Thus, it often happens that some subjects have just a handful of authorities in the entire world.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>What's the consequence?</b></span></div>
<div style="text-align: justify;">
The consequence is that every time you submit a paper, it ends up with one of those handful. Even researchers are humans. And humans have their own biases, favourites, eyesores, rivals.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>Are you pointing towards unethical conduct?</b></span></div>
<div style="text-align: justify;">
Not necessarily. But communities develop their own lingo. And the authority figures of any field often start defining what's acceptable as a valid contribution to that area, how it ought to be presented etc.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>What's wrong with that system?</b></span></div>
<div style="text-align: justify;">
In spirit, nothing. But, I think, much goes missing in the way things get implemented. There's a continuous tussle between the need to evaluate new work through a meticulous formation of credibility structures. The process has become so complex now it's not anymore possible to say if it's working.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="color: red;">Which means you can't even say if it's <i>not</i> working. Then why crib?</span></b></div>
<div style="text-align: justify;">
If you look at the output values, you will realise that I don't need to defend myself. There's severe inefficiency. If you count the number of good papers that get published, and the number of good stuff that gets done and thought, you won't find much coincidence. More and more number of students enter the profession of research with their eyes fixed on getting high impact publication. The whole thing eventually is no different from our current examination oriented education system. The trick boils down to cracking the system and fairing well in it. The way current research publication process fails in identifying good research is the same as the one in which current education system fails in identifying and nurturing intellectual talent in the society. And going by that comparison, the job this process must be doing in bringing out good research to the world for their fruitful consumption can't be very good!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>That's a very roundabout argument.</b></span></div>
<div style="text-align: justify;">
Well, to tell you the truth, I am drawing from a bunch of my own personal experiences. In my own circles, I have seen a large number of good researchers competing and failing in this process of publication. They end up dejected and depressed. On the other hand, I have seen many people who aren't necessarily all that good as researchers, but have somehow conquered a way of thinking and presenting, which keeps a steady flow of publications coming in. I know, nobody means any harm in all this. But, nevertheless, the process ends up being very unfair and ineffective. Just like our education system.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>I still don't see anything unfair. Is there anything wrong happening over here?</b></span></div>
<div style="text-align: justify;">
There are many researchers who start out very naive. Which is fine. They should pick up ways of working, learning, discovering, inventing and sharing their work as they go. Instead, the pressure of getting their work published puts a similar pressure on their minds which the fear of exams does on many. Often the fear is crippling for a large number of researchers. They aren't necessarily worse researchers. But they fear the prospect of being evaluated and written off. They fear the threat of not being allowed to <i>belong</i> to the community. May be, they have a weakness. But the weakness isn't scientific. It's psychological. The problem should be addressed instead of being dismissed as an inevitability, simply because the talent it is causing the society to lose out upon is sizable.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
<span style="color: purple;">The Proposed System</span></h3>
<div style="text-align: justify;">
<span style="color: red;"><b>OK. Enough of picking faults. How do you think, all this should work?</b></span></div>
<div style="text-align: justify;">
I feel, there are two things which get mixed up in the given model of research publication. One is <i>reporting</i> your work. And the other is <i>earning credibility</i> for your work. Inability to earn credibility shouldn't deter you from reporting your work. The basic idea of our alternative model of reporting research tries to decouple these two things. We say, reporting must happen immediately at any rate. And the moment you do it, you are in. All threats of ever being disowned, ignored and persecuted by the community are annihilated. Now comes the other part: of earning credibility, of doing something influential. Well, that's important too. But let that happen subsequently. In fact, ideally, you don't need to earn any credibility. It should come to you for your good work. Without your having to work separately for it. You focus on doing good work. Report it as soon as you have it ready to report. And let accolades flow in by themselves.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>But how, unless you publish it somewhere where people are looking for good work?</b></span></div>
<div style="text-align: justify;">
Here's where I feel technology today is ripe enough to play a part. Google takes a bunch of keywords and pulls out anything you are looking for from the Web. I am sure that Google, or whatever engine that runs underneath, is capable enough to tell you what relates to your work. If you are writing an article, you anyway use Google to fish out related papers, don't you?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>What's going to change?</b></span></div>
<div style="text-align: justify;">
Consider the scenario today. You work on something. You write it up in the form of a paper. And you go to these ACM, IEEE journals or all the other equivalent places for other fields. All this while, you are afraid that the hard-disc of your computer will be the grave of your paper if. That fear shapes your approach to the whole thing. You locate the influential people of your field. You adjust the tone of your paper to resemble the lingo these people have tacitly certified for that field. You take care not to say something that challenges their authority. Just novel enough so that it catches <i>their</i> attention. You have to be politically correct. In our so-called scientific world, you end caring too much about the politics of publication.</div>
<div style="text-align: justify;">
Now consider this other model. You just write it up. Put it up on the web for anyone willing to read. Now, it's in the interest of the ACMs and IEEEs to find your work out if it's good. And they have all the technologies to do that for them. They search the web. They do data mining. They do machine learning. They do whatever they want. But hell they must do a good job when someone asks them to feature a bunch of relevant articles on the web using some keywords. ACMs and IEEEs don't publish your work anymore. They just recommend.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>They close their businesses, right?</b></span></div>
<div style="text-align: justify;">
I don't know. I don't think so. Recommending good stuff will be a big thing. And then there are ads and promotions. The whole business model will probably change. What will go is this big difference between publishing and not publishing which comes in the way of a researchers primary responsibility to the society: reporting his work.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Today, choosing the right forum to publish your work is a big thing. You get too ambitious, and you get rejections. You get too modest, and your work is tagged for oblivion forever. And each time either happens, you run a little run out of little bit more steam. Remember that in the current model, publication can happen only once. And publishing in a wrong place merely makes sure that your work will never probably be looked at with interest.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
What should happen instead is that there ought to be only one publication platform: the Web. And the probability of a work being read by an interested audience shouldn't dwindle with time just because it's first weekend revenue didn't cross a mark. Research works are not feature films. They are potentially for the eternity. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>So what's the difference? What happened earlier between publication and non-publication will now happen between credibility and non-credibility.</b></span></div>
<div style="text-align: justify;">
I agree. This model we propose is in no way a socialistic model swearing by equal wealth etc. And if research wants to be of any value, it must come with some way to measure its quality. However, understand that there's this huge artificially created chasm created by the current system of research publication: the chasm between publication and non-publication. You are either this way or that way. And the fear of falling into the chasm will keep a large number of people from even trying. On the other other hand, we propose to fill up this chasm. You do your best. And your rewards are somewhere in a <i>continuous</i> space depending on the quality of your work, your good luck, influence, whatever. But surely, there's no disgrace associated with trying and failing. There's only one failure in this model: that of not trying. Rest of it is all degree of success. And that, I agree, can vary as wildly as it does in the present day research world.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>What gives you the confidence that what you are talking about is realistic and not a figment of your imagination?</b></span></div>
<div style="text-align: justify;">
I give you a few examples. Consider blogosphere. Today everyone blogs. There's immense crowding out there. But there are some blogs which are popular. And there are those which no one reads. Since there's Google to help us out, searching relevant online articles isn't such big headache, even if it may require some bit of work. Publishing a blog article is such a low entry barrier job: just a push of a button! But getting hits. Of course, that's a very different ball game. And people do play all sorts of silly games there. Links and backlinks. Guest posts. Ads. Promotions. It's again a <i>you scratch me and I scratch you</i> culture. But, you continue to publish, because there's no cost associated with it. And the only game that seems to really win is the game of quality. Put up good stuff, and you get hits.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Another example is of open source software. People write programs in thousands everyday. It's a breeze to upload your code. But not all of them are as popular as Linux or Eclipse or Apache. There's not such a big deal created out of whether you have contributed anything to the open community or not. But making a hugely popular piece of software is a big deal.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Yet another example is from one of the biggest computer scientists of our times: Edger Dijkstra. He wasn't a very keen publisher in the regular sense of the word. But he used to write profusely. And used to distribute his work among his peers. That was his way of reporting his work. All those notes which Dijkstra used to number as EWD #### are now archived in the University of Texas Austin website.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>Now there's been only one Dijkstra in the history. And Dijkstra could afford to be unconventional. Doesn't mean everyone can.</b></span></div>
<div style="text-align: justify;">
I understand. I am not talking about what we can currently afford, but what's the best way to do things. The collection has all sorts of things: papers, letters, little rough notes, rebuttals... Dijktra never distinguished between them, I suppose. But the readers do, I am sure. I would bet my head on that some of the EWDs receive more hits than some others. The distinction is left to the reader, not on a broker. The need of brokers and agents is gradually becoming obsolete even in real estate. We have the Web and automatic recommender systems to do that job for us.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: left;">
<span style="color: purple;">Wrap Up</span></h3>
<div style="text-align: justify;">
<span style="color: red;"><b>OK. Can we have a quick summary of this new system of research publication?</b></span></div>
<div style="text-align: justify;">
Well. I will just sketch it out. You have an idea you wish to share. Well, write it up and put it out on the web. The information retrieval engines on the Web get down to work immediately. They fetch out links on other published stuff that may have a bearing on your work. It's your wish to notice or ignore them. However, it's in your benefit to notice those recommendations. The more you analyse, the better you will be able to place your work in a continuously evolving semantic web of related research.</div>
<div style="text-align: justify;">
People turn up at your page. They read it if they want. They rate it if they want. They provide comments if they want. The recommender system again comes to your rescue in sorting these feedback comments in terms of their relevance, importance, quality and potential impact. You work on the feedback comments and update your work to your heart's content. That way, a research paper isn't something done away with. It's an ever evolving working document. Hopefully you acknowledge the contribution of any review comment in any improvement that you are able to incorporate due to them.</div>
<div style="text-align: justify;">
Someone in ACM or IEEE may want to feed all this activity happening in the semantic neighbourhood of your article to compute some sort of an impact factor for it. Going forward, someone may decide to feature your article highly based on this impact factor.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: red;"><b>Got it. And what, in very brief, would we gain from this change?</b></span></div>
<div style="text-align: justify;">
More research will get reported. No thoughts goes wasted. No work goes unreported.</div>
<div style="text-align: justify;">
The latency between a work and publication will almost disappear. </div>
<div style="text-align: justify;">
More reviews will happen.</div>
<div style="text-align: justify;">
The ratings of a scholarly work will depend on automated algorithms, not on the private judgement of a select few.</div>
<div style="text-align: justify;">
A research missing an initial wave of popularity will not be doomed to an eternity of oblivion. It may spring back to popularity ages after it was reported if someone gets interested, because searching will be done by machines. And machines don't forget as easily as we humans do.</div>
<div style="text-align: justify;">
Just like bloggers, researchers will realise that the only surefire way to popularity is quality. They will direct their efforts into doing good work and writing well, not on knocking at the doors of brokers and agents.</div>
<div style="text-align: justify;">
There is plenty of work, good work, happening out there. It is not always backed up by timeliness, influence, alignment with `important' work, or some other technical reason. And it thus loses out. However, immediate publication makes sure it will probably be seen by an interested audience someday. At least the probability isn't ruled out. Our new model aims to give such work their much needed another chance.</div>
<div style="text-align: justify;">
Isn't that quite a handful? :)</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
<span style="color: purple;">Postscript</span></h3>
<div style="text-align: justify;">
<b><span style="color: blue;"><i>The above article is itself an example of how I think this new system of research publication should be implemented. I got an idea. I wrote it down in an informal tone. As of now, I stake claim only on this article, not on the idea. If I am fortunate, it may actually turn out to be a novel idea. But now, no one can steal it from me. But, if it happens to be a novel idea indeed, I put my faith on the ever-improving information retrieval technology to make sure that any other claim to coining the same idea will eventually be detected.</i></span></b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="color: blue;"><i>The above work is rather raw. I wanted to get it out the moment it occurs. I want to claim it to be my own, but I don't want to depend on keeping it secret for some period while I work on it with the fear that someone else may be faster than me in cashing it out. I believe that if someone else gets inspired by this idea and gets it into a shape before I can, it's perfectly OK. But I also promise that I will keep working on it as and when I have a way to improve it, either through my own ideas, or through those which my readers, or the search technology provide. In the latter case, I pledge to acknowledge the same.</i></span></b></div>
<div style="text-align: justify;">
<b><span style="color: blue;"><i><br /></i></span></b></div>
<div style="text-align: justify;">
<span style="color: blue;"><b><i>If the above inspires you in any of your work, I invite you to cite it.</i></b></span></div>
<div style="text-align: justify;">
<br /></div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com4tag:blogger.com,1999:blog-22044226.post-8249710944609228472013-04-01T17:29:00.002+05:302013-04-03T10:16:02.750+05:30Showing the Lady Her Right Place<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: center;">
<a href="http://commons.wikimedia.org/wiki/File%3AEight_queens.png" title="By FlankerFF (Own work) [CC-BY-SA-3.0-2.5-2.0-1.0 (http://creativecommons.org/licenses/by-sa/3.0) or GFDL (http://www.gnu.org/copyleft/fdl.html)], via Wikimedia Commons"><img alt="Eight queens" src="//upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Eight_queens.png/512px-Eight_queens.png" style="cursor: move;" width="512" /></a>
</div>
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
The <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle">eight queen</a> puzzle is a well-known problem having been used in teaching algorithms design techniques and programming. The problem is simple: place 8 queens and place them on a chess board such that none of them is in the line of attack of any other. Does such a solution exist? Yes. 92 of them, apparently (keep reading).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In fact, finding a solution manually doesn't turn out to be too hard, but may be an interesting exercise if you are interested in that kind of puzzles. But our objective here is to find an algorithmic solution. That is, to write an algorithm that finds us the solution to the problem. Again, it's a solved problem. The algorithm is all there. Nothing new. But implementing it was a challenge nevertheless.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let me try and summarise the approach as follows:</div>
<div style="text-align: justify;">
Firstly, a bit of staring at the problem will reveal that each queen must have her own row (column).</div>
<div style="text-align: justify;">
Consequently, a succinct representation of a solution would be a list of numbers corresponding to the column in which the queen is placed, the knowledge that they are placed in separate rows being implicit.</div>
<div style="text-align: justify;">
For example, to represent the following solution:</div>
<br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | | | X | | | | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | | | | | X | | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | | | | | | | X | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | | X | | | | | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| X | | | | | | | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | | | | | | X | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | | | | X | | | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;">| | X | | | | | | | </span><br />
<span style="font-family: Courier New, Courier, monospace;">-----------------------------------------</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<div style="text-align: justify;">
<span style="font-family: Courier New, Courier, monospace;"> we just say:</span></div>
<br />
<div style="text-align: justify;">
<span style="font-family: Courier New, Courier, monospace;"><b>[3, 5, 7, 2, 0, 6, 4, 1]</b></span></div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
Now, for some bit of notations. Let's say we have come up with a positioning <i>pos</i>. We say, <i>satisfy(pos, i)</i>, when the sublist of <i>pos</i> from <i>i</i> to 7 (denoted by <i>pos[i:]</i>) forms a satisfying solution, i.e. no pair of elements in <i>pos[i:]</i> attack, or <i>conflict</i> with, each other. The above very <i>satisfactory</i> condition can be described declaratively as follows:</div>
</div>
<div style="text-align: center;">
<div style="text-align: justify;">
<i><b>for i < 7, satisfy(pos, i) <=> satisfy(pos, i + 1) and for all j in [i + 1...7], conflict(pos[i], pos[j]) = false</b></i></div>
</div>
<div style="text-align: left;">
<div style="text-align: justify;">
<br />
<div style="text-align: center;">
<div style="text-align: justify;">
<i><b>for
i = 7, satisfy(pos, i)</b></i></div>
</div>
<br />
which means <i>satisfy(pos, i) </i>is true if and only if <i>satisfy(pos, i+1)</i> is true and the <i>i</i>th element of pos (<i>pos[i])</i> doesn't conflict with any of the subsequent elements. And the recursion bottoms up with <i>i</i> = 7, for which <i>satisfy(pos, i)</i> is true no matter what.<br />
<br />
That's all the notation I can bear before I really dive into the algorithm, which is what I really want to present. But the above also pretty completes the conceptual groundwork for writing the algorithm, which is nearly a lexical replication of the above thought. And that should convince you why recursive thinking is such a good way of designing algorithms: because it allows you to write your algorithms as declaratively as possible. What may have appeared to be very complex a phenomenon if thought of as a procedure, becomes ridiculously simple if thought of as a condition to be satisfied.</div>
</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #aa22ff; font-weight: bold;">import</span> <span style="color: blue; font-weight: bold;">random</span>
<span style="color: #aa22ff; font-weight: bold;">from</span> <span style="color: blue; font-weight: bold;">counter</span> <span style="color: #aa22ff; font-weight: bold;">import</span> <span style="color: #666666;">*</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">conflict</span>(a, b, diff):
<span style="color: #aa22ff; font-weight: bold;">return</span> (a <span style="color: #666666;">==</span> b) <span style="color: #aa22ff; font-weight: bold;">or</span> <span style="color: #aa22ff;">abs</span>(a <span style="color: #666666;">-</span> b) <span style="color: #666666;">==</span> diff
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">satisfy</span>(lst):
<span style="color: #aa22ff; font-weight: bold;">if</span>(<span style="color: #aa22ff;">len</span>(lst) <span style="color: #666666;">==</span> <span style="color: #666666;">1</span>):
<span style="color: #aa22ff; font-weight: bold;">return</span> <span style="color: #aa22ff;">True</span>
<span style="color: #aa22ff; font-weight: bold;">if</span>(satisfy(lst[<span style="color: #666666;">1</span>:])):
<span style="color: #aa22ff; font-weight: bold;">for</span> i <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #aa22ff;">range</span>(<span style="color: #666666;">1</span>, <span style="color: #aa22ff;">len</span>(lst)):
<span style="color: #aa22ff; font-weight: bold;">if</span>(conflict(lst[<span style="color: #666666;">0</span>], lst[i], i)):
<span style="color: #aa22ff; font-weight: bold;">return</span> <span style="color: #aa22ff;">False</span>
<span style="color: #aa22ff; font-weight: bold;">return</span> <span style="color: #aa22ff;">True</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">solve</span>(pos):
inc <span style="color: #666666;">=</span> makeCounter_rec(<span style="color: #666666;">8</span>)
<span style="color: #aa22ff; font-weight: bold;">while</span>(<span style="color: #aa22ff; font-weight: bold;">not</span> satisfy(pos)):
pos <span style="color: #666666;">=</span> inc(pos)
<span style="color: #aa22ff; font-weight: bold;">return</span> pos
</pre>
</div>
<div style="text-align: left;">
<br />
<div style="text-align: justify;">
The function satisfy works recursively, calling itself as it goes down the board, one row at a time looking for smaller and smaller partial solutions.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Did you notice that this algorithm uses a base-8 counter to sweep through the search space of all solutions (which is 8 raised to 8)? And that should answer any doubt as to the practical application of the counter program that I presented <a href="http://sujitkc-techbits.blogspot.in/2013/03/counter-in-python.html">here</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You want to see the above running? Just add the below main function to the above code.</div>
<br /></div>
<div>
<i><br /></i></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">if</span> __name__ <span style="color: #666666;">==</span> <span style="color: #bb4444;">'__main__'</span>:
sol <span style="color: #666666;">=</span> solve([random<span style="color: #666666;">.</span>randint(<span style="color: #666666;">0</span>, <span style="color: #666666;">7</span>)<span style="color: #666666;">%8</span> <span style="color: #aa22ff; font-weight: bold;">for</span> i <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #aa22ff;">range</span>(<span style="color: #666666;">8</span>) ])
<span style="color: #aa22ff; font-weight: bold;">print</span> sol
</pre>
</div>
<div style="text-align: left;">
<br />
<br />
<div style="text-align: justify;">
Want to see a pretty printed solution? Add the below function somewhere in the above code:</div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">printSolution</span>(sol):
hline <span style="color: #666666;">=</span> <span style="color: #bb4444;">'-----------------------------------------'</span>
<span style="color: #aa22ff; font-weight: bold;">print</span> hline
<span style="color: #aa22ff; font-weight: bold;">for</span> pos <span style="color: #aa22ff; font-weight: bold;">in</span> sol:
<span style="color: #aa22ff; font-weight: bold;">print</span> <span style="color: #bb4444;">'| '</span>,
<span style="color: #aa22ff; font-weight: bold;">for</span> i <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #aa22ff;">range</span>(<span style="color: #666666;">8</span>):
<span style="color: #aa22ff; font-weight: bold;">if</span>(i <span style="color: #666666;">!=</span> pos):
<span style="color: #aa22ff; font-weight: bold;">print</span> <span style="color: #bb4444;">' | '</span>,
<span style="color: #aa22ff; font-weight: bold;">else</span>:
<span style="color: #aa22ff; font-weight: bold;">print</span> <span style="color: #bb4444;">'X | '</span>,
<span style="color: #aa22ff; font-weight: bold;">print</span>
<span style="color: #aa22ff; font-weight: bold;">print</span> hline
</pre>
</div>
...and add the following line in your main function shown above:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> printSolution(sol)
</pre>
</div>
<br />
If you want to go ahead and find all the solutions, here's the function and the modified main function:<br />
<br />
<br />
<div>
<br /></div>
</div>
</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">solveAll</span>():
inc <span style="color: #666666;">=</span> makeCounter_rec(<span style="color: #666666;">8</span>)
solutions <span style="color: #666666;">=</span> []
pos <span style="color: #666666;">=</span> [<span style="color: #666666;">0</span>] <span style="color: #666666;">*</span> <span style="color: #666666;">8</span>
n <span style="color: #666666;">=</span> <span style="color: #666666;">0</span>
<span style="color: #aa22ff; font-weight: bold;">while</span>(<span style="color: #aa22ff;">True</span>):
solution <span style="color: #666666;">=</span> solve(pos)
<span style="color: #aa22ff; font-weight: bold;">if</span>(solution <span style="color: #aa22ff; font-weight: bold;">in</span> solutions):
<span style="color: #aa22ff; font-weight: bold;">break</span>
<span style="color: #aa22ff; font-weight: bold;">else</span>:
<span style="color: #aa22ff; font-weight: bold;">print</span> solution
solutions<span style="color: #666666;">.</span>append(solution)
pos <span style="color: #666666;">=</span> inc(solution)
n <span style="color: #666666;">=</span> n <span style="color: #666666;">+</span> <span style="color: #666666;">1</span>
<span style="color: #aa22ff; font-weight: bold;">print</span> <span style="color: #bb4444;">'found '</span> <span style="color: #666666;">+</span> <span style="color: #aa22ff;">str</span>(n) <span style="color: #666666;">+</span> <span style="color: #bb4444;">' solutions.'</span>
<span style="color: #aa22ff; font-weight: bold;">return</span> solutions
</pre>
</div>
<br />
<div style="text-align: justify;">
If you print out the output of this function, after running for a couple of minutes, it will show you all the solutions of the problem. As mentioned above, they turn out to be 92 in number.</div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-18660911792933569922013-03-29T12:23:00.004+05:302013-03-30T11:29:51.056+05:30Counter in Python<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Presenting here two implementations of a counter.
</div>
<h3 style="text-align: justify;">
What does the counter do?</h3>
<div>
<div style="text-align: justify;">
Given a base <i>n, </i>this counter will allow you to do base <i>n</i> counting. What's base-<i>n</i> counting? There are <i>n</i> digits: 0, 1, 2, ..., <i>n - </i>1. At each place, the digit changes from <i>i </i>to <i>i + </i>1 if <i>i < n - </i>1, and to 0 if <i>i = n - </i>1. This change happens when the change at that place is <i>triggered.</i> And when does the trigger happen. For the unit's place, the trigger happens whenever the function is called. For all other places, the trigger happens when the previous place's digit rolls over from <i>n</i> - 1 to 0. That's all. That's a bit technical description for the simple act of counting we learn in our KG. But if we want to implement the counter, it needs to be written in this algorithmic language.</div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
A 3-bit binary (base-2) counter goes like:</div>
</div>
<div>
<div style="text-align: justify;">
<span style="font-family: Courier New, Courier, monospace;"><b>000, 001, 010, 011, 100, 101, 110, 111, 000, ...</b></span></div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A 2-digit base-4 counter would count as:</div>
<div style="text-align: justify;">
<span style="font-family: Courier New, Courier, monospace;"><b>00, 01, 02, 03, 10, 11, 12, 13, 20, 21, 22, 23, 30, 31, 32, 33, 00, ...</b></span></div>
<br />
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace; font-weight: bold;"><br /></span></div>
<div style="text-align: justify;">
What do we usually do in day-to-day counting? decimal (base-10) counting.</div>
<br />
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
How do we Use the Counter Program?</h3>
<div>
<div style="text-align: justify;">
<br /></div>
<h3>
<div style="font-size: medium; font-weight: normal;">
<div style="text-align: justify;">
Below is a piece of code that could be used to implement a binary counter on a 3-bit number.</div>
</div>
<div style="font-size: medium;">
</div>
</h3>
</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">base <span style="color: #666666;">=</span> <span style="color: #666666;">2</span>
inc <span style="color: #666666;">=</span> makeCounter_iter(base)
n <span style="color: #666666;">=</span> [<span style="color: #666666;">0</span>, <span style="color: #666666;">0</span>, <span style="color: #666666;">0</span>]
<span style="color: #aa22ff; font-weight: bold;">print</span> n
<span style="color: #aa22ff; font-weight: bold;">for</span> i <span style="color: #aa22ff; font-weight: bold;">in</span> <span style="color: #aa22ff;">range</span>(base <span style="color: #666666;">**</span> <span style="color: #aa22ff;">len</span>(n)):
n <span style="color: #666666;">=</span> inc(n)
<span style="color: #aa22ff; font-weight: bold;">print</span> n
</pre>
</div>
<div>
<br /></div>
<div style="text-align: justify;">
The <span style="font-family: Courier New, Courier, monospace;"><b>inc(n)</b></span> gives <span style="font-family: Courier New, Courier, monospace;"><b>n + 1</b></span> in the base n number system which is pre-decided while instantiating the counter:</div>
<div style="font-size: medium;">
<div style="text-align: justify;">
<span style="font-family: 'Courier New', Courier, monospace;">base = 2</span></div>
</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">makeCounter_iter</span>(base):
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">isZero</span>(lst): <span style="color: #aa22ff; font-weight: bold;">return</span> lst <span style="color: #666666;">==</span> [<span style="color: #666666;">0</span>] <span style="color: #666666;">*</span> <span style="color: #aa22ff;">len</span>(lst)
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">inc</span>(num):
<span style="color: #aa22ff; font-weight: bold;">if</span>(<span style="color: #aa22ff;">len</span>(num) <span style="color: #666666;">></span> <span style="color: #666666;">1</span>):
rem <span style="color: #666666;">=</span> inc(num[:<span style="color: #666666;">-1</span>])
<span style="color: #aa22ff; font-weight: bold;">if</span>(isZero(rem)):
<span style="color: #aa22ff; font-weight: bold;">if</span>(num[<span style="color: #666666;">-1</span>] <span style="color: #666666;">==</span> base <span style="color: #666666;">-</span> <span style="color: #666666;">1</span>): rem<span style="color: #666666;">.</span>extend([<span style="color: #666666;">0</span>])
<span style="color: #aa22ff; font-weight: bold;">else</span>: rem<span style="color: #666666;">.</span>extend([num[<span style="color: #666666;">-1</span>] <span style="color: #666666;">+</span> <span style="color: #666666;">1</span>])
<span style="color: #aa22ff; font-weight: bold;">else</span>: rem<span style="color: #666666;">.</span>extend([num[<span style="color: #666666;">-1</span>]])
<span style="color: #aa22ff; font-weight: bold;">return</span> rem
<span style="color: #aa22ff; font-weight: bold;">else</span>:
new <span style="color: #666666;">=</span> [<span style="color: #666666;">0</span>]
<span style="color: #aa22ff; font-weight: bold;">if</span>(<span style="color: #aa22ff; font-weight: bold;">not</span> num[<span style="color: #666666;">0</span>] <span style="color: #666666;">==</span> base <span style="color: #666666;">-</span> <span style="color: #666666;">1</span>): new[<span style="color: #666666;">0</span>] <span style="color: #666666;">=</span> num[<span style="color: #666666;">0</span>] <span style="color: #666666;">+</span> <span style="color: #666666;">1</span>
<span style="color: #aa22ff; font-weight: bold;">return</span> new
<span style="color: #aa22ff; font-weight: bold;">return</span> inc
</pre>
</div>
</div>
<br />
Now follows the recursive version.
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #f8f8f8; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">makeCounter_rec</span>(base):
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">incDigit</span>(num, pos):
new <span style="color: #666666;">=</span> num[:]
<span style="color: #aa22ff; font-weight: bold;">if</span>(num[pos] <span style="color: #666666;">==</span> base <span style="color: #666666;">-</span> <span style="color: #666666;">1</span>):
new[pos] <span style="color: #666666;">=</span> <span style="color: #666666;">0</span>
<span style="color: #aa22ff; font-weight: bold;">if</span>(pos <span style="color: #666666;"><</span> <span style="color: #aa22ff;">len</span>(num) <span style="color: #666666;">-</span> <span style="color: #666666;">1</span>): <span style="color: #aa22ff; font-weight: bold;">return</span> incDigit(new, pos <span style="color: #666666;">+</span> <span style="color: #666666;">1</span>)
<span style="color: #aa22ff; font-weight: bold;">else</span>:
new[pos] <span style="color: #666666;">=</span> new[pos] <span style="color: #666666;">+</span> <span style="color: #666666;">1</span>
<span style="color: #aa22ff; font-weight: bold;">return</span> new
<span style="color: #aa22ff; font-weight: bold;">def</span> <span style="color: #00a000;">inc</span>(num): <span style="color: #aa22ff; font-weight: bold;">return</span> incDigit(num, <span style="color: #666666;">0</span>)
<span style="color: #aa22ff; font-weight: bold;">return</span> inc
</pre>
</div>
<h3 style="text-align: left;">
</h3>
<div style="text-align: left;">
<div style="text-align: justify;">
Any day, the recursive implementation trumps over the iterative version. The recursive implementation is smaller and more readable because it's very like the way the process of counting is formally defined in the beginning of the article.</div>
</div>
<h3 style="text-align: justify;">
Functional Programming Flavour
</h3>
<div>
<div style="text-align: justify;">
One thing to notice is that we use functional language aspect of python. The function <span style="font-family: Courier New, Courier, monospace;"><b>makeCounter</b></span> (<span style="font-family: Courier New, Courier, monospace;"><b>makeCounter_iter</b></span> and <span style="font-family: Courier New, Courier, monospace;"><b>makeCounter_rec</b></span>) is a <i><a href="http://en.wikipedia.org/wiki/Higher-order_function">higher order function</a></i> that returns another function <span style="font-family: Courier New, Courier, monospace;">inc</span>, the increment function. Also, the value of base is fixed in the creation context of <span style="font-family: Courier New, Courier, monospace;">inc</span> inside the <span style="font-family: Courier New, Courier, monospace;">makeCounter</span> function. The <span style="font-family: Courier New, Courier, monospace;">inc</span> function uses the value of <span style="font-family: Courier New, Courier, monospace;">base</span> at a place in the code which is typically outside the lexical scope where <span style="font-family: Courier New, Courier, monospace;">base</span> is defined. This is known as the <i>closure </i>feature of <a href="http://en.wikipedia.org/wiki/Functional_programming">functional programming</a>. In a typical <i><a href="http://en.wikipedia.org/wiki/Object_oriented">object-oriented</a></i> scenario, this effect is achieved using the <i><a href="http://en.wikipedia.org/wiki/Builder_pattern">builder design pattern</a></i>.</div>
</div>
</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-6410593967972436422013-03-20T11:32:00.001+05:302013-03-31T17:18:18.509+05:30Backup Script in Python<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">Sometime back I put out a <a href="http://sujitkc-techbits.blogspot.in/2012/07/script-for-backing-up.html">backup script</a> written in bash shell script. After having used it successfully for a while, I decided to re-write it in Python. Several reasons:</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">It had bugs. The bugs were known (it's not as if it's a million lines of code). But I couldn't get rid of them. Simply because I could never understand the semantics of the language well enough to write what I wanted to, exactly.</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">On the other hand, Python has this elegant, readable, syntax. The things do as you would except them to. Compilation is not minimal as in the case of shell. So, it throws up errors when there are any, and you can catch them. Consequently, the python code that I came up with is smaller and more readable.</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">My initial experience in using it is that it seems to run quicker too. But I can't vouch for that.</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">I managed the re-implementation in a couple of hours, as opposed to probably several days worth of effort (with gaps) that went into the shell-script. Part of the reason was of-course that the design was absolutely clear in my mind as I had already done the implementation earlier. So, I don't repent having spent my effort building my first prototype and throwing it away. But another part is (please don't read this sentence if you are a shell-script fan): Python is more modern and better than shell-script.</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<span style="font-family: Georgia, Times New Roman, serif;">Here are the main features:</span><br />
<br />
<ol>
<li><span style="font-family: Georgia, 'Times New Roman', serif;"><span style="color: purple;">It will make the contents under <i>sourceRoot</i> identical to <i>destinationRoot</i>.</span></span></li>
<li><span style="font-family: Georgia, 'Times New Roman', serif;"><span style="color: purple;">It will do selective copying. Means, it will copy a file anywhere inside <i>sourceRoot</i> to the right place inside <i>destinationRoot</i> if and only if there's no corresponding copy in<i> destinationRoot</i>, or destination copy is found to be older than the source copy.</span></span></li>
<li><span style="font-family: Georgia, 'Times New Roman', serif;"><span style="color: purple;">It allows you to specify any subdirectory of<i> sourceRoot</i> that you want to backup. This is useful when you know that changes since the last backup are localised to a particular location, and you don't want to waste time scanning other locations. For large data, this saves a lot of time.</span></span></li>
</ol>
<br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">So, I invite you to prefer this new one to the old one. It does everything that the shell-script did. And it doesn't have the old bugs. So here goes the code:</span></div>
<br />
<br /></div>
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-style: italic">#!/usr/bin/python</span>
<span style="color: #AA22FF; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">os</span>
<span style="color: #AA22FF; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">sys</span>
<span style="color: #AA22FF; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">shutil</span>
<span style="color: #AA22FF; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">os</span> <span style="color: #AA22FF; font-weight: bold">import</span> <span style="color: #666666">*</span>
<span style="color: #AA22FF; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">string</span> <span style="color: #AA22FF; font-weight: bold">import</span> <span style="color: #666666">*</span>
sourceRoot <span style="color: #666666">=</span> <span style="color: #BB4444">""</span>; <span style="color: #008800; font-style: italic"># fill in appropriate value</span>
destinationRoot <span style="color: #666666">=</span> <span style="color: #BB4444">""</span>; <span style="color: #008800; font-style: italic"># fill in appropriate value</span>
backupDirectoryName <span style="color: #666666">=</span> <span style="color: #BB4444">""</span>; <span style="color: #008800; font-style: italic"># fill in appropriate value</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">isSubdirectory</span>(dir1, dir2):
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF">len</span>(dir1) <span style="color: #666666"><</span> <span style="color: #AA22FF">len</span>(dir2)):
<span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">False</span>
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> dir1[:<span style="color: #AA22FF">len</span>(dir2)] <span style="color: #666666">==</span> dir2):
<span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">False</span>
<span style="color: #AA22FF; font-weight: bold">return</span> <span style="color: #AA22FF">True</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">getRelativeName</span>(dirName, root):
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> isSubdirectory(dirName, root)):
<span style="color: #AA22FF; font-weight: bold">raise</span> <span style="color: #D2413A; font-weight: bold">Exception</span>(dirName <span style="color: #666666">+</span> <span style="color: #BB4444">' is not a subdirectory of '</span> <span style="color: #666666">+</span> root)
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF">len</span>(dirName) <span style="color: #666666"><</span> <span style="color: #AA22FF">len</span>(root)):
<span style="color: #AA22FF; font-weight: bold">return</span> dirName
<span style="color: #AA22FF; font-weight: bold">if</span>(root[<span style="color: #666666">-1</span>] <span style="color: #666666">==</span> <span style="color: #BB4444">'/'</span>):
<span style="color: #AA22FF; font-weight: bold">return</span> dirName[<span style="color: #AA22FF">len</span>(root):]
<span style="color: #AA22FF; font-weight: bold">else</span>:
<span style="color: #AA22FF; font-weight: bold">return</span> dirName[<span style="color: #AA22FF">len</span>(root) <span style="color: #666666">+</span> <span style="color: #666666">1</span>:]
<span style="color: #008800; font-style: italic"># always provide the full path name</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">backupDir</span>(dirName):
<span style="color: #AA22FF; font-weight: bold">global</span> sourceRoot
<span style="color: #008800; font-style: italic"># print 'going into directory: ' + dirName</span>
relativePathName <span style="color: #666666">=</span> getRelativeName(dirName, sourceRoot)
currentDestinationDir <span style="color: #666666">=</span> destinationRoot <span style="color: #666666">+</span> <span style="color: #BB4444">'/'</span> <span style="color: #666666">+</span> relativePathName
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>exists(currentDestinationDir)):
os<span style="color: #666666">.</span>mkdir(currentDestinationDir)
allnames <span style="color: #666666">=</span> listdir(dirName)
<span style="color: #AA22FF; font-weight: bold">for</span> name <span style="color: #AA22FF; font-weight: bold">in</span> allnames:
sourceName <span style="color: #666666">=</span> dirName <span style="color: #666666">+</span><span style="color: #BB4444">'/'</span> <span style="color: #666666">+</span> name
<span style="color: #AA22FF; font-weight: bold">if</span>(os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>isfile(sourceName)):
destinationFileName <span style="color: #666666">=</span> currentDestinationDir <span style="color: #666666">+</span> <span style="color: #BB4444">'/'</span> <span style="color: #666666">+</span> name
<span style="color: #AA22FF; font-weight: bold">if</span>((<span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>exists(destinationFileName)) <span style="color: #AA22FF; font-weight: bold">or</span> (os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>getmtime(sourceName) <span style="color: #666666">></span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>getmtime(destinationFileName))):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">'copying '</span> <span style="color: #666666">+</span> sourceName <span style="color: #666666">+</span> <span style="color: #BB4444">' to '</span> <span style="color: #666666">+</span> currentDestinationDir <span style="color: #666666">+</span> <span style="color: #BB4444">' ...'</span>
shutil<span style="color: #666666">.</span>copyfile(sourceName, destinationFileName)
<span style="color: #008800; font-style: italic"># else:</span>
<span style="color: #008800; font-style: italic"># print 'not copying ' + sourceName + ' to ' + currentDestinationDir + ' ...'</span>
<span style="color: #AA22FF; font-weight: bold">elif</span>(os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>isdir(sourceName)):
backupDir(sourceName)
<span style="color: #AA22FF; font-weight: bold">else</span>:
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">'Something wrong with '</span> <span style="color: #666666">+</span> name
<span style="color: #008800; font-style: italic"># print 'going out of directory: ' + dirName</span>
<span style="color: #008800; font-style: italic"># path is relative to root, not an absolute path</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">createPath</span>(path, root):
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">getPathName</span>(path):
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF">len</span>(path) <span style="color: #666666">></span> <span style="color: #666666">1</span>):
<span style="color: #AA22FF; font-weight: bold">return</span> path[<span style="color: #666666">0</span>] <span style="color: #666666">+</span> <span style="color: #BB4444">'/'</span> <span style="color: #666666">+</span> getPathName(path[<span style="color: #666666">1</span>:])
<span style="color: #AA22FF; font-weight: bold">return</span> path[<span style="color: #666666">0</span>]
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>exists(root <span style="color: #666666">+</span> <span style="color: #BB4444">'/'</span> <span style="color: #666666">+</span> getPathName(path))):
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF">len</span>(path) <span style="color: #666666">></span> <span style="color: #666666">1</span>):
createPath(path[:<span style="color: #666666">-1</span>], root)
os<span style="color: #666666">.</span>mkdir(root <span style="color: #666666">+</span> <span style="color: #BB4444">'/'</span> <span style="color: #666666">+</span> getPathName(path))
<span style="color: #008800; font-style: italic"># given a full/absolute pathname dirName, this returns the path relative to root.</span>
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">getRelativePath</span>(dirName, root):
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> isSubdirectory(dirName, root)):
<span style="color: #AA22FF; font-weight: bold">raise</span> <span style="color: #D2413A; font-weight: bold">Exception</span>(dirName <span style="color: #666666">+</span> <span style="color: #BB4444">' is not a subdirectory of '</span> <span style="color: #666666">+</span> root)
<span style="color: #AA22FF; font-weight: bold">return</span> split(getRelativeName(dirName, root), <span style="color: #BB4444">'/'</span>)
<span style="color: #AA22FF; font-weight: bold">def</span> <span style="color: #00A000">backup</span>(s, d):
<span style="color: #AA22FF; font-weight: bold">global</span> backupDirectoryName
<span style="color: #AA22FF; font-weight: bold">global</span> sourceRoot
<span style="color: #AA22FF; font-weight: bold">global</span> destinationRoot
sourceRoot <span style="color: #666666">=</span> s
destinationRoot <span style="color: #666666">=</span> d
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF">len</span>(sys<span style="color: #666666">.</span>argv) <span style="color: #666666">!=</span> <span style="color: #666666">2</span>):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">'usage: backup.py dirname'</span>
sys<span style="color: #666666">.</span>exit()
backupDirectoryName <span style="color: #666666">=</span> sys<span style="color: #666666">.</span>argv[<span style="color: #666666">1</span>]
<span style="color: #AA22FF; font-weight: bold">if</span>(sourceRoot <span style="color: #666666">==</span> <span style="color: #BB4444">''</span>):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"sourceRoot hasn't been set"</span>
sys<span style="color: #666666">.</span>exit()
<span style="color: #AA22FF; font-weight: bold">if</span>(destinationRoot <span style="color: #666666">==</span> <span style="color: #BB4444">''</span>):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"destinationRoot hasn't been set"</span>
sys<span style="color: #666666">.</span>exit()
<span style="color: #AA22FF; font-weight: bold">if</span>(backupDirectoryName <span style="color: #666666">==</span> <span style="color: #BB4444">''</span>):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"backupDirectoryName hasn't been set"</span>
sys<span style="color: #666666">.</span>exit()
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>isdir(sourceRoot)):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"sourceRoot = "</span> <span style="color: #666666">+</span> sourceRoot <span style="color: #666666">+</span> <span style="color: #BB4444">" doesn't exist."</span>
sys<span style="color: #666666">.</span>exit()
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>isdir(destinationRoot)):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"destinationRoot = "</span> <span style="color: #666666">+</span> destinationRoot <span style="color: #666666">+</span> <span style="color: #BB4444">" doesn't exist."</span>
sys<span style="color: #666666">.</span>exit()
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>isdir(backupDirectoryName)):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"backupDirectory = "</span> <span style="color: #666666">+</span> backupDirectoryName <span style="color: #666666">+</span> <span style="color: #BB4444">" doesn't exist."</span>
sys<span style="color: #666666">.</span>exit()
<span style="color: #AA22FF; font-weight: bold">if</span>(<span style="color: #AA22FF; font-weight: bold">not</span> isSubdirectory(backupDirectoryName, sourceRoot)):
<span style="color: #AA22FF; font-weight: bold">print</span> <span style="color: #BB4444">"backupDirectoryName isn't a subdirectory of the sourceRoot."</span>
sys<span style="color: #666666">.</span>exit()
createPath(getRelativePath(backupDirectoryName, sourceRoot), destinationRoot)
backupDir(backupDirectoryName)
</pre></div>
</div>
<br />
The above code is a sort of library, which you use along with a driver script. An example follows:<br />
<pre style="background-color: #eeeeee; border-bottom: #999999 1px dashed; border-left: #999999 1px dashed; border-right: #999999 1px dashed; border-top: #999999 1px dashed; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code>
#!/usr/bin/python
from backup import *
sourceRoot = '/home/sujitkc/my_work'
destinationRoot = '/home/sujitkc/work_backup'
backup(sourceRoot, destinationRoot)</code></pre>
<br />
<span style="font-family: Georgia, Times New Roman, serif;">We usually have multiple backup scenarios. For example, I have the following scenarios:</span><br />
<br />
<ol style="text-align: left;">
<li><span style="font-family: Georgia, Times New Roman, serif;">I take daily (approximately) backup of my work folder at office.</span></li>
<li><span style="font-family: Georgia, Times New Roman, serif;">I take fortnightly or monthly backup of my personal data at home.</span></li>
<li><span style="font-family: Georgia, Times New Roman, serif;">I take monthly backup of my entire data.</span></li>
</ol>
<br />
<span style="font-family: Georgia, Times New Roman, serif;">In the above three cases, the only thing that changes is the</span> <span style="color: blue; font-family: Courier New, Courier, monospace;"><b>sourceRoot</b></span> <span style="font-family: Georgia, Times New Roman, serif;">and </span><span style="color: blue; font-family: Courier New, Courier, monospace;"><b>destinationRoot</b></span>. <span style="font-family: Georgia, Times New Roman, serif;">Therefore, I have a separate driver for each of the above scenarios:</span><span style="font-family: Georgia, Times New Roman, serif;"> </span><b><span style="color: blue; font-family: Courier New, Courier, monospace;">backup_work.py</span></b>, <span style="color: blue; font-family: Courier New, Courier, monospace;"><b>backup_personal.py</b></span> and <b><span style="color: blue; font-family: Courier New, Courier, monospace;">backup_all.py</span></b><span style="font-family: Georgia, Times New Roman, serif;"> respectively. In each of these drivers, I have set the </span><span style="color: blue; font-family: Courier New, Courier, monospace;"><b>sourceRoot</b></span> and <span style="color: blue; font-family: Courier New, Courier, monospace;"><b>destinationRoot</b></span> <span style="font-family: Georgia, Times New Roman, serif;">variables to a different appropriate value. Depending on my backup scenario, I just have to run the corresponding driver script. That's all!</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"> </span><br />
<span style="font-family: Georgia, Times New Roman, serif;">All you need to do to use the script are the following:</span><br />
<ul style="text-align: left;">
<li><span style="font-family: Georgia, Times New Roman, serif;">Save script 1 as</span> <span style="color: blue; font-family: Courier New, Courier, monospace;"><b>backup.py</b></span><span style="font-family: Georgia, Times New Roman, serif;"> somewhere and make it executable using:</span></li>
</ul>
<blockquote class="tr_bq">
<b style="color: blue; font-family: 'Courier New', Courier, monospace;">chmod +x backup.py</b></blockquote>
<ul style="text-align: left;">
<li><span style="font-family: Georgia, Times New Roman, serif;">Save script 2 as, say, </span><span style="color: blue; font-family: Courier New, Courier, monospace;"><b>backup_work.py</b></span><span style="font-family: Georgia, Times New Roman, serif;">, at the same location and make it executable using:</span></li>
</ul>
<blockquote class="tr_bq">
<b style="color: blue; font-family: 'Courier New', Courier, monospace;">chmod +x backup_work.py</b></blockquote>
<ul style="text-align: left;">
<li><span style="font-family: Georgia, Times New Roman, serif;">In script 2, change the values of the</span> <span style="color: blue; font-family: Courier New, Courier, monospace;"><b>sourceRoot</b></span> <span style="font-family: Georgia, Times New Roman, serif;">and </span><span style="color: blue; font-family: Courier New, Courier, monospace;"><b>destinationRoot</b></span><span style="font-family: Georgia, Times New Roman, serif;"> variables to appropriate locations.</span></li>
<li><span style="font-family: Georgia, Times New Roman, serif;">You are all set! Now run the script as follows:</span></li>
</ul>
<blockquote class="tr_bq">
<b><span style="color: blue; font-family: Courier New, Courier, monospace;">./backup_work.py your_backup_directory</span></b></blockquote>
<span style="font-family: Georgia, Times New Roman, serif;">If you are just starting off with this script and are wondering what to put as </span><b style="color: blue; font-family: 'Courier New', Courier, monospace;">your_backup_directory</b><span style="font-family: Georgia, Times New Roman, serif;">, here's a clue: often, the </span><span style="color: blue; font-family: Courier New, Courier, monospace;"><b>your_backup_directory</b></span><span style="font-family: Georgia, Times New Roman, serif;"> parameter has the same value as </span><span style="font-family: Courier New, Courier, monospace;"><span style="color: blue;"><b>sourceRoot</b></span>.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<br />
<h4 style="text-align: left;">
<span style="font-family: Georgia, Times New Roman, serif;">Request</span></h4>
<div style="text-align: justify;">
<span style="color: purple; font-family: Georgia, Times New Roman, serif;"><i>If you find the above script useful, it will be highly appreciated if you drop me a word of acknowledgement as a comment to this post. Feel free to communicate if you find any problem with the code.</i></span></div>
<span style="color: purple; font-family: Georgia, Times New Roman, serif;"><i>
</i></span>
<br />
<h3 style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;">Related Post:</span></h3>
<br />
<a href="http://sujitkc-techbits.blogspot.in/2012/07/script-for-backing-up.html"><span style="font-family: Georgia, Times New Roman, serif;">A Script for Backing Up</span></a><br />
<br /></div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-59058667312342280702012-07-10T21:50:00.001+05:302013-03-31T21:46:40.418+05:30A Script for Backing Up<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: Georgia,"Times New Roman",serif;">Backing up your data is supposed to be easy: just ctrl-C, ctrl-V the folders you want to backup. In a typical case, there would be 10s of 1000s of files to copy. It would typically take hours to finish the job in that case. That's OK, because I could issue my command, and then get busy in something else, and let my machine do the copying. The problem arises when something goes wrong in between. Sometimes there would be a customary error message which isn't much helpful. If there is none, a crude way to find that out is to compare the sizes of the source and destination folders. You may find that they aren't the same! Someone please tell me what went wrong! Which file couldn't get copied? Did it just give up there and proceed? Where there multiple failures? So, now do I have to do it all over again? How do I know it won't fail this time?</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia,"Times New Roman",serif;">That motivates me to have a script which does it a bit more systematically. In the sense that if something goes wrong, it leaves me with some information about where it went wrong so that I can go and fix it. Thereafter, when I resume my backup process, it shouldn't just start all over again, because that would be such an awful waste of time. Instead, it should just skip the part which has got backed up successfully, and copy those parts of my data which didn't get backed up.</span><br />
<div>
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span></div>
<span style="font-family: Georgia,"Times New Roman",serif;">Actually, this is technically called data synchronisation, or more precisely, file synchronisation.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<br />
<div>
<span style="font-family: Georgia, Times New Roman, serif;">Another important feature I wish it to have is that it doesn't result in proliferation of data in the backup drive. Let me try to briefly explain what this particular problem is and how we intend to handle it.</span></div>
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<span style="font-family: Georgia, Times New Roman, serif;">In the next few paragraphs, I will explain the problem of data synchronisation in some more detail. I will explain the ideas which lead to the algorithm as I have implemented in the script. <b>However, if you are here in search of the script, by all means, feel free to skip over to the source code.</b> </span><br />
<h3>
<span style="font-family: Georgia, Times New Roman, serif;">
Data Synchronisation</span></h3>
<span style="font-family: Georgia, Times New Roman, serif;">What are we trying to do in backup? As hinted above, we are just trying to create a copy of some data in a source location <i>S</i>, into a destination location <i>D</i>. In the process, we also want that all items that get copied must be related to each other in the same way both in <i>D</i> and <i>S</i>. For example, if there's a file <i>f</i> somewhere in <i>S</i>, it should also be found in <i>D</i>. Additionally, if there's a directory <i>d</i> somewhere in <i>S</i>, with a file <i>f</i> and a directory <i>d'</i>, then we expect that in <i>D</i>, we would find a <i>d</i>, with file <i>f</i> and directory <i>d'</i> contained in it.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<span style="font-family: Georgia, Times New Roman, serif;">A good way to look at this logical arrangement of data is the tree data-structure. Treat <i>S</i> and <i>D</i> as the roots of two trees. Each file and directory in <i>S</i> and <i>D</i> are nodes of the respective trees. The files and directories contained in a directory <i>d</i> are its child nodes, and <i>d</i> is their parent. Since directory nodes can have child nodes, they are <i>non-leaf</i> or <i>internal</i> nodes. And since files can't contain anything else, they can't have child nodes. Thus, they are called <i>leaf </i> nodes.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<span style="font-family: Georgia, Times New Roman, serif;">With the above terminology in place, we could rephrase our description of the back process concisely as follows: At the end of the backup, we would like to have the tree rooted at <i>D</i> look exactly the same as that rooted at <i>S</i>.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<span style="font-family: Georgia, Times New Roman, serif;">Declaratively, the process to achieve it is ridiculously simple:</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><br /></span>
<br />
<ul>
<li><span style="font-family: Georgia, Times New Roman, serif;">Each file <i>f</i> in <i>S</i> should have a copy <i>f</i> in <i>D</i> too. Each directory <i>d</i> in <i>S</i> should have a copy <i>d</i> in <i>D</i> too.</span></li>
<li><span style="font-family: Georgia, Times New Roman, serif;">Let <i>D.d</i> be the copy in <i>D</i> of a directory <i>d</i> in <i>S,</i> denoted likewise by <i>S.d</i>. For every node <i>S.n</i> (whether a file or a directory) which is a child of <i>S.d</i>, its copy <i>D.n</i> should be the child of <i>D.d</i>.</span></li>
<li><span style="font-family: Georgia, Times New Roman, serif;">For every file <i>S.f</i> and <i>D.f</i>, <i>D.f</i> should be copied from <i>S.f</i>. This implies that if <i>S.f</i> is found newer than <i>D.f</i>, <i>S.f</i> is copied to <i>D.f</i>. Otherwise, the copying is skipped.</span></li>
</ul>
<span style="font-family: Georgia, 'Times New Roman', serif;">One more step of rephrasing the thoughts, and we have the following:</span></div>
<div style="text-align: justify;">
<span style="font-family: Georgia, 'Times New Roman', serif;">Any node <i>n</i> in <i>S</i> (again, denoted by <i>S.n</i>) is synchronised if:</span></div>
<div style="text-align: justify;">
<ul>
<li><span style="font-family: Georgia, 'Times New Roman', serif;">There exists </span><i style="font-family: Georgia, 'Times New Roman', serif;">D.n.</i></li>
<li><span style="font-family: Georgia, 'Times New Roman', serif;">If </span><i style="font-family: Georgia, 'Times New Roman', serif;">S.n</i><span style="font-family: Georgia, 'Times New Roman', serif;"> happens to be a file, then </span><i style="font-family: Georgia, 'Times New Roman', serif;">D.n</i><span style="font-family: Georgia, 'Times New Roman', serif;"> is newer than </span><i style="font-family: Georgia, 'Times New Roman', serif;">S.n</i><span style="font-family: Georgia, 'Times New Roman', serif;">.</span></li>
<li><span style="font-family: Georgia, 'Times New Roman', serif;">If </span><i style="font-family: Georgia, 'Times New Roman', serif;">S.n</i><span style="font-family: Georgia, 'Times New Roman', serif;"> happens to be a directory, then all its children are synchronised.</span></li>
</ul>
<span style="font-family: Georgia, Times New Roman, serif;">The above way of writing </span><span style="font-family: Georgia, 'Times New Roman', serif;">(particularly the last point)</span><span style="font-family: Georgia, 'Times New Roman', serif;"> </span><span style="font-family: Georgia, 'Times New Roman', serif;">brings out a very important </span><i style="font-family: Georgia, 'Times New Roman', serif;">recursive</i><span style="font-family: Georgia, 'Times New Roman', serif;"> structure of the solution. To ensure that a directory is synchronised, all we have to make sure is that all its contents are synchronised. In other words:</span></div>
<pre style="background-color: #eeeeee; border-bottom: #999999 1px dashed; border-left: #999999 1px dashed; border-right: #999999 1px dashed; border-top: #999999 1px dashed; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code>
proc synchronise(directory d)
forall(n in d)
synchronise(n)
endfor
end proc
</code></pre>
<div style="text-align: justify;">
<span style="font-family: Georgia, 'Times New Roman', serif;"><br /></span></div>
<div style="text-align: justify;">
The above procedure makes explicit the recursive nature of the synchronisation algorithm. Note that <span style="font-family: Times, Times New Roman, serif;">synchronise</span> procedure calls itself as many times as there are nodes in <span style="font-family: Times, Times New Roman, serif;">d</span>.<br />
<ul>
</ul>
<div>
<span style="font-family: Georgia, Times New Roman, serif;">The algorithm to achieve the above post-condition is a bit more complicated. Its implementation in shell-script is significantly more complicated with my knowledge level. It would be very exciting if someone provided a much simpler implementation.</span></div>
<br />
<h3>
The Script</h3>
<div style="font-family: Georgia,"Times New Roman",serif;">
So, here goes:</div>
</div>
<div>
</div>
<!-- HTML generated using hilite.me --><div style="background: #111111; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #0086d2">#!/</span><span style="color: #ff0086; font-weight: bold">bin/</span><span style="color: #fb660a">bash</span>
<span style="color: #ff0086; font-weight: bold">TRUE=</span><span style="color: #0086f7; font-weight: bold">1</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">FALSE=</span><span style="color: #0086f7; font-weight: bold">0</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">sourceRoot=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">""</span>; <span style="color: #ffffff">#</span> <span style="color: #fb660a">fill</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ff0086; font-weight: bold">appropriate</span> <span style="color: #ff0086; font-weight: bold">value</span>
<span style="color: #ff0086; font-weight: bold">destinationRoot=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">""</span>; <span style="color: #ffffff">#</span> <span style="color: #fb660a">fill</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ff0086; font-weight: bold">appropriate</span> <span style="color: #ff0086; font-weight: bold">value</span>
<span style="color: #ff0086; font-weight: bold">backupDirectory=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">""</span>; <span style="color: #ffffff">#</span> <span style="color: #fb660a">fill</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ff0086; font-weight: bold">appropriate</span> <span style="color: #ff0086; font-weight: bold">value</span>
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">backupDir</span>(){
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">prefix=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"$1"</span>; <span style="color: #ffffff">#</span> <span style="color: #fb660a">name</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">directory</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">be</span> <span style="color: #ff0086; font-weight: bold">backed</span> <span style="color: #ff0086; font-weight: bold">up</span><span style="color: #ffffff">.</span>
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">completeName=</span><span style="color: #0086d2">$(</span><span style="color: #ff0086; font-weight: bold">getCompletePathName</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${prefix}"</span>)<span style="color: #ffffff">;</span> <span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">complete</span> <span style="color: #ff0086; font-weight: bold">name</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">directory</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">be</span> <span style="color: #ff0086; font-weight: bold">backed</span> <span style="color: #ff0086; font-weight: bold">up</span><span style="color: #ffffff">.</span>
<span style="color: #fb660a">if</span> [ ! <span style="color: #ffffff">-</span><span style="color: #fb660a">d</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${completeName}"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${completeName} is not a directory. Returning ..."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ff0086; font-weight: bold">1</span>;
<span style="color: #fb660a">fi</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"entering directory '${completeName}'"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">suffix=</span><span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">completeName</span><span style="color: #ffffff">#</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${sourceRoot}"</span>}<span style="color: #ffffff">;</span> <span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">name</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">directory</span> <span style="color: #ff0086; font-weight: bold">relative</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">sourceRoot</span><span style="color: #ffffff">.</span>
<span style="color: #fb660a">if</span> [ ! <span style="color: #ffffff">-</span><span style="color: #fb660a">d</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationRoot}/${suffix}"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span> <span style="color: #ffffff">#</span> <span style="color: #ffffff">$</span>{<span style="color: #fb660a">destinationRoot</span>}<span style="color: #ff0086; font-weight: bold">/</span><span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">suffix</span>} <span style="color: #ff0086; font-weight: bold">is</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">complete</span> <span style="color: #ff0086; font-weight: bold">name</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">destination</span> <span style="color: #ff0086; font-weight: bold">folder</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"creating destination ${destinationRoot}/${suffix}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">mkdir</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationRoot}/${suffix}"</span><span style="color: #ffffff">;</span> <span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">there</span> <span style="color: #ff0086; font-weight: bold">should</span> <span style="color: #ff0086; font-weight: bold">be</span> <span style="color: #ff0086; font-weight: bold">a</span> <span style="color: #ff0086; font-weight: bold">way</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">check</span> <span style="color: #ff0086; font-weight: bold">if</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">make</span> <span style="color: #ff0086; font-weight: bold">directory</span> <span style="color: #ff0086; font-weight: bold">succeeded</span><span style="color: #ffffff">.</span>
<span style="color: #fb660a">fi</span>
<span style="color: #ff0086; font-weight: bold">isDirectoryEmpty</span> <span style="color: #ffffff">$</span><span style="color: #ff0086; font-weight: bold">completeName</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">result=</span><span style="color: #0086d2">$?</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ ! <span style="color: #008800; font-style: italic; background-color: #0f140f">"$result"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"$TRUE"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">for</span> <span style="color: #ff0086; font-weight: bold">name</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ffffff">$</span>{<span style="color: #fb660a">completeName</span>}<span style="color: #ff0086; font-weight: bold">/*</span>; <span style="color: #fb660a">do</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">for</span> <span style="color: #ff0086; font-weight: bold">name</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ffffff">`</span><span style="color: #ff0086; font-weight: bold">find</span> <span style="color: #ffffff">$</span><span style="color: #ff0086; font-weight: bold">completeName</span> <span style="color: #ff0086; font-weight: bold">-</span><span style="color: #fb660a">maxdepth</span> <span style="color: #ff0086; font-weight: bold">1</span><span style="color: #ffffff">`</span>; <span style="color: #fb660a">do</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"$name"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"$completeName"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">continue</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">inBetween=</span><span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">suffix%</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span>};
<span style="color: #fb660a">isSubdirectory</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${completeName}"</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">result=</span><span style="color: #0086d2">$?</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">filename=</span><span style="color: #ffffff">`</span><span style="color: #fb660a">basename</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"$name"</span><span style="color: #ffffff">`;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #ffffff">-</span><span style="color: #fb660a">d</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">backupDir</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">elif</span> [ <span style="color: #ffffff">-</span><span style="color: #fb660a">f</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">destinationFileName=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationRoot}/${inBetween}/${filename}"</span>
<span style="color: #fb660a">if</span> [ <span style="color: #ffffff">-</span><span style="color: #fb660a">f</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"$destinationFileName"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">whichFileIsOlder</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationFileName}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">older=</span><span style="color: #0086d2">$?</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"${older}"</span> <span style="color: #ffffff">-</span><span style="color: #fb660a">eq</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"2"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"copying file ${name} to ${destinationFileName}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">cp</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationRoot}/${inBetween}"</span><span style="color: #ffffff">;</span> <span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">there</span> <span style="color: #ff0086; font-weight: bold">should</span> <span style="color: #ff0086; font-weight: bold">be</span> <span style="color: #ff0086; font-weight: bold">a</span> <span style="color: #ff0086; font-weight: bold">way</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">check</span> <span style="color: #ff0086; font-weight: bold">if</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">file</span> <span style="color: #ff0086; font-weight: bold">copy</span> <span style="color: #ff0086; font-weight: bold">succeeded</span><span style="color: #ffffff">.</span>
<span style="color: #ffffff">#</span> <span style="color: #fb660a">else</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"No need to copy ${name}."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">else</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"copying file ${name} to ${destinationFileName}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">cp</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationRoot}/${inBetween}"</span><span style="color: #ffffff">;</span> <span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">there</span> <span style="color: #ff0086; font-weight: bold">should</span> <span style="color: #ff0086; font-weight: bold">be</span> <span style="color: #ff0086; font-weight: bold">a</span> <span style="color: #ff0086; font-weight: bold">way</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">check</span> <span style="color: #ff0086; font-weight: bold">if</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">file</span> <span style="color: #ff0086; font-weight: bold">copy</span> <span style="color: #ff0086; font-weight: bold">succeeded</span><span style="color: #ffffff">.</span>
<span style="color: #fb660a">fi</span>
<span style="color: #ff0086; font-weight: bold">else</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"Something wrong with $name"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">exit</span> <span style="color: #ff0086; font-weight: bold">1</span>;
<span style="color: #fb660a">fi</span>
<span style="color: #ff0086; font-weight: bold">done</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"exiting directory ${prefix} ..."</span><span style="color: #ffffff">;</span>
}
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">whichFileIsOlder</span>() {
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">file1=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"$1"</span>;
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">file2=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"$2"</span>;
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">sdate=</span><span style="color: #ffffff">`</span><span style="color: #fb660a">date</span> <span style="color: #ff0086; font-weight: bold">+%</span><span style="color: #fb660a">s</span> <span style="color: #ff0086; font-weight: bold">-</span><span style="color: #fb660a">r</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${file1}"</span><span style="color: #ffffff">`;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">ddate=</span><span style="color: #ffffff">`</span><span style="color: #fb660a">date</span> <span style="color: #ff0086; font-weight: bold">+%</span><span style="color: #fb660a">s</span> <span style="color: #ff0086; font-weight: bold">-</span><span style="color: #fb660a">r</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${file2}"</span><span style="color: #ffffff">`;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">diff=</span><span style="color: #ffffff">`</span><span style="color: #fb660a">expr</span> <span style="color: #ffffff">$</span>{<span style="color: #fb660a">ddate</span>} <span style="color: #ff0086; font-weight: bold">-</span> <span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">sdate</span>}<span style="color: #ffffff">`;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"${diff}"</span> <span style="color: #ffffff">-</span><span style="color: #fb660a">lt</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"0"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ff0086; font-weight: bold">2</span>;
<span style="color: #fb660a">else</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ff0086; font-weight: bold">1</span>;
<span style="color: #fb660a">fi</span>
}
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">isSubdirectory</span>(){
<span style="color: #fb660a">if</span> [ ! <span style="color: #0086d2">$#</span> <span style="color: #ff0086; font-weight: bold">==</span> <span style="color: #0086f7; font-weight: bold">2</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"isSubdirectory : function takes 2 parameters; your provided $#."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">exit</span> <span style="color: #ff0086; font-weight: bold">1</span>;
<span style="color: #fb660a">fi</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">dir1=</span><span style="color: #0086d2">$(</span><span style="color: #ff0086; font-weight: bold">getCompletePathName</span> <span style="color: #ffffff">$</span><span style="color: #ff0086; font-weight: bold">1</span>)<span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">dir2=</span><span style="color: #0086d2">$(</span><span style="color: #ff0086; font-weight: bold">getCompletePathName</span> <span style="color: #ffffff">$</span><span style="color: #ff0086; font-weight: bold">2</span>)<span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">l=</span><span style="color: #ffffff">`</span><span style="color: #fb660a">expr</span> <span style="color: #ff0086; font-weight: bold">length</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${dir1}"</span><span style="color: #ffffff">`;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">p=</span><span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">dir2:</span><span style="color: #0086f7; font-weight: bold">0</span><span style="color: #ffffff">:$</span>{<span style="color: #fb660a">l</span>}}<span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"${p}"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${dir1}"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ffffff">$</span>{<span style="color: #ffffff">TRUE</span>}<span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ffffff">$</span>{<span style="color: #ffffff">FALSE</span>}<span style="color: #ffffff">;</span>
}
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">createParentDirectories</span>(){
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">name=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"$1"</span>; <span style="color: #ffffff">#</span> <span style="color: #fb660a">name</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">directory</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">directory</span> <span style="color: #ff0086; font-weight: bold">structure</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">whose</span> <span style="color: #ff0086; font-weight: bold">ancestor</span> <span style="color: #ff0086; font-weight: bold">directories</span> <span style="color: #ff0086; font-weight: bold">has</span> <span style="color: #ff0086; font-weight: bold">to</span> <span style="color: #ff0086; font-weight: bold">be</span> <span style="color: #ff0086; font-weight: bold">created</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ff0086; font-weight: bold">the</span> <span style="color: #ff0086; font-weight: bold">destinationRoot</span><span style="color: #ffffff">.</span>
<span style="color: #fb660a">local</span> <span style="color: #ff0086; font-weight: bold">completeName=</span><span style="color: #0086d2">$(</span><span style="color: #ff0086; font-weight: bold">getCompletePathName</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"$1"</span>)<span style="color: #ffffff">;</span> <span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">complete</span> <span style="color: #ff0086; font-weight: bold">name</span> <span style="color: #ff0086; font-weight: bold">of</span> <span style="color: #ff0086; font-weight: bold">name</span>
<span style="color: #ff0086; font-weight: bold">isSubdirectory</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${sourceRoot}"</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${completeName}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">result=</span><span style="color: #0086d2">$?</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ ! <span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">result</span>} <span style="color: #ff0086; font-weight: bold">==</span> <span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">TRUE</span>} ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"createParentDirectories : Can't create the parent directories because ${name} is not a subdirectory of ${sourceDirectory}."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">return</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">suffix=</span><span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">completeName</span><span style="color: #ffffff">#</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${sourceRoot}"</span>}<span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"${suffix}"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">""</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"createParentDirectories : No directories to be created."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">return</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">inBetween=</span><span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">suffix%</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${name}"</span>};
<span style="color: #fb660a">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"${inBetween}"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">""</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"createParentDirectories : No directories to be created."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">return</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">subDirectories=</span>( <span style="color: #ffffff">`</span><span style="color: #fb660a">echo</span> <span style="color: #ffffff">$</span>{<span style="color: #fb660a">inBetween</span>} <span style="color: #ff0086; font-weight: bold">|</span> <span style="color: #fb660a">tr</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"/"</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"\n"</span><span style="color: #ffffff">`</span> )<span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">dirName=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${destinationRoot}"</span>;
<span style="color: #fb660a">for</span> <span style="color: #ff0086; font-weight: bold">n</span> <span style="color: #ff0086; font-weight: bold">in</span> <span style="color: #ffffff">$</span>{<span style="color: #fb660a">subDirectories</span>[<span style="color: #ffffff">@</span>]}<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">do</span>
<span style="color: #ff0086; font-weight: bold">dirName=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"${dirName}/${n}"</span>;
<span style="color: #fb660a">if</span> [ ! <span style="color: #ffffff">-</span><span style="color: #fb660a">d</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${dirName}"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ffffff">#</span> <span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"creating directory ${dirName}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">mkdir</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${dirName}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">done</span>
}
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">getCompletePathName</span>(){
<span style="color: #fb660a">if</span> [ ! <span style="color: #0086d2">$#</span> <span style="color: #ff0086; font-weight: bold">==</span> <span style="color: #0086f7; font-weight: bold">1</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"completePathName : function takes 1 parameters; your provided $#."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">name=</span><span style="color: #0086d2">$1</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">local</span> <span style="color: #ff0086; font-weight: bold">completeName=</span><span style="color: #0086d2">$1</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ ! <span style="color: #0086d2">${</span><span style="color: #ff0086; font-weight: bold">name:</span><span style="color: #0086f7; font-weight: bold">0</span><span style="color: #ffffff">:</span><span style="color: #ff0086; font-weight: bold">1</span>} <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"/"</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">completeName=</span><span style="color: #008800; font-style: italic; background-color: #0f140f">"`pwd`/${name}"</span>;
<span style="color: #fb660a">fi</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${completeName}"</span><span style="color: #ffffff">;</span>
}
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">isDirectoryEmpty</span>(){
<span style="color: #fb660a">if</span> <span style="color: #ff0086; font-weight: bold">find</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"$1"</span> <span style="color: #ff0086; font-weight: bold">-</span><span style="color: #fb660a">maxdepth</span> <span style="color: #ff0086; font-weight: bold">0</span> <span style="color: #ffffff">-</span><span style="color: #fb660a">empty</span> <span style="color: #ff0086; font-weight: bold">|</span> <span style="color: #fb660a">read</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ffffff">$</span><span style="color: #ff0086; font-weight: bold">TRUE</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">else</span>
<span style="color: #ff0086; font-weight: bold">return</span> <span style="color: #ffffff">$</span><span style="color: #ff0086; font-weight: bold">FALSE</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
}
<span style="color: #ff0086; font-weight: bold">function</span> <span style="color: #ff0086; font-weight: bold">backup</span>(){
<span style="color: #fb660a">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"backupDirectory = $backupDirectory"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"$backupDirectory"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">""</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"backupDirectory can't be empty. Quitting ..."</span>
<span style="color: #ff0086; font-weight: bold">return</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">if</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"$destinationRoot"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">""</span> ] <span style="color: #ff0086; font-weight: bold">||</span> [ <span style="color: #008800; font-style: italic; background-color: #0f140f">"$sourceRoot"</span> <span style="color: #ffffff">==</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">""</span> ]<span style="color: #ffffff">;</span> <span style="color: #ff0086; font-weight: bold">then</span>
<span style="color: #ff0086; font-weight: bold">echo</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"destinationRoot or sourceRoot variable can't be empty. Quitting ..."</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">return</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">fi</span>
<span style="color: #ff0086; font-weight: bold">createParentDirectories</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${backupDirectory}"</span><span style="color: #ffffff">;</span>
<span style="color: #ff0086; font-weight: bold">backupDir</span> <span style="color: #008800; font-style: italic; background-color: #0f140f">"${backupDirectory}"</span><span style="color: #ffffff">;</span>
}
</pre></div>
<div>
<br />
<h3 style="text-align: left;">
Additional Resources:</h3>
<a href="http://rsync.samba.org/">rsync Utility</a> (thanks Sumantro)</div>
</div>
Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-10350932162044901852012-06-22T16:33:00.001+05:302012-06-25T17:36:34.748+05:30To Make Your Code Snippet Blogger Ready<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
<pre style="background-color: #eeeeee; border-bottom: #999999 1px dashed; border-left: #999999 1px dashed; border-right: #999999 1px dashed; border-top: #999999 1px dashed; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code>
#!/bin/bash
function toHTML(){
local inFile=$1;
local outFile="${inFile}.dat";
if [ -f ${outFile} ]; then
rm ${outFile};
fi
sed 's/\t/\ \ \ \ /g' ${inFile} > ${outFile}
sed 's/$/ /g' ${outFile} > tempFile.dat;
mv tempFile.dat ${outFile};
}
fileName="";
if [ $# == 0 ]; then
fileName="\.";
else
fileName=$1;
fi
toHTML ${fileName};
</code></pre>
</div>Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0tag:blogger.com,1999:blog-22044226.post-80092672858041524392012-06-13T15:20:00.000+05:302012-06-27T15:16:07.961+05:30A Lines of Code Counter<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
</div>
<div style="text-align: justify;">
<span style="font-family: Georgia, "Times New Roman", serif;">The script below is a simple lines of code counter for you. Following interesting features of the script are:</span></div>
<ol style="text-align: left;">
<li><div style="text-align: justify;">
<span style="font-family: Georgia, "Times New Roman", serif;">It recursively counts the lines of code within all subdirectories of the location mentioned.</span></div>
</li>
<li><div style="text-align: justify;">
<span style="font-family: Georgia, "Times New Roman", serif;">It counts the lines of code of only those files whose extensions are considered as source file name extensions in the list <span style="font-family: "Courier New", Courier, monospace;">srcFileExtensions</span> defined early in the script.</span></div>
</li>
<li><div style="text-align: justify;">
<span style="font-family: Georgia;">Optionally, you could make it exclude the blank lines from the lines of code.</span></div>
</li>
</ol>
<div style="text-align: justify;">
<span style="font-family: Georgia;">Caution: The script doesn't run like lightning! Suggested optimisations will be gratefully accepted.</span><br />
<br />
<span style="font-family: Georgia;">Also, there are plenty of superior LOC tools out there. Just google! But for simple plain lines of code counting, this one would still be good for you to begin with. Just copy paste into a bash shell script and go!</span></div>
<br />
<br />
<br />
<pre style="background-color: #eeeeee; border-bottom: #999999 1px dashed; border-left: #999999 1px dashed; border-right: #999999 1px dashed; border-top: #999999 1px dashed; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"><code>
#!/bin/bash
FALSE=0;
TRUE=1;
srcFileExtensions=( \
# java # Java
# cpp # C++
# cc # C++
# h # C, C++
# hh # C++
# hpp # C++
# c # C
# py # Python
# pl # Perl
sh # Shell
# flex # flex
# lex # lex
# y # yacc
# yy # yacc
# cs # C#
); # File name extensions which will be considered as source files. Remove/add as needed. Keep the list to minimum to keep the speed good.
function loc_dir(){
local prefix=$1;
if [ ! -d ${prefix} ]; then
echo "${prefix} is not a directory. Quitting...";
exit 1;
fi
local names=( `ls ${prefix}` );
for name in ${names[@]}; do
local fullName=${prefix}/${name};
if [ -d "${fullName}" ]; then
loc_dir "${fullName}"
elif [ -f "${fullName}" ]; then
isSrcFile ${fullName};
local result=$?;
if [ "${result}" == "${TRUE}" ]; then
echo "including ${fullName} ...";
cat "${fullName}" >> "${locFile}";
fi
else
echo "Something wrong with ${fullName}";
fi
done;
}
function remove_empty_lines(){
local prefix=$1;
echo "Removing empty lines...";
local loc="${prefix}/loc.dat";
local loc1="${prefix}/loc1.dat";
mv ${loc} ${loc1};
while read line
do
if [ "${line}" != "" ]; then
echo ${line} >> ${loc};
fi
done <${loc1}
rm ${loc1};
}
function isSrcFile(){
local fileName=$1;
for ext in ${srcFileExtensions[@]}; do
local extLength=`expr length ".${ext}"`;
local nameLength=`expr length "${fileName}"`;
local startPosition=`expr ${nameLength} - ${extLength}`;
local len=`expr ${nameLength} - 1`;
local subString=`echo ${fileName:${startPosition}:${len}}`;
if [ "${subString}" == ".${ext}" ]; then
return ${TRUE};
fi
done;
return ${FALSE};
}
# main
dirname="";
if [ $# == 0 ]; then
dirname="\.";
else
dirname=$1;
fi
locFile="${dirname}/loc.dat";
loc_dir ${dirname};
# remove_empty_lines ${dirname};
if [ -f "${locFile}" ]; then
result=( `wc -l "${locFile}"` );
else
result=0;
fi
loc=${result[0]};
echo "${loc} lines of code."
rm "${locFile}";
<div align="justify">
</div>
</code></pre>
</div>Sujit Kumar Chakrabartihttp://www.blogger.com/profile/11424095559961037990noreply@blogger.com0