Wednesday, August 31, 2011

Controlling Blogger's BR tags

I usually write in HTML mode when I use Blogger. This means I tend to put in my own <p> and other formatting tags. But when Blogger replaces every line-break with a <br>, this causes some ugly formatting. <pre> blocks, in particular, come out double-spaced.

Here's a solution I came up with. I added the following CSS to my blog's template:

.entry-content BR {display: none;}
BR.real {display: inline;}

This means any <br>s added to my post's content are ignored. (I added the .entry-content context to avoid conflict with any <br>s used by Blogger elsewhere on the page, although I don't think there usually are any.)

The second line lets me add <br>s of my own provided I do it like this:

<br class="real">

Feel free to replace "real" with your own preferred class name (provided you do it in both the CSS definition and and in the HTML when you use a <br>).



APPENDIX: There is a potentially easier solution. Just switch to the new editor under Blogger's Settings -> Basic. However, in my limited fiddling. it still behaves a little oddly as Blogger tries to guess where you want line breaks and where you don't.

Tuesday, August 30, 2011

Settling into Eclipse


As part of my current software engineering course, I've installed the latest version of Eclipse (Indigo). I've used Eclipse before, but not for some time, so I'm going through a period of reacquaintance and reconfiguring.


As a settling-in exercise, I implemented the following FizzBuzz program:


/**
* The sort of problem given to intro programmers in a job interview:
* print the numbers 1 to 100, one per line, with "Fizz" replacing those
* divisible by 3, "Buzz" replacing those divisible by 5, and "FizzBuzz"
* for those divisible by both 3 and 5.
*
* @author Zach Tomaszewski
* @version 29 Aug 2011
*/
public class FizzBuzz {

/**
* Returns a String version of num or else "Fizz", "Buzz", etc. according
* to the rules of FizzBuzz. Applies the rules even if num is <= 0.
*/
public static String fizzBuzz(int num) {
if (num % 3 == 0 && num % 5 == 0) {
return "FizzBuzz";
}else if (num % 3 == 0){
return "Fizz";
}else if (num % 5 == 0) {
return "Buzz";
}else {
return Integer.toString(num);
}
}

/**
* Prints results of {@link #fizzBuzz()} for 1 to 100 to the screen.
*/
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
System.out.println(fizzBuzz(i));
}
}
}


It took me 22 minutes to create a project, write the code, and test it. Since I wrote this program on paper in 3.5 minutes in class the other day, most of this time spent went into playing around with Eclipse.


Part of this time was adjusting to initially-annoying things that Eclipse does. For example, at one point it suddenly highlighted in grey all the return statements in the current method. I wasn't at first able to see why this happened or how to make it go away. I now understand that Eclipse does this highlighting for any variable or return statement you are currently lingering on with the cursor, and it won't change the highlighting until you move your cursor elsewhere.


I also tried to decide how detailed to get for something that is obviously a one-off practice program. For example, should I bother with a package? Should I bother documenting the simple methods using @param and @return tags? Should I prevent fizzBuzz(int) from accepting negative numbers? In the end, I decide no for all these things.


I did move the fizzBuzz logic into its own method, though, in order to make it easier to test. This is something I saw done in class. I wrote a JUnit test too:


import static org.junit.Assert.*;

import org.junit.Test;

public class FizzBuzzTest {

@Test
public void test() {
assertEquals("fizzBuzz(4)", FizzBuzz.fizzBuzz(4), "4");
assertEquals("fizzBuzz(9)", FizzBuzz.fizzBuzz(9), "Fizz");
assertEquals("fizzBuzz(20)", FizzBuzz.fizzBuzz(20), "Buzz");
assertEquals("fizzBuzz(45)", FizzBuzz.fizzBuzz(45), "FizzBuzz");
}
}


This is the first time I've used JUnit, but, for something this simple, it was pretty self-explanatory (once you know about the assertEquals method). I'm looking forward to learning more about JUnit--particularly best practices. Right now, I find writing the test descriptions to be unnecessary duplication. It's easy for the description of the test to get out of sync with the test itself. I'm guessing that perhaps test descriptions should be stated at a higher level: what the test is testing, rather than the details of how it is testing it (as I did here). For example, perhaps the second test here would be better described as "Divisible by 3".


I also set up SyntaxHighlighter to use on this blog for code samples. Various instructions for Blogger installation are here. I went through the extra work of hosting SyntaxHighligher on my own server and then linking to the necessary scripts from here. This took much longer than the above code.


Saturday, August 27, 2011

Timmon and the Three Prime Directives


Philip Johnson proposes Three Prime Directives to guide open-source software development. While provided as goals for developers to aim for, Johnson claims that the developer of a system cannot verify whether their own system actually achieves these goals. Only an external user or developer can do this.


As an example of using the Three Prime Directives as a framework for software review, here is my own review of Timmon Time Monitor. I've actually been a Timmon user for about four years now. Unable to explain how many of my days seemed to get away from me without much to show for it, I searched for a good time tracker program. Of the three or four programs I eventually downloaded and tried, Timmon was my favorite.

PD1: The system successfully accomplishes a useful task.



I think the reason I finally settled on using Timmon is that it is fairly simple. It does exactly what I wanted in a time tracker. I can define my own hierarchy of activities or projects. Then, with a click of a button, I can start tracking time for any of those activities. Another click of the same button stops the timer. It is also easy to edit the time spent on a task, to add a complete task that covers a given time period, or to add a comment describing the work done on a task.


It is then possible to view the accumulated time for all activities at different levels of the hierarchy. For example, I have a Personal category that includes Emailing and Surfing. For the current day, week, month, or year, I can easily see the total time spent either Emailing or Surfing. I can also see the total for both activities combined, plus any other activities I labelled as simply Personal.


Here's a screenshot of Timmon in action:




Timmon has a couple extra features I don't use, such as reports or setting the max time for a given activity.


PD2: An external user can successfully install and use the system.



It's been a while since I installed Timmon, so I had to revist the process. The project homepage lets you try Timmon as JNLP program, so, assuming you don't mind visiting the website every time you wanted to use Timmon and you don't mind giving the self-signed web application full access to your computer, it's actually possible to run Timmon without installing it all. This is a pretty nice feature. When run this way, Timmon still saves its time record in a number of XML files in a .timmon directory in your home folder, so this is a viable option for a novice user.


Installing is a little tricky because the Timmon project provides both a .zip and a .tar.gz. However, the .zip is damaged and unopenable, so you have to be able to unzip a .tar.gz on your system. Also, running the program requires executing a jar file. I think this is foreign to many users, though the main project page provides fairly clear instructions on how to do so.


The Documentation link from the project home page is broken. The project README file included in the download mentions a .pdf manual that doesn't exist. However, the download does include an HTML manual. The manual basically covers the program menus and buttons, so it doesn't add much beyond what could be learned by simply exploring the program. I think Timmon's interface is fairly self-explanatory, though; I don't think I ever used the manual when I initially installed it.


PD3: An external developer can successfully understand and enhance the system.



In the four years I've used it, I have discovered a few little bugs. For example, if I close Timmon while tracking time for a particular activity, Timmon will resume tracking for that task every time I open it. I have to delete the task and restart Timmon to break it of this. So I was interested to see how easy it would be to modify the program.


The project has been dead for about four years. The project README that it is included in the download explains how to build the project manually or by using Ant. The source code for the current version of the project is supposed to be in the damaged .zip file and so is not currently available for easy download. It is still available for checkout from the sourceforge CVS, though.


Browsing the CVS reveals that the code is well-formatted and well-documented with javadoc comments. So it would be easy to extract a javadoc overview of this project's files. However, I did not find an overview document intended for a new developer. There are a number of packages and classes here. Based on the README, the project also builds on 5 separate open-source libraries. With no high-level overview, it would certainly take a fair amount of work for a new developer to build a mental picture of how this program is structured.




In conclusion, I think Timmon clearly satisfies PD1 (does something useful). It does fairly well on PD2 (easy to install and use)--the .zip file and documentation link just need to be fixed. Though well-documented, Timmon needs to provide a short introduction or overview document for a new developer to really satisfy PD3 (easy to enhance).

Wednesday, August 24, 2011

Beginnings

I am starting this blog as part of a Software Engineering class, though I expect it to survive beyond the end of the course.