Cymen Vig

Software Craftsman

Brother HL-2270DW and DD-WRT

The Brother HL-2270DW is an excellent and inexpensive laser printer with support for both wireless network connection and duplex printing. DD-WRT is a useful firmware replacement for many network devices. At first, the two did not want to play together but I figured out that the network settings for DW-WRT need to be:

  • Security Mode: WPA2 Personal
  • WPA Algorithms: AES

The key is the second option – if it is set to TKIP or TKIP+AES, the Brother printer cannot successfully connect via wireless.

Comments and Reactions

Debricking the Netgear WNR3500L

A recent attempt to flash a new firmware to my Netgear WNR3500L resulted in the top power light staying orange. At first, it seemed to take a tftp attempt to 192.168.1.1 on boot up with the special boot up sequence however I could not get it to work.

After reading online, I purchased a USB-TTL adapter on eBay and waited for it to arrive. Following the unbricking guide, I could see the router boot up via the serial port (using the USB-TTL adapter). I was able to enter the CFE console (I found it easier to press and hold down CTRL-C and then power up the device as PuTTY kept sending the key sequence). However the Ethernet portion of the router never came online so while I could ask it to accept a tftp attempt by starting tftpd, it was of no use.

I almost gave up, however some searching found a report of the same problem and the suggestion to try nvram erase. I ran the command and after the prompt came back, cycled the power to the device. On boot, I was again able to enter the CFE console but this time the Ethernet portion of the router came up and a quick tftp of the stock firmware and I was back online.

Comments and Reactions

Modular JavaScript

JavaScript is a complicated language. One of the difficult areas is scope. We can think of scope as the world a particular line of code can see. In JavaScript, if we neglect to use the var keyword for a variable, that variable is seen by the whole world from any line of code. Some large JavaScript applications intentionally use global variables to organize the system. Alternatively, a better pattern has emerged in which modules are used to access the other parts of the system. At first glance, this appears to be similar to an import in Java, a #include in C/C++, or a require in Ruby. But there is a very important difference: in most modular JavaScript approaches, the module is a scope that can hold state which is shared between all consumers of that module.

Almost a year ago, I started working on a huge JavaScript web application. At one point, it surpassed 600,000 lines of JavaScript not including third party libraries. The application used a framework that allowed for the creation of controllers and views. When a controller was defined, it was attached to the global scope by, in effect, omitting the var keyword. If this controller needed to be used by other JavaScript code, one could simply use the global variable to access it. The use of globals tightly coupled the system together in ways which made it hard to write new code using test-driven development. The tests would need to mock out all of the globals accessed by the code under test. After working with the system for a couple of months, it was apparent to us that this two year old application felt like it had four to five years of technical debt.

The good news was that we were not the only ones who felt this way. While the framework was firmly entrenched in the application, the team began to chip away at the globals and the whole approach that encouraged creation of these globals. The first step was adding asynchronous module definition to the frameworks dependency management function with define and require functions. We took this old school code:

thieve('subject_controller.js', function() {
  ...
});

And converted it to:

define(['subject_controller.js'], function(SubjectController) {
  ...
});

Here SubjectController is defined by subject_controller.js. This makes it trivial to define SubjectController as a mock. However one of the problems is that now the mock has replaced the SubjectController for the entirety of the scope. Having to put all the tests that depend on the mock in one file and the other tests in a different file seemed like a serious limitation, particularly when one might want to use different mocks for the same module.

In response, the team added a factoryFor function that would behave like so:

var subjectControllerFactory = thieve.factoryFor('subject_controller.js');

Now if subjectcontroller.js_ depends on modules like so:

define(['jquery', 'subject', 'grinder'], function($, Subject, Grinder) {
  ...
});

We can, with the factory, inject our own definitions for these modules:

var controller = subjectControllerFactory(mockJquery, mockSubject, grinder);

While these examples are simple, they are obfuscating some aspects. So lets rewind and see a practical example.

browser.js:

 1 define(['jquery'], function($, userAgent) {
 2 
 3     var ua = userAgent || navigator.userAgent;
 4     ua = ua.toLowerCase();
 5 
 6     var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
 7         /(webkit)[ \/]([\w.]+)/.exec(ua) ||
 8         /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
 9         /(msie) ([\w.]+)/.exec(ua) ||
10         ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
11 
12     var engine = match[1];
13     var version = match[2];
14 
15     return {
16         engine: function() {
17             return engine;
18         },
19 
20         version: function() {
21             return version;
22         }
23     };
24 });

browser_spec.js:

 1 require(['jquery.js', 'browser.js'], function(jQuery) {
 2     describe("Browser", function() {
 3 
 4         //...
 5 
 6         it('can parse the IE10 user agent string', function() {
 7             var browserFactory = thieve.factoryFor('browser.js');
 8             var Browser = browserFactory(jQuery, "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)");
 9 
10             expect(Browser.engine()).toBe('msie');
11             expect(Browser.version()).toBe('10.0');
12         });
13 
14         //...
15     });
16 });

The point of this code is to check the web browser engine and version. The code in browser.js is a slightly modified version of the deprecated jQuery.browser. Remember the part about how modules are basically shared scope? We can see this in browser.js, because any consumer of the module is going to get the exact same instance as the first consumer. The first time the code is consumed, lines 3-13 are executed. These extract the engine and the version. The scope within the module now has engine and version defined. All consumers after the first will have only the return value supplied to them. This return value is an anonymous object with engine and version methods. These methods are run within the scope of the module so they will of course have access to the already set variables.

Moving on to the test, it becomes clear that we need to be able to inject a userAgent string that typically would be accessed from the current browser via navigator.userAgent (as it is done on line 3 of browser.js). After getting the factory for browser, we inject jQuery and a known userAgent string for Internet Explorer 10.

At this point, I hope that it is clear what a JavaScript module is in the context of asynchronous module definition. The aspect of scope within the module shared across all consumers is an oddity, yet it has many benefits. If you want to try this approach, choose your implementation of asynchronous module definition carefully. Some offer access to the factory while others do not (in particular, require.js does not – wire.js is a good place to start). The team that I am working with on the large web application has made great progress modularizing the application using this approach. An interesting benefit is that the modular approach encourages good practices like splitting up your code into smaller pieces that are not tightly coupled. As the work to remove globals has gained momentum, the mood of the team has turned from pessimism to optimism.

Comments and Reactions

Modular JavaScript

I wrote a post for the 8th Light blog on Modular JavaScript:

Modular JavaScript

Comments and Reactions

Why I am excited about the health care insurance marketplace

I am excited because:

  • entrepreneurs will have affordable access to health care
  • separates health care from employer
  • might push for stronger reforms in health care
  • fixes the gap in coverage that impacts a lot of people in society
  • ends the “I/my family went bankrupt due to health problems”

It appears that the plans are going to be more expensive than going with an employer-subsidized plan. I suspect I’ll wait a year or two to see how things go but I hope that the health care reform succeeds. I think the trade off of raising the cost for some to provide access to all is worth it and I hope employers offer to subsidize plans from health care markets. A lot of it is still unclear to me but hopefully my employer will have more details soon. The current system is clearly not working for anyone except the very rich and sometimes the destitute.

Comments and Reactions

The Importance of Exercise

Almost two months ago, I got in a bicycle accident during my daily commute to work. It was serious enough that the front fork on the bicycle was bent backwards and I had cuts on my hands including my face. A couple days later, I went to Japan and had a great two week trip walking every day. When I returned, I wasn’t quite ready to get back on the bicycle again. It wasn’t that I was scare but rather angry at the whole experience. As time went on, I realized that I was growing more and more grouchy. I had more headaches than usual and had trouble sleeping at night. I didn’t put it all together until a couple days ago: I need exercise. After almost a year of riding my bicycle to work, my body has become used to regular physical exertion. At least that was my theory. I got back on the bicycle and I think that is indeed what happened. I was sleeping better after one day and now two days in I feel much more relaxed. So exercise for the win. I know we all knew that but…

Comments and Reactions

Professionalism and Finances

There are a number of topics related to the intersection of being a professional and finances. It is important to have a basic understanding of these ideas. At times, you may feel like you are asking for more money than you deserve however having a sound financial plan will make it easier to gain the fortitude to go outside of your comfort zone. You are a professional and you should spend the time to ensure your financial success.

Interviews

Apply for a couple of jobs a year. The point of doing this is to:

  • verify your worth on the job market
  • practice your interview skills
  • learn what is out there on the market
  • improve your negotiation skills
  • potentially end up with a new job

It is important to approach this task with the mind set that if you are happy with the outcome of the meeting you might just take the job. It is also important to not divulge the reason for your interview; as a professional, you have an obligation to continue to grow and considering new prospects is an important part of your career.

Note that it is important to be discreet about this activity. The point is not to go out for an interview and then come back to your employer and try to use that offer to negotiate a raise. The point is to know your value on the market so that you are in a good position to negotiate the salary you want for the position you want. Remember that a position is more than just a salary; it comes with expectations for the numbers of hours worked per week and may have odious requirements that make work miserable. In other words, not all jobs are created equally and some well paid positions may not make sense for you. Focus on what you want.

Salary

Read the basic ideas behind salary negotiation and go out and try them. At first, you may be intimidated. But fear not! The worst that can happen is that someone says no. An interesting blog post on this topic is: Salary Negotiation: Make More Money, Be More Valued.

Raises

As with all aspects of a job, raises are negotiable. Your employer may offer you a fixed raise but it is completely within your right to negotiate your raise. It is important to think carefully about this though because you need sound reasons for why you deserve a bigger raise than your coworkers. If you do not have these reasons or feel it is a bad time to negotiate a raise, simply accept the offered raise and move on.

There is no set time for negotiating a raise. It may be easier for your employer to entertain your proposition if it is closer to the annual review time but if you contribute significantly to the bottom line 6 months before that review, why not ask for a raise now?

Work Ethic

Focus on getting things down that contribute positively over clocking in your hours. As a professional, it is important to do the tasks that you might find annoying like working on an outdated technology, entering hours and submitting expense reports in a timely fashion. The point is that you can make a difference for both yourself and the company and both of you are better off for it. This sets things up well for reviews and negotiations on raises.

Internal Projects: Know When to Pass Responsibility on

In many jobs, you may end up working on something to keep the office going well just because you happen to have a particular skill. This is a good thing to do as long as you can do it well. If you reach a point where things outside of your control cause frustration and you can not fix things, there is nothing wrong with passing responsibility on to someone else. Someone with a fresh set of eyes or just a different personal relationship with whomever is involved can get things back on track. Do not let your frustrations effect your work.

Retirement

A basic rule of thumb is that you want to have saved enough money so that you can live on 4% of it per year. In other words, estimate your yearly expenses (say $30,000) and divide that by 0.04 (so $30,000 / 0.04 = $750,000). You will arrive at a figure that is pretty damn overwhelming. However it is within your reach. The earlier you start, the less you will need to save per year if you plan on retiring at a set age (say 65).

There is an opposing viewpoint here: once you accumulate enough wealth to potentially retire, you are now free to do whatever you would like to do. Your expenses like rent and food can be taken from the investment returns on your retirement account. It would be a great time to sail around the world or start a business. One important issue to consider though is health insurance.

It is also important to be somewhat pessimistic when considering the total amount you need to retire. Both in terms of what you think your annual expenses will be and in terms of your target amount. A couple extra years of work can give you enough buffer to weather serious financial setbacks.

Emergency Fund

In life, you will have setbacks. These setbacks may be financial in nature such as a loss of a job, needing to suddenly buy a new vehicle or some other unexpected event. A good rule of thumb is to have roughly 6 months of income saved in an account that you can access within a day or two. You should be prepared to weather these setbacks without undue stress so that you can continue being a professional in your daily life.

Additional Resources

  • Reddit r/personalfinance (note the sidebar with details on different types of retirement accounts)

Conclusion

There are many topics not covered here. It is important to understand your investment options. Research the difference between a pre-tax retirement account such as a 401k or Simple IRA and a post-tax retirement account such as a Roth IRA. Also note that I am not a financial advisor and the above is an outline of my understanding in some areas. While the 4% rule for retirement is widely known, some critique it as being too optimistic. As with all things, your experience may vary. However understanding these topics will set you on a path of financial success.

Comments and Reactions

Do I Have Too Much Experience to Become an Apprentice?

I wrote a post for the 8th Light company blog focusing on why I decided to take an apprenticeship even though I had a number of years of professional experience.

Do I Have Too Much Experience to Become an Apprentice?

Comments and Reactions

Low Cost ARM Computer

The RaspberryPi has a lot going for it but you can get started with a small ARM computer without the hassle of ordering from one or two venders and waiting for a bare board computer that also needs a power supply, case, memory storage, USB cable, HDMI cable, ethernet cable, etc. One alternative is a Pogo Plug. In the USA, you can order one for $20-40 from a number of sellers. It comes with a case, multiple USB ports, and a built-in power supply. You will need an ethernet cable but otherwise you’re all set. The one thing you can’t do with it easily compared to a RaspberryPi is hook it up to a display. But if you wanted a small Linux-based computer that sips electricity and is ready to go hardware-wise out of the box it fits the bill.

The software on the Pogo Plug can be easily changed to an ARM build of Arch Linux with specific instructions at archlinuxarm.org. After the install, I was able to hook up an external drive and setup bittorrent and other applications that are nice to have running all the time but don’t need a lot of computing resources. It is a shame leaving a full desktop powered on using 60-100 watts but a small ARM device like this uses something close to 10-15 watts.

Comments and Reactions

Software Craftsman Update

JavaScript

I’ve been working as a Software Craftsman with 8th Light for a little over seven months. The projects I’ve worked on have been interesting. All of them have involved JavaScript to some degree. I enjoy working with JavaScript but I’ve also started to see where frameworks can cause pain and where event-heavy code can become difficult to work with when the tools lag behind the practices. I want to spend some time digging into PhantomJS to see if it is possible to hook into events to make debugging easier. I spent some time digging around but it is early days.

I’m also interested in see if it would be possible to get more information on memory usage. Identifying DOM leakage is difficult. And of course identifying it on webkit is only going to help for browsers based on webkit however it would be a start. I would expect there to be more tools to help with this but I want tools I can run on the command line and have interfaces which can be used with tests.

In short, the developer tools with Chrome and other browsers are phenomenal however sometimes things seem more painful than they should be. Note that I am not blaming the tools but rather pointing out it seems like some don’t exist yet.

Apprenticeship

I took on a novice apprentice named Andrew beginning in January, 2013. It has been challenging his pipeline full while keeping up with all the other regular duties however it has also been rewarding to see the apprenticeship from the other side. He has made great progress with picking up TDD and with programming in general.

Waza

At 8th Light, we have Friday afternoons to work on whatever we would like to. I have been spending my time working on Abacus which is an invoicing system. The front end is written in Backbone.js with Mustache templates and the backend is in Ruby on Rails. The purpose of the system is to produce a PDF which has the invoice. I’ve started to move that to Clojure and iText after becoming frustrated with Prawn (Ruby PDF generation). Prawn is very capable however it has been hard to keep it from turning into a big ball of mud. I’ve also been working on putting Cucumber tests on the application using poltergiest (PhantomJS wrapped to use with Cucumber). The idea is to make it easier to simplify the backend so that it doesn’t have the requirement to generate PDFs and make it possible to refactor the application without breaking it.

Comments and Reactions

Dell Studio 15 versus MacBook Pro 15 Retina

During my apprenticeship at 8th Light I used a Dell Studio 15 notebook which had 15.6 inch LCD with 1920x1080 resolution. I upgraded the hard drive to a solid state disk (SSD) once they came down in price and it came with 8 GB of RAM and a quard core Intel i5 CPU. The configuration I brought on the Dell Outlet also had a 9 cell battery. It ran Ubuntu well and overall worked great except for the touch pad. Occasionally, it would go wonky and just stop working and it didn’t seem as sensitive on the edges as some of my other notebooks. It had a more modern “seamless” touchpad which might have been part of the problem.

When I became a craftsman with 8th Light I chose a MacBook Pro 15 Retina with 16 GB of RAM (not possible to upgrade later) and a 512 GB SSD. The screen resolution at the optimal retina setting is not that great. The LCD panel can display 2880x1800 pixels however the slider on the display settings limits it out at 1920x1200. The optimal setting is 1440x900 which is great when my eyes are tired and looks really nice with fonts and vector images but just feels small. What I like about the display is that I can scale between 1440x900 and 1920x1200 when I feel like it and I’m not sacrificing quality with the lower setting like I would if I ran a lower resolution on my Dell notebook LCD.

The biggest difference between the two is the touchpad. The MacBook Pro has a phenominal touchpad. It is big and it is sensitive and I really wish my Dell Studio 15 had this touchpad or one even a faint glimmer of it. By comparison, the Dell touchpad feels like a dollar store special. Of course there are other nicer things on the MacBook Pro however I would expect that given the price difference. But it really only comes down to the touchpad between the two. I simply can’t explain how bad the Dell one is compared to the MacBook Pro. Note that I do believe this is partly due to the particular touchpad on the Dell. Other Dells and ThinkPads with the non-seamless touchpads have been decent. But even those are a far cry from the MacBook Pro touchpad.

Now if only it was easier to get Ubuntu running on the MacBook Pro Retina!

Comments and Reactions

Challenges finished, on to Craftsman

I completed my apprenticeship challenges on July 6th, 2012. To recap, I began an apprenticeship in Software Craftsmanship at 8th Light with Doug Bradbury as my mentor on February 1st, 2012. I came to 8th Light because I suspected test-driven development was the right way to go. At the time, there were three main reasons I wanted to make a change: improving the quality of my work by reducing bugs, improving the accuracy of my estimates and the approach to meeting the estimates and improving the approach to long term maintenance. These concerns came out of other projects I worked on and I hoped that TDD would help me with my goals.

I am happy to say 5 months later that I do indeed think TDD will help. I accepted a position with 8th Light as a Software Craftsman on Monday. I look forward to continuing to work toward my goals and am very curious about the other methods in use at 8th Light.

I would like to thank Doug, Paul, Micah and the rest of 8th Light for their commitment to software craftsmanship. If you are reading this and are curious about 8th Light or any of these topics, I encourage you to stop by on a Friday at noon (check university.8thlight.com to confirm there is a scheduled event and RSVP so we have enough food). You can talk to employees and other people involved in the industry, grab some food and hear a presentation and spend the afternoon pairing on open source projects or on a topic you’d like to work on.

Comments and Reactions