tag:blogger.com,1999:blog-11534853863020286062024-03-16T08:52:46.497-10:00David on SoftwareComputer Science and Software EngineeringDavid Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.comBlogger30125tag:blogger.com,1999:blog-1153485386302028606.post-21654553941739307162015-10-08T14:55:00.003-10:002015-10-09T13:00:47.733-10:00LeetCode - Wildcard Matching<b>Link</b><br />
<a href="https://leetcode.com/problems/wildcard-matching/">https://leetcode.com/problems/wildcard-matching/</a><br />
<br />
<b>Problem</b><br />
Implement wildcard pattern matching with support for '?' and '*'.<br />
<br />
<pre style="background-color: whitesmoke; border-radius: 4px; border: 1px solid rgb(204, 204, 204); box-sizing: border-box; color: #333333; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; line-height: 1.42857; margin-bottom: 10px; overflow: auto; padding: 9.5px; word-break: break-all; word-wrap: break-word;">'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
The matching should cover the <span style="box-sizing: border-box; font-weight: 700;">entire</span> input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false</pre>
<br />
<b>Solution</b><br />
<br />
<script src="https://gist.github.com/linwdav/0ee5d2c70ab0d8fc2668.js"></script>
<b>Approaches to the Problem</b><br />
<br />
#1<br />
<br />
The general approach is to loop through each character in <i>s</i> and <i>p</i> and compare them. Break out of the loop once the end is reached for either <i>s</i> or <i>p</i>.<br />
<br />
- If the characters match, then move on to the next set of characters.<br />
<br />
- If the pattern character is '?', then move on to the next set of characters.<br />
<br />
- If the pattern character is a wildcard '*', then call the function recursively with the wildcard character removed. If the recursive call returns true, then the candidate string and pattern matches. If the recursive call returns false, then move on to the next character in the candidate string.<br />
<br />
- If the characters don't match, then return false.<br />
<br />
Finally, return true if the end <b>has been reached</b> for <b>both</b> <i>s</i> and <i>p</i>. Otherwise, return false if the end <b>has not been reached</b> for <b>either</b> <i>s</i> or <i>p</i>.<br />
<br />
#2<br />
<br />
The first approach works, but has an incredibly inefficient runtime complexity of O(2^n). This is caused by the fact that whenever a wildcard is encountered, it performs a recursive call and possibly recomputes the same exact <i>s</i> and <i>p</i> multiple times. Due to the O(2^n) time complexity, LeetCode threw a 'Time limit exceeded" error.<br />
<br />
<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://upload.wikimedia.org/wikibooks/en/f/fb/Algorithms-F6CallTreeMemoized.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="232" src="https://upload.wikimedia.org/wikibooks/en/f/fb/Algorithms-F6CallTreeMemoized.PNG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This problem is analogous to the fibonacci problem where the same computation is performed many times.</td></tr>
</tbody></table>
<br />
To solve the issue of duplicate computations, we can use a technique called memoization. By creating a lookup table to store failed matches, we can avoid going down the same rabbit hole by checking if <i>s</i> and <i>p</i> has already failed to match.<br />
<br />
#3<br />
<br />
The second approach significantly improves runtime complexity, but LeetCode still threw a 'Time limit exceeded" error on the inputs:<br />
<br />
s = "aaaaabbbbbababbabbbbaaabbaabaaabaabbbbabaaaabaaabbbbbbabbaaaaabbbaaababbaaabaabbaabbbbaaabaabbbaabbbbabbabaabbabbbbaabbaabbabaababababbaabbabbbaaabaaababaaaabbaaaaabbbaaaabbbababbabaaaabbbaabaabbaaaabaaab"<br />
<br />
p = "*aab***aaab**a*b**b*aa***baabababb*abbbbb**a**ba******b**b*a*ab*b***aa*****a*aba*a***aa*b****a*a*****"<br />
<br />
Upon closer inspection, we can infer that the contiguous wildcards was causing the algorithm to branch out wildly. To solve this issue, we can remove contiguous wildcards from <i>p</i> so it looks like<br />
<br />
p = "*aab*aaab*a*b*b*aa*baabababb*abbbbb*a*ba*b*b*a*ab*b*aa*a*aba*a*aa*b*a*a*"<br />
<br />
<b>Conclusion</b><br />
<br />
By combining the three approaches above, LeetCode accepted my submission.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizvvrbEZ4nvPMHY05h2u7Yh67GvUWUWv-Oo79dEAARKkfdFzuK5FB6VDw16CE8Uho4ORSjw5GTH0vJ-zvgJbETJO-GYxSIuF1KYCJGqvxvH25Ad3OoQXV8IeddJ4g16pGuBnpvAPaxtqE3/s1600/LeetCode-WildcardMatchingResult.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizvvrbEZ4nvPMHY05h2u7Yh67GvUWUWv-Oo79dEAARKkfdFzuK5FB6VDw16CE8Uho4ORSjw5GTH0vJ-zvgJbETJO-GYxSIuF1KYCJGqvxvH25Ad3OoQXV8IeddJ4g16pGuBnpvAPaxtqE3/s640/LeetCode-WildcardMatchingResult.png" width="640" /></a></div>
<br />
This was one of the more challenging problems I have encountered, and justifiably so because the solution acceptance rate is 15.8% (13th lowest out of 273 problems on the site) and its difficulty is rated 'Hard'.<br />
<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/AVvXsEgCe2ErTzaC7hTsMt6daDZPp6vVpYKS_29-pkcKoSdL17n2GVLWxzMQ6d5IEMbMPAwaA29YjaB7juQUmCCN6TfYY-D3ATwhqAyay8DUs5UyPFCgXnFrO72PYd8UpOwnn0L82rl_sqh-r2FF/s1600/LeetCode-WildcardMatchingDifficulty.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="504" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCe2ErTzaC7hTsMt6daDZPp6vVpYKS_29-pkcKoSdL17n2GVLWxzMQ6d5IEMbMPAwaA29YjaB7juQUmCCN6TfYY-D3ATwhqAyay8DUs5UyPFCgXnFrO72PYd8UpOwnn0L82rl_sqh-r2FF/s640/LeetCode-WildcardMatchingDifficulty.png" width="640" /></a></div>
<br />
<br />
The real world application of the wildcard matching problem includes anything that uses text search, some of which are: Google search, Microsoft Word, text editors, etc.David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-66539978298032243162015-05-09T17:02:00.000-10:002015-07-15T14:57:27.077-10:00Computational Time Complexity of Algorithms<div>
Computer science problems often have multiple solutions/algorithms for a given problem. For example, what algorithm would you use to find the largest number in an array of integers? You could sort the array and get the largest number in O(n log(n)) time, or simply iterate through the array and maintain a variable that keeps track of the largest number in O(n) time.</div>
<div>
<br /></div>
<div>
We usually want to use the optimal (most efficient) algorithm because it makes our software run faster. In order to find the optimal algorithm, it helps to understand the major time complexity 'classes' and the common problems and algorithms that fit within each class.</div>
<div>
<br /></div>
<div>
<b>O(1)</b></div>
<div>
<ul>
<li>Single operation, e.g. setting a value or performing a math operation</li>
<li>Lookup/delete nth element from an array</li>
<li>Lookup/insert/delete element from a hash table (average case, where there are few collisions)</li>
</ul>
<div>
<b>O(log n)</b></div>
</div>
<div>
<ul>
<li>Continuously splitting a data set or number of operations in half</li>
<li>Binary search</li>
<li>Search/insert/delete element from a binary search tree (average case, where tree is balanced)</li>
<li>Search/insert/delete element from a min/max heap</li>
</ul>
<div>
<b>O(n)</b></div>
</div>
<div>
<ul>
<li>Iterating through an entire data set</li>
<li>Search/insert/delete from a linked list</li>
</ul>
<div>
<b>O(n log n)</b></div>
</div>
<div>
<ul>
<li>Merge sort, quick sort, heap sort</li>
</ul>
<div>
<b>O(n^2)</b></div>
</div>
<div>
<ul>
<li>Looking at all pairs of items</li>
<li>Selection sort, insertion sort, bubble sort</li>
<li>0/1 knapsack problem using dynamic programming</li>
</ul>
<div>
<b>O(2^n)</b></div>
</div>
<div>
<ul>
<li>Continuously doubling a data set or number of operations</li>
<li>Naive fibonacci</li>
<li>Travelling salesman problem using dynamic programming</li>
</ul>
<div>
<b>O(n!)</b></div>
</div>
<div>
<ul>
<li>Generating all permutations of a set</li>
<li>Naive travelling salesman problem</li>
</ul>
</div>
David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-81853184440584814522015-02-22T14:38:00.004-10:002015-11-07T06:49:21.967-10:00Objection Orientation: Polymorphism, Abstraction, Encapsulation, and InheritanceDevelopers who are new to object-oriented programming often struggle to understand the long-winded explanations that are scattered across the interwebs. The intent of this post is to ease the pain (hopefully) by summarizing the main concepts of object orientation in a <b>concise</b> and <b>precise</b> format by providing a definition, two examples, and a brief explanation of its benefits.<br />
<h2>
<b><span style="font-size: large;"><u>Polymorphism</u></span></b></h2>
<b>Definition</b>: Polymorphism is the concept where a parent type can have many sub-types.<br />
<br />
<b>Example #1:</b> <i>ArrayList</i> and <i>LinkedList </i>are sub-types of the parent type <i>List</i>.<br />
<br />
<script src="https://gist.github.com/linwdav/dfbde8d3fec79b8d25eb.js"></script><b>
Example #2</b>: <i>Car</i>, M<i>otorcyle</i>, and B<i>us </i>are sub-types of the parent type <i>Vehicle</i>.<br />
<br />
<script src="https://gist.github.com/linwdav/39aa269c18a527efa53c.js"></script><b>
Benefits:</b> Polymorphism allows you to use a single parent type to interact with all possible sub-types. It also helps to decouple your code. When you are working with a <i>List </i>object, you can freely swap out the underlying implementation from an ArrayList to a LinkedList and vice-versa.<br />
<br />
<h2>
<b><span style="font-size: large;"><u>Abstraction</u></span></b></h2>
<b>Definition</b>: Abstraction is the generalization of common functionality across different objects.<br />
<br />
<b>Example #1:</b> <i>List</i> is an abstraction of <i>ArrayList </i>and <i>LinkedList</i> because it generalizes the common functionality of adding and removing elements.<br />
<br />
<script src="https://gist.github.com/linwdav/d8af65528dd597f6adbb.js"></script><b>
Example #2</b>: <i>Vehicle</i> is an abstraction of <i>Car</i>, <i>Motorcyle</i>, and <i>Bus </i>because it generalizes the common functionality of accelerating and braking.<br />
<br />
<script src="https://gist.github.com/linwdav/6b5446208fe6895c5b4e.js"></script><b>
Benefits:</b> Abstraction allows you to interact with different objects via a common interface.<br />
<br />
<h2>
<u><span style="font-size: large;">Encapsulation</span></u></h2>
<b>Definition:</b> Encapsulation is the packing (hiding) of data and implementation details into a class or function.<br />
<br />
<b>Example #1:</b> Data and implementation details about a car are encapsulated (packed, hidden) into a <i>Car</i> class. Access to its data can be controlled via public, protected, and private modifiers.<br />
<br />
<script src="https://gist.github.com/linwdav/0fd8facbc47f200987cc.js"></script>
<b>Example #2:</b> The functionality to <i>accelerate</i> and <i>brake</i> a car is encapsulated (packed, hidden) into functions. Access to these functions can be controlled via public, protected, and private modifiers.<br />
<br />
<script src="https://gist.github.com/linwdav/c3a7b0d057417997504c.js"></script>
<b>Benefits:</b> Encapsulation allows you to hide implementation details and protect against mis-use by other classes. It also helps to decouple your code. For example, I could modify the formula in the <i>accelerate</i> function without breaking any code dependencies on that function.<br />
<br />
<h2>
<u><span style="font-size: large;">Inheritance</span></u></h2>
<b>Definition:</b> Inheritance is the re-use of a base class's functionality by a sub-class.<br />
<br />
<b>Example #1:</b> <i>Car</i> is a sub-class that inherits the functionality of its base class <i>Vehicle</i>, including the data (currentHeading, velocity, weight) and functions (turn, accelerate, brake).<br />
<br />
<script src="https://gist.github.com/linwdav/89ea2110ceb86157dc3e.js"></script>
<b>Example #2:</b> A <i>Car </i>can turn because it inherited the functionality from its base class <i>Vehicle</i>.<br />
<br />
<script src="https://gist.github.com/linwdav/75234c7557bfe530daa4.js"></script><b>
Benefits:</b> Inheritance allows you to re-use functionality and reduce duplicate code.<br />
<br />
Polymorphism, abstraction, encapsulation, and inheritance are distinctly different concepts, but together they support the paradigm of object orientation. I hope this post cleared up any misunderstandings of these four pillars object orientation!David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com16tag:blogger.com,1999:blog-1153485386302028606.post-62150709523035130502012-06-27T07:31:00.000-10:002012-06-27T14:08:20.366-10:00How to create a web app using Java, MySQL, JDBC, Servlets, and TomcatIf you ask developers what technologies are used to build modern web applications today, you would probably get something along the lines of <b><a href="http://www.playframework.org/">Play</a></b>, <a href="http://www.springsource.org/" style="font-weight: bold;">Spring</a> and <b><a href="http://www.hibernate.org/">Hibernate</a></b>. These tools are great because they hide all the lower level implementation details such as servlets and the actual SQL itself, but as a developer, it is beneficial to understand what goes on beneath these layers of abstraction. To fulfill my own curiosity, I created a simple web application using Java, MySQL, JDBC, Servlets, and Tomcat. The rest of this post describes what I did.<br />
<div>
<br /></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/AVvXsEj1RK5BGfjRMsEI7toeWHhyna8Nzj2gFStMvk_gBiSviNLdVTyJx66dXZ_qQbUca2L__sr2HyfBkhO1ad9SqP8kuKVp6RwkdpqAFubI6M4Mw7gAAB3J3mWodbmRRxAZU8I88M1e5y9g5xZz/s1600/Spring_Framework.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1RK5BGfjRMsEI7toeWHhyna8Nzj2gFStMvk_gBiSviNLdVTyJx66dXZ_qQbUca2L__sr2HyfBkhO1ad9SqP8kuKVp6RwkdpqAFubI6M4Mw7gAAB3J3mWodbmRRxAZU8I88M1e5y9g5xZz/s1600/Spring_Framework.png" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_2CCvGS5qvhrRy50uYoPpOBboMQbe11JLkErWgtCCh1rEeQ3By75rDkDYvFtITtv-uOpcsw1mzuadVetvAuxJNsZFU0p2qPPQ7yGEoIu2D-RBXMJcCm2Gwk7V4HV54dnDo02fLCJCP3vq/s1600/Hibernate.png" imageanchor="1" style="background-color: white; margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_2CCvGS5qvhrRy50uYoPpOBboMQbe11JLkErWgtCCh1rEeQ3By75rDkDYvFtITtv-uOpcsw1mzuadVetvAuxJNsZFU0p2qPPQ7yGEoIu2D-RBXMJcCm2Gwk7V4HV54dnDo02fLCJCP3vq/s1600/Hibernate.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<b>Step 1: Download MySQL</b><br />
The first step is to download <a href="http://www.mysql.com/downloads/"><b>MySQL</b></a> and get it up and running. Follow the installation instructions, start up the server, and make sure you can log in using "mysql -u root -p" in the terminal. This <a href="http://code.google.com/edu/tools101/mysql.html#Getting_Started_with_MySQL"><b>link</b></a> provides a good resource for a refresher on SQL.<br />
<br />
<b>Step 2: Download Connector/J</b><br />
Connector/J can be downloaded <a href="http://dev.mysql.com/downloads/connector/j/"><b>here</b></a>. All we really need is mysql-connector-java-5.1.20-bin.jar in the src/lib folder. This jar file is the JDBC driver that lets us communicate with MySQL using Java code.<br />
<br />
<b>Step 3: Establish a connection to MySQL using JDBC</b><br />
Create a new Java project and add mysql-connector-java-5.1.20-bin.jar to the build path. This <a href="http://docs.oracle.com/javase/tutorial/jdbc/basics/processingsqlstatements.html"><b>link</b></a> provides a good tutorial on JDBC.<br />
<br />
<b>Step 4: Download Tomcat</b><br />
Tomcat 7 can be downloaded <a href="http://tomcat.apache.org/download-70.cgi"><b>here</b></a>. Unpack and follow the instructions in RUNNING.txt. Once Tomcat is running, you should be able to see the default web page at http://localhost:8080. Add mysql-connector-java-5.1.20-bin.jar to apache-tomcat-7/lib.<br />
<br />
<b>Step 5: Understand the directory structure of a Java web application</b><br />
Java web applications should have the following directory structure<br />
<br />
<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/AVvXsEjeQJ-ETyLn-ABj_qFcOq57uUeRmBzEL-kyngCgvDDB3wlTe8bFCuvR1MfPMnvDxmuhKgwV1ha3rD8WJJCBL6ElV2Y-AkzhKQnL7izSOGusQ-COYmUBn-sJkqQcvqFpwuVlDtUoiC8NEoMT/s1600/Screen+Shot+2012-06-27+at+8.52.14+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeQJ-ETyLn-ABj_qFcOq57uUeRmBzEL-kyngCgvDDB3wlTe8bFCuvR1MfPMnvDxmuhKgwV1ha3rD8WJJCBL6ElV2Y-AkzhKQnL7izSOGusQ-COYmUBn-sJkqQcvqFpwuVlDtUoiC8NEoMT/s320/Screen+Shot+2012-06-27+at+8.52.14+AM.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Directory structure of a Java web app</td></tr>
</tbody></table>
<br />
The root folder is the name of your Java project. Under the root folder, there should be another folder called WEB-INF. Under the WEB-INF folder, there should be a classes folder, a lib folder, and a web.xml file. Java source files and compiled .class files belong in the classes folder. Libraries belong in the lib folder. The web.xml file is used by Tomcat to map a URL to a servlet.<br />
<br />
<b>Step 6: Write a simple Java application using JDBC and servlets</b><br />
Create a new Java project using the directory structure above. If you don't know where to begin with JDBC and servlets, make sure Tomcat is running and go to http://localhost:8080/examples/servlets. Look at the code samples and execute them. Don't forget to add apache-tomcat-7/lib/servlet-api.jar to your project build path.<br />
<br />
I created a to-do list web application. It queries a JDBC/MySQL backed database for a list of items, displays it in a table, and lets you add or delete items. The full source code is available at my Github repository <a href="https://github.com/linwdav/simple-servlet"><b>here</b></a>.<br />
<br />
<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/AVvXsEgZzYMSIWXiXYUI8XZcRWA_3c6MMaAfZ0kd10OhwsxWc9NKKXOTXlnryZLPKB0yfZ63Gt7BOM94gsVsvkoRd6bqe-vfXwYmxotL2rAzSKBZKimKgk__VETPGXcdcneIWycHhmRpH38UtrRi/s1600/ss.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="291" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZzYMSIWXiXYUI8XZcRWA_3c6MMaAfZ0kd10OhwsxWc9NKKXOTXlnryZLPKB0yfZ63Gt7BOM94gsVsvkoRd6bqe-vfXwYmxotL2rAzSKBZKimKgk__VETPGXcdcneIWycHhmRpH38UtrRi/s400/ss.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Screenshot of my web app</td></tr>
</tbody></table>
<b>Step 7: Configure web.xml</b><br />
Configure web.xml to map the URL to your servlet class. Below is my sample web.xml file.<br />
<br />
<script src="https://gist.github.com/3005687.js">
</script>
<br />
When a client visits http://localhost:8080/simple-servlet/example, the request is handled by the application server. Tomcat scans for the servlet-mapping containing the "/example" URL pattern, looks up the servlet-name which is "todo", matches the servlet-name to the right servlet , and routes the HTTP request to TodoServlet.class. Then TodoServlet.class executes its logic and returns a response back to the client through Tomcat.<br />
<div>
<br /></div>
<div>
<b> Step 8: Package web application into WAR file and deploy on Tomcat </b><br />
First, compile all source files. In a terminal/console, navigate to your project's root directory. Then type in "jar cvf simple-servlet.war .". This creates a WAR (Web application ARchive) which is simply a jar file with a .war extension. Drop this war file into your apache-tomcat-7/webapps directory and test by going to http://localhost:8080/simple-servlet/example. <br />
<br />
<br />
That's it! Your database-backed web application is up and ready to go. <br />
<br />
<b>Note:</b> Creating HTML in servlets is actually not a good practice. Ideally, you should use some type of view technology like JavaServer Pages or JavaServer Faces to move data between the view and logic layers. Also, the database login username and password should be passed in to the program as parameters instead of being hardcoded. For the purpose of keeping it quick and simple, I did not follow these guidelines in my project.<br />
<br /></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com16tag:blogger.com,1999:blog-1153485386302028606.post-7615468260170750322012-03-20T22:54:00.011-10:002012-03-21T07:16:01.363-10:00A ToDoList for the MassesI have started work on a new social media web app for sharing one's to-do list with friends and coworkers.<br />
<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/AVvXsEiAk5ISJ7tY5yyEgaYVDacqzMofs8-LL36DVbejia1wxg-co7ynIymfG7QirV441sHIAknjwnfwkeYrVVYDweZoxK8lWxlyMaXumtK96WoUbkCMvUG95neaHadxXMbTexWybdP818xWCw4Q/s1600/site.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAk5ISJ7tY5yyEgaYVDacqzMofs8-LL36DVbejia1wxg-co7ynIymfG7QirV441sHIAknjwnfwkeYrVVYDweZoxK8lWxlyMaXumtK96WoUbkCMvUG95neaHadxXMbTexWybdP818xWCw4Q/s640/site.png" width="622" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Initial proof of concept design.</td></tr>
</tbody></table>My motivations for this project are numerous:<br />
<ol><li>To fulfill a personal need for a web based to-do list.<br />
</li>
<li>To create something cool and learn some new skills along the way.<br />
</li>
<li>To build a free, open-source platform that provides a more efficient way for people to work together.</li>
</ol><div><br />
Here are some use cases:</div><div><ol><li>People who need a generic to-do list for everyday tasks like feeding the dog, buying milk, paying the bills, etc.<br />
</li>
<li>Students who want to sync up all class assignments and eliminate confusion on due dates. Teachers/professors will be able to form groups and electronically push assignments to their students.<br />
</li>
<li>People who need to work collaboratively in team projects. Developers already have tools like issue trackers, but what about the non-developer masses? Every single organization can benefit from project management tools.<br />
</li>
<li>Friends who want to know what their friends are up to.</li>
</ol></div><div><br />
I found a great site that offers free icons <b><a href="http://www.freeiconsweb.com/">here</a></b>.<br />
<br />
My project is hosted on GitHub <b><a href="https://github.com/linwdav/Todo-List">here</a></b>.<br />
<br />
Stay tuned for more updates!</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com1tag:blogger.com,1999:blog-1153485386302028606.post-9168398128785170432012-03-15T17:49:00.009-10:002012-06-26T17:36:28.489-10:00How to Set Up Play Framework 2.0 Javadocs for Eclipse<b><a href="http://www.playframework.org/">Play framework 2.0</a></b> was released a few days ago and many developers are wondering how to set up the Javadocs for Eclipse. The <b><a href="http://www.playframework.org/documentation/2.0/IDE">documentation</a></b> is quite lacking so I hope this post will show up on Google and save some people a few hours.<br />
<div>
<br /></div>
<div>
The Problem:</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/AVvXsEh78YRaeVblLHUNf-aarhnHkRbRIYQHKvlc60uHyLt5E6Z9wXB5x1EzyWvKtA6MQn7b2gJY9Xf8vVDoqPT2ZK8LE7yhh6UOQpLdENszazBEltvggQ72LgmcobhtZ8nFzMT8Q6rjXv8XL8_e/s1600/before.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="387" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh78YRaeVblLHUNf-aarhnHkRbRIYQHKvlc60uHyLt5E6Z9wXB5x1EzyWvKtA6MQn7b2gJY9Xf8vVDoqPT2ZK8LE7yhh6UOQpLdENszazBEltvggQ72LgmcobhtZ8nFzMT8Q6rjXv8XL8_e/s640/before.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">No Javadocs!</td></tr>
</tbody></table>
<div>
The Solution:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZYqc5ELeciHGc7-Xi82BXpgO_4_LzGhB4RDBdayW_aIA2mdSa1JrlZbp6RieIZ9XDfbqkJYZm31kdxdxlaoABPsgbHzca66Vbl50PGLK7XjjeDX2Zn8a6eYmYuGbJEMr2eHkr017vVsQ5/s1600/libraries.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="340" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZYqc5ELeciHGc7-Xi82BXpgO_4_LzGhB4RDBdayW_aIA2mdSa1JrlZbp6RieIZ9XDfbqkJYZm31kdxdxlaoABPsgbHzca66Vbl50PGLK7XjjeDX2Zn8a6eYmYuGbJEMr2eHkr017vVsQ5/s640/libraries.png" width="640" /></a></div>
<div>
<ul>
<li>In Eclipse, select your project in the Project Explorer</li>
<li>In the menu bar, select Project > Properties > Java Build Path > Libraries</li>
<li>Scroll down and look for play_2.9.1.jar</li>
<li>Click the arrow on play_2.9.1.jar and set the Source attachment and Javadoc location</li>
<li>Edit the Source attachment, click External Folder, and point to play-2.0/framework/src/play/src</li>
<li>Edit the Javadoc location, click Browse under Javadoc URL, and point to play-2.0/documentation/api/java</li>
</ul>
<div>
<br />
The Result:</div>
</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/AVvXsEjoCktMVjwV0ACEJf1wrrKDmlJSW1RP-w4life6h5XyC4EAAcFgOU0qf6q-A1RMZUwCkvBy5U-eYsBBEnHThn-GgzdYZIM4lWiQ3KuPSly2ufxkR0mBQbWXtmrDc9P6MMsDwJzVw_tnZF-z/s1600/after.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="506" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoCktMVjwV0ACEJf1wrrKDmlJSW1RP-w4life6h5XyC4EAAcFgOU0qf6q-A1RMZUwCkvBy5U-eYsBBEnHThn-GgzdYZIM4lWiQ3KuPSly2ufxkR0mBQbWXtmrDc9P6MMsDwJzVw_tnZF-z/s640/after.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Yay Javadocs!</td></tr>
</tbody></table>
<div>
Some other helpful tips:</div>
<div>
<br /></div>
<div>
Be sure to install the Scala plugin for Eclipse <a href="http://scala-ide.org/download/current.html"><b>here</b></a>. Play 2.0 now uses Scala so the plugin will fix any pesky problems in Eclipse where it can't resolve some classes and methods provided by the framework.</div>
<div>
<br /></div>
<div>
If you're using Git to host your Play projects, check out the sample .gitignore file <a href="https://github.com/linwdav/Todo-List" style="font-weight: bold;">here</a>. Just stick it into your Play project folder. It automatically excludes all Eclipse configuration files and makes it easy to work across multiple environments and developers.</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com8tag:blogger.com,1999:blog-1153485386302028606.post-89737029979277291442012-03-03T21:58:00.005-10:002012-03-04T20:41:38.651-10:00Tech News RoundupHere are some great sites for the tech-minded reader. They cover the entire gamut from software, hardware, startups, and science in general. I have these all bookmarked myself.<br />
<br />
Reddit - <a href="http://www.reddit.com/r/programming/">http://www.reddit.com/r/programming/</a><br />
<br />
HackerNews - <a href="http://news.ycombinator.com/">http://news.ycombinator.com/</a><br />
<br />
TechCrunch - <a href="http://techcrunch.com/">http://techcrunch.com/</a><br />
<br />
DZone - <a href="http://www.dzone.com/links/index.html">http://www.dzone.com/links/index.html</a><br />
<br />
DailyTech - <a href="http://www.dailytech.com/">http://www.dailytech.com/</a><br />
<br />
TechReport - <a href="http://techreport.com/">http://techreport.com/</a><br />
<br />
CNNMoney - <a href="http://money.cnn.com/technology/">http://money.cnn.com/technology/</a><br />
<br />
CNet News - <a href="http://news.cnet.com/">http://news.cnet.com/</a>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-63014943226314839772012-01-15T13:12:00.073-10:002012-02-22T13:36:10.724-10:00Parallel Image Processing<div>The emergence of AJAX, Facebook, Youtube, iPhone, iPad, and cloud computing has created the perfect storm for the greatest societal changes in history-- social media. We have become crazed consumers of content on the web. This blog post will explain the basics behind a digital image.</div><div><br />
</div><div>Videos are made up of frames. Think of the term 'frames per second'. A frame is just a still image. When you flash a bunch of frames at a rate of thirty per second, the human eye perceives it as video. Each frame can be edited individually to achieve various visual effects such as inversion or smearing.</div><div><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/AVvXsEiJRK6CNJVcSQmqq8OzOmYcdDactxRQv80RqFGFX0Ap4Z3yUt1Hq21k-sTGYjkG9YGl5GFG1b7J_BOxlIC1diocnB1zu3wT04QYHoHj3L4rui3ndhrfFVWJMWtkn0bfp08o7zcT2DLlxAnu/s1600/effect.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJRK6CNJVcSQmqq8OzOmYcdDactxRQv80RqFGFX0Ap4Z3yUt1Hq21k-sTGYjkG9YGl5GFG1b7J_BOxlIC1diocnB1zu3wT04QYHoHj3L4rui3ndhrfFVWJMWtkn0bfp08o7zcT2DLlxAnu/s400/effect.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This frame uses smear + black-and-white image filters.</td></tr>
</tbody></table><div><br />
Let's break it down a bit further. The first question is-- what is an image? An image is made up of a bunch of pixels. For example, a 100x100 resolution image has 100 rows and 100 columns for a total of 10,000 pixels.</div><div><br />
</div><div>Breaking it down even further, the second question is-- what is a pixel? A pixel is a dot of color. A pixel is a mixture of three different colors in the <b><a href="http://en.wikipedia.org/wiki/RGB_color_model">RGB model</a>--</b> red, green, and blue. Most images use 24-bit pixels with red, green, and blue taking 8 bits each. This allows for a depth range between 0 and 255 (8 bits unsigned can go up to 255). A depth range of 256 means that the color can have 256 different shades of intensity. Since the final pixel color is the result of mixing red, green, and blue together, the total number of possible pixel colors is 256*256*256 = 16,777,216. Many R,G,B charts like <a href="http://www.web-source.net/216_color_chart.htm" style="font-weight: bold;">this</a> can be found online.<br />
<br />
Let's recap. A video is made from images. An image is made from pixels. A pixel is made from three R,G,B values. Now that we've broken down the process completely, it is easy to understand that image processing boils down to the manipulation of individual pixels via their R,G,B values. For example, we can transform a black pixel into a white pixel by changing its R,G,B value from (0,0,0) to (255,255,255).<br />
<br />
We can apply a visual effect to an entire image by using something called an image filter. It is a fancy term for describing an algorithm that manipulates a set of pixels to achieve a certain effect. To show what goes on behind the scenes in actual code, I wrote two Java programs that take an image file as input, applies an invert/oil filter, then outputs the new image file. The full source code is available at my <b><a href="https://github.com/linwdav/Parallel-Image-Processing">GitHub project site</a></b>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5q6vdKnonIqMaqNmdHFT9wJ0ZRvl8l_XHMlwOOob6mFORBGjT50dwVrku4ed1L0VpIVMA9e82E9ojsjKg_u0grKU2cIQ5uSndIZfpXF-GJWnc-JdSqcxYes8uuowsYTekv03WjdVB4_6R/s1600/image.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5q6vdKnonIqMaqNmdHFT9wJ0ZRvl8l_XHMlwOOob6mFORBGjT50dwVrku4ed1L0VpIVMA9e82E9ojsjKg_u0grKU2cIQ5uSndIZfpXF-GJWnc-JdSqcxYes8uuowsYTekv03WjdVB4_6R/s200/image.jpg" width="150" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Original</td></tr>
</tbody></table><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyxmfSb_pMMly3I6UELt2zjvz2zGZV8UiJw7DZy6cfskQvFQTB9JhYPhlqv5DxJ3fbNiPdvwHhOf8GpGT4rtK-loFkxf48Yc1kPAOmaaaS6ucUN6VROQ_Cbf25Ye1U-_zl3RgjTQARNt4Y/s1600/inverted.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyxmfSb_pMMly3I6UELt2zjvz2zGZV8UiJw7DZy6cfskQvFQTB9JhYPhlqv5DxJ3fbNiPdvwHhOf8GpGT4rtK-loFkxf48Yc1kPAOmaaaS6ucUN6VROQ_Cbf25Ye1U-_zl3RgjTQARNt4Y/s200/inverted.jpg" width="150" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Inverted</td></tr>
</tbody></table><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfOhKL1BeaXezPh5stSvUFM8OJd1V3UpAwuVDq9AS7S4sHQNkGI6-a-QwRhA2k8vnUFLyGJRIk5qoAqKTipt72PSPMTsFCpOFGCWg7tjDUeOq65Q7EE8Cz4Sl4tOeO0G85yDBCth-E-_m/s1600/oiled.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfOhKL1BeaXezPh5stSvUFM8OJd1V3UpAwuVDq9AS7S4sHQNkGI6-a-QwRhA2k8vnUFLyGJRIk5qoAqKTipt72PSPMTsFCpOFGCWg7tjDUeOq65Q7EE8Cz4Sl4tOeO0G85yDBCth-E-_m/s200/oiled.jpg" width="150" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Oiled</td></tr>
</tbody></table><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<p>The algorithm for inverting an image is<br />
<ul><li>For each pixel (x,y) in the original image with (R,G,B) values:</li>
<li>Subtract 255 from the value of R</li>
<li>Do the same for the G and B values</li>
<li>For example, the inversion of a white pixel (255,255,255) is a black pixel (0,0,0)</li>
</ul><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/AVvXsEgCnB27XlkU2JfPu8Lw3uvCwO6HshjDWIOhOvLtCFBj2SUAgkkovn2VuZ8135Na8EAVFdbjFQ5yjBLxAber_dcAgacArj6ag1w1mhPfVX8zNz-Dd11r46EgITz84s80lXdMBvv6hVSeIagD/s1600/Screen+shot+2012-01-15+at+1.21.25+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCnB27XlkU2JfPu8Lw3uvCwO6HshjDWIOhOvLtCFBj2SUAgkkovn2VuZ8135Na8EAVFdbjFQ5yjBLxAber_dcAgacArj6ag1w1mhPfVX8zNz-Dd11r46EgITz84s80lXdMBvv6hVSeIagD/s1600/Screen+shot+2012-01-15+at+1.21.25+PM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The complete source code is available <a href="https://github.com/linwdav/Parallel-Image-Processing/tree/master/src" style="font-weight: bold;">here in ConcurrentInvert.java</a></td></tr>
</tbody></table><br />
The algorithm for oiling an image is<br />
<ul><li>For each pixel (x,y) in the original image with (R,G,B) values:</li>
<li>Replace the R value by the most common R value among all pixels with x-coordinates between (x - radius) and (x + radius) and with y-coordinates between (y - radius) and (y + radius)</li>
<li>Do the same for the G and B values</li>
<li>For example, if radius = 1, one must find the most common R,G,B values among 9 pixels (in a 3x3 grid). If radius = 2, one must find the most common R,G,B values values among 25 pixels (in a 5x5 grid)</li>
</ul><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/AVvXsEg9haZOx7aK-K6agzy6PDGtEBQ-j8o6Oep_hFcHSEV3q7m_wBArWOFSbGfJT68uJpaCT6HCIC-FR0G8LZdm0a7kSMS-vxbhmdA6IKdl4ch-tPpx1ww2w58EU3Y_c4WgebbqVG4fSBJeyODt/s1600/Screen+shot+2012-01-15+at+1.22.38+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9haZOx7aK-K6agzy6PDGtEBQ-j8o6Oep_hFcHSEV3q7m_wBArWOFSbGfJT68uJpaCT6HCIC-FR0G8LZdm0a7kSMS-vxbhmdA6IKdl4ch-tPpx1ww2w58EU3Y_c4WgebbqVG4fSBJeyODt/s640/Screen+shot+2012-01-15+at+1.22.38+PM.png" width="462" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The complete source code is available <a href="https://github.com/linwdav/Parallel-Image-Processing/tree/master/src" style="font-weight: bold;">here in ConcurrentOil.java</a></td></tr>
</tbody></table><br />
Inverting an image has a time complexity of O(n) so the program runs pretty quickly. However, oiling an image has a time complexity of O((2n+1)*(2n+1)*n) = O(4n^3 + 4n^2 + n) so it runs slower by several orders of magnitude.<br />
<br />
Luckily, we can achieve a big speedup by using parallelization, also known as multi-threading. The concept is simple. We create additional threads and split the pixels as evenly as possible across all cores.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyT-SEWreNHdPMCk4qm-4_HmxMsLc4qjC1mgsw85cEb7gn2fvFHiD3H_8k46kYFEee3BKI55FZSBxdNj5Gvpe0v_SFuw1nW0taYFHF-jGwlrJ4AAYOg1wePGvtUxmugchkIyMWLYk_ZBYO/s1600/Screen+shot+2012-01-15+at+12.10.49+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyT-SEWreNHdPMCk4qm-4_HmxMsLc4qjC1mgsw85cEb7gn2fvFHiD3H_8k46kYFEee3BKI55FZSBxdNj5Gvpe0v_SFuw1nW0taYFHF-jGwlrJ4AAYOg1wePGvtUxmugchkIyMWLYk_ZBYO/s1600/Screen+shot+2012-01-15+at+12.10.49+PM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Workload on a single thread </td></tr>
</tbody></table><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6oAm7HE85WZX3I44LNENVdu_N9sFCvLzkQ9-8fKZGJ1EioFTtHutOd40YG2r3Xa5i5zwmp39Zq4jM4MlqDfze3v6B86nOPFL5McBto_sRALzLU2Rg4atOGeABJn2mM8VCX6Vtl3lvBpt_/s1600/Screen+shot+2012-01-15+at+12.11.23+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6oAm7HE85WZX3I44LNENVdu_N9sFCvLzkQ9-8fKZGJ1EioFTtHutOd40YG2r3Xa5i5zwmp39Zq4jM4MlqDfze3v6B86nOPFL5McBto_sRALzLU2Rg4atOGeABJn2mM8VCX6Vtl3lvBpt_/s1600/Screen+shot+2012-01-15+at+12.11.23+PM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Workload on two threads</td></tr>
</tbody></table><br />
<br />
<br />
<br />
<br />
<br />
<br />
The caveat is that parallelization only works when the order of execution does not matter, or when the result of a computation does not depend on the result of another computation. For example, the following piece of code can be parallelized<br />
<br />
<br />
<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/AVvXsEibJ3zUiZwoPai6YftL4ENQ5hptM-FcesQqC5NbpWBlVuIm9N3RxGNPYFv8niuA_uIZOpiwPFZsKeKWlGPXeHN9pGCPtKes4MgudPnw84YsHcjcod9kCVVBcOEVzflggpo23nj4g6v5f9Uk/s1600/Screen+shot+2012-01-15+at+1.26.08+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibJ3zUiZwoPai6YftL4ENQ5hptM-FcesQqC5NbpWBlVuIm9N3RxGNPYFv8niuA_uIZOpiwPFZsKeKWlGPXeHN9pGCPtKes4MgudPnw84YsHcjcod9kCVVBcOEVzflggpo23nj4g6v5f9Uk/s1600/Screen+shot+2012-01-15+at+1.26.08+PM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The order in which this for loop executes does not matter. We could parallelize this computation across 2 threads by having the first thread compute iterations i=0 to i=4, and the second thread compute iterations i=5 to i=9.</td></tr>
</tbody></table><br />
whereas the next piece of code cannot be parallelized<br />
<br />
<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/AVvXsEiogFO-VfFS-qoP79K6InXCClwLsOyb5TQU8QMHRp8Ww7xHWlf2rwhpCJy1pqq7uzudFLUO0DGPRVleu8yn2SP6kGKs6kC0ePa8yQPoT820DqXkC-U0yUaRza8AYzG0FLuIAv-IQz8V6Ha4/s1600/Screen+shot+2012-01-15+at+1.26.18+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiogFO-VfFS-qoP79K6InXCClwLsOyb5TQU8QMHRp8Ww7xHWlf2rwhpCJy1pqq7uzudFLUO0DGPRVleu8yn2SP6kGKs6kC0ePa8yQPoT820DqXkC-U0yUaRza8AYzG0FLuIAv-IQz8V6Ha4/s1600/Screen+shot+2012-01-15+at+1.26.18+PM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The order in which this for loop executes does matter. We must compute iteration i=2 before i=3, i=3 before i=4, and so on.</td></tr>
</tbody></table><br />
Test results show that the algorithm for inverting and oiling an image is perfectly parallelizable and scalable to an infinite number of cores.<br />
<br />
<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/AVvXsEhQPlims2LPjVNzeDzDJdrTdWEWLoplcVNO8Ue8xw4fCye514I4zBHGaKHozamF-hvu4QK8yit6WSZs7gQhY51yoH639J2Buoi7x7pi_O6_bylydDlwztlP8brdkaTHGY1jYOIMq9JufPmy/s1600/invert.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPlims2LPjVNzeDzDJdrTdWEWLoplcVNO8Ue8xw4fCye514I4zBHGaKHozamF-hvu4QK8yit6WSZs7gQhY51yoH639J2Buoi7x7pi_O6_bylydDlwztlP8brdkaTHGY1jYOIMq9JufPmy/s640/invert.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Inverting the cliff image above is twice as fast on 2 cores vs 1 core</td></tr>
</tbody></table><br />
<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/AVvXsEguF1m7F2yxpGGwhSH2GdyIUQFDzMjs8rmF8kpLjlwPZbyNiI0opLCluYgSFHk07B4NqQvILsKRYhbRkaJAvRE7DI-h-bvtCiR7xPKhBE-Q7UPMclqAhzz4ACGE_WJVAho4K4OFXV_iuM7Y/s1600/oil.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguF1m7F2yxpGGwhSH2GdyIUQFDzMjs8rmF8kpLjlwPZbyNiI0opLCluYgSFHk07B4NqQvILsKRYhbRkaJAvRE7DI-h-bvtCiR7xPKhBE-Q7UPMclqAhzz4ACGE_WJVAho4K4OFXV_iuM7Y/s640/oil.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Oiling the cliff image above is twice as fast on 2 cores vs 1 core</td></tr>
</tbody></table><br />
The concepts presented here form the basic backbone of all digital image and video processing in programs like Photoshop, Final Cut Pro, and even the camera in your smartphone. In this age where image and video sharing is an epidemic on social media sites like Facebook and Youtube, I hope that readers have gained a better appreciation for how images and videos work.David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-80393132211642615572011-09-25T20:14:00.025-10:002012-07-01T11:58:49.972-10:00Multithreading with Java and SwingIt was seven years ago when Intel released the world's first <a href="http://en.wikipedia.org/wiki/Celeron#Celeron_D"><b>dual-core processor</b></a> for the consumer market. Back then, concurrency was completely new and anyone who knew how to program for multiple cores was considered a hotshot programmer. Physical limitations (mainly heat and power leakage) limited individual cores to operating frequencies of ~3.5 GHz. Their solution? <a href="http://en.wikipedia.org/wiki/Die_shrink" style="font-weight: bold;">Die shrinks</a> and multiple cores.<br />
<br />
<div style="text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3cw7qtGI-3pTofn0f-PWlxcETWkVxvxkfbPamKAcWTygnWWaQIQ0-lmnLuBT3_jUy6tR0df78h9XVHB2ijiruylEzli5Kz0wnxxcbND6mlci5bPoDFrvimCAkYlgSU3u5iFm4Tesx2a6g/s1600/intel_quad.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3cw7qtGI-3pTofn0f-PWlxcETWkVxvxkfbPamKAcWTygnWWaQIQ0-lmnLuBT3_jUy6tR0df78h9XVHB2ijiruylEzli5Kz0wnxxcbND6mlci5bPoDFrvimCAkYlgSU3u5iFm4Tesx2a6g/s200/intel_quad.jpg" width="200" /></a></div>
<br /></div>
Today, dual-core and quad-core processors have become mainstream in mobile electronics and home computers. As a result, concurrency skills are no longer considered a luxury, but a requirement for any serious developer. The rest of this post will detail my first recent experience with multithreaded programming using Java and Swing.<br />
<br />
Applications that have graphical user interfaces (GUIs) are naturally multithreaded. Usually you have one thread that draws the GUI, and another thread that runs the logic behind the scenes. By splitting these two tasks into separate threads, you can get a nice performance boost if each thread runs on a separate core. The GUI is quick n' snappy. The user is happy. And the developer is happy, well, for the most part if the job gets done correctly (issues of race conditions, deadlocks, and starvation may be covered in a future post).<br />
<br />
Moving on, Java SE6 provides two convenient libraries for getting our hands dirty with GUI-based multithreading, <b><a href="http://download.oracle.com/javase/tutorial/uiswing/components/index.html">Swing</a></b> and <b><a href="http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Thread</a></b>. I used these libraries to whip up an application to spawn multiple threads, assign a priority to each thread, perform a computationally intensive calculation in a loop, and report the average time for each thread to complete a calculation.<br />
<br />
<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/AVvXsEiVYe778i-IPw9vJlOMIXuF6hPRp1iON2xnwecFICuEUO69zZTPB3W99EFF6T6Wdk1pE2i9Jg5-Ccg_qspyvuV_Di2AS0Af_crHl5UQcBKfBUao0HLXzsn_sRWLgLi0dvpDs9xN9ShX_sGQ/s1600/Screen+shot+2011-09-26+at+6.39.45+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVYe778i-IPw9vJlOMIXuF6hPRp1iON2xnwecFICuEUO69zZTPB3W99EFF6T6Wdk1pE2i9Jg5-Ccg_qspyvuV_Di2AS0Af_crHl5UQcBKfBUao0HLXzsn_sRWLgLi0dvpDs9xN9ShX_sGQ/s640/Screen+shot+2011-09-26+at+6.39.45+PM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Screenshot of Swing application</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
The workflow for my Swing application is:<br />
<ol>
<li>Create the GUI elements like the frame, start button, dropdown lists, panels, checkboxes, and labels.</li>
<li>Attach an event listener to the start button.</li>
<li>Set the frame to visible with <i><span style="color: #0000c0; font-family: 'Courier New'; font-size: 10pt;">frame</span></i><span style="color: black; font-family: 'Courier New'; font-size: 10pt;">.setVisible(</span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">true</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;">).</span></li>
<li>Handle an event in the <span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px;"><a href="http://download.oracle.com/javase/1.4.2/docs/api/java/awt/event/ActionListener.html"><b>actionPerformed</b></a></span> method when the user clicks the start button. The event handler checks the number of threads that the user wants to start. Then it creates the threads with the user-selected thread priority.</li>
<li>Calculate the sum of the first 1000 cosines for 120 times in a loop for 3 minutes on each thread.</li>
<li>After each iteration of the loop, calculate the average amount of time it took (in milliseconds) to perform the calculation and update the GUI.</li>
</ol>
<div>
So how does this relate to GUI-based multithreading? Swing incorporates a separate thread called the <b><a href="http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html">Event Dispatch Thread (EDT)</a></b>. It is the thread that is responsible for <b>handling all events and updating the GUI</b>. This means that you, as a programmer, cannot manually update the GUI yourself in the main thread or a runnable thread that you have created yourself. To update a GUI component properly, you must either place your code in the <span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px;"><a href="http://download.oracle.com/javase/1.4.2/docs/api/java/awt/event/ActionListener.html"><b>actionPerformed</b></a></span> method (because it runs on the EDT), or place your code in another class and invoke it using the <span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px;"><b><a href="http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)">SwingUtilities.<i>invokeLater</i></a></b></span> method (which tells it to run on the EDT).</div>
<div>
<br /></div>
<div>
The main idea is to break the program into threads that perform background computation and thread(s) that update the GUI (the EDT does this for us). Since you want to keep the GUI responsive, and the EDT is responsible for updating the GUI, you don't want to have long-running pieces of code on the EDT. Instead, have the EDT spawn off new threads and run your (slower) code in these new threads. Proper usage of these concepts can be seen in my program and source code <b><a href="http://www2.hawaii.edu/~lindavid/ics432/ManyPanels.java">here</a></b>. Compile with "javac ManyPanels.java" and run with "java ManyPanels 0".</div>
<div>
<br /></div>
<div>
I ran an experiment to see how thread priority scheduling works on different operating systems. On a Windows machine with 2 cores and a Mac machine with 2 cores, I ran 10 threads with priorities ranging from 1 to 10. The first number under each panel indicates the average amount of time (in milliseconds) it took to get through one iteration, and the second number in parentheses indicates the number of iterations that the thread was able to execute in 3 minutes.</div>
<div>
<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/AVvXsEjGbUlBLFffLz47ALplKiTxdAEH05IyeqWzri213gQyNx5ph0H397AgxULJIiu4Sup3djfGU4hoHm5k8EjHIo1gY6ZVZMAecGWt1lDIydnrFKPLPn4pCV8vH5BrVYRtLL46qTUTtIzS_LrG/s1600/windowspriority.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGbUlBLFffLz47ALplKiTxdAEH05IyeqWzri213gQyNx5ph0H397AgxULJIiu4Sup3djfGU4hoHm5k8EjHIo1gY6ZVZMAecGWt1lDIydnrFKPLPn4pCV8vH5BrVYRtLL46qTUTtIzS_LrG/s640/windowspriority.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br />
Windows. Thread priorities are all over the place. A thread with priority 1 should not run faster than a thread with priority 8.</td></tr>
</tbody></table>
<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/AVvXsEh-c27n3zyC8_Bjtd9XibSp-jbjQxDOC6Ts2H-fDSb6VjUFkNeJWW8tI_PrAN8w7RFezvB568YAg1s76lk-ejZruVfnOsxD7hpnGAfPmoCHbwO1lJiwGImFEpsqVDA4iGZQvDls4DtmUwAx/s1600/Macpriority.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="144" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-c27n3zyC8_Bjtd9XibSp-jbjQxDOC6Ts2H-fDSb6VjUFkNeJWW8tI_PrAN8w7RFezvB568YAg1s76lk-ejZruVfnOsxD7hpnGAfPmoCHbwO1lJiwGImFEpsqVDA4iGZQvDls4DtmUwAx/s640/Macpriority.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Mac. Thread priorities are in order, with 1 running the slowest and 10 running the fastest.</td></tr>
</tbody></table>
The results show that thread priority scheduling in the JVM and Windows is completely unreliable, while thread priority scheduling in the JVM and Mac works as expected. This is food for thought for developers who program with thread priorities.</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com1tag:blogger.com,1999:blog-1153485386302028606.post-30565627759400126132011-07-25T16:01:00.031-10:002011-09-13T19:24:18.541-10:00How to Get SharePoint ASP.NET Auto Generated Control ID Using JavaScriptOne of the most irking problems I have encountered while working with ASP.NET are auto-generated server control IDs. My particular issue was figuring out how to gain a handle on the Hour and Minute fields in the DateTime object shown below<br />
<div><br />
<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/AVvXsEgD9Nt4iTSNJ_M3slqsvqx9xdNuGdVNsOhyphenhyphen6A-kceXEQyj6Ya9FrqZdmtrDtldp1GhPhBEazmItmmx5VaCL342sAbOibVKXNUjTI4PaanxfrUIxIjHNL79UjJcWBdEfXfQKBGXr8chDlKFm/s1600/ss.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="35" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD9Nt4iTSNJ_M3slqsvqx9xdNuGdVNsOhyphenhyphen6A-kceXEQyj6Ya9FrqZdmtrDtldp1GhPhBEazmItmmx5VaCL342sAbOibVKXNUjTI4PaanxfrUIxIjHNL79UjJcWBdEfXfQKBGXr8chDlKFm/s640/ss.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">SharePoint's version of the DateTimePicker</td></tr>
</tbody></table><div><br />
Everytime a client loads the page, the server generates its own ID for the Hour and Minute elements.</div><div><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/AVvXsEjUhmrCuWuXh6OXnESmUoA4q0b5PnJfNhABvhlhBtZlZY47h539sBfK5yioM_XzqMDBWSUIE5pcfOEem8hNpxzEnhgUBu2oJCG51Ys1VUpgRQbe62Qyk9zQ-Zyrf-MbtBpOk-3VpI_2bbkE/s1600/DateTimeField2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUhmrCuWuXh6OXnESmUoA4q0b5PnJfNhABvhlhBtZlZY47h539sBfK5yioM_XzqMDBWSUIE5pcfOEem8hNpxzEnhgUBu2oJCG51Ys1VUpgRQbe62Qyk9zQ-Zyrf-MbtBpOk-3VpI_2bbkE/s640/DateTimeField2.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">HTML for the Hour dropdown</td></tr>
</tbody></table><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/AVvXsEiQXq3G54ClkjhkXHqFFfWbIf-gE25u-DhlQ0GnpX62dVRCoFNAHKq5jRvVULzl58LMorRp_DlNcc2RbsAybeKtHANdAQzTXfsEQ9Lxq_h_xAYZHBr6-vkOsbUEP4_UTv4KePkr6cWc8J50/s1600/DateTimeField3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQXq3G54ClkjhkXHqFFfWbIf-gE25u-DhlQ0GnpX62dVRCoFNAHKq5jRvVULzl58LMorRp_DlNcc2RbsAybeKtHANdAQzTXfsEQ9Lxq_h_xAYZHBr6-vkOsbUEP4_UTv4KePkr6cWc8J50/s640/DateTimeField3.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">HTML for the Minute dropdown</td></tr>
</tbody></table><div><br />
As you can see in the screenshots above, ASP.NET mauled the client-side IDs with "ct100........."</div><div><br />
</div><div>Google searching yielded one possible solution: <%=#YourControlID.ClientID%>. I tried this and got "<i>An error occurred during the processing of Page.aspx. Code blocks are not allowed in this file.</i>" This error meant that my SharePoint environment was configured to stop any server-side code from being executed on the client-side. Asking my SharePoint administrator to relax the security settings would be pretty stupid so it was not an option.</div><div><br />
</div><div>After five additional hours of futile Google searching, I got lucky and found this <a href="http://sympmarc.com/2009/05/20/pre-filling-column-values-in-a-sharepoint-form/"><b>post</b></a> on Marc Anderson's blog. Although it was not a direct solution, it was something I could work with. I modified the function to return the control's client-side generated ID and used it with jQuery to gain a handle on the Hour and Minute fields.</div><div><span class="Apple-style-span" style="font-family: Consolas, 'Courier New', Courier, monospace; font-size: 13px; white-space: pre;"></span><br />
<pre style="color: black; font-family: Consolas, 'Courier New', Courier, monospace; margin-bottom: 8px; margin-left: 8px; margin-right: 8px; margin-top: 8px;"><span class="Apple-style-span" style="font-size: 13px;"><pre style="color: black; font-family: Consolas, 'Courier New', Courier, monospace; font-size: 1em; margin-bottom: 8px; margin-left: 8px; margin-right: 8px; margin-top: 8px;">$(document).ready(<span _mce_style="color: blue;" style="color: blue;">function</span>() {
<span _mce_style="color: green;" style="color: green;">// Get the control IDs of the DateTimePicker dropdowns</span>
<span _mce_style="color: blue;" style="color: blue;">var</span> startHourID = getTimeID(<span _mce_style="color: #a31515;" style="color: #a31515;">'ff3_1'</span>, <span _mce_style="color: #a31515;" style="color: #a31515;">'DateTimeFieldDateHours'</span>);
<span _mce_style="color: blue;" style="color: blue;">var</span> startMinuteID = getTimeID(<span _mce_style="color: #a31515;" style="color: #a31515;">'ff3_1'</span>, <span _mce_style="color: #a31515;" style="color: #a31515;">'DateTimeFieldDateMinutes'</span>);
<span _mce_style="color: green;" style="color: green;">// Get the hour and minute value from their IDs using jQuery</span>
<span _mce_style="color: blue;" style="color: blue;">var</span> startHour = $(<span _mce_style="color: #a31515;" style="color: #a31515;">"[id='"</span> + startHourID + <span _mce_style="color: #a31515;" style="color: #a31515;">"'] :selected"</span>).text();
<span _mce_style="color: blue;" style="color: blue;">var</span> startMinute = $(<span _mce_style="color: #a31515;" style="color: #a31515;">"[id='"</span> + startMinuteID + <span _mce_style="color: #a31515;" style="color: #a31515;">"'] :selected"</span>).text();
<span _mce_style="color: green;" style="color: green;">// Display the hours and minutes</span>
alert(<span _mce_style="color: #a31515;" style="color: #a31515;">"Hour: "</span> + startHour);
alert(<span _mce_style="color: #a31515;" style="color: #a31515;">"Minute: "</span> + startMinute);
});
<span _mce_style="color: green;" style="color: green;">/** Get the client-side ID of the Hours or Minutes control in the DateTimePicker field.
* @param fieldID The control's ID before being mauled client-side
* @param fieldType Use DateTimeFieldDateHours or DateTimeFieldDateMinutes
* @return The client-side ID
*/</span>
<span _mce_style="color: blue;" style="color: blue;">function</span> getTimeID(fieldID, fieldType) {
<span _mce_style="color: green;" style="color: green;">// Get all dropdown elements in the page</span>
<span _mce_style="color: blue;" style="color: blue;">var</span> tags = document.getElementsByTagName(<span _mce_style="color: #a31515;" style="color: #a31515;">'select'</span>);
<span _mce_style="color: blue;" style="color: blue;">var</span> controlID;
<span _mce_style="color: blue;" style="color: blue;">for</span> (<span _mce_style="color: blue;" style="color: blue;">var</span> i = 0; i < tags.length; i++) {
<span _mce_style="color: green;" style="color: green;">// alert(' tags[' + i + '].id=' + tags[i].id);</span>
<span _mce_style="color: green;" style="color: green;">// Find the element with the matching fieldID and fieldType</span>
<span _mce_style="color: blue;" style="color: blue;">if</span> (tags[i].id.indexOf(fieldID) > 0 && tags[i].id.indexOf(fieldType) > 0) {
controlID = tags[i].id;
}
}
<span _mce_style="color: blue;" style="color: blue;">return</span> controlID;
}</pre></span></pre></div><div><br />
</div><div>To get the control's client-side generated ID, simply call getTimeID with the appropriate parameters. The caveat here is that fieldID and fieldType must always be present in the generated ID <i>ctl00_PlaceHolderMain</i><i>_</i><i>g_dcc91698_d7a9_43a3_baf2_91d2ae764f94</i><i>_</i><i><b><span class="Apple-style-span" style="color: red;">ff3_1</span></b></i><i>_</i><i>ctl00</i><i>_</i><i>ctl00</i><i>_</i><i>DateTimeField</i><i>_</i><i><b><span class="Apple-style-span" style="color: red;">DateTimeFieldDateHours</span></b></i>. This function will not work if a completely random ID is generated each time the page is loaded because there will be nothing static for you to latch onto.<br />
<br />
To test whether I hooked on correctly to the Hour and Minute fields, I alerted their values.</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitJWMa2dFONt8-nCVv94ffP99JMtHZmt7DfRDiYMIQxTEw05n6LF3C4mzSuEIId50RWSCS3I8NIzoa_9KouJOqwhkyoU7gtVZV6_jYnzfuzJEFVH2pwr39Dp1eXXov_siao31-pxvoP_M3/s1600/DateTimeField5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitJWMa2dFONt8-nCVv94ffP99JMtHZmt7DfRDiYMIQxTEw05n6LF3C4mzSuEIId50RWSCS3I8NIzoa_9KouJOqwhkyoU7gtVZV6_jYnzfuzJEFVH2pwr39Dp1eXXov_siao31-pxvoP_M3/s320/DateTimeField5.jpg" width="320" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGI8UmTibMLviLw_TVH_zYdKyQQ3GelS_wLVDR48JYgSZJyW2D4wcbSqPvWz7DeRFzOakIGyVxGAQgGC3eRIj6N8nH6goFVOHTZPAY9ocJHguHcYZM0ugGIE2zMXnZvopJxj8j-kAr0ds3/s1600/DateTimeField4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGI8UmTibMLviLw_TVH_zYdKyQQ3GelS_wLVDR48JYgSZJyW2D4wcbSqPvWz7DeRFzOakIGyVxGAQgGC3eRIj6N8nH6goFVOHTZPAY9ocJHguHcYZM0ugGIE2zMXnZvopJxj8j-kAr0ds3/s320/DateTimeField4.jpg" width="320" /></a></div><div><br />
</div><div>I hope this saves many people hours of anguish. Happy coding!</div></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-82751229002734693432011-06-12T16:19:00.023-10:002011-09-23T01:10:29.405-10:00How to Build a Balanced Binary Search Tree From an Array<b><u>Problem</u></b><br />
<div>Create a balanced binary search tree from an array of <i>n</i> elements.</div><div><br />
</div><div><b><u>Solution</u></b></div><div>It's always easier to have an example to follow along with, so let the array below be our case study.</div><div><br />
</div><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPCRUTcex8nFOUwINwfmc1CIAUXr__SmgljmuokwhuXZq8WDp0ET8pravD2QOgtUJJRpiEiI5n2qHKxCldEprTF3umHELSK3qbye3o31kQ2nlXpyX4GLqx28ooS-VQh1ItItm7yrsvsD6g/s1600/array.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="36" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPCRUTcex8nFOUwINwfmc1CIAUXr__SmgljmuokwhuXZq8WDp0ET8pravD2QOgtUJJRpiEiI5n2qHKxCldEprTF3umHELSK3qbye3o31kQ2nlXpyX4GLqx28ooS-VQh1ItItm7yrsvsD6g/s320/array.JPG" width="320" /></a></div><div><br />
</div><div>The first step is to sort the array. The next step is to load the tree with these elements. A simple way to do it is to use binary search with recursion, except that we're adding an element to the tree instead of 'searching' for it.</div><div><div class="MsoNormal" style="margin-bottom: 0.0001pt; margin-left: 0in; margin-right: 0in; margin-top: 0in;"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"></span><br />
<div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span></span><span class="Apple-style-span" style="color: #3f5fbf; font-family: 'Courier New'; font-size: 13px;">/**</span><br />
<div class="MsoNormal"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * Create binary search tree.</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * </span><b><span style="color: #7f9fbf; font-family: 'Courier New'; font-size: 10pt;">@param</span></b><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> array of elements</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></div><div class="MsoNormal"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * </span><b><span style="color: #7f9fbf; font-family: 'Courier New'; font-size: 10pt;">@return</span></b><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> The root of the tree.</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></div><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> */</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">public</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> Node makeTree(String[] array) {</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">int</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> low = 0;</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">int</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> high = array.</span><span style="color: #0000c0; font-family: 'Courier New'; font-size: 10pt;">length</span><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> - 1;</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">return</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> makeTree(low, high, array);</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> }</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;">/**</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * Create binary search tree.</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * </span><b><span style="color: #7f9fbf; font-family: 'Courier New'; font-size: 10pt;">@param</span></b><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> low The lowest array position.</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * </span><b><span style="color: #7f9fbf; font-family: 'Courier New'; font-size: 10pt;">@param</span></b><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> high The highest array position.</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * </span><b><span style="color: #7f9fbf; font-family: 'Courier New'; font-size: 10pt;">@param</span></b><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> array of elements</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> * </span><b><span style="color: #7f9fbf; font-family: 'Courier New'; font-size: 10pt;">@return</span></b><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> The root of the tree.</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: #3f5fbf; font-family: 'Courier New'; font-size: 10pt;"> */</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">private</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> Node makeTree(</span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">int</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> low, </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">int</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> high, String[] array) {</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">if</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> (low > high) {</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">return</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">null</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;">;</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> }</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">else</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> {</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><span style="color: #3f7f5f; font-family: 'Courier New'; font-size: 10pt;">// Same as (low + high) / 2</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">int</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> mid = (low + high) >>> 1;</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> Node node = </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">new</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> Node(array[mid]);</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> node.</span><span style="color: #0000c0; font-family: 'Courier New'; font-size: 10pt;">left</span><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> = makeTree(low, (mid - 1), array);</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> node.</span><span style="color: #0000c0; font-family: 'Courier New'; font-size: 10pt;">right</span><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> = makeTree((mid + 1), high, array);</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> </span><b><span style="color: #7f0055; font-family: 'Courier New'; font-size: 10pt;">return</span></b><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> node;</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> }</span><span style="font-family: 'Courier New'; font-size: 10pt;"><o:p></o:p></span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: x-small;"><span style="color: black; font-family: 'Courier New'; font-size: 10pt;"> }</span></span></div></div><div class="MsoNormal" style="margin-bottom: 0.0001pt; margin-left: 0in; margin-right: 0in; margin-top: 0in;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt; margin-left: 0in; margin-right: 0in; margin-top: 0in;">The function recursively adds all the elements in the left subtree and then all the elements in the right subtree. Note that it works for edge cases where the input size is zero or one. The resulting balanced binary search tree is</div><div class="MsoNormal" style="margin-bottom: 0.0001pt; margin-left: 0in; margin-right: 0in; margin-top: 0in;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTJ9dJvtXhBLCOePZ0bcx3Eacd5JiGs4RSgYeXB9mpk9566oXRu8o1r5as8xOR2WjMPDKGDJ7vKDBHWzZRZ20Gt4jhTr6sFERTvxHykO7zOle_CEx9fvXmQ7AQwJOO6BoWUEasDZ7wWYI4/s1600/untitled.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTJ9dJvtXhBLCOePZ0bcx3Eacd5JiGs4RSgYeXB9mpk9566oXRu8o1r5as8xOR2WjMPDKGDJ7vKDBHWzZRZ20Gt4jhTr6sFERTvxHykO7zOle_CEx9fvXmQ7AQwJOO6BoWUEasDZ7wWYI4/s320/untitled.JPG" width="320" /></a></div><div class="MsoNormal" style="margin-bottom: 0.0001pt; margin-left: 0in; margin-right: 0in; margin-top: 0in;"><br />
</div><div class="MsoNormal" style="margin-bottom: 0.0001pt; margin-left: 0in; margin-right: 0in; margin-top: 0in;">Now the next question is, how do we check that the solution is correct? For this trivial example, we can verify it just by looking at the tree. We can see that every child on the left is less than its parent, and every child on the right is greater than its parent.<br />
<br />
For a large input with hundreds or thousands of elements, it would be too time consuming to draw and visually verify the tree like we did above. The solution to this proceeding problem will be in a future blog post which will cover preorder, inorder, and postorder tree traversals.</div></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPCRUTcex8nFOUwINwfmc1CIAUXr__SmgljmuokwhuXZq8WDp0ET8pravD2QOgtUJJRpiEiI5n2qHKxCldEprTF3umHELSK3qbye3o31kQ2nlXpyX4GLqx28ooS-VQh1ItItm7yrsvsD6g/s1600/array.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br />
</a></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com3tag:blogger.com,1999:blog-1153485386302028606.post-66521166829748259962011-06-05T20:58:00.152-10:002012-04-25T08:10:04.854-10:00Why Every Student Should Take A Software Engineering Course<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Software development is still a relatively young practice. Unlike traditional engineering where things are built to spec most of the time, we are still figuring out how to write applications that do not <a href="http://en.wikipedia.org/wiki/Therac-25" style="font-weight: bold;">irradiate people to death with high-powered electron beams</a>, <a href="http://www.bbc.co.uk/news/health-11572898" style="font-weight: bold;">cause wrong organs to be removed from donors</a>,<b> </b><b><a href="http://www.cbsnews.com/stories/2011/06/05/60minutes/main20066899.shtml">or plunge the stock market by 600 points in 15 minutes</a></b>. Software engineering attempts to solve these problems by adopting the traditional engineering practices of defining a systematic, disciplined, and quantifiable approach towards the development of software.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQp1FU-1m0zMKFO2gQYXOiaVA3bcnAsJ1GRkJ5kt5Qo8Y08kRfxQW8gcpYJ-QLLjdpi58UkWPD_nkChQKT1m9Z7547-oGVVrm53H2skuL-D6W4atSGHxOsPTL_xMWRxbbJivpUrGkh9gmM/s1600/gears.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQp1FU-1m0zMKFO2gQYXOiaVA3bcnAsJ1GRkJ5kt5Qo8Y08kRfxQW8gcpYJ-QLLjdpi58UkWPD_nkChQKT1m9Z7547-oGVVrm53H2skuL-D6W4atSGHxOsPTL_xMWRxbbJivpUrGkh9gmM/s200/gears.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
So why should a student majoring in computer science take a software engineering course before graduating? As a student, you most likely blew through your lower level classes like data structures, discrete mathematics, and algorithms without a clue of why or how any of it is relevant. The problem with traditional academia is that they teach a whole lot of theory without a whole lot of real-world application. If your university offers a software engineering course like <a href="https://sites.google.com/site/ics413fall2010/schedule"><b>mine</b></a>, take the opportunity to put theory into actual practice <i>while you're still in school and before you join the workforce</i>. You will learn how to develop a high quality software system in a team-oriented environment, and all the tools and concepts that come with it: </div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>1. Version control</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Version control is essential for the organization of multi-developer projects. The benefits of version control are revision tracking and source code management. Revision tracking records any changes to the project and attaches a timestamp to it. This is useful for tracking down bugs and it offers a chance to revert back to a previous version in case of a critical error.<br />
<br />
Source code management facilitates the merging of changes to a project. When multiple developers are working on different sections of code, source control (also known as version control) automatically merges their work together, or solves the problem that arises when their work involves the same lines of code.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
The two most popular version control systems today are <a href="http://subversion.tigris.org/"><b>Subversion</b></a> and <a href="http://git-scm.com/"><b>Git</b></a>.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnemYIHV6JtAETrdOD__FWv5lm2Tfpp_TckXBNuMo_FQgFGd1ML5bea-mv6urcZZLtQijfu3ZAuEI-NAksyFHDs7D5d8IF_rwq4r9g1TWEkm6jlbuoQoG0AyvkvI4BPcObvjsSW5lO2_wq/s1600/subversion.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="26" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnemYIHV6JtAETrdOD__FWv5lm2Tfpp_TckXBNuMo_FQgFGd1ML5bea-mv6urcZZLtQijfu3ZAuEI-NAksyFHDs7D5d8IF_rwq4r9g1TWEkm6jlbuoQoG0AyvkvI4BPcObvjsSW5lO2_wq/s200/subversion.png" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaEeHrjR-z6E3hA9_RlHbDNo8Fa5a9DYiZWBl-1l3CROxXElJay99pnmk9iffZJsbIKOxbrRan7NxMJJlltZ7TZiuqY5OkpRuIlbq4KcTpAhtXrL-tYNniLgcjx-6KRIWu5xWRjuKRwDk3/s1600/git.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="26" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaEeHrjR-z6E3hA9_RlHbDNo8Fa5a9DYiZWBl-1l3CROxXElJay99pnmk9iffZJsbIKOxbrRan7NxMJJlltZ7TZiuqY5OkpRuIlbq4KcTpAhtXrL-tYNniLgcjx-6KRIWu5xWRjuKRwDk3/s200/git.gif" width="200" /></a></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>2. Testing</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Would you buy a car without taking it for a test drive? Would you purchase a cool new smartphone without reading reviews on it? Would you test your next foothold if you were rock climbing without a rope? I think you get the idea. Testing does not guarantee that something works perfectly, but it is a good indicator of its <i>reliability</i>, especially if other people have already used it. If many people have used ProductX, and many people have said ProductX was good, then by inference, ProductX <i>is good</i>.<br />
<br />
In software, there are different types of testing. The most important types are unit and usability testing. Unit testing verifies that a function is working correctly by returning the expected value. However, it does not prove correctness because the expected value may not be the correct value. This is classified as a logical error on the programmer's part. Two popular testing frameworks are <b><a href="http://www.junit.org/">JUnit</a></b> for Java, and <a href="http://www.nunit.org/" style="font-weight: bold;">NUnit</a> for C#. There are other tools like <b><a href="http://www.blogger.com/"><span id="goog_958550906"></span>Jacoco<span id="goog_958550907"></span></a></b> that show you which sections of code have been run, thereby testing those sections of code.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhliNe6BHib3mmR5Cf75aNamCdZi4hlQx0IaN1IR284JacEYm5X-XrBlGpwuyOVop8S9dcCXzC4YiFUVDudXgQaOCua0lRe4pUcGjSlT_4nxaSd5i9uAcCP_PFGQt7MKURjpANdpJ5RlNXm/s1600/jacoco.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhliNe6BHib3mmR5Cf75aNamCdZi4hlQx0IaN1IR284JacEYm5X-XrBlGpwuyOVop8S9dcCXzC4YiFUVDudXgQaOCua0lRe4pUcGjSlT_4nxaSd5i9uAcCP_PFGQt7MKURjpANdpJ5RlNXm/s640/jacoco.JPG" width="640" /></a></div>
<br />
While unit testing verifies whether your code is up to par, usability testing verifies if you made good design choices. Would-be users literally use your software, point out problems, and suggest improvements. This is arguably the most critical type of testing because if would-be users are happy with your pre-release software, then they will also be happy with your post-release software.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>3. Build systems</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Build systems automate a variety of tasks such as: compiling source code into binary code, packaging binary code into an executable, deploying executable into a production system, creating documentation, and most importantly, running automated tests. A developer should be able to start a build in one step, or in other words, with one line in the terminal or one click of a button. If the build passes all phases of the process without any errors, then the software can be considered to be in a good, clean, shippable condition. Joel Spolsky explains more in depth the benefits of a build system <b><a href="http://www.joelonsoftware.com/articles/fog0000000023.html">here</a></b>.<br />
<br />
Two popular build systems are <b><a href="http://maven.apache.org/">Apache Maven</a></b> and <b><a href="http://ant.apache.org/">Apache Ant</a></b>.<br />
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFT8-syoPbLJQFEta0__UpJLV81NmEPuJXxKslVLWPX4JTXJOapobTQv5hBcPV-IQ6pXsbftNLKOMvrZ6MCdAlAAzpuYfAekTkSAswiRWVGzAh5qzeuVmis29Rb7iopdfl2BeUdyfy4Ctf/s1600/project-logo.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFT8-syoPbLJQFEta0__UpJLV81NmEPuJXxKslVLWPX4JTXJOapobTQv5hBcPV-IQ6pXsbftNLKOMvrZ6MCdAlAAzpuYfAekTkSAswiRWVGzAh5qzeuVmis29Rb7iopdfl2BeUdyfy4Ctf/s1600/project-logo.gif" /></a></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b>4. Software development lifecycle</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
A software engineer is responsible for the entire life cycle of a software project. This includes interacting with the client to gather requirements, designing a specification to meet those requirements, writing code that conforms to the specifications, testing the software, and maintaining the software post-release.<br />
<br />
Requirements gathering and design tend to be the most difficult phases because it requires a software engineer to fully understand what the client is asking for, in addition to the technologies and skills required to produce a solution.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz0HAVP0j0CUFcLMJYfamwJf9JtRPxXaq5NMMpLQOcMfr5776Ly9smET2gfKg255iov_z_0L1JH-QT3ML5mV2Kb0yO71tRcGFl_-q6yOULpRKK6v_39aSni_JGXBunrwUW0ZdhwOk59TRn/s1600/Waterfall_model.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz0HAVP0j0CUFcLMJYfamwJf9JtRPxXaq5NMMpLQOcMfr5776Ly9smET2gfKg255iov_z_0L1JH-QT3ML5mV2Kb0yO71tRcGFl_-q6yOULpRKK6v_39aSni_JGXBunrwUW0ZdhwOk59TRn/s320/Waterfall_model.png" width="320" /></a></div>
<b>5. Project management</b></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Contrary to popular belief, most software developers are not socially inept Asperger's geeks who sit in front of a computer and code all day. In a sufficiently large and challenging project, there are usually three or more developers working together as a team. This in itself requires project management, which is a concerted effort by team members to communicate and distribute tasks such that project goals can be successfully accomplished.<br />
<br />
Two popular project management platforms are <b><a href="http://code.google.com/hosting/">Google's Project Hosting</a></b> and <b><a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/team-foundation-server/overview">Microsoft's Team Foundation Server</a></b>. Both offer source control and task tracking to facilitate collaboration between developers.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIQ7b643-EES81cd-lJIp91bw1bqv0bqXJcQtwU1cAuQ1hi4Jl16tw_107Z1EDghoTvZPdC1g32S3X_mO0U0d_ycfJZ2RU-2vFYMgGtMA9YMPWCLpMysC7YdZ3rKzGgktWfOKM2FavMNIx/s1600/800px-Visual_Studio_2005_Team_Suite_with_a_bug_rate_report.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIQ7b643-EES81cd-lJIp91bw1bqv0bqXJcQtwU1cAuQ1hi4Jl16tw_107Z1EDghoTvZPdC1g32S3X_mO0U0d_ycfJZ2RU-2vFYMgGtMA9YMPWCLpMysC7YdZ3rKzGgktWfOKM2FavMNIx/s320/800px-Visual_Studio_2005_Team_Suite_with_a_bug_rate_report.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Why should every student take a software engineering course in college? Because it will teach students the fundamentals of developing a high quality software system and introduce them to the tools that professional developers use everyday. Not to mention that software engineering was rated the <b><a href="http://www.careercast.com/jobs-rated/10-best-jobs-2011">best job of 2011</a></b>.</div>
</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-3519399593065868982011-04-14T10:57:00.010-10:002011-06-08T19:17:47.756-10:00Career PlanIt's that time again when a computer science student needs to figure out what to do for the summer. Coincidentally, one of my professors made it an assignment to have each student reflect and present their career plans to everyone else in the class.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1_G6BiSE1ZTG1vMuQyXPBa_N3cCmxhMwLpSZfXSrmctNWPiiQGyTIPq95wsB1-Rlf5HIGm7wEmvcNQhhww1Zj8aOSszZUqs6JosvlAp9XF2EjG8bQw1A9q-Cb_KjLGmiNNhrnd1aBDJDn/s1600/Slide1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1_G6BiSE1ZTG1vMuQyXPBa_N3cCmxhMwLpSZfXSrmctNWPiiQGyTIPq95wsB1-Rlf5HIGm7wEmvcNQhhww1Zj8aOSszZUqs6JosvlAp9XF2EjG8bQw1A9q-Cb_KjLGmiNNhrnd1aBDJDn/s400/Slide1.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4yo6oWJBTrUF7woSyOANVXc955dyBN4K-FPHV1AFYUImUuQxJC-NoNIWMjZPRYvSNThKkWuuKY_vbn0befkFHMCEapyw5K38NmyosTP_Pgxrp03eSv5JTR-sYh5EQ99Oqd_9yPK39ernN/s1600/Slide2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4yo6oWJBTrUF7woSyOANVXc955dyBN4K-FPHV1AFYUImUuQxJC-NoNIWMjZPRYvSNThKkWuuKY_vbn0befkFHMCEapyw5K38NmyosTP_Pgxrp03eSv5JTR-sYh5EQ99Oqd_9yPK39ernN/s400/Slide2.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcyeBNI_ULMSkkJ-wyLTJmw9etwWkydZWwXA_uNziZhMiNd6wlkmsS2R5TQFKpYWDa_Fx6JYr05FaMcDyBWuB-sR6XYqSKmfqHGxhNY35uKeQ6N_MncgRgc6jtEjlpaomZJiScPyeNp7Hk/s1600/Slide3.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcyeBNI_ULMSkkJ-wyLTJmw9etwWkydZWwXA_uNziZhMiNd6wlkmsS2R5TQFKpYWDa_Fx6JYr05FaMcDyBWuB-sR6XYqSKmfqHGxhNY35uKeQ6N_MncgRgc6jtEjlpaomZJiScPyeNp7Hk/s400/Slide3.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil1nUWCw67gcBxAGvnDm-OU-obXUtsTD3_ewX8vHDsmPIITDLwrLqUX2MId3xM40pjOzOxnP8Cdd3p5SOyvcHmN69X391eSP_CWe8Di8cKTbq0QnMiq8i1PgWQCON7s8pa1YhAsmfcJpag/s1600/Slide4.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil1nUWCw67gcBxAGvnDm-OU-obXUtsTD3_ewX8vHDsmPIITDLwrLqUX2MId3xM40pjOzOxnP8Cdd3p5SOyvcHmN69X391eSP_CWe8Di8cKTbq0QnMiq8i1PgWQCON7s8pa1YhAsmfcJpag/s400/Slide4.JPG" width="400" /></a></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/AVvXsEj-BMZK5mu_Vn292hQokw8yT4Qt7T4jdZNC5skT4wtKRs_aq8vJxtwBL9Di48OkR6pvNLRNyYZgEL_HRbUKS8T9j5G1n7VDzAAt6dXV1n8dxYbUhtgAhvAAUA_qnJL2hxIa3D9r5eCZNBxv/s1600/Slide6.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-BMZK5mu_Vn292hQokw8yT4Qt7T4jdZNC5skT4wtKRs_aq8vJxtwBL9Di48OkR6pvNLRNyYZgEL_HRbUKS8T9j5G1n7VDzAAt6dXV1n8dxYbUhtgAhvAAUA_qnJL2hxIa3D9r5eCZNBxv/s400/Slide6.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb5GubwJKkPd_h-I8UenoEHAHVGnom0kOjTqb0eqfEteOLZWqc-yfcz0WIBzsUdoWaALw1DMc6xrAfcPUgSpDPY6qp8ekNNS-7RTV6F8bA-7azatK7TAd9efbdcL2q_wiBH3Bf16L4MmyP/s1600/Slide7.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb5GubwJKkPd_h-I8UenoEHAHVGnom0kOjTqb0eqfEteOLZWqc-yfcz0WIBzsUdoWaALw1DMc6xrAfcPUgSpDPY6qp8ekNNS-7RTV6F8bA-7azatK7TAd9efbdcL2q_wiBH3Bf16L4MmyP/s400/Slide7.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGOngNaVnDiCYI4BFohLnwoYs6Zi7Trc9wBmg3W6mT7rhvvtYV703pOqjrHOFHRvKwvXcC81nZzPrYTeGjbPWcHBA5sDo6aP9ZCoAevLzpb6j6j5ucDqgBARmwtQ8cuk4hVuV9vp7wiVLq/s1600/Slide8.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGOngNaVnDiCYI4BFohLnwoYs6Zi7Trc9wBmg3W6mT7rhvvtYV703pOqjrHOFHRvKwvXcC81nZzPrYTeGjbPWcHBA5sDo6aP9ZCoAevLzpb6j6j5ucDqgBARmwtQ8cuk4hVuV9vp7wiVLq/s400/Slide8.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHaZks47rQJ8CSu9DX3FLUt5ZjWYzVS3OOjXkrJFgDxLmtSGr3Qo9YlOYT8H9rQEHQuMJtAOETR0t9dAdkPQ96_z0ewsZv5r41VidAQNhq82XNXahPqmU-UYFPlkefRe1874tjTMg0KZ45/s1600/Slide9.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHaZks47rQJ8CSu9DX3FLUt5ZjWYzVS3OOjXkrJFgDxLmtSGr3Qo9YlOYT8H9rQEHQuMJtAOETR0t9dAdkPQ96_z0ewsZv5r41VidAQNhq82XNXahPqmU-UYFPlkefRe1874tjTMg0KZ45/s400/Slide9.JPG" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjROr2D3TImPU2urcaR8Kgjc8jjV46vUl_sUX1RX6e_CC7TJd5-fWIXmMfS6rB5JKMpYkuuv4nswLw3LuDCxJ2yBB9ME1AaZeQom9A4GPUHkOIUfMqXIOluqickAEEYwFWi6FGZ-P7HTyJc/s1600/Slide10.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjROr2D3TImPU2urcaR8Kgjc8jjV46vUl_sUX1RX6e_CC7TJd5-fWIXmMfS6rB5JKMpYkuuv4nswLw3LuDCxJ2yBB9ME1AaZeQom9A4GPUHkOIUfMqXIOluqickAEEYwFWi6FGZ-P7HTyJc/s400/Slide10.JPG" width="400" /></a></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-24649666612837513442011-02-07T18:36:00.008-10:002011-09-13T19:18:54.946-10:00API DesignAs a software developer, I have used a number of APIs for programming languages, documentation writing, web frameworks, etc. Like many who are starting out in the field, I did not think I would ever need to write an API... until now. Before delving into the details of my experience in API design, let us start with the basics.<br />
<div><br />
</div><div>API stands for Application Programming Interface. An example is the <b><a href="http://download.oracle.com/javase/6/docs/api/">Java SE6 API</a></b>. An API documents the sets of rules that define how software systems can interact with each other, and the boundaries for what a programmer can do. For an easy analogy, a LCD TV manual lists all of the possible ways to use the TV, from turning it on via the power button to changing color temperatures via a combination of buttons. Likewise, an API is the programmers' manual that describes the functions that can be used to do something useful.</div><div><br />
</div><div>APIs are not written only for programming languages, but for a wide variety of technologies including applications, libraries, operating systems, etc. They are sometimes synonymous to the terms "reference guide" or "reference manual". The technology for which I have designed and written an API is the <b><a href="https://sites.google.com/site/ics414spring2011/ihale/requirements">iHale system</a></b>. The top-level architecture can be visualized as follows:</div><div><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://sites.google.com/site/ics414spring2011/ihale/requirements/architecture.3.jpg?attredirects=0" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="205" src="https://sites.google.com/site/ics414spring2011/ihale/requirements/architecture.3.jpg?attredirects=0" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Diagram of the iHale system.</td></tr>
</tbody></table><br />
<div><span class="Apple-style-span" style="font-family: inherit;">The iHale API serves as a point of interaction between the house systems, web user interface, repository, and other optional interfaces. I designed a <b><a href="http://code.google.com/p/solar-decathlon-teamhawaii/wiki/iHaleRestApiHoike">REST API</a></b> and a <b><a href="http://code.google.com/p/solar-decathlon-teamhawaii/source/browse/#svn%2Ftrunk%2Fhoike%2Fsrc%2Fedu%2Fhawaii%2Fihale%2Fapi">Java API</a></b>. The REST API specifies how the different house systems and optional interfaces communicate with the iHale system through HTTP requests and commands. The Java API specifies how information is stored and retrieved in the repository based on the HTTP requests it receives.</span></div><div><br />
</div><div>Designing the APIs was not particularly challenging because I had already written user stories and had a sense of what the possible requirements were. For example, the <b><a href="http://code.google.com/p/solar-decathlon-teamhawaii/wiki/iHaleRestApiHoike#Aquaponics_Resource">Aquaponics system</a></b> would need to support functions to return information pertaining to water volume, temperature, PH, oxygen level, and time of data procurement. However, this may not fully describe all the fields and functions required for the aquaponics system.</div><div><br />
</div><div>As we make progress on the solar decathlon project in the following weeks, my team and I will gather requirements in greater detail by speaking with the engineers and referring to specification sheets for the sensors and meters that will be used in the house. As we gain a better understanding of what is possible and what isn't, we will revise and update our API.</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-64537486656531233732011-01-30T09:24:00.019-10:002011-09-13T19:20:37.989-10:00Berkeley DBBerkeley DB is a Java based non-relational database that is scalable and offers multiple thread and process support. This is ideal for use in the Solar Decathlon home management system, now renamed to <b><a href="https://sites.google.com/site/ics414spring2011/ihale/requirements">iHale</a></b>. The main idea is shown in the diagram below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"></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/AVvXsEjxdQYKSOtfEfpVfelZjUJ8bHRMGzfoMyNMSeX4pOsvx0mUKNCYzn1RCla1nyDM7wTsJeXjFg1XtdhI7XBcknqdpssZxo2ioRnIYccLM7QwLohcxcSL23IgcmLirMoW8veUHVuXmKQ5_1L5/s1600/diagram.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxdQYKSOtfEfpVfelZjUJ8bHRMGzfoMyNMSeX4pOsvx0mUKNCYzn1RCla1nyDM7wTsJeXjFg1XtdhI7XBcknqdpssZxo2ioRnIYccLM7QwLohcxcSL23IgcmLirMoW8veUHVuXmKQ5_1L5/s320/diagram.JPG" width="306" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Client-server-database communication</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: left;">On the client side, Wicket provides the front end user interface via a webpage. Through this webpage, a user may request to perform a GET, PUT, or DELETE operation. The client communicates to the server via HTTP over the Restlet framework, where the request is interpreted and executed by the server. Information in the database is persisted through a file saved on the disk.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">To get familiar with Berkeley DB, I worked on two code katas that dealt with the storage and retrieval of contacts. These were modified versions of the katas I completed on Restlet in the last two blog posts. More details can be seen <b><a href="https://sites.google.com/site/ics414spring2011/modules/persistency">here</a></b>.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><b>Kata 1: Timestamp as a secondary index</b></div><div class="separator" style="clear: both; text-align: left;">The primary index for a contact is their unique ID. This means that entries can be added or searched in the database via a unique ID. The task was to add a timestamp as a secondary index. The timestamp is appended to a contact when it is created. The most time-consuming part of Kata 1 was writing unit tests and learning Berkeley DB's API to query the database. It was fairly straightforward and took about 3 hours to complete.</div><div class="separator" style="clear: both; text-align: left;"><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/AVvXsEgv_Ya4xr-3QSE3a-UgIbrrcA2u9uL8QPQ6qXXhFXJhUwgwn3Cyu3CW2fOUfE0bBvPOtukiEqtUKq1P0XAmE5DMc5uLnBAqaNDAu5a8GSkc1pheQvpTxB9Zt5CzSyCyoZLVv5yaaXTA8SRm/s1600/kata1.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv_Ya4xr-3QSE3a-UgIbrrcA2u9uL8QPQ6qXXhFXJhUwgwn3Cyu3CW2fOUfE0bBvPOtukiEqtUKq1P0XAmE5DMc5uLnBAqaNDAu5a8GSkc1pheQvpTxB9Zt5CzSyCyoZLVv5yaaXTA8SRm/s400/kata1.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Command line usage of all the available operators: put, get, get-timestamp, get-range.</td></tr>
</tbody></table><br />
<div class="separator" style="clear: both; text-align: left;"><b>Kata 2: Wicket, REST, and Berkeley DB: A match made in heaven</b></div><div class="separator" style="clear: both; text-align: left;">This kata is a combination of all the technologies I have learned so far which includes Wicket, REST, and Berkeley DB. It combines the use of Wicket in Restlet Part I, concepts of persistency from Restlet Part II, and Berkeley DB from Kata 1 above. The difference is that contact information is now persisted in a file on the disk via Berkeley DB instead of in-memory.</div><div class="separator" style="clear: both; text-align: left;"><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/AVvXsEjFWFehD8Jcsk-Uz6sLZZ5ihPO3_HS_vXWtzNxuhv8WE76rmpIWERPdUjFrzal11XlrldqiujjO5MDCwdj_HyLirzp9421BUz7446lk9WvJe4MrBYiTqfcCHMI4lnt8D-FMjwKJauStzEgr/s1600/kata2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFWFehD8Jcsk-Uz6sLZZ5ihPO3_HS_vXWtzNxuhv8WE76rmpIWERPdUjFrzal11XlrldqiujjO5MDCwdj_HyLirzp9421BUz7446lk9WvJe4MrBYiTqfcCHMI4lnt8D-FMjwKJauStzEgr/s400/kata2.JPG" width="305" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Webpage for adding entries and querying the database.</td></tr>
</tbody></table><div class="separator" style="clear: both; text-align: left;"><br />
</div>The overall layout of Wicket, REST, and Berkeley DB is readily understood, but getting it all working properly together is a whole different story. So far, this kata has been a debug-fest. It took about 5 hours to code the core Wicket, resource server, database, and ant build files, but debugging has taken over 7 hours.<br />
<div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Some of the problems I encountered were trivial, such as forgetting to attach the timestamp to a contact XML document. These resulted in exceptions when trying to get or put a contact into the database. Other problems were due to communication errors between Wicket and the resource server, which resulted in odd exceptions such as Internal resource error 500. I was able to resolve these by desk checking my code several times.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">The lessons that I learned from this exercise is that one must be extra careful when copying and pasting code from working modules in past projects. This method is extremely error-prone. Also, it is ideal to import small portions of code at a time and perform frequent testing instead of importing huge blocks of code all at once and testing everything afterwards.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">The final distribution of my katas can be downloaded <b><a href="https://sites.google.com/site/linwdav/wicket-katas/berkeleydb-contactdb-lindavid-1.0.130.zip?attredirects=0&d=1">here</a></b>.</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com1tag:blogger.com,1999:blog-1153485386302028606.post-22607442016097250762011-01-22T23:48:00.026-10:002011-09-13T19:21:52.584-10:00Restlet Part II<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">In continuation from Restlet Part I, Part II includes three new katas that exercised the use of GET, PUT, and DELETE operators. It was many times more difficult to implement because it required six different components to interact with each other: a client, record of a client, in-memory persistent database, server for accessing the database, server for handling individual requests for a contact, and a server for handling requests for all contacts in the database. More details can be found <a href="https://sites.google.com/site/ics414spring2011/modules/rest"><b>here</b></a>.<br />
<br />
<b><span class="Apple-style-span" style="font-family: inherit;">Kata 5: Contacts resource</span></b><br />
<span class="Apple-style-span" style="font-family: inherit;">The task was to add a new resource that returns an XML representation of all the contacts in the database. In other words, the contacts were stored in a Java collection and the goal was to transform it into an XML document. At first I felt overwhelmed, but I identified the steps required to get the job done in about 4 hours:</span><br />
<ol><li><span class="Apple-style-span" style="font-family: inherit;">Create an XML document.</span></li>
<li><span class="Apple-style-span" style="font-family: inherit;">Iterate through each contact in the collection, then attach it to the document.</span></li>
<li><span class="Apple-style-span" style="font-family: inherit;">Return the XML document when the servers asks for this resource.</span></li>
</ol><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/AVvXsEg8CTnfaKoRRgn1ic79lcSAJc5Z6B_it7uSAMIh8tE6nBmOhqB_yrU9gfcMovzBb6EPSNcMWcpuHDS4Tr-F0XdpzpfASZjmAOMCXaqXeTDw_ZTPniFLxI0rKdDt_VM9vd3EGkTFZqU7kgDl/s1600/kata5.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8CTnfaKoRRgn1ic79lcSAJc5Z6B_it7uSAMIh8tE6nBmOhqB_yrU9gfcMovzBb6EPSNcMWcpuHDS4Tr-F0XdpzpfASZjmAOMCXaqXeTDw_ZTPniFLxI0rKdDt_VM9vd3EGkTFZqU7kgDl/s400/kata5.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">XML representation of contact resources in the database</td></tr>
</tbody></table><br />
<b><span class="Apple-style-span" style="font-family: inherit;">Kata 6: Command line client manipulation of Contacts resource</span></b><br />
<span class="Apple-style-span" style="font-family: inherit;">The task was to extend the command line client functionality to include additional operators "get-all" and "delete-all". The get-all operation would retrieve all contacts in the database, retrieve their respective URLs, then print out contact information. The steps required to do this was similar to Kata 5 but in reverse; an XML representation of a contact had to be transformed into its Java representation. This kata took about 5 hours to complete because I had to look online and learn how to play with XML nodes.<br />
</span><br />
<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;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTgD0E7puz0nHO48Qh5RpYeNpcnJ-rDza_gk1TnoQGntcr2GkZ88-She5ByrA5SM3vi7Af7lHklQaaSPg3paMZe2_7hxsZBwmzmV7Yor7bvTl8BlV_taMc7UgOS4Kz_aJjX2QymHY7cAMo/s1600/kata6.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTgD0E7puz0nHO48Qh5RpYeNpcnJ-rDza_gk1TnoQGntcr2GkZ88-She5ByrA5SM3vi7Af7lHklQaaSPg3paMZe2_7hxsZBwmzmV7Yor7bvTl8BlV_taMc7UgOS4Kz_aJjX2QymHY7cAMo/s400/kata6.JPG" width="400" /></a></div></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Printout of contact information after calling the get-all operator</td></tr>
</tbody></table><br />
<b><span class="Apple-style-span" style="font-family: inherit;">Kata 7: Add a telephone number to the Contact resource</span></b><br />
<span class="Apple-style-span" style="font-family: inherit;">The task was to extend the Contact resource to include a person's phone number. In addition, the server would check to see if it was in the correct format ###-####. If not, it would throw an error. This kata was particularly easy and took about 1 hour to complete.<br />
</span><br />
<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/AVvXsEjW0eeNTTRw85UzEPlQc7fjHn4WVGn0EWwkzUChUVUiFjeYHhJM8qV_l7G3rF3XBVnwH66jzubZfN9JdeQPNcieIbg8ppdanpJ_IG3zD2IshejBqDyERp1bI3EDBcRrQswjx1FvdAW564Wm/s1600/kata7.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW0eeNTTRw85UzEPlQc7fjHn4WVGn0EWwkzUChUVUiFjeYHhJM8qV_l7G3rF3XBVnwH66jzubZfN9JdeQPNcieIbg8ppdanpJ_IG3zD2IshejBqDyERp1bI3EDBcRrQswjx1FvdAW564Wm/s400/kata7.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Error code 417 when the phone number does not adhere to the xxx-xxxx format</td></tr>
</tbody></table><br />
By completing these katas, I learned how to implement a RESTful client and server system that uses an in-memory persistent database. I also improved my skills in performing meaningful unit testing to meet quality assurance standards.<br />
<br />
A distribution of my work can be downloaded <a href="http://www2.hawaii.edu/~lindavid/ics413/restlet-contactservice-lindavid-1.0.122.zip"><b>here</b></a>.</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-28661173495856068872011-01-18T11:18:00.019-10:002011-09-13T19:22:26.940-10:00Restlet Part I<div class="separator" style="clear: both; text-align: center;"><a href="http://www.restlet.org/"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw0o0XFSfDHGLIM3re-UbnAyMcoKF2TBtn8iCITotLaLxxxnXK711Vp9NrxwECOkhh6gl1_FawvMU4ltuitqe9SaOhmspSilS6bVz9RhPhUqDODXaw3Mx9WxPrtNJEYDwG6JSH7FYAWrBk/s1600/logo200.gif" /></a></div><br />
Representational State Transfer (REST) is a software architecture designed for use on the web. Whereas the web is mainly used for interaction between a client and a server, REST allows for interaction between servers themselves. It relies on an architectural usage of HTTP URLS which includes resources and verbs such as GET, PUT, DELETE, and POST. For example, http://hawaii.com/news would have the resource (hawaii.com) and the verb GET (news). Its action is to retrieve news from Hawaii.<br />
<br />
A system like REST can be implemented with a Java framework called Restlet, which is the topic for today's blog post. To introduce myself to this new framework, I practiced on four Restlet Code Katas. Additional information on these katas can be found <a href="https://sites.google.com/site/ics414spring2011/modules/rest"><b>here</b></a>.<br />
<br />
<b>Kata 1: Time resources</b><br />
The task was to add three new resources to return the current hour, minute, and second. I completed it in about 10 minutes. Since it was the first introductory kata, the most difficult part was figuring out the actual resource and verb, which was localhost:8111/dateservice/[hour/minute/second].<br />
<br />
<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/AVvXsEgHszuNMG9IYKzEQgfKzBQ3Mzen1pmbk5fEj9lWp7EKbA6Ir0k2GF5uGmXvY9u-f3nBj6_XqSnnwpHV67ikBzJq3dM3omquDTkwwJaORofd9H6k-dlQ-1o60mfIj7YP-TeH4RNgVzR4fpUf/s1600/kata1.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHszuNMG9IYKzEQgfKzBQ3Mzen1pmbk5fEj9lWp7EKbA6Ir0k2GF5uGmXvY9u-f3nBj6_XqSnnwpHV67ikBzJq3dM3omquDTkwwJaORofd9H6k-dlQ-1o60mfIj7YP-TeH4RNgVzR4fpUf/s400/kata1.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The current month is January so the output corresponds to 0.</td></tr>
</tbody></table><b>Kata 2: Logging</b><br />
The task was to log Restlet's messages into a log file instead of having it display in the console. The program was to read configuration settings from a properties file and use a handler to record all messages into a text file. I completed this in about 2 hours. The bulk of the time was spent trying to understand the whole process and just figuring out how to get it done. A really handy explanation of logging is explained <a href="http://www.crazysquirrel.com/computing/java/logging.jspx">here</a>.<br />
<br />
<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/AVvXsEgockHZYAFvVdR-3Ew5WOynuhu-gAjjrlDmoj7ke0oF02COfI6Y3q-RmiIfgxP8bTRvkjikXxT5-ghOzSnx8gD34XbaztpLn8Bd-rIwoEoo7gf5CDgnb2VCMl8rdOJ5hW95LuCSSmiHkUSG/s1600/kata2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgockHZYAFvVdR-3Ew5WOynuhu-gAjjrlDmoj7ke0oF02COfI6Y3q-RmiIfgxP8bTRvkjikXxT5-ghOzSnx8gD34XbaztpLn8Bd-rIwoEoo7gf5CDgnb2VCMl8rdOJ5hW95LuCSSmiHkUSG/s400/kata2.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Console output from Restlet is recorded into this log file.</td></tr>
</tbody></table><br />
<b>Kata 3: Authentication</b><br />
The task was to authenticate a user by asking for a username and password and verifying it against locally stored credentials. Similar to Kata 2, this took me about 2 hours to complete. Nearly all of the time was spent on research. The solution can be found <a href="http://wiki.restlet.org/docs_2.1/13-restlet/27-restlet/46-restlet/112-restlet.html"><b>here</b></a>. Most of the problems I had were finding only outdated articles. One article recommended using the class Guard, which was dated back to Java 1.4.<br />
<br />
[Update (Jan. 24): I discovered that this feature is buggy. The application does not always challenge the user with a username and password even after the server has been restarted. I will update this section with an appropriate screenshot and reupload a new .zip distribution file once I figure out the problem.]<br />
<br />
<b>Kata 4: Wicket</b><br />
The task was to create a client that could access the server via a webpage instead of the command line. This required the use of the Wicket web framework. I was able to complete this kata with about 6 hours of effort. Several hours were wasted in debugging a client-to-server connection issue. At first, I thought it might have been due to authentication but it turned out to be trivial problem. The issue was due to a simple mismatch in ports; the server was being hosted on port 8111 but the client was trying to connect to 8112.<br />
<br />
<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/AVvXsEj0_kQKJtYuNkJVbdiSXK-ZAKPbhZZUBmmome4VIO50AhZDH2r_69Nty4jKG47TKiJKvQjxWDBuXCvdkAjXBB-J2rsFLcmEzvlTVM9snvr0hdhQ78CpygiL9dAoBbNRftNQs5FrD2FwGrxo/s1600/kata4.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0_kQKJtYuNkJVbdiSXK-ZAKPbhZZUBmmome4VIO50AhZDH2r_69Nty4jKG47TKiJKvQjxWDBuXCvdkAjXBB-J2rsFLcmEzvlTVM9snvr0hdhQ78CpygiL9dAoBbNRftNQs5FrD2FwGrxo/s400/kata4.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Basic webpage with buttons for requesting the date.</td></tr>
</tbody></table><br />
By completing these four katas, I learned the concepts of the Restlet framework. I also learned the basics of networking in setting up a client and server side system. <br />
<br />
A distribution of my files are available <a href="http://www2.hawaii.edu/~lindavid/ics413/restlet-dateservice-lindavid-1.0.124.zip"><b>here</b></a>.David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-79064750933672461572010-12-17T02:32:00.012-10:002011-09-13T19:22:47.091-10:00Solar Decathlon Design 3For this third round of design for the Solar Decathlon's home management system,<b> <a href="http://code.google.com/p/solar-decathlon-teamhawaii-3/">my team</a></b> and I developed a web application using HTML, CSS, and Wicket. We used our Balsamiq mockup designs from earlier on as the basis for the general look and feel of each page. However, our actual implementation in HTML turned out to be dramatically worse than the look of our mockup design. We decided to break off from our initial design and gave the interface a major facelift.<br />
<br />
<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/AVvXsEg_ggY-7wEatxs7uOvJ-_tm68Gwf0kBNzdxO2QrRXo39DmAqaaXKuPOQ7df_evGikhYIDP8f4mqX3lsvYE9fKsVa0mWT3Xyi6-fuuJ5qwJpbtvxJpCZELSbL62whZhrw3VgQj2I4uepIQMJ/s1600/AC.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="293" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_ggY-7wEatxs7uOvJ-_tm68Gwf0kBNzdxO2QrRXo39DmAqaaXKuPOQ7df_evGikhYIDP8f4mqX3lsvYE9fKsVa0mWT3Xyi6-fuuJ5qwJpbtvxJpCZELSbL62whZhrw3VgQj2I4uepIQMJ/s400/AC.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Balsamiq mockup design</td></tr>
</tbody></table><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/AVvXsEgRjgsXgsJjEsOkOVYsw76cy-fjVXeJ7JcuNCqc5iMkldKEhl5TetrByE9iUpdKrcvJ6NB2-AUUYnajKBh56ahyphenhyphen-EV6O6DDXfqUv26kAUASIxKUHjEXlweId6RSML1QrtIA9NUxFXPFlzi_/s1600/AC2.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRjgsXgsJjEsOkOVYsw76cy-fjVXeJ7JcuNCqc5iMkldKEhl5TetrByE9iUpdKrcvJ6NB2-AUUYnajKBh56ahyphenhyphen-EV6O6DDXfqUv26kAUASIxKUHjEXlweId6RSML1QrtIA9NUxFXPFlzi_/s400/AC2.PNG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First round of implementation</td></tr>
</tbody></table><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/AVvXsEio_9l2yiDp5o4fikq9vNQhGkI2DJSVo40Zskqw5AXbd8c3aWL_t_UlmE-Mo_LRiS7can7-MySGoBRJc3-k_Pyq9HrmGY1dtRm3VEvbBNM8BRCdV4yAndBSKpBVivDO4yzdvg5npoFSkcfp/s1600/AC3.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio_9l2yiDp5o4fikq9vNQhGkI2DJSVo40Zskqw5AXbd8c3aWL_t_UlmE-Mo_LRiS7can7-MySGoBRJc3-k_Pyq9HrmGY1dtRm3VEvbBNM8BRCdV4yAndBSKpBVivDO4yzdvg5npoFSkcfp/s400/AC3.PNG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Second round of implementation</td></tr>
</tbody></table><br />
<div class="separator" style="clear: both; text-align: left;">As seen above, we simply tried to mimic our mockup designs during the first round of implementation. After a short presentation/demo, we incorporated some of the feedback we received into the second round of design. A few changes included a sleeker navigation bar and tooltip alerts in the upper right hand corner.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">In terms of fulfilling the three prime directives of software engineering, I feel that we were successful in 1) developing a system that accomplishes a useful task 2) developing a system such that an external user can install and use the system 3) developing a system that can be understood and enhanced by another developer. Our <b><a href="http://code.google.com/p/solar-decathlon-teamhawaii-3/w/list">Wiki pages</a> </b>help to satisfy these directives by providing user and developer documentation for our web application.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">If we were given additional time to work on our web application, we would continue to improve the look and feel by adding more colors and images. Functionality-wise, we would add a right-side column to each page that offered tips and educational content. For example, the right-side column of the Aquaponics page would explain what pH is, why it is important, how it affects the fish in the tank, and recommendations for controlling the pH level. Due to time constraints, we could not implement this feature before the deadline.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Prior to working on this project, I had minimal experience with HTML and I knew nothing about CSS. Now I can do basic web development using both technologies in conjunction with Wicket. In addition, I gained an entirely new perspective on project management. Each member of the team started out with varying degrees of experience in web development so we had to work with each other's strengths and weaknesses. We also had to deal with time conflicts due to work and final exams, but we managed to squeeze in a very fruitful meeting with 3/4 members before the deadline. All in all, we learned to deal with it and contributed what we could to the success of the project.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Download our web application <a href="http://solar-decathlon-teamhawaii-3.googlecode.com/files/solar-decathlon-team3.jar"><b>here</b></a> or visit our project site <b><a href="http://code.google.com/p/solar-decathlon-teamhawaii-3/">here</a></b>.</div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-49529477614946421002010-11-30T07:57:00.018-10:002011-06-08T19:36:41.511-10:00Wicket KatasA <b><a href="http://en.wikipedia.org/wiki/Kata_(programming)">code kata</a></b> is an exercise in programming which helps hone your skills in through practice and repetition. I completed 11 different Wicket katas by making small changes to existing Wicket systems. These katas are thoroughly defined at <a href="https://sites.google.com/site/ics413fall2010/home/31-wicketkatas" style="font-weight: bold;">31.WicketKatas</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlzYELxyKUAeo2QEMSteEe8HBPjD_G5n6trqzg4ZWw_sy7XHG1MQbvsm4bN2pK95aYzVWDi4KKXBIgyZ8oeFE2ljZ0koV0HdBrIqYqgTfbcWgrlGY74YlR_kKSFwKRhfpfaBcEOZRX3fGO/s1600/wicket_logo.png" /></div><b>Example 01:</b><br />
Kata 1A: The task was to display a timestamp one week in the future. This took about 20 minutes to complete. Instead of using a Date class, I used to a Calendar class because it supported the addition of days to the current time.<br />
<br />
Kata 1B: The task was to add a button that refreshed the timestamp when clicked. This took about 20 minutes to complete. I added a form that refreshed the page and consequently the time displayed.<br />
<br />
Kata 1C: The task was to have Wicket run in "Deployment" instead of "Production" mode. This took about 2 minutes to complete. I simply looked up the appropriate method and added its 3 lines of code into ExampleApplication class.<br />
<br />
<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/AVvXsEjtm-1NuBdQzyXU_l-wCavH1ymB85wpbwBC428ElFkdiaBn67-E4OleqD9bjS2msqJoFQSiTyuYib2lsxEv1iG0GsosJYzQmEiL3T8I_dOM1coje0d9lVqkr9x7ADc3DV709FoFWN-_eFHk/s1600/e1.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtm-1NuBdQzyXU_l-wCavH1ymB85wpbwBC428ElFkdiaBn67-E4OleqD9bjS2msqJoFQSiTyuYib2lsxEv1iG0GsosJYzQmEiL3T8I_dOM1coje0d9lVqkr9x7ADc3DV709FoFWN-_eFHk/s320/e1.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Kata 1A and 1B</td></tr>
</tbody></table><b>Example 02:</b><br />
<b></b>Kata 2A: The task was to add a link to a page that embedded a locally saved image. This took about 1 hour to complete. The difficulty was in figuring out the correct path to the image.<br />
<br />
Kata 2B: The task was to add a button that made all text bold, italic, or normal in a linear order. This task was the most difficult and took about 5 hours to complete. First, all text and links in the html file were made into components so that they could be modified by Wicket. Then depending on the current state, the text was changed to reflect the appropriate behavior such as adding <b> and <\b> to make it bold. Finally, the method setEscapeModelStrings was set to false so that Wicket did not escape '<' and '>' characters.<br />
<br />
<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/AVvXsEgjMAwLJwJdKISjxJAQfAd_dsomF6eDbJwmDwrR6TehynzWHgva4Mymy-37bCeeoKoAVbGI0Fphyphenhyphen1H6kdIXqGfxDzLrBSl4k_2mqJ_WUBonJwQgsdcXGtEKShIecjK5YLxqP7HMi-jpV7mH/s1600/e2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjMAwLJwJdKISjxJAQfAd_dsomF6eDbJwmDwrR6TehynzWHgva4Mymy-37bCeeoKoAVbGI0Fphyphenhyphen1H6kdIXqGfxDzLrBSl4k_2mqJ_WUBonJwQgsdcXGtEKShIecjK5YLxqP7HMi-jpV7mH/s320/e2.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Kata 2B</td></tr>
</tbody></table><b>Example 03</b>:<br />
Kata 3A: The task was to add a link to a page that embedded a locally saved image. This took about 10 minutes to complete. It was very similar to 2A with the exception that I had to create a separate package for the image page.<br />
<br />
<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/AVvXsEjOWvkYKk1Rig4gaCQw29iXJM6NQRhlpIm3vpRPZijS028sMp_H3Xg0ntdjR_OXcOPXsdi3Zw0mRvKyJaAMa39BcRYzcWvLpV8ecYAB6-ekYyYsYLSwOSdU2RzohhHCGXKbUJjGIAMI6EGG/s1600/e3.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOWvkYKk1Rig4gaCQw29iXJM6NQRhlpIm3vpRPZijS028sMp_H3Xg0ntdjR_OXcOPXsdi3Zw0mRvKyJaAMa39BcRYzcWvLpV8ecYAB6-ekYyYsYLSwOSdU2RzohhHCGXKbUJjGIAMI6EGG/s320/e3.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Kata 3A</td></tr>
</tbody></table><b>Example 04</b>:<br />
Kata 4A: The task was to add a new cheese called "Velveeta" with a cost of $0.25/lb. This took about 10 minutes to complete. The most time-consuming part was finding the class file that contained the collection of cheeses.<br />
<br />
Kata 4B: The task was to add an additional "country" field to the checkout page. This took about 15 minutes to complete. The most difficult part was tracking down the changes had to be made in different class and html files.<br />
<br />
<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/AVvXsEg6mjZ_PY4FNrHQ8YKzJBQlopyNY83O4NgEtuunE2SPiSNF6Ec5Nqk6nFfvn9FeTE9NEC8QNBx0-6D42-iUnYFRyr7oilVL-iTb1jNB8o__6WjZzrB6MF05S50sNtemwJnxT-lXRAt9GhVj/s1600/e4.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6mjZ_PY4FNrHQ8YKzJBQlopyNY83O4NgEtuunE2SPiSNF6Ec5Nqk6nFfvn9FeTE9NEC8QNBx0-6D42-iUnYFRyr7oilVL-iTb1jNB8o__6WjZzrB6MF05S50sNtemwJnxT-lXRAt9GhVj/s320/e4.JPG" width="271" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Kata 4A</td></tr>
</tbody></table><b>Example 06</b>:<br />
Kata 6A: The task was to remove the blue columns on the website. This took about 15 minutes to complete. I simply had to track down the showgrid option in the css file and delete it.<br />
<br />
Kata 6B: The task was to place the image underneath the form instead of to the right. This took about 5 minutes to complete. I did this by removing the <div> <\div> tags in the html file.<br />
<br />
Kata 6C: The task was to have the application run in deployment or production mode depending on the "deployment" status in a configuration file. This took about 1.5 hours to complete. The difficulty was in figuring out the correct path of the configuration file and testing to see that it worked.<br />
<br />
<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/AVvXsEifanFmvDNIJTAMH96PpkzYdHEGrQZ2t3UHAs3SVm9j9FIfneEWanf9M2r9loDb9xKnC5LbwcNlLDV9kpBeoUNpu3mFnqXfoOhdtDutufBArptWh2_M2oz_3e-8zSGUxM8bbZ7NUMGOsvGC/s1600/e6.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifanFmvDNIJTAMH96PpkzYdHEGrQZ2t3UHAs3SVm9j9FIfneEWanf9M2r9loDb9xKnC5LbwcNlLDV9kpBeoUNpu3mFnqXfoOhdtDutufBArptWh2_M2oz_3e-8zSGUxM8bbZ7NUMGOsvGC/s320/e6.JPG" width="261" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Kata 6B</td></tr>
</tbody></table><b>Conclusion</b>:<br />
These Wicket katas were very useful in transitioning to a new framework. I learned how to add forms, buttons, images, and much more by modifying existing systems. These exercises also reinforced how Wicket components interact with hypertext markup language.<br />
<br />
My modifications are available for download below:<br />
<br />
<b><a href="https://sites.google.com/site/linwdav/wicket-katas/example01-lindavid-1.1.1130.zip?attredirects=0&d=1">Example 01</a></b><br />
<b><a href="https://sites.google.com/site/linwdav/wicket-katas/example02-lindavid-1.1.1130.zip?attredirects=0&d=1">Example 02</a></b><br />
<b><a href="https://sites.google.com/site/linwdav/wicket-katas/example03-lindavid-1.1.1130.zip?attredirects=0&d=1">Example 03</a></b><span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: small;"><span class="Apple-style-span"></span></span><br />
<b><a href="https://sites.google.com/site/linwdav/wicket-katas/example04-lindavid-1.1.1130.zip?attredirects=0&d=1">Example 04</a></b><br />
<b><a href="https://sites.google.com/site/linwdav/wicket-katas/example06-lindavid-1.1.1130.zip?attredirects=0&d=1">Example 06</a></b>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-21971244253688674682010-11-18T07:03:00.017-10:002011-09-13T19:23:07.186-10:00Apache Wicket<a href="http://wicket.apache.org/"><b>Apache Wicket</b></a> is a Java web application framework that bridges the mismatch between stateless HTTP and stateful server-side programming in Java. Its goal is to be easy, reusable, non-intrusive, safe, and scalable. Large companies like IBM, VeriSign, Amazon, and SAS have already joined the Wicket community for large, scalable front-end websites or internal projects with a high degree of UI complexity.<br />
<br />
My involvement with Wicket is geared toward learning a framework that will enable me to build rich and interactive webpages for the 2011 Solar Decathlon competition. My initial experience with Wicket was parallel to learning a completely new language. I would be taking a giant leap into the unknown, but it would be a pivotal point in learning how to create useful real-world applications. This leap was made much easier with the guidance of <b><a href="http://code.google.com/p/ics-wicket-examples/">ics-wicket-examples</a></b>.<br />
<br />
<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/AVvXsEhF09Fr1KYsog2ug7yYV5bEeAgszTn8lYKazRuJYQTj3tpv6VK32deMpsqBNqkyCkiry671UPKNTFuc9EeDi5DIDBPkvzaXH8w3M2CP7i_Ipe5-xsTCzL2V2ZZmlS_T8euwGVrZ2PJGyatm/s1600/page.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF09Fr1KYsog2ug7yYV5bEeAgszTn8lYKazRuJYQTj3tpv6VK32deMpsqBNqkyCkiry671UPKNTFuc9EeDi5DIDBPkvzaXH8w3M2CP7i_Ipe5-xsTCzL2V2ZZmlS_T8euwGVrZ2PJGyatm/s400/page.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An interactive web page made with HTML, Java, Wicket, CSS, and Google Visualizations.</td></tr>
</tbody></table><br />
My task was to develop a simple but interactive webpage that enabled users to modify the parameters of the <a href="http://imagecharteditor.appspot.com/"><b>GoogleOMeter</b></a><b> </b>seen above. First, Wicket is used to pull user input values from the webpage into Java. Second, Java is used to process and edit the chart's parameters with the user's input values. Finally, the chart is updated and displayed with its new URL.<br />
<br />
The key to Wicket was knowing that components in HTML and Java are linked together by a common identifier. Once this was understood, the next and most difficult step was interpreting user input and responding with appropriate output. The difficulty was in part due to Wicket's new libraries and API.<br />
<br />
From this experience, I learned that the career of a web application developer is not easy. Jumping from framework to framework is time-consuming and frustrating, but there are tools like Wicket that ease the pain by helping developers create modular components that can be reused between projects.<br />
<br />
My Wicket project is available <b><a href="http://www2.hawaii.edu/~lindavid/ics413/wicket-chart-1.1.1118.zip">here</a></b>.David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-79129807288361428322010-11-18T06:50:00.014-10:002011-09-13T19:23:16.421-10:00Solar Decathlon Design<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">Building on the the last three blog entries, my task for this week was to design a web-based interface for the solar house's home management system. <a href="http://balsamiq.com/"><b>Balsamiq</b></a> provided a free copy of their wireframing tool to aid me in this task.</div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">The initial design process was extremely difficult because it was a first in designing a web-based user interface. The first round of designs were a failure because I did not have a good grasp on what constituted a great web design. After receiving feedback, some key elements were ironed out. The most important element was to accompany each data visualization with an interpretation and offer a way for the user to respond.</div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">A subsequent round of design brought an improvement to the user interface, but it still lacked the most important element described above. For the third round of design, I was assigned to work in a team of four (<a href="http://code.google.com/p/solar-decathlon-teamhawaii-3/"><b>Team 3</b></a>) and to practice issue driven project management.</div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></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/AVvXsEiF_FKfz0WnTSMBPlgXRzse1q31k6qq2pO29y-TDOseYdH-xJoK-RGHawLlxB6MND6KYIaGylZNTggA5f3eA60c0WUcmuXBczV47XwWQEVHeX8O_gU3Vmqok0mUUKE0r_nCe9NpnbKpO9CT/s1600/Aquaponic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF_FKfz0WnTSMBPlgXRzse1q31k6qq2pO29y-TDOseYdH-xJoK-RGHawLlxB6MND6KYIaGylZNTggA5f3eA60c0WUcmuXBczV47XwWQEVHeX8O_gU3Vmqok0mUUKE0r_nCe9NpnbKpO9CT/s400/Aquaponic.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">2nd round of design.</td></tr>
</tbody></table><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/AVvXsEgqqZPUAoe0hOvV0vJCe7kYwIHXzJATdTa8IxOYR3CrbwoIDbR12bYv6KsuBOgget3hoB0hn8Lr5EjgTh43Mb4TJRJ3gclcoGBgRND33PQt94GRHcWL2IAfGLEVaLL83tKdzCOLdDPLni9f/s1600/aquaponics.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqqZPUAoe0hOvV0vJCe7kYwIHXzJATdTa8IxOYR3CrbwoIDbR12bYv6KsuBOgget3hoB0hn8Lr5EjgTh43Mb4TJRJ3gclcoGBgRND33PQt94GRHcWL2IAfGLEVaLL83tKdzCOLdDPLni9f/s400/aquaponics.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">3rd round of design.</td></tr>
</tbody></table><br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">As seen above, the quality of the aquaponics page improved in each round of design. Users are now able to see statistics easily, have the system recommend a course of action, and respond accordingly to the situation. We took the best ideas from each team member's design and combined them to make a higher quality page. Individual members' previous designs are available <b><a href="http://code.google.com/p/solardecathlon-hawaii-software-mockups/source/browse/#svn/trunk">here</a></b>.<br />
<br />
With the bulk of our pages complete, the final steps were to create the homepage, iron out any glaring inconsistencies between our team members' work, and then link everything together in preparation for the presentation.</div></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-49588170370522417482010-11-11T07:33:00.019-10:002011-06-08T19:25:05.005-10:00Issue Driven Design Project ManagementFor the third round of the Solar Decathlon design, I was assigned to work in a team of four (<a href="http://code.google.com/p/solar-decathlon-teamhawaii-3/"><b>Team 3</b></a>) and to practice issue driven project management. Issue driven project management describes a project management technique that is based on creating many small tasks (or issues) that require only a day or two to complete. These tasks are divided equally among project members and the goal is to create a more comprehensive solution for the Solar Decathalon home management system.<br />
<br />
<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/AVvXsEjf7REXG6bmhf2LudSt96ruQayXKZNT7GtPuUc6AKq8cAfVPxlRBk3fGXd0eFjv8MW7yGjhneqIJPFJdd9bPePbrJUxoByZFX6gBgocORWwIrucJPyQ0ZOXOsu1opeF9KONObbxycyXb2S_/s1600/editissue.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf7REXG6bmhf2LudSt96ruQayXKZNT7GtPuUc6AKq8cAfVPxlRBk3fGXd0eFjv8MW7yGjhneqIJPFJdd9bPePbrJUxoByZFX6gBgocORWwIrucJPyQ0ZOXOsu1opeF9KONObbxycyXb2S_/s400/editissue.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">In Google Project Hosting, issues are first created and then given both an owner and a status.</td></tr>
</tbody></table><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/AVvXsEirpd-wS6Xs180eYvHBdMpz9zZA-EINlr8iDawXzQQgKJKc2TiIhzbgHB5iUhEnt5DmTESFGvBmvIPwvR5gTsO0ag_DCGF0w5I25gVByNIEsrdgtuOFeWJM41S9-1mP10IhsDodm70FV8H5/s1600/Issues.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirpd-wS6Xs180eYvHBdMpz9zZA-EINlr8iDawXzQQgKJKc2TiIhzbgHB5iUhEnt5DmTESFGvBmvIPwvR5gTsO0ag_DCGF0w5I25gVByNIEsrdgtuOFeWJM41S9-1mP10IhsDodm70FV8H5/s400/Issues.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Generally, the progressions of issues are New > Accepted > Started > Done > Fixed.</td></tr>
</tbody></table>Working in teams produced the best results because it allowed us to spend more time on each page since the workload for each individual person was lessened. The first problem my team encountered was deciding on a standard template. This issue blocked us for several days until we all agreed on the template. From there, we incorporated all the feedback we were given into our third round of designs. To ensure that requirements were met and consistency was maintained, I created a <b><a href="http://code.google.com/p/solar-decathlon-teamhawaii-3/source/browse/trunk/Requirements-Standards.txt">checklist</a></b> that each page should adhere.<br />
<br />
Although issue driven project management may have had a lot of overhead in the beginning (via meetings and time spent to standardize our designs), I think it was worth it because we were able to achieve a much higher level of quality in a shorter amount of time. We always knew what we had to do and what other project members were doing, and thus, this made us more efficient in working together.David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-52838848697417148502010-10-28T23:20:00.016-10:002011-06-08T19:29:12.917-10:00Decathlon User Stories<div>The <a href="http://www.solardecathlon.gov/"><b>U.S. Department of Energy Solar Decathlon</b></a> is a biannual competition that challenges 20 collegiate teams to design, build, and operate solar-powered houses that are cost-effective, energy-efficient, and attractive. The winner of the competition is the team that best blends affordability, consumer appeal, and design excellence with optimal energy production and maximum efficiency.</div><div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div></div><div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"><span class="Apple-style-span" style="font-family: inherit;"><img border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgclI9R-xmUM-eZdWIlJtixMQnMpPYvKdQKXMYXizJMIWLfBBa27HDv0B6UjEI4kdOgNucIqvw8Lq5WFwP0WXy3LR48QvLLGjYAM92k2Gt8NN1BRXOp7M2EVZYpcemMFHijRjKxHFlfhPsq/s320/head_sd_logo.gif" width="320" /></span></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;">The University of Hawaii, dubbed as <b><a href="http://www.solar.hawaii.edu/">TeamHawaii</a>,</b> was selected to be a competitor for the 2011 Solar Decathlon. TeamHawaii's mission is to create a sustainable and affordable housing solution that is adaptable to varied cultures and climates with an emphasis on Hawaii and tropical climates.</span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div></div><div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"></div><div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"><span class="Apple-style-span" style="font-family: inherit;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb8V7qxyMdK-XHrm19avThza-E-XELMCIkN-ATkORcfn3zgzdXwZ3rr33x-sW_MOcHpuonNhOtFBgR-WgFGfqTECVQrI0qobNEWxDqHoXJsnUS-844LPNGkML3BETWUss-3E03xuKzxetB/s1600/design01.jpg" /> </span><span class="Apple-style-span" style="font-family: inherit;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKvqFc9m-LqCX-3cDIAKMs76Ep2NnVc560NjZRpuqFr1IuDQuWZlgQQoZFu9_xFLls6nFVevzBhdmRt9Y9v7efIFc8XHqCXF1c0rf6jMUPYllFEdfh5_AMm0_DGLyu84_Ng1N8yr3Y76CE/s1600/design02.jpg" /></span></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;">As a software designer and developer for the solar decathlon house, my first task was to define the requirements for the home management software system. I did this by creating user stories that encompassed the most essential management functions in the solar decathlon house. User stories define the role of the person interacting with the system, the goal(s) of the interaction, and the benefits that would accrue from the interaction. I created 10 user stories below:</span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: inherit;">Energy</span></b></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></b><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to know the current levels of energy generation, expenditure, and storage. Based on these metrics, the system will approximate the available energy budget and energy usage for the day. If energy consumption is estimated to be greater than the budget, the system will alert me and offer suggestions to reduce power usage. Thus, I will be able to achieve a net energy consumption of as close to zero for the day.</span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;"><br />
<b>Water Heating</b></span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></b><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to know how long it would take to heat a given volume of water to 110<span class="apple-style-span"><span style="color: black;">°F</span></span>, and how much hot water has been used for the day. The water heating system will alert me if hot water usage is substantially higher than what I normally use, which may indicate a running faucet or leak. Thus, I will be aware of my daily hot water usage and its impact on total energy expenditure.<br />
<b><br />
</b></span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: inherit;">Lighting</span></b></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;"><br />
As a home occupant, I would like to have a lighting system that will respond to voice commands or a touchscreen interface.</span></span><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;"> </span></span><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;">There will be multiple voice commands, one being able to turn on lights in the immediate vicinity around each occupant.</span></span><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;"> </span></span><span class="Apple-style-span" style="font-weight: normal;"><span class="Apple-style-span" style="font-family: inherit;">Thus, voice-activated lights will provide convenience and save energy by turning off unneeded lighting.</span></span></b></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: inherit;"><br />
Air Conditioning</span></b></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><o:p><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></o:p></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to know and be able to control the current temperature and humidity in each room. If I do not specify a temperature and humidity, the air conditioning system will default to a temperature within 71<span class="apple-style-span"><span style="color: black;">°F</span> to 76°F</span> and a relative humidity below 60% when there is an occupant in the home. Thus, the AC system will maintain a comfortable environment to live in.<o:p></o:p></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><o:p><b><span class="Apple-style-span" style="font-family: inherit;">Security</span></b></o:p></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span style="color: black;"><o:p><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></o:p></span></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to have a security system that will allow entry to the home through face, fingerprint, or voice recognition. A database will maintain a modifiable list of people who may enter the home at certain times of the day. For example, immediate family members will be allowed entry 24 hours a day, while friends will be allowed entry only during a time that I have specified. Thus, I will never be locked out of my home and expected visitors will not be inconvenienced.<o:p></o:p></span></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to have a surveillance system that activates only when someone enters the surrounding premises of the house. If an unidentified person loiters around the home for more than 20 seconds, the security system will alert me on my phone or computer and offer a live video feed. Thus, I will be able to respond remotely to security situations and secure my home from intruders.<o:p></o:p></span></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><o:p><b><span class="Apple-style-span" style="font-family: inherit;">Aquaponics</span></b></o:p></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><o:p><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></o:p></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to know the current levels of oxygen and carbon dioxide in the aquaponics ecosystem. The system will alert me if gas levels become unbalanced, and will offer suggestions to correct the problem. Thus, I will be able to address any issues before they get out of hand.<o:p></o:p></span></span>></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: inherit;">Appliances</span></b></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to know the current refrigerator, freezer, and dishwasher temperature. In addition, I would like to know how long it would take to wash a given load of laundry. The refrigerator will maintain a temperature within 34°F</span></span><span class="Apple-style-span" style="font-family: inherit;"> to 40°F</span><span class="Apple-style-span" style="font-family: inherit;">. The freezer will maintain a temperature within -20°F to 5°F. The dishwasher will reach a temperature of at least 120°F during a wash cycle. If any of these conditions fail, the system will alert me and indicate which has failed. Thus, I will be able to ensure the safety of my food and assess the condition of my home appliances.<o:p></o:p></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><b><span class="Apple-style-span" style="font-family: inherit;">Home Entertainment</span></b></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant, I would like to control my home entertainment systems through an interface on a single device. I will be able to adjust various settings for the lights, television, speakers, and computer(s). Thus, I will be able to enjoy the convenience of entertaining myself and my guests without having to get up.<o:p></o:p></span></span></div></div><div class="MsoNormal" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><br />
</div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"></span></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="apple-style-span"><b><span class="Apple-style-span" style="font-family: inherit;">General User and Repair</span></b></span></span></div></div><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="apple-style-span"><span class="apple-style-span"><span style="color: black;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></span></span></span></div></div><span class="apple-style-span"><span class="Apple-style-span" style="font-family: inherit;">As a home occupant and repairman, I would like to have access to all metrics and status information for each system in the house. In addition, any problems that arise will generate an error report containing the date, time, location, and a snapshot of current conditions. These will be viewable through an interface on a single device. Thus, I will be able to quickly troubleshoot and repair any hardware problems.</span></span></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-74984844142614861232010-10-26T07:15:00.013-10:002011-06-08T19:25:37.194-10:00Website Usability Review<div><span class="Apple-style-span" style="font-family: Arial;"><b><span class="Apple-style-span" style="font-size: x-large;">What is effective web design and usability?</span></b></span></div><div><span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></span></div><span class="Apple-style-span" style="font-family: Arial;">The field of web design has become more important than ever in this world that has embraced the internet as a source of business and entertainment. Whether a business is online-based or a brick and mortar, nearly all have online websites that advertise the company and their products or services. Thus, knowing what constitutes good web design and usability can be immensely helpful in gaining a greater presence online.</span><br />
<div><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: Arial;">The most important points in effective web design and usability are:</span></div><div><ol><li><span class="Apple-style-span" style="font-family: Arial;">Ease of navigation.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial;">Giving users the information instead of making them fish for it.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial;">Simplicity.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial;">White space.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial;">Organization.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial;">Minimal number of ads, and anything that looks like an ad.</span></li>
<li><span class="Apple-style-span" style="font-family: Arial;">High quality content.<br />
</span></li>
</ol><div><span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-weight: bold;"><span class="Apple-style-span" style="font-size: x-large;">Good web designs</span></span></span></div></div><div><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"><a href="http://newegg.com/"><b>Newegg.com</b></a> is an example of a website that has achieved good usability. The navigation bar at the top, and the guided search on the left make it easy for users to find exactly what they need. The product page displays the relevant info such as price, hardware specs, and user reviews. Despite packing lots of information onto the webpage, it still feels uncluttered because it is organized into 4 distinct modules: navigation bar (top), guided search bar (left), product reviews (right), and products (center).</span></div><div><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdpPWCc2BUJOI9Wlrl7vTRAChAT76gfy8KJi-hPu4_C1Aap3fF_oaqrxf9qANh5PS9BsTJewNAu-8vReFkKFjzzK9ckOtunk3JHJ8zShczIzk3cK0Nk7US9b9tJxpZVqTY_ItbQbwJYrOr/s1600/newegg.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdpPWCc2BUJOI9Wlrl7vTRAChAT76gfy8KJi-hPu4_C1Aap3fF_oaqrxf9qANh5PS9BsTJewNAu-8vReFkKFjzzK9ckOtunk3JHJ8zShczIzk3cK0Nk7US9b9tJxpZVqTY_ItbQbwJYrOr/s400/newegg.JPG" width="376" /></a></div><div><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div><span class="Apple-style-span" style="font-family: Arial;"><a href="http://dailytech.com/"><b>DailyTech.com</b></a> also achieves good usability. Like Newegg.com, it has a navigation bar at the top, organizes content into sensible categories, and makes liberal use of white space. </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">The webpage feels simple, organized, and offers high quality content.</span></div><div><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></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/AVvXsEjWJ5m2GzB0vFd-AB1cCo2S18XLBRdJtmnB2wkYsNnQpbHS1QezbuJHB_22L6JqEi7BG_Map5PW4F5rMFA3AEvcmBzw-_vT05UGSeZB0UsTidnz1m5kqfrigMI9Dn4yK-axpWhWwUWXIIfA/s1600/dailytech.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWJ5m2GzB0vFd-AB1cCo2S18XLBRdJtmnB2wkYsNnQpbHS1QezbuJHB_22L6JqEi7BG_Map5PW4F5rMFA3AEvcmBzw-_vT05UGSeZB0UsTidnz1m5kqfrigMI9Dn4yK-axpWhWwUWXIIfA/s400/dailytech.JPG" width="372" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><b><span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span" style="font-size: x-large;">Bad web designs</span></span></b></div><div class="separator" style="clear: both; text-align: left;"><b><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></b></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><a href="http://staradvertiser.com/"><b>StarAdvertiser.com</b></a> is an example of a website that has not achieved good usability. It violates the points of simplicity, white space, organization, and minimal ads. </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">The rightmost column could be mistaken for ads. A visit to the site and a bit of scrolling down will reveal how cluttered and claustrophobic the webpage feels. There is simply too much information jammed into a single webpage.</span></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLgfU1dbq8cITfnhRUe09Y5-DVlIHvAIWjibHm-gTgjtaHeI7gxdyCiH782yYC3kBiyvpCCJbUGyg16mx7JbcqoRHNz_u5B8y30xSp7o0qdvv9V63TZOXuiOYWKh9YO2pWumqHFJ31hlqc/s1600/staradvertiser.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLgfU1dbq8cITfnhRUe09Y5-DVlIHvAIWjibHm-gTgjtaHeI7gxdyCiH782yYC3kBiyvpCCJbUGyg16mx7JbcqoRHNz_u5B8y30xSp7o0qdvv9V63TZOXuiOYWKh9YO2pWumqHFJ31hlqc/s400/staradvertiser.JPG" width="377" /></a></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><a href="http://news.cnet.com/"><b>news.cnet.com</b></a> also fails to achieve good usability. Like StarAdvertiser.com, the rightmost column could be mistaken for ads. </span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">Although the webpage is more usable than StarAdvertiser's, word density is still high and the webpage is littered with miscellaneous buttons everywhere.</span></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></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/AVvXsEjAPhsD4qgZzvYLsc4CSafzRALjG5go3kEo6bJFzH7DO8J78jWtTqolh164M02JSMt5bo6eCBH7OyrrFWy-mBWrVgUFF9Tuv4MgURMGKikjDzSKbXPKgDsYlOtQYMD4uQROCORX6ROkhukT/s1600/cnetnews.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAPhsD4qgZzvYLsc4CSafzRALjG5go3kEo6bJFzH7DO8J78jWtTqolh164M02JSMt5bo6eCBH7OyrrFWy-mBWrVgUFF9Tuv4MgURMGKikjDzSKbXPKgDsYlOtQYMD4uQROCORX6ROkhukT/s400/cnetnews.JPG" width="385" /></a></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><br />
</span></div><div class="separator" style="clear: both; text-align: left;"><span class="Apple-style-span" style="font-family: Arial;"><b><span class="Apple-style-span">Note:</span><span class="Apple-style-span" style="font-size: x-large;"> </span></b></span><span class="Apple-style-span" style="font-family: Arial;">The websites above were viewed using the Chrome web browser and an extension called AdBlock Plus.</span></div>David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0tag:blogger.com,1999:blog-1153485386302028606.post-87577369259059470722010-10-14T22:03:00.100-10:002011-06-08T19:25:51.528-10:00Subversion and Google Project HostingThis week, I was introduced to Subversion (SVN) and Google Project Hosting. SVN is a tool for developers to maintain current and historical versions of files such as source code, web pages, and documentation. Google Project supports the open source community by providing scalable, reliable, and fast collaborative development environment for open source software, docs, and standards that promotes best practices in open source software engineering.<br />
<br />
For my Windows development environment, I used <a href="http://tortoisesvn.tigris.org/"><b>TortoiseSVN</b></a> which provides a Windows shell extension for Subversion. The program is very easy to use. One simply needs to obtain the SVN checkout URL and select the target files to upload.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxPu-ecm7OLdG91C-ZoQjkxhGS1Mq3TRF9C0dNSZdVGyqeXrO6Zwo_DLZk2nv4jTz5zz2YxKEtC0YwPJ9Plhv2RgKOa-SNnLsrDmA0O0cxlp0GUap3tSv5iMQUg6YybQSCeXYCLKxDs6WV/s1600/svn.JPG" /></div><br />
In addition to being able to upload files for other users and developers to see, SVN and Google Project lets many developers work simultaneously on the same project. I was able to gain some first-hand experience with the <a href="http://code.google.com/p/robocode-pmj-dacruzer/"><b>robocode-pmj-dacruzer</b></a> project. I improved the source code and successfully committed it to the repository.<br />
<br />
I then proceeded to create my own <a href="http://code.google.com/p/robocode-dwl-robotfighter/"><b>robocode-dwl-robotfighter</b></a> project. I created a Google discussion group, added several of my colleagues, uploaded my robocode robot system, edited the project home page, and created a UserGuide and DeveloperGuide wiki page. I successfully accomplished all tasks required for this particular assignment.<br />
<br />
The most difficult part of the assignment was using <a href="http://code.google.com/p/support/wiki/WikiSyntax"><b>WikiSyntax</b></a> to create my wiki pages. Although the creators of wiki-style markup may have thought it was a great idea, I disagree. It is nonintuitive and made my life more difficult. They could have at least created a simple GUI with buttons.<br />
<br />
Prior to this experience, I did not understand how large-scale software development worked. I did not understand how companies could assign hundreds of developers on the same project. After learning that tools like SVN and Google Project Hosting exist, I am very eager to get my hands dirty in collaborative open source software development.David Linhttp://www.blogger.com/profile/04106069359869144990noreply@blogger.com0