Monday, October 24, 2011

5 Important Points of Software Engineering

While there are countless aspects of Software Engineering that are extremely important-- to the point where you could call many of them "the most important aspect of software engineering", I would like to share with you all just five of those points in the format of a mini quiz. See if you can answer all of them!

Questions:

  1. Why should you use annotations in Java even though they are not necessary?
  2. Automated quality assurance tools are also very important to programming effectively. The following code will result in which automated quality assurance tool (Checkstyle, PMD, or FindBugs) to report an error?: if (true) { x = 6; }
  3. What is JaCoCo used for, and what is one aspect to beware of when using it?
  4. Give an example of a good way to incorporate different types of software reviewing at various stages along the lifespan of a program.
  5. How and why would you recommend using an IDE to someone who normally codes using a text editor?
Think you got all the answers? Check out my answers below and see how much you know about these software engineering components!:

Answers:
  1. (Why should you use annotations in Java even though they are not necessary?Although the Java Interpreter ignores them, annotations are useful in that they associate various “metadata” with elements within the program. They allow Java tools such as the compiler and Javadoc, and even automated quality assurance tools such as Checkstyle and PMD to find errors in your code more effectively. Annotations are sort of like extra tools that help make sure that what you are writing is actually what you mean to write. For example, if you are intending to override a superclass method but you spell the name wrong or use different arguments, having put the @Override annotation will give you an error saying that the method does not in fact override a superclass method. After realizing this, you can fix the error in your code right away without having to ponder and search through your code later to figure out what is causing the problem.
  2. (Automated quality assurance tools are also very important to programming effectively. The following code will result in which automated quality assurance tool (Checkstyle, PMD, or FindBugs) to report an error?: if (true) { x = 6; }) This code will result in PMD reporting an error. Because PMD searches for possible bugs, dead and suboptimal code, overcomplicated expressions, and duplicate code, the above will be flagged as it is redundant; the condition inside the if statement is always true. It is syntactically correct and will not show up as a bug in the Java bytecode, so neither Checkstyle nor FindBugs will raise a concern for this statement.
  3. (What is JaCoCo used for, and what is one aspect to beware of when using it?) JaCoCo is a tool for automatically analyzing how many lines of code in a program are covered by test cases that are written for that program. When using JaCoCo, it is important to keep in mind that coverage does not equal perfect testing. Although it is important to make sure that as many lines as possible are tested, just because you have a 100% line coverage does not mean that your code will be unbreakable if the tests pass. You could very much have a test that runs through only 50% of the lines but is a much better test than a test that runs through 100% of the code, because the test case itself is much more rigorous and exposes more flaws. So when testing code, just use JaCoCo to get a sense of how many lines you have covered, and then work on making sure those lines are covered as best as possible. Then you can add more to the test or make another test in the same way to cover more lines of code, and your program will be extremely robust!
  4. (Give an example of a good way to incorporate different types of software reviewing at various stages along the lifespan of a program.) Following the general software development process: Requirements specification, Design, Implementation (Coding), and Testing, you should incorporate a reviewing process between each of these four stages. One example of how you could go about doing this is to first start off with a Walkthrough after analyzing the requirements. Since there is no code or design produced yet, just a basic check to make sure the idea is valid or thinking about other general issues may be sufficient at this point. Then, after coming up with a software design, it would probably be good to perform a little more in-depth Technical Review, since there will be more technical specifications at this point, so it would be a good way to check the design and find any defects and resolve ambiguities, before moving on to code the program. Another walkthrough could perhaps be performed in addition, to informally check the overall integrity of the program. Finally, after the coding is done, some nitty-gritty Inspections ought to be performed, to really detect and remove defects. Technical reviews and walkthroughs may also be good to incorporate, but streamline programs that are to be distributed for public use should definitely go through thorough inspection to get rid of as many bugs as possible, even before moving on to test the code.
  5. (How and why would you recommend using an IDE to someone who normally codes using a text editor?) IDEs are made to do more work for you, so that you don't have to. They do not only simple tasks such as closing open parentheses and braces and automatically indenting new lines of code, but IDEs also contain libraries that enable things such as auto-complete, allowing you to view the available methods right then and there in case you forgot the exact spelling or what parameters are needed. IDEs will also tell you if something is spelled wrong or is invalid syntax, and also provide a place for compiling (which is done in the background), running, and debugging code, without having to compile and execute the code manually. All in all, IDEs allow for far more efficient programming that is also much more accurate, so you will probably never have to dig through code to fix an error caused by forgetting to close a brace or by using the wrong method name, because the IDE will take care of that for you.
Did you get them all correct? I know the answers are rather lengthy, but if you got the general idea down in your head, then congratulations, you know quite a bit of tools that can help you in productive software engineering! If not, then please be sure to learn to love these tools and tips; they will certainly come in handy in your experience as a software engineer. Please be aware though, that these are not the only vital tools to know for software engineering; there are tons and tons more that I have not covered here that are absolutely essential to programming, so please, search and play around with them, and read up on my other blog posts to gain more tools to put under your belt, so that you too may be on your way to becoming an excellent software engineer!

Tuesday, October 18, 2011

Getting a Sense of the Real World

This week, I'll be sharing with you my experiences with Configuration Management of a project, specifically my Robocode project that I have been working on so far. My robot is ready to be deployed out into the bigger world and be used and improved by people around the world. This is where Configuration Management comes in, and I have chosen to use Google Project Hosting to house my robot, and Subversion as the version control system. But before we get into making my own hosted project, I had to get a taste of what Configuration Management is like.

I have used TortoiseSVN once before on Windows, but since I do my coding primarily on Ubuntu Linux, I was left to find alternative clients. My first approach was to use Subversion from the command line. After downloading Subversion for the Ubuntu Linux terminal, I checked out the robocode-pmj-dacruzer project, made a minor change (setting the scan color to be white) and committed the changes back to the repository. Everything was going rather smoothly except for when it came time to commit the changes. For some reason, my commits were doing nothing; I wasn't being prompted for a user name or a password. I found this to be very strange, since everything seemed to be working-- checking out, updating, making changes. I had two option to solve this problem-- either install an SVN client with a GUI (like SmartSVN) to diagnose the issue, or try and figure out what was wrong by myself. I didn't have much time, nor did I know how long it would take to install SmartSVN and figure out how to use it. So I decided to stick with the command line version and focus on diagnosing the problem myself. After about 45 minutes of frustration, I discovered that the problem was with Eclipse. For some reason, the changes I made weren't being saved, so when I tried to commit back to the server, it would have no reason to do so because there were no changes made. So I opened up the java file in a text editor, made my changes, committed the changes successfully, done. Just in the nick of time.
(I did eventually download and set up SmartSVN just in case, for easier visual diagnostic purposes.)

Now, with a basic feel for Configuration Management, I was ready to tackle hosting my own project up for the world to see. As aforementioned, I used Google Project Hosting to house my project, and posted the zip file (created using Ant) there. I even included a Developer Guide as well as a User Guide so that developers can verify that it works and can be tweaked, and so that users can add Narchi to their systems and watch how it plays out in a battle. I did not encounter many issues at all-- in fact, the hardest part was actually figuring out how to upload the file onto the Google Project page. It took me quite a bit of searching, only to find that it was just in the Downloads tab. Other than that, all has been going rather smoothly so far, and Narchi is sitting cozily at Google waiting for people to check him out, take him home, and make him a better robot.
The robocode-cht-narchi project can be found here.

What I learned from this was the basics on how Configuration Management works. I previously had a running idea of why it is important to have systems like this, but I had never actually gotten to use one for my own project. Now I am able to host my projects on Google, and use Subversion to keep it up to date with the changes that people can commit to it. This is what happens in the real world with real open-source software, so this is a great skill to know and is a big step towards becoming a bona fide software engineer! The future of having a career as a professional is becoming a lot less scary, and I hope that I can learn a lot more so that I am prepared to face on the world with software engineering.

Sunday, October 9, 2011

Getting Ready for the Big Arena

The number of days until the big event is counting down, and quickly! I'm going through a training regime with my robot (named Narchi) to get into tip-top shape for the big Robocode competition taking place this coming Tuesday, October 11th. Each athlete has their own strategy to winning, and Narchi is no different. We are working in collaboration with each other, brainstorming and trying out different strategies, keeping ones that work, and dismissing the ones that we come to find aren't fruitful. Unfortunately, it seems like there are many more happenings of the latter versus the former, but I think we have finally come up with a strategy (at least a general one) that is a keeper. The journey up until here has been long, with lots of dead-ends and backing-ups, as illustrated here:


Thursday, October 4th
Our first approach was to start off simple-- just to get moving and/or shooting. Since the corners of the battle field seem to be the best hiding spots, we decided to go there first. Finding and going to the closest corner appeared to be the most efficient plan, but I quickly found this to be troubling, because the many (not-so-simple) calculations made the lines of code grow and grow, and grow and grow. Furthermore, this proved to be inefficient, because when I added tracking and firing capabilities to Narchi, he would forget about moving to the corner once he spotted an enemy, and would just keep firing, only remembering to go to the corner once the enemy was annihilated..


Saturday, October 8th
So, back to the drawing board it was.. I needed to work on Narchi's ease to get distracted! I'm thinking that we might simplify the movements, and just focus on getting a good firing strategy. Previously, Narchi would fire based on the enemy's distance, using less power if the enemy was far away. But as I watched Narchi practice against robots such as Corners, he would miss a lot while Corners was moving away, and once Corners stayed still, Narchi would only fire small bullets if he was far away enough. I realized that this was pretty wasteful, so we'll try and change it so that if Narchi misses a shot, then he will decrease his bullet power, and if he hits an enemy, then he will increase his power. However, this is proving to be rather difficult, because sometimes Narchi wants to fire again, but the bullet is still traveling, so he doesn't know whether to use more or less power on the next bullet.
Back to more training! Stay posted for more news!


Monday, October 10th
Well, the final version of Narchi is completed, and ready for the big unveiling tomorrow! It took quite a lot of tweaking to get it ready, but we're finally ready to roll out. For the final specifications of Narchi, we have the following:
  1. Movement - The first thing that Narchi does is moves to the closest corner to its starting point (i.e. the one defined by the quadrant that he starts off in. The algorithm is a very simple "follow-along-the-walls" one, which may work better in terms of evading enemy attacks compared to a direct path to the corner. But the movement doesn't stop there! No, for when Narchi gets hit by a bullet, he tries to move to a new (supposedly random) spot to avoid getting hit again.
  2. Targeting - Narchi is an excellent targeting robot, able to lock on to the enemy that it can see. From the beginning of the match, if another robot crosses his view, he will abandon the task of moving to the nearest corner and just focus on locking on to this target instead. One flaw that Narchi has with targeting, however, is that once he starts moving around from being hit, he quickly changes plans and abandons his targeting scheme. In terms of "fight-or-flight", he is definitely a "flight" kind of guy.
  3. Firing - Alongside targeting, Narchi will fire during his initial "lock-on" period of the battle. He is wise about his actions, and decreases his bullet power when he knows that he has previously missed a shot, and increases the power when he knows that he has shot an enemy. However, just like the targeting problem, once Narchi gets hit and goes into "flight" mode, he seldom reverts back to firing, which could spell out losses.
Results
As a result, we have a robot that can do some interesting things, but is not quite perfect. It can reliably beat the sample bots that don't fire, such as SittingDuck and Target, but does not fare very well with those that shoot, due to Narchi's tendency to freak out when getting shot. Before implementing the evasion tactics, Narchi could beat Corners and even Walls sometimes, but it seems that adding the extra functionality caused Narchi to be unable to go back to its previous task, or to do them well simultaneously. As such, it probably would be better to remove the evasion portion from the code, but then Narchi would be nearly identical to Corners, and so we'll leave it in and show off a little of Narchi's ninja skills. If this tactic could be incorporated more smoothly into the overall strategy, Narchi could possibly become a tough contender to beat.

Testing
Rather than doing any unit testing, I decided to test Narchi's behaviors, and acceptance to opponent robots. I tested the movement to a corner, whether bullet power increased upon hitting, whether bullet power decreased upon missing, and evasion when hit by a bullet. For the first two, I tested against a non-moving enemy, so that the feedback on just the movement and firing could be tested. For the latter two, I tested against enemies which Narchi struggled against. By finding a bullet that had less power than before, I was able to determine that Narchi must have missed, thus turning the dial down on the power. And by seeing that Narchi first moved to a corner and then ended up in a different spot some time later in the round, I was able to determine that Narchi must have tried to move upon getting shot. The two acceptance tests were against SittingDuck and Target, since those were the only two that Narchi could beat because he would freak out if it got hit by any other robots.

Lessons Learned
Well, I can certainly say that Robocode was quite an adventure, to say the least. It was very difficult to get started and get used to the rules, physics, and flow of Robocode, which made it even more agonizing to figure out how to code my robot effectively. I still do not completely understand some subtle nuances with the execution flow, but overall, my understanding has increased greatly. But more so than Robocode specifically, I learned a lot about build systems and tools such as JUnit, Checkstyle, PMD, FindBugs, and Jacoco, that although sometimes gave me unnecessary headaches, are very useful in writing clean, concise, and effective code, and I am very glad to have learned about this. While there are many things that I could do differently if I were to do this again, I think that the only thing I would do (other than try and spend more time on it) is figure out in more detail about how Robocode works, so that I could be a more efficient programmer when implementing strategies. I feel that I wasted a lot of time simply because I didn't know a lot of the methods and classes that could have been really helpful to me. But, what's done is done, and now it's off to see how Narchi does against the fierce competitors!