This week's Peeblogs will be heavily dominated by several words of financial advice, but first, a quote from The Man himself,
"Don't focus on why you can't do something. Focus on what needs to be done, and find a way to do it."
Financial Principles:
-- Live 2-3 pay-cuts lower than what you make.
-- First priority after graduating college is to construct an emergency fund equivalent to 6 months of your salary.
-- The two most important financial decisions you can make are marrying a frugal woman, and never getting a divorce. (addendum from Troy, "Don't get married.")
-- Bonuses should NEVER be counted on when budgeting.
-- Setup student loans to be paid automatically, as missing a payment kills your credit score.
-- Pay debts in order of descending interest rates.
-- Pay the minimum on loans that have a lower interest rate than the rate of inflation.
-- Sign up for zero tax exemptions. This guarantees a large tax return check and assures that you will not have to pay any money back to the government.
-- When debating between using money to pay off a loan or using it to invest, the following formula applies:
I began reading "Code Complete," by Steve McConnell. This week I read the preface, chapter one, and most of chapter two. Yeah, pretty lame...I will try to do better this week. The following quote explains why Code Complete is applicable to me, "The recent graduate is often rich in theoretical knowledge but poor in the practical know-how that goes into building production programs. The practical lore of good coding is often passed down slowly in the ritualistic tribal dances of software architects, project leads, analysts, and more-experienced programmers. Even more often, it's the product of the individual programmer's trials and errors. This book is an alternative to the slow workings of the traditional intellectual potlatch....It's a hand up for the student making the transition from an academic environment to a professional one."
In order to uphold tradition, I will be beginning this post with this week's all-famous Peeblogs. Unfortunately Mr. Peebles was abroad for the majority of the week, so Peeblogs were few and far between. However, despite the scarcity of these little nuggets of truth, I still managed to garner just a few:
--It is very difficult to implement a system that regulates employee promotions and bonuses accurately. This is primarily caused by what Sir Peebles referred to as "optimizing to the metric." In other words, if you setup a metric that is supposed to measure how much an employee has accomplished, that employee will always pay extra-special attention to that metric, making sure to go "above and beyond the call of duty" in the specific area of that metric. This makes it seem that the employee deserves a raise or a promotion, when, in reality, they have merely "optimized to the metric."
--It is quite common for an employee to be promoted to his "highest level of incompetency." This results from the employee working his way up the career ladder, earning rightful promotions until he eventually gets promoted to such a high position that he is no longer competent to do his job. The employer is then faced with a dilemma. Should the employee continue to underperform in his current role, be demoted back to his highest level of competency, or be let go?
--The corollary to the previous point is that managers must think very long and hard before they promote an employee. Demotions are rarely a feasible option, as it generally leaves the employee dejected, dispirited, and embarrassed. Promoting an employee too far is a good way for a company to lose of its most valuable and successful workers.
Moving on, week 5's assigned reading involved three articles on unit testing, which were helpful, because I ended up spending the majority of Week 5 writing my first unit test. I will touch upon each of the three articles briefly.
Article #1 was entitled "Why are we embarrassed to admit that we don't know how to write tests?" It's author drove home the point that "The secret in testing is in writing testable code!" He gave several practices to avoid in order to write code that can very easily have unit tests written for it. I will now quote his second point, which I felt was his best comment in the entire article, "The developers are where the mistakes are made, and testers are the ones who feel the pain. Do you think that the developers have any incentive to change their behavior if they don't feel the pain of their mistakes?" I feel that Sentry addresses this issue by requesting that the developer also be the one to write a corresponding unit test for his own code.
Article #2 was "The Advantages of Unit Testing Early." Three advantages that stood out to me:
Instantaneous Gratification-
-Writing a unit test as you code or even before you code allows you to test a small component of a larger application that has not yet been completed.
Refactoring Safety Net-
-Having a pre-existing unit test allows a developer to refactor code and then check to make sure that he did not break anything.
Documentation-
-Unit tests can be used as a reference to find out what a particular method or class is supposed to do and how.
Article #3--"How to Write 3v1L, Untestable Code." This last article was a blend of poorly written and hilarious. The author decided to turn his blog into satire, writing from a purely sarcastic standpoint. I couldn't have agreed more with one of the readers who aptly commented that, "While the content of this post was excellent, the disingenuous, sarcastic, say-the-opposite-of-what-I-mean style of it was a complete turn-off. I hope you consider re-posting this information in a positive, "what-to-do" style, so that people don't have to parse through all of your negations just to get some good tips." The principle that hit home for me was that I should not use lengthy/intricate if-branches. I have a nasty habit of doing such at school on projects that are merely tested for functionality, and this was a good reminder to break such a habit. I will let points #2 and #3 speak for themselves as they are quite comical and will allow a small glimpse of the sarcastic style of the article:
"Macros are your Friends - Always use #ifdef PROD and other compile-time switches to make sure the testies can't get at your really important blocks of code and test them. In fact, this code won't even run: until it gets to production!"
"Final Methods - Use final classes and methods all the time. They can't be overridden for testing (-; But don't bother making fields final, or using value objects (without setters) - just let your objects' state be changed by anything and anyone. No sense in guaranteeing state, it'd make things too easy."
As parting words of hope, I would just like to let you know that it is merely Monday, and I have already acquired useful material for next week's Peeblogs!
Just as with every other week here in SoFlo, this one has flown by. I don't have any new, exciting experiences to add to the list that I started last week, so I will skip that section until (hopefully) next week. I will jump straight to the work that I have done this week here at Sentry.
Wednesday marked a milestone in my time at Sentry thus far. My mentor, answerer of every question that my brain can possibly come up with, and endless pool of knowledge, Joe Heth, began a week-long vacation. Do not get the wrong impression, this was not a milestone because Joe Heth took a vacation, rather, it was the first time that I attempted to walk around on my own two wobbly legs without Joe there to give direction. Liken it to a child taking the training wheels off of his bike for the first time. I spent the remainder of the week on a ticket that originally involved just making the Audit/Search tool's "Details" link point to its corresponding invoice instead of its purchase order. However, as I dug deeper into the cause of the issue, more and more errors became evident in the tool's design, and those whom I consulted instructed more and more changes to be made to the tool. In the end, I was doing pretty much a full revamp of the entire invoice feature of the tool. This primarily involved working with Jay Ohms to tweak the InvoiceManager object that he was in the process of creating. After a lot of communication back and forth, we have succeeded in providing a function in his object that returns all of the necessary elements for my reporter object. I made the following modifications to the Invoice report:
--Originally the user could choose between searching from "All Invoices," "340B Invoices," or "Non-340B Invoices." Separate reporter objects were extending a parent reporter object and being used to display the 340B and non-340B invoices. I combined these two objects into the parent object which they formerly had been extending, eliminating the necessity of the two "child" objects. Both types of invoices are now displayed in the same report with a new column called "Order Type" that distinguishes whether an invoice is "340B" or "Non-340B."
--The speed is optimized due to not using binding for $site_id in the SQL query. It is also optimized as a result of Jay writing a more efficient query that eliminated the need to look in any cardinal tables.
--The "Details" link no longer exists, but its functionality has been replaced by making the invoice number into a clickable link.
--The expandable rows feature has been done away with.
--When searching for invoices by NDC, the drug count number actually displays the number of different drugs in the invoice, rather than always displaying "1" like it did before.
--The report is now default displayed as sorted by date in descending order.
--All rows in the report display invoice numbers. (many did not previously)
--All results displayed in the report now match the search string. (Many times invalid results were previously displayed or not all of the correct results were displayed.)
--Invoices with a common PO# are displayed, rather than just displaying one of them.
That pretty much sums up my week of work. I have been talking with Cyrus, Ben Mahan, and JJ Foote about a few more modifications which I feel would really improve the functionality of the tool for the user, and I will likely be presenting a mock-up of what the UI will look like in the upcoming week. Other than this ticket, I also teamed up with QA to solve an issue in one of the tickets that I had submitted last week, and I began working on another ticket involving the Drug search option in the "Search/Audit" tool.
Week four makes me feel like I didn't get a lot done, just because I didn't close any tickets, but, now that I've written everything down, I feel a little better about my accomplishments.
Before touching on this week's "official" reading assignment, I am going to reflect upon a couple less official, yet, no less educational experiences. Some might call them "Choctaws," others might refer to them as rants, still others might call them "Soapbox Specials," however, I choose to label them "Peeblogs." That's right, educational, hysterical life experiences and musings by none other than your very own John Peebles. During this week's near-daily Peeblogs, I learned the following very important principles:
It is key in life to have the ability to take that which you learn/hear/read and be able to apply it to, and associate it with, the real-life situations that you find yourself in everyday.
The three most important life skills are:
-Writing
-Reading
-Being able to conduct yourself according to the surroundings that you find yourself in, so as to make a good impression and establish good standing. (i.e. People skills in any situation)
In order to be great, a man must read no less than one book per week. As a result of this principle, I have begun attempting to teach myself how to speed-read, according to an article on the Internet.
Companies' incentive plans, when regulated poorly, can actually end up demotivating their employees. Sir Peebles went on to explain how his friend had quit working for a company because they denied him his $20k bonus, which resulted in the company losing one of its best employees to a staunch competitor. He explained that, in the long run, the company was ruining themselves. He followed this story up with what was by far the best analogy that I heard all week: "You end up plugging a grenade up your ass. Sure, it feels great until it goes off, and then you're screwed."
And now on to this week's official reading assignment, "Continuous Integration," by Martin Fowler. Fowler's article was an outright home run, endorsing and explaining the ins and outs of CI and hitting upon the principle from every angle. Here is a brief synopsis of what I took from the article.
In CI, "everybody develops off of a shared stable base and never gets so far away from that base that it takes very long to integrate back with it. This results in in less time spent trying to find bugs." Every developer keeps and maintains a copy of the current integrated source on his machine. Updating this copy is called "checking out." This copy must stay up to date with the mainline, or, current source code. In short, there is a single source repository maintained by a program such as Subversion, which contains all of the source code for the product/system. When a developer wants to edit some of this code, he makes sure that he has an updated copy of that source code on his own machine and then works with that copy while editing and initially testing. Eventually, after extensive testing, that edited code will be integrated back into the mainline using a continuous integration server such as Cruise Control.
The following are a few important practices in CI:
Maintain a single source repository: A mainline with very few branches, which might be necessary for bug fixes and temporary experiments.
Automate the build: Everything should be able to be built/linked by issuing one single command.
Make the build self-testing: A close runner up to the above-mentioned John Peebles quote: "Imperfect tests, run frequently, are much better than perfect tests that are never written at all."
Keep the build fast: Make the build staged: a "commit build" that should quickly test a large amount of the code and a "secondary build" that runs some of the more time-consuming tests. The following is very important in regards to creating an optimally staged build, "As much as possible you want to ensure that any secondary build failure leads to new tests in the commit build that would have caught the bug, so the bug stays fixed in the commit build. This way the commit tests are strengthened whenever something gets past them. There are cases where there's no way to build a fast-running test that exposes the bug, so you may decide to only test for that condition in the secondary build."
Until week five, that is all I have for you. Come back next week for more Peeblogs if you dare.
I can HARDLY believe that I have already completed my first three weeks here at Sentry! Working here has been phenomenal thus far, and I see no reason why this shouldn't continue. I really enjoy the "Work hard, play hard" mentality that exists here.
And now, I am going to start a new "blogging tradition" where I make a list of different experiences that I have had here in SoFlo! So far:
-Chipotle (x6) (Barbacoa is my last remaining meat to try)
-Boxing Match (The Heavy Weight Factory)
-YMCA B-ball league (Yesterday we won 70-68 on a buzzer-beating treybomb!)
-Golfing at Deer Creek (Sorry about the tough defeat that you suffered, Kyle...)
-Bowling at Boca Strikes ($1 games/shoes!)
-Fishing on the ocean! (THANKS Keith!)
-Boating/swimming on the ocean off of Key Biscayne Island!
(I am rather certain that I am forgetting several things, but I can add them next week.)
Lastly, I will try to give a speedy glimpse of the things that I worked on this week. I experience my first interaction with QA. The rolodex widget that I added to the VPN Setup Tool this past week apparently didn't display in the correct spot exclusively in IE6...BIG SURPRISE...world's WORST browser! But, as Troy pointed out, many hospitals are still operating with VERY outdated software/hardware, and IE6 is VERY prevalent. Thus, I must be very conscious of this when programming. Other work that I accomplished includes converting four more reports to the reporter framework, adding the date widget to these reports, fixing a link in the PIM log, and the very minor tweak of preventing a search from being conducted on a string of less than 3 characters in the Reverse Mapping CDM search.
Week 2 has been vastly encouraging in comparison to week 1. Though I don't feel that I have suddenly transformed into a coding ninja, my overall fluency in the system has easily tripled that of week 1's. I feel more confident about finding files, reading them, and understanding how they relate to one another.
The majority of my week was spent trying to add rolodex widgets to the VPN and FTP setup tool pages. Robert and I decided to take a pair programming approach, because we were basically assigned identical tasks, Robert handling the FTP Setup Tool, and myself handling the VPN Setup Tool. Apparently everyone dreads any tasks involving the word "rolodex," because every time I would mention that I was working on this, I would get a mischievous smirk or a knowing wince of pain. Luckily Joe Heth decided to make my life easier by making a universal RolodexLinkContact.php file which allowed for a one-to-many relationship between the rolodex and various types of contacts. Had it not been for this, I probably would STILL be working on this project!
A small amount of Thursday and most of Friday were spent on my current task, which is revamping the Replenishment Rollover Report. I had to create a reporter object from scratch in PHP, which I ended up enjoying very much. This was much more of the object-oriented type of work that I am used to doing, so it was much easier to understand. By the end of the day Friday, which came all too soon thanks to TF2, I had my reporter object functioning quite nicely and in need of just a few small tweaks. Overall, this has been my favorite project thus far, largely due to the fact that it has been my most successful and required the least amount of outside help due to the fact that Clearspace had very helpful and extensive documentation.
And now, I must bid adieu to week 2, as week 3 is already upon me!
I am happy to report that Week 2's reading load paled in comparison to Week 1's. For the most part, we were assigned two documents: Practical Styles of Pair Programming, by Iwein Fuld, and The Art of Agile Development: Collective Code Ownership, by James Shore.
For the most part, pair programming has been a foreign concept to me, but this past semester in my Compilers class we were instructed to group into two-person teams. So, this is how I was introduced to pair programming. Fuld identifies two roles in pair programming, which are the "driver," who is the one behind the keyboard, and the "navigator," who is the one following and guiding the driver's work. Though the article talked about many of the benefits of pair programming, it seemed that the only benefit that I received was that my partner was smarter than I, and he shouldered a majority of the load, acting as a "driver" with no navigator while I sat and watched. I refer to this as a "benefit," but it in reality, it was no such thing....it was, in fact, a crutch, minimizing my understanding and interest in projects and the class as a whole. Reading this article helped me to identify several of the mistakes that we made in our rather lackluster attempt at pair-programming. The following quote from the article seems to describe my situation perfectly, "The driver knows what he's doing and because the navigator doesn't pick up on what he's saying he turns silent and speeds up. The navigator sees that the driver is doing ok and decides not to slow him down but space out and look out the window a bit." It appears that we were committing several pair programming blunders. A) We were both low on sleep, B) we stopped thinking aloud, C) I didn't always stop the driver when something didn't makes sense, and lastly and most importantly, we never tried switching roles. All of this resulted in what Fuld has labeled "The Disconnected Pair or The Sleeping Navigator."
Now that I have touched upon a pair programming failure, I will briefly report a success. As I mentioned in my other Week 2 blog-post, Robert and I have been working on similar tasks this past week and decided to take this pair programming article to heart. We employed many of the concepts covered in this article, and it definitely resulted in a quicker process which created a higher quality product and allowed me to gain an abundance of knowledge. We successfully fulfilled our roles as driver and navigator.
The article on Collective Code Ownership was also very enlightening, but in a different sort of way. Seeing as I have had absolutely zero past situations in which collective ownership could be employed, this article served more as warning and guidance. I found a great deal of healthy responsibility being placed upon my shoulders. The article explained that it is my duty to always leave code better than I found it. Though not directly stated, I felt that the number one point of the article was that laziness is NOT an option. When coding, I cannot do a half-hearted job, assuming that somebody else will fix my mistakes, as collective code ownership doesn't mean "no-code ownership." In summary, A) I should always be looking to improve other's code, and B) I should take pride in the work that I do, but not be so proud that I try to be the sole owner of that code and get offended when someone else modifies it.