Well, it was released sooner than I was anticipating, but have at it! I’ll personally make a few adjustments to this version and release a more refined version soon.
AutoChimp 2.0 coming soon
Status
Woohoo! Fundraising has succeeded. Look for AutoChimp 2.0 very soon.
List Yo’ Files is on Github
Status
Hello developers and folks who wish to make contributions to List Yo’ Files. List Yo’ Files is now available on github. Feel free to fork it, make your changes, and send pull requests!
https://github.com/DerWanderer/list-yo-files
As your making changes, make sure that they’re for the good of the community and not just a solution to a domain-specific problem that you may have. Thank you!
AutoChimp 2.0 Seeking Contributions!
AutoChimp 2.0 needs your support!
There have been no shortage of requests for Autochimp. So, in the spirit of helping the community out, AutoChimp 2.0 is seeking contributions from the MailChimp community, especially those who use MailChimp in conjunction with WordPress.
AutoChimp 2.0 is now a “crowd-funding” project on Indiegogo, a site which brings like-minded people together to help raise funds for projects that they care about.
This is great for AutoChimp because so many people ask for the same features. With “crowd-funding”, we can spread the cost of development around a large number of people, thereby eliminating the need to have just one person fund features. That’s how AutoChimp funded many features in the past. Believe me, crowd-funding is a great step forward!
AutoChimp chose a modest fund amount of $1500 mainly because this is our first attempt at crowd-funding. For sure, there will be plenty of learning opportunities along the way. If all goes well, then we’ll be able to crank through version 2.0 in about a month as well as be set up for future enhancements.
You can visit AutoChimp’s crowd-funding page on Indiegogo.com here:
Be sure to check out the bonuses! We hope you can contribute!
Oh, and one other thing: If AutoChimp 2.0 does not meet its funding goal, then all contributions will be refunded. It’s all or nothing. Either AutoChimp 2.0 gets funded and built, or you get your money back!
Call Me in China 2.0 Released
Call Me in China released a big and bold new version, which we’re calling 2.0. Technically, it’s really a 3.0 version, but because of the new design, and the fact that 1.0 was really just a test beta version, we’re calling it 2.0.
OK, now that I got that background stuff out of the way, here are the big new features – and they are quite big:
- Perhaps the biggest change is a greatly expanded inventory of home country numbers. You can now pick a number in specific regions of your home country, even down to the granularity of small towns.
- A growing list of supported home countries. We’ve added a couple more for this release with more on the way. It’s easier now than ever before to find a number that will fit what you’re looking for.
- For some strict countries that require documentation in order to receive a number, we’ve streamlined the process to ensure that you get your number as quickly as possible, in 99% of cases this happens in less than 24 hours. For other countries, of course, you can start receiving calls on your new Call Me in China number instantly.
There were several updates on the backend, especially on the admin side which makes it easier for us to provide service to our customers. It’s also easier to understand trends. We also have some new ways to offer benefits and bonuses to our customers.
Let me test out this affiliate link to, just for fun. Send us a mail if you’re interested in the affiliate program.
Finding Info
The first seven years or so of my career as a software developer were good ones. One way I felt that I distinguished myself from others wasn’t anything typical like coding up some super efficient algorithm (in fact, I’m quite bad at that), but rather the ability to hunt down information. Back then Google was just in its infancy. The primary source of info was the MSDN collection of CDs, books, and magazines, all of which I read and I became very good at searching. Whenever there was a hard problem facing our team, I just went to these sources and eventually found a solution.
Even with the advent of Google and other search mechanisms, I don’t feel I have the edge that I used to, but here’s a recent example in WordPress of how I hunted down info about solving a problem for a client. He needed to present admins with a list of templates installed in the user’s theme. Easy problem, but how do you go about finding the answer?
Thankfully, unlike other open source techs I use now, WordPress is a very clean project where finding answers is pretty easy. The first idea I had was: ”Obviously, this must be easy because WordPress itself does this.” Have a look at the template section of the “page edit” admin page:
This “Page Attributes” area is a box on the right side of the page. What I usually do in this case is search the WordPress codebase for a visual text string that is likely to turn up only a few times. In this case, the options weren’t so go, so I just went with the title: ”Page Attributes:”. Fortunately, there were results in the file edit-form-advanced.php:
if ( post_type_supports($post_type, 'page-attributes') )
add_meta_box('pageparentdiv', 'page' == $post_type ? __('Page Attributes') : __('Attributes'), 'page_attributes_meta_box', $post_type, 'side', 'core');
That doesn’t quite get us there, but you can see there’s a function call to “add_meta_box”, so let’s search for “function add_meta_box”. The results are found in meta-boxes.php:
<p><strong><?php _e('Template') ?></strong></p>
<label class="screen-reader-text" for="page_template"><?php _e('Page Template') ?></label><select name="page_template" id="page_template">
<option value='default'><?php _e('Default Template'); ?></option>
<?php page_template_dropdown($template); ?>
</select>
OK, getting closer. There’s a function called page_template_dropdown(). Searching the WordPress Codex doesn’t yield much on this function, so let’s search the source again. This time “function page_template_dropdown”. Here are the results:
function page_template_dropdown( $default = '' ) {
$templates = get_page_templates();
ksort( $templates );
foreach (array_keys( $templates ) as $template )
: if ( $default == $templates[$template] )
$selected = " selected='selected'";
else
$selected = '';
echo "\n\t<option value='".$templates[$template]."' $selected>$template</option>";
endforeach;
}
No we’re getting close! See, there’s a function called “get_page_templates()” which is obviously returning a list of page templates. Exactly what we want. At this point, I assumed that there was a documented function in the Codex for this function. There is, but there’s almost no information on it. So, it’s time to go to the code one more time. And of course, I search for “function get_page_templates”. Here are the results (in theme.php):
/**
* Get the Page Templates available in this theme
*
* @since 1.5.0
*
* @return array Key is the template name, value is the filename of the template
*/
function get_page_templates() {
$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];
$page_templates = array();
if ( is_array( $templates ) ) {
$base = array( trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()) );
foreach ( $templates as $template ) {
$basename = str_replace($base, '', $template);
// don't allow template files in subdirectories
if ( false !== strpos($basename, '/') )
continue;
if ( 'functions.php' == $basename )
continue;
$template_data = implode( '', file( $template ));
$name = '';
if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) )
$name = _cleanup_header_comment($name[1]);
if ( !empty( $name ) ) {
$page_templates[trim( $name )] = $basename;
}
}
}
return $page_templates;
}
Great! Exactly what we need. You can even see the code that implements the behavior as described in the guides on theme development: That in order to register your template with the system, you just need to add comments at the beginning with the text “Template Name:” All we need to do now is pop in this function to our code and we’re good to go!
Too Defensive
The topic of this post sorts reminds me of the whole DbC mess that paralyzed our group for years. Wow, the fallout from some key bad decsions! Well, this example is much more harmless, but I thought it was interesting.
A tester discovered that the SQM code wasn’t achieving the correct code coverage numbers. The target is normally 85% and the SQM code was hovering somewhere around 60%. Why was this?
Because there was a lot of code that looked like this:
if( FAILED( sqmInitStatus_ ) )
{
HWSW::Trace( L"SQMSession::Initialize:: SQM temporary file path error: %s", pSqmFileLocation );
return sqmInitStatus_;
}
Normally, getting inside an “if” statement like this is quite easy from a unit test. You simply have to write a test that forces that error condition. Then, testing your error handler is a simple matter. The only problem was that the author used a traditional method for validating string arguments at the beginning of functions. These traditional validation methods are fine for string validation when you’re using functions like strcat and strcpy. But, if you’re using the safe string functions (StringCch*), then is it overkill?
if ( pAppVersion == NULL || ( ::wcslen( pAppVersion ) == 0 ) || ( ::wcslen( pAppVersion ) > MAX_VERSION ) ||
…
If these any of these conditions fail, the function will return an INVALID_PARAMETER return value. It’s therefore basically impossible for the StringCch* functions to fail, which makes getting inside those if statements impossible.
So, what should be done?
My opinion is to modernize this sort of code. The code does not need so much argument validation at the beginning because the StringCch* functions manage a lot of this. Also, writing unit tests early could have helped catch this sort of problem.
Code Reviews
History:
After some time, I started getting the idea that the evolved code review process may not be so good. Basically, team members use SD Pack and email. Everyone on the team gets the email and everyone sends the review back to the author. The author then pastes all the responses back into another email, comments on each response, and then sends the email. It suffices to say: Not a great use of time (the author has to do a lot of reading, synchronizing email directions with real code), and encourages superficial comments (everyone spends the same amount of time on general areas).
Action:
I started brainstorming ways to improve code reviews. At first I was just thinking of having more sit down paper code reviews. Fortunately, and very serendipitously, an EE training class on code reviews came to Shenzhen. It was taught by a principle developer on loan here in China from Redmond. He’s a solid guy, awesome dev, and one of the best teachers I’ve seen here.
The training was exactly what we were looking for. The great thing was that it actually demonstrated an easy way to measure how useful your code reviews are. We brainstormed some more on this topic, I gave three presentations to the team on the various ideas, we had one quick sample code inspection, and have derived a streamlined process that we’re trying out here at MACH.
My goal: Make the process easy and rewarding.
Process:
The training focused mostly on “code inspections”. We’ve taken some of the ideas and simplified it:
For example, code inspections identifies roles like: Gatekeeper, Moderator, Scribe. We’ve rolled many of these together. We still see value in a moderator (someone other than the author who runs the meeting), but that person can also act as the scribe (writing down bug statistics). The Gatekeeper (the one who ensures the code is ready to be reviewed) can be performed by each author (using an optimized and more visible version of the style guide, there should be no style issues).
There are simple but effective statistics that we will take too:
1. Counting the total number of issues.
2. Of the total issues, which ones are major? Major issues should be labeled and counted. Right now, we’re defining “major” as: Any issue that causes a crash, leaks a resource, hangs the application, affects performance, serious thread issues, or maintainability and design problems. If we know our team’s bug fix rate (we are calculating this now), then we can calculate if the code review was a good use of time. Also, as the percentage of major issues rise (without the overall of quantity of Major issues rising), we’re getting better at Gatekeeping and style.
3. Of the total issues, which ones overlap? Meaning, how many people found the same issue? This helps us to judge the effectiveness of the review. If similar issues, especially major issues, are found, the we have higher confidence in the effectiveness of the code review at finding bugs.
There are two other documents that fell out of this exercise:
1. Improved Style Guide: This idea came from the realization that most of our comments were high level style issues. So, how do we fix it? The first thought was to have a more useful style guide. So, I took the initiative to cut 80% out of the style guide so that it only covered style (not coding best practices or project settings)! We want to refer to it frequently and make changes as needed. One of the main goals though is to keep it short.
2. Code Review Checklist: This idea came from the training class. The team brainstormed and created this list. We haven’t made much use of this yet, but the idea is it’s a reminder of what’s important to review and, more importantly, if we need someone to focus deeply in a particular area, the checklist helps with this.
Of course, this process would not be not required for all code reviews, but only for the biggest, most important reviews. Walk-in peer reviews are still useful for quick reviews, SD Pack and email reviews are still useful in small sections of existing code that you’ve already touched, etc. Part of my job here will be to help the team members understand just when the appropriate review is necessary.
LINQ – .NET Language-Integrated Query for Relational Data
LINQ is basically a translation layer between the class paradigm for programming languages and rows in a relational database. Instead of the programming languages using SQL to query the database, they use instances of their classes and LINQ together. LINQ does all the SQL interaction.
When I first started reading about it, it reminded me of “Ruby on Rails”, specifically the “Convention over Configuration” paradigm.
For example, look at this C# class:
[Table(Name="Customers")]
public class Customer
{
public string CustomerID;
public string City;
}
And now this quote from the MSDN help: “The Table attribute has a Name property that you can use to specify the exact name of the database table. If no Name property is supplied, LINQ to SQL will assume the database table has the same name as the class.”
Except, there’s one little problem. Does the class really need to have the same name as the Table, or does the class need to have the same name as the Table minus the “s”?
Hopefully, I’ll remember to update this post when I learn the answer.
Oh, but look at this code!
[Table(Name="Customers")]
public class Customer
{
[Column(IsPrimaryKey=true)]
public string CustomerID;
[Column]
public string City;
}
Now, there’s a “Column” keyword that tags the data member as a column in a database table. According to the same MSDN Help, “As with the Table attribute, you only need to supply information in the Column attribute if it differs from what can be deduced from your field or property declaration.”
This is “Convention over Configuration” at work.
Code Review Process
If I were to answer the question, “What are the elements of a worthwhile code review?”, to a IT reporter in need, I would answer something like this:
A proper code review is a valuable tool to any software team. The longer that bugs go undiscovered, the more costly it is to fix them. For example, if a developer works out a design on a whiteboard, updates and improvements can be made very cheaply, just by erasing part of the software diagram and starting again. After the product has shipped, an undiscovered bug becomes very expensive to fix, usually through a laborious patching process. A code review is a way to reduce costs by eliminating bugs early. Code reviews occur early enough to catch bugs before they have an opportunity to become very expensive to fix.
But, in order for the code review to be useful, it should be conducted in a responsible manner by a mature team with a good leader. All developers have certainly experienced code review horror stories or at least ones that qualify as wastes of time: Reviewers come to the meeting unprepared and begin reading the code line-by-line, or, reviewers focus on silly issues like “oh, this ‘for’ statement should have a space after the opening parenthesis.”
There are ways to eliminate these sorts of time-waster. There are even ways to measure if your code reviews are worth the time spent. After all, if you’re spending more time in your code review than you could have been fixing bugs, then your code reviews are not useful. Of course, this is rare.
First of all, to eliminate the silly code review comments like spaces or capitalization, you need a good style guide. A style guide describes how the team prefers to comment, how the team prefers to name classes, variables, and methods, and how to format. It should not attempt to convey software best practices, like how best to deal with memory that can’t be allocated, or tracking threads, and so on. It should only focus on style. The style guide should be short enough so that it can be easily grasped by everyone on the team and not cover every nauseating detail so that team members still have a sense of freedom to write the code the way they see fit. After all, writing code can be very personal.
Developers are then held accountable that they will have no style issues in their code. If the team has established good style guidelines which are readily accessible and used frequently, this ought to be easy.
To ensure that everyone prepares in advance, you can create some fun rules. For example, we have simple rule that says, “If you have no red marks on your code print-out’s you’re not allowed into the review. Red marks are the ticket!”
To help the team focus on important issues, a code review checklist is useful. The team can create this together, again keeping it very short so that it’s easy to refer to, and then use it to coordinate focusing on specific areas. Too often, poorly run code reviews has everyone focus on the same superficial issues. A code review checklist can help encourage a smaller group to focus deeply on a specific area, another group to focus on a different area, and so on. This helps the code review achieve depth.
It’s also a good idea to have someone other than the author to run the code review meeting. Software developers tend to be a proud lot and an independent moderator can keep the discussion from getting too personal. A good moderator is someone good at running meetings, keeping people on track and focused on important issues.
Finally, you can calculate just how effective your code reviews are by having two pieces of information: The average bug fix rate for a team member (usually ranges between 1 and 2 per day), and how many major issues you uncovered in your code review. Assume you found five major issues in your last code review and your team’s major bug fix rate is one per day. If there was no code review, it would have cost approximately five days to fix those bugs (the number of bugs times how long it takes to fix a major issue). If your code review had five participants, each prepared for one hour, and the review meeting lasted one hour, the total time is 10 hours. That’s well less than five days, so your code review was worthwhile!
Our team in China is just now adopting these changes and we’re excited about it. We especially enjoy being able to measure the effectiveness our our reviews.