Greenshot for Screenshots

I used to knock on Snagit from TechSmith. I didn’t get why somebody would pay for a screenshot utility when Windows comes with one built-in. Then I got a license, and I was converted. I loved not having to hand-draw crappy arrows, boxes, and highlights. It upped my screenshot game, big-time!

snipping_tool

But, like all good things, my time with Snagit came to an end. I left the job that brought us together, and with it, my license. I was back to living in the screenshot dark ages with Snipping Tool and Paint. After a few months, I’d had enough. I was ready to put down $50 for a personal Snagit license so that I’d never be without it again. I’m pretty sure I even went as far as putting it into my cart on the TechSmith website, but I never quite pulled the trigger.

I don’t know why it took me so long to think of this, but I finally headed over to Google and searched for Snagit alternatives. And that’s where I met one of my new best friends: Greenshot.

Greenshot has all the features that I’d grown to love about Snagit, but it’s free & open-source. Here’s a quick list of what I love most:

  • PrtSc to select a region (Ctrl+PrtSc for entire desktop, Alt+PrtSc for current window)
  • Screen grabs open in editor with drawing tools like rectangles, ellipses, arrows, highlighter, textboxes, and speechbubbles
  • Obfuscation tool to draw a box around & blur sensitive data
  • Auto-incrementing counter circles — perfect for giving directions!

greenshot

The only thing I didn’t love right out of the gate is that the default keybinding for copying the image from the editor to the clipboard is Ctrl+Shift+S instead of just Ctrl+C. But I’ve gotten used to it, and it’s nice being able to use Ctrl+C/Ctrl+V to copy/paste elements in the editor. It lets me do things like have arrows that are the exact same size and parallel, which is great since I’m super anal about stuff like that!

So, if you’re stilling using Snipping Tool and/or Paint or looking for a great alternative to Snagit, give Greenshot a try. You won’t be disappointed! Unless you want something that also takes videos. Then you’d be disappointed and would probably want to go get Snagit. But for screenshot editing, go Greenshot!

Broadcast Changes to Angular Factory Properties

I was making a little website with Angular the other day, and I wanted to have a search box in my nav bar that could be used from any page. When the search control is used, the user is sent to a search page that displays results but also lets users run additional searches. Both search functions use the same angular factory to execute their searches. Unfortunately, I was finding that the nav bar search control wouldn’t update search results when used from the search page.

I was able to solve the problem by using $broadcast and $on. It’s pretty simple, and it looks a lot cleaner than a lot of $watch solutions that I ran into while looking for a solution.

Here’s what my factory looks like:

app.factory('searchService', ['$rootScope', '$http', function ($rootScope, $http) {
    var factory = {
        search: search,
        getResults: getResults
    };
    
    var _results = [];
    
    function search(criteria) {
        return $http.post(_serviceBase + 'api/search', criteria).then(function (results) {
            _results = results.data;
            $rootScope.$broadcast('searchCompleted', _results);
            return results;
        });
    };

    function getResults() {
        return _results;
    }

    return factory;
}]);

And here’s my searchController that handles the broadcast event with $on:

app.controller('searchController', ['$scope', 'searchService', function ($scope, searchService) {
    $scope.criteria = {};
    $scope.results = searchService.getResults();

    $scope.search = function () {
        searchService.search($scope.criteria).then(function (results) {
            $scope.results = results.data;
        }, function (error) {
            console.error(error.data.message);
        });
    };

    $scope.$on('searchCompleted', function (results) {
        $scope.results = searchService.getResults();
    });
}]);

Note the use of $rootScope in the factory. Broadcasting the change is a single line of code, and handling the event in relevant controllers is pretty simple, too. Nice!

String Formatting with Regex

My latest favorite trick with regular expressions is to shortcut string formatting. We’ve all written some code like this:

if (/* string is not formatted a certain way */)
{
    /* make it formatted that way */
}

Now, there’s nothing wrong with that code, but for simple examples you could do it all in one step with a regular expression!

Here are a few examples:

// remove "www." from a domain if one exists
// domain.com     -> domain.com
// www.domain.com -> domain.com
Regex.Replace(input, @"^(?:www.)?(.+)$", "$1");

// format phone number
// 1234567890       -> 123-456-7890
// (123) 456-7890   -> 123-456-7890
// (123) 456 - 7890 -> 123-456-7890
Regex.Replace(input, @"^\(?(\d{3})\)?\s*(\d{3})\s*-?\s*(\d{4})$", "$1-$2-$3");

Yay, regular expressions!

A Better Table.CreateInstance() for SpecFlow

SpecFlow remains my top choice for automated integration testing. I love writing cute little cukes and putting them together in different ways to create different test scenarios. And one of my favorite cuke tricks is using tables to define an object, which I wrote about some time ago.

The CreateInstance<T> extension method provides an easy way to convert that table data into objects for testing, but I really think there should be a better way to populate child properties of complex objects.

Consider this example:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

It would be nice if you could write a cuke like this:

Given a person
	| field          | value         |
	| firstName      | adam          |
	| lastName       | prescott      |
	| address.street | 123 number ln |
	| address.city   | anytown       |
	| address.state  | ny            |
	| address.zip    | 10000         |

And then convert it to a person like this:

[Given(@"a person")]
public void GivenAPerson(Table table)
{
    var person = table.CreateInstance<Person>();
    ScenarioContext.Current.Set(person);
}

But you can’t. Well, you can, but the address property won’t be populated. I didn’t like that, so I decided to grow my own. It works by identifying the child properties in the table and creating sub-tables, then using reflection to find and set the property on the result object. It works recursively, too, so you could even go n properties deep (i.e., address.state.abbreviation).

At its core, it’s just using CreateInstance<T> so you get all the niceties that go along with that. Note also that it only works with the 2-column, vertical tables with field and value columns. I called my extension method BuildInstance since CreateInstance was already taken. Here it is… Enjoy!

using System;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;

public static class TableExtensions
{
    public static T BuildInstance<T>(this Table table)
    {
        T result = table.CreateInstance<T>();

        // find sub-properties by looking for "."
        var propNames = table.Rows.OfType<TableRow>()
            .Where(x => x[0].Contains("."))
            .Select(x => Regex.Replace(x[0], @"^(.+?)\..+$", "$1"));

        foreach (var propName in propNames)
        {
            // look for matching property in result object
            var prop = typeof(T).GetProperty(
                propName,
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

            if (prop != null)
            {
                // create sub-table with relevant rows (field == propName.something)
                var subTable = new Table("field", "value");
                var re = new Regex(string.Format(@"^{0}\.([^\.]*)$", propName), RegexOptions.IgnoreCase);
                table.Rows.OfType<TableRow>().Where(x => re.IsMatch(x[0]))
                    .Select(x => new[] { re.Replace(x[0], "$1"), x[1] })
                    .ToList()
                    .ForEach(x => subTable.AddRow(x));

                // make recursive call to create child object
                var createInstance = typeof(TableExtensions)
                    .GetMethod(
                        "BuildInstance",
                        BindingFlags.Public | BindingFlags.Static,
                        null,
                        CallingConventions.Any,
                        new Type[] { typeof(Table) },
                        null);
                createInstance = createInstance.MakeGenericMethod(prop.PropertyType);
                object propValue = createInstance.Invoke(null, new object[] { subTable });

                // assign child object to result
                prop.SetValue(result, propValue);
            }
        }

        return result;
    }
}

Selective Revert in Git

Uh oh, a mistake was made in your Git repository, and it needs to be undone. I use SourceTree for the majority of my Git-in’, and reverting changes is really easy. Just right-click a commit, choose “Reverse Commit,” answer “Yes” in the confirmation box, and the deed is one. On one hand, it’s nice because it’s so simple. On the other, it doesn’t give you much control.

I recently had to deal with a bad merge that contained many files. Some of the merge was legit, but part of it was also undoing valid changes. I wanted to partially revert the commit and pick which files/changes to keep. Unfortunately, I couldn’t find a way to do this in SourceTree, but it’s pretty simple to do from the command line.

git revert can be run with -n or –no-commit to revert a commit but not automatically commit the result.

git revert --no-commit <sha-1>

My commit was a merge, and undoing merges can be more complicated. For my purpose, simply adding -m 1 was sufficient.

git revert --no-commit -m 1 <sha-1>

My Year in Gadgets

I like gadgets, and so I tend to buy a lot of them. Some are life-changers, and some fizzle out after a few weeks or months. Here’s a rundown of notable gadgets I’ve acquired this year.

Bose SoundLink Mini Bluetooth Speaker

This little guy ended up on my wish list after playing with a demo at Best Buy. I definitely had a “whoa” moment when I heard it for the first time. So, when I moved into an office at work, I decided it was time to pull the trigger. I mean, it would be silly for me to listen to headphones in a room all by myself, right?

This is one purchase that I have zero regrets about. I use it almost every day. I listen to music in the office, NPR in the kitchen, and have toddler dance parties in the living room. It’s also great for being outside. The battery life is really good. I can’t tell you exactly what it is because I think it’s only gone dead on me once or twice. (It has a charging dock that I keep on my desk, and that’s it’s usual resting place.) I think you get a good 10+ hours on a full charge, though.

JayBird BlueBuds X Sport Bluetooth Headphones

After going to the gym for a few weeks, I decided it was time to invest in a pair of quality workout headphones. I wanted to go wireless because I’ve never really liked having the cord flopping around while I run, but I also wanted great sound since I could be using them 5-10 hours each week between workouts and other uses.

First, the good. The sound quality did not disappoint. I was nervous that I’d regret not going for a pair of wired buds with better quality, but these were great. The battery life is pretty good. I charge them every few days, and that’s sufficient to keep them from ever dying on me.

There is some bad with these, though. It took me a week or two to get used to them. In the first few days, I was really disappointed. I had tried a few different configurations (cord over the ear, under the ear, different size buds & wedges), but they weren’t comfortable and kept falling out during workouts. However, I stuck with them, found a configuration that I like, and no longer have any problems–so don’t give up! The only problem I have with them now is that every now and then, I’ll have problems with the audio just stopping. I don’t know if it’s my phone or the headphone that’s the culprit, but I’ll be listening to a song and it will just stop. There is no indication that I have disconnected, but I can take a few steps to reconnect and everything will be fine. I have tried rebooting my phone, power-cycling the headphones, and anything else I could think of. Most days everything is fine, but it’s super annoying on that one day every other week where it’s being temperamental. There have been a couple of days where I’ve given up on them and just stuffed them into my pocket during a workout.

One final gripe is that when I’ve used these to watch Netflix in bed, the audio has been out-of-sync with the picture. The audio sounds great, so I don’t blame the headphones here, but it’s out-of-sync due to bluetooth. So it’s not a problem that I’d have if I’d gone with wired ear buds.

Despite this seemingly negative review, I’m happy with what I’ve got. I’m sure that if I’d selected a wired pair, I’d have regrets about the cord. I love the sound and they’re comfortable. Great for listening to music, not-so-much for video.

Jackery Giant+

A portable power bank is one of those things that I never seemed to think about unless I was in need of one. Before my most recent trip out to the west coast, I decided to pick one up. I was initially deciding between the Lumsing 10400mAh and the Jackery Giant. I liked the Lumsing because it’s super-economical ($25), but I ultimately went with the Giant+ because of–of all things–the location of the USB ports.

One of the reviews of the Lumsing pointed out that it was awkward to use the charger from a pocket. I don’t expect that I’ll be doing my charging from my pants (but who knows), but I like that I can stick the Giant+ in an inner pocket of my backpack and still have the ports exposed. When I need some juice on the go, I can easily plug-in without any fuss and toss the device in need of charging into my backpack. The Giant+ is also slightly bigger (12000mAh) and has a flashlight. The flashlight seems like it could be useful, but the question is whether I’ll have the Giant with me when I need it!

Microsoft Band

When the Band was first announced, I was very “meh” about it. I had been looking for a watch with a built-in timer or stopwatch to help me with my workouts, and so I convinced myself to try it out. I headed over to my local Microsoft Store and they were all out of stock. Now that I couldn’t have one, I really wanted one. So I got myself on a list and waited.

It came a couple of weeks later. I’ve had it for about a month now, and I’m pretty happy with it. The thing I like most is something that I did not expect: the email and text alerts. You can’t really read or reply to these messages, but it’s great to take a quick peek by flipping your wrist to then determine if the it’s worthy of bringing my phone out of my pocket and dealing with it. Payment notification from Verizon, ignore. Text from wife, address immediately.

I haven’t really tried the guided workouts, I don’t really go on runs, and I don’t really care about my step count. I like the workout tracker (essentially just a timer + heart monitor) and sleep tracking, and, as mentioned previously, I really like the email and text alerts. It’s still early with this one, but it seems like a win.

Kindle Voyage

The Kindle Voyage is my latest toy. I had a 1st generation Kindle Fire that was ironically lost in a fire. I like it for reading at night, but I didn’t use many of the tablet features (browser or apps) and the glare was not so good for daylight reading at times. So, I decided to go for a pure e-reader this time. I’ve read just one book so far, but the more I use it, the more I like it.

I decided to get the Voyage for the auto-brightness adjustment, and it works nicely. I also like the page turn buttons on the side but wouldn’t consider this to be any sort of killer feature. All-in-all, I’m happy with this. It’s definitely better for reading than my Kindle Fire was, but I can’t say how it compares to another pure reader like the Paperwhite.

Wagan Power Dome EX 400-Watt Jump Starter with Built-In Air Compressor

This is less techy, but it is no less awesome. I’m a stickler for tire pressure, but the condo that I’ve been living in does not have a nearby power source for me to connect my small air compressor. The gas station air is a pain since it’s usually not free, and I probably don’t have correct change. So, I wanted to find a wireless air compressor that I could keep in my car to use when I need it.

There were mixed reviews about this, but I decided to take a chance. I’m glad I did–I love it. Low pressure? I just pull this puppy out of the cargo area, and I’m back to normal in no time! It doesn’t fill up super fast (about 1-2 lbs every 30 sec), but it definitely gets the job done. Putting a few pounds of air into all four tires is easy work. There are gripes about the valve cord not being long enough, but just tip it on its side and it’s plenty.

It’s also got a jump starter. I haven’t had to use it, but it’s nice to know that I’ve got it. (I’ve been burned by jump starters in the past, so I’m keeping regular jumper cables around, too!) It has USB ports for charging devices, a radio, a flashlight, and both AC and DC power outlets. Plus it looks cool and seems to impress dads and grandpas. I’m happy with this thing just as a portable air compressor, but it does a lot more!

Getting Started with Selenium in Python

I just spent a day doing some browser automation with Selenium in Python, and man-oh-man is it fun! I was surprised at how quickly I was able to get setup and productive, and I thought I’d put together a quick getting started guide to celebrate.

Installation

If you’re starting from scratch (no Python), then the first thing you’ll want to do is install Python. Head on over to python.org and grab a copy. If you install Python 2, you’ll also want to install pip. (Python 3 ships with pip, so it is not necessary to install it yourself.)

With Python and pip, installing Selenium is done with a single command:

pip install selenium

That’s it, now you’re ready to get to automatin’!

Hello World

Open your favorite text editor and create a new file. The first thing you’ll do is import the selenium.webdriver module. Then, you’ll instantiate a webdriver. And then you’ll automate whatever you want!

Here is a script that goes to google and types “hello world” into the box.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.google.com")
driver.find_element_by_id("gbqfq").send_keys("hello world")
driver.close()

Development

I only have one day’s worth of knowledge as I’m writing this, but what I’ve found to work well is to use Chrome’s right-click > Inspect element function for each element that I need to find or interact with and type it into my Python script.

For example, if I wanted to automate entering data into a form, I’d inspect the element to find its id or other identifiable trait (name, css), then type it into my script.

Here’s how you might automate logging into a website:

<form>
    <input id="username" type="text"></input>
    <button id="login-submit" type="submit">Submit</button>
</form>
driver.find_element_by_id("username").clear()
driver.find_element_by_id("username").send_keys("admin")
driver.find_element_by_id("login-submit").click()

And here’s how you might validate that the login was successful:

<div class="banner">
    <span>Welcome, admin</span>
</div>
assert "Welcome, admin" in driver.find_element_by_css_selector("div.banner span").text

Super easy, super fun! Want to learn more? Start here!

Output Parameters in Argument Constraints with Rhino Mocks… Again!

One of my favorite things about being a blog owner and operator is when I’m looking for something and find that I’ve already answered my own question. This just happened to me as I was trying to re-figure out how to use output parameters with argument constraints with Rhino Mocks.

I found an article on this very topic written by me (thanks, self!), but as I was reading I noticed that I left something important out. So here’s a quick, mini do-over!

Let’s say we need to stub function Bar as it’s defined in the following interface:

public interface IFoo
{
    bool Bar(out string outty);
}

To use an argument constraint with the output argument, I need to do two things. First, I need to use Arg<T>.Out. The second thing–the thing that I failed to mention in my previous post–is that I need to use the Dummy property to make it compile.

Here’s what an example might look like. I stubbed the Bar function to return true and assign the value fake value! to the output argument.

IFoo mockFoo = MockRepository.GenerateMock<IFoo>();
mockFoo(x => x.Bar(out Arg<string>.Out("fake value!").Dummy)).Return(true);

Not too shabby!

Edit Environment Variables in the Registry

I’m annoyed with the state of environment variables, more specifically the PATH variable. It used to be not entirely intuitive but relatively easy to edit. You’d right-click My Computer > Properties > Advanced > Environment Variables and be home free.

Recently, I needed to add a value to my PATH variable. In Windows 8.1, finding the advanced system properties is a little different, but I made it there without too much trouble. So, I selected the PATH variable, clicked the edit button, and was presented with a dialog box. It looked good, but I couldn’t type anything!

I believe I wasn’t able to type because my existing value exceeded the the character limit of 1024. I’m sure this limit has been there all along, but it was super annoying to deal with. I was able to get around the problem by using PowerShell. This worked fine for adding a new path to the environment variable, but I don’t think it would be so great for editing to remove an unneeded path or correct a mistake. But whatever, it worked, and I thought I was in the clear until today when I found that my added path had inexplicably been removed! Gah!

I headed back to Google for a better solution, and I think I found a winner. You can edit the values in the registry, which gives me everything I’m looking for. I can copy the entire existing value into a text editor, make whatever changes, and then copy it back into the registry and save. Oh, and then you have to reboot. (Ugh.) This all seems WAY harder than it should be, but it does work, and I found it to be less annoying than the alternatives I could find.

Here are the registry keys:

  • User – [HKEY_CURRENT_USER\Environment]
  • System – [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment]

 

nullybool == true

It’s always been a pet peeve of mine to see conditions where a boolean variable is compared to a boolean value.

if (someBoolean == true) // ew!
{
    ...
}
if (someBoolean) // omg, better!
{
    ...
}

It bothers me because it’s redundant. You already have a true or false, do you really need to compare it to true or false to know if it’s true or false?

I picked up this little bugbear back in the VB6 world. As I moved into the .Net realm, I was introduced to a new spin on booleans: Nullable<bool>. At it’s core, it’s still a boolean though, right? So my peeve lived on.

if (nullybool.HasValue && nullybool.Value == true) // blech!
{
    ...
}
if (nullybool.HasValue && nullybool.Value) // omg, yes!
{
    ...
}
if (nullybool.GetValueOrDefault()) // OMG, EVEN BETTER!
{
    ...
}

But alas, I have just learned that comparing nullable booleans to boolean values is actually quite nice. It saves you a lot of .HasValue-ing. I am officially ending my lifelong campaign against removing “== true” and “== false” from any and all code I come across; I’m making exceptions for nully-bools.

if (nullybool.GetValueOrDefault()) // gettin' paid per keystroke?
{
    ...
}
if (nullybool == true) // noice!
{
    ...
}

Now, all that said, there is still a place for HasValue. Sometimes you need to know if the value has actually been set, but I won’t want to see any more nullybool.HasValue && nullybool.Value-business. I’m done with that! (And a new peeve is born…!)