Dollar Shave Club (Executive) Review as a Gillette Mach 3 User

I decided to try the Dollar Shave Club Executive (6 blade) model for a month. The shave butter broke down too quickly for my skin and facial hair thickness. After shaving, I had a lot of spots in my facial hair that were about a half day’s worth of growth in length. Whether using the shave butter or my Gillette Sensitive Skin shaving cream, I experienced a small amount of irritation–not as much as a cheap disposable, but a little more than the Schick Quattro. The closeness of the shave is ultimately as close as the Quattro, but with noticeably more irritation. I’ll stick with the $$$$ for the Gillette razors.

For comparison:

  • I use the base Gillette Mach 3 razor normally, usually with the Gillette Sensitive Skin shaving cream.
  • I generally shave twice a week, partly because my skin is too sensitive if I shave more frequently than that.
  • I have sparse and uneven facial hair.
  • Dollar store and disposable Bic razors break the skin for me.
  • The Schick Quattro razor didn’t irritate the skin any more than my Mach 3, but the shave isn’t that close for me.
  • Electric razors turn my skin red with irritation.

Hope this helps you decide if Dollar Shave is an option for you.

Using a vimscript to run through a list of substitutions with dictionary pairs

I wanted to modify a test suite to call a method using ruby 2’s keyword arguments. There were several calls to the same initialization function that followed a pattern that made it a good candidate for a series of `%s` calls using key-value pairs in a dictionary.

Interesting how vimscript uses a leading slash as line continuation instead of a trailing slash at the end of the continued line.

Also, it took me a while to figure out that interpolating a variable in an Ex command required “execute” and string concatenation with periods.

let fields = { 'public_key' : 'public_pem_key',
              \'private_key' : 'private_pem_key',
              \'username' : 'username',
              \'password' : 'password',
              \'url' : 'url',
              \'ssl_verify_host' : 'ssl_verify_host'
            \}
 
for key in keys(fields)
  execute '%s/\([ \t]*\)\(.*TestCommon::' . fields[key] . '\)/\1' . key . ': \2/'
endfor

Mac OS X Mavericks, rbenv, and ruby-build “Missing the OpenSSL lib?”

openssl version: 1.0.1i, rbenv version: 0.4.0, ruby-build as plugin in the ~/.rbenv/plugins directory.

The version of openssl on a Mavericks machine got out of sync with rbenv and ruby-build for some reason. For every attempt at installing a ruby version through rbenv attempted, we got the following message:

“The Ruby openssl extension was not compiled. Missing the OpenSSL lib?”

Tried every permutation of trying to fix one thing at a time, but ultimately ended up doing the following:

~/.rbenv/plugins/ruby-build directory
brew unlink openssl rbenv ruby-build
brew uninstall openssl rbenv ruby-build
brew update
brew install openssl
brew link openssl --force
brew install rbenv
eval "$(rbenv init -)"
brew install ruby-build

Then we were able to install whatever ruby version we wanted.

I’m sure some of the above process was overkill and unnecessary, but the steps in total did the job.

Excel for Mac Breaks Up Spreadsheets Into Pages

Excel for Mac seems to use “Page Layout” view by default. This can be switched to the more sane Normal view by selecting View -> Normal from the menu.

You can change the default view in Excel -> Preferences -> View -> Preferred view for new sheets.

Still trying to figure out if there is a way to force all document openings to this setting as well.

powerline vim, NameError, invalid expression error on the latest update.

I have vim with pathogen and on the latest update of the powerline.vim, everything broke.

It turns out that my old default config files are incompatible with the new version of powerline. See GitHub issue.

When I ran vim with --cmd 'let g:powerline_config_overrides={"common":{"log_file":"/tmp/powerline.log"}}' as suggested, a bunch of config mapping errors showed up:

2014-09-03 15:36:33,992:ERROR:vim:matcher_generator:Failed to import attr ctrlp from module powerline.matchers.plugin.ctrlp: No module named plugin.ctrlp
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/__init__.py", line 311, in get_module_attr
    return getattr(__import__(module, fromlist=(attr,)), attr)
ImportError: No module named plugin.ctrlp
2014-09-03 15:36:33,993:ERROR:vim:matcher_generator:Failed to import attr gundo_preview from module powerline.matchers.plugin.gundo: No module named plugin.gundo
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/__init__.py", line 311, in get_module_attr
    return getattr(__import__(module, fromlist=(attr,)), attr)
ImportError: No module named plugin.gundo
2014-09-03 15:36:33,995:ERROR:vim:matcher_generator:Failed to import attr nerdtree from module powerline.matchers.plugin.nerdtree: No module named plugin.nerdtree
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/__init__.py", line 311, in get_module_attr
    return getattr(__import__(module, fromlist=(attr,)), attr)
ImportError: No module named plugin.nerdtree
2014-09-03 15:36:33,998:ERROR:vim:matcher_generator:Failed to import attr gundo from module powerline.matchers.plugin.gundo: No module named plugin.gundo
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/__init__.py", line 311, in get_module_attr
    return getattr(__import__(module, fromlist=(attr,)), attr)
ImportError: No module named plugin.gundo
2014-09-03 15:36:34,010:ERROR:vim:segment_generator:Failed to generate segment from {u'name': u'mode', u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,010:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 10, u'name': u'visual_range', u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 10, u'name': u'paste_indicator', u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 30, u'name': u'branch', u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'after': u' ', u'name': u'readonly_indicator', u'draw_soft_divider': False}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 40, u'name': u'file_directory', u'draw_soft_divider': False}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'name': u'file_name', u'draw_soft_divider': False}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'name': u'file_vcs_status', u'draw_soft_divider': False, u'before': u' '}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'name': u'modified_indicator', u'before': u' '}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 50, u'module': u'powerline.segments.plugin.syntastic', u'exclude_modes': [u'nc'], u'name': u'syntastic'}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,011:ERROR:vim:segment_generator:Failed to generate segment from {u'draw_soft_divider': False, u'priority': 50, u'module': u'powerline.segments.plugin.tagbar', u'exclude_modes': [u'nc'], u'name': u'current_tag'}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,012:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 60, u'name': u'file_format', u'draw_soft_divider': False, u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,012:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 60, u'name': u'file_encoding', u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,012:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 60, u'name': u'file_type', u'exclude_modes': [u'nc']}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,012:ERROR:vim:segment_generator:Failed to generate segment from {u'priority': 50, u'width': 4, u'align': u'r', u'name': u'line_percent'}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,012:ERROR:vim:segment_generator:Failed to generate segment from {u'width': 3, u'align': u'r', u'name': u'line_current', u'draw_soft_divider': False}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'
2014-09-03 15:36:34,012:ERROR:vim:segment_generator:Failed to generate segment from {u'name': u'virtcol_current', u'align': u'l', u'priority': 20, u'width': 3, u'draw_soft_divider': False, u'before': u':'}: u'function'
Traceback (most recent call last):
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 240, in get
    contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
  File "/Users/tpowell/.vim/bundle/powerline/powerline/segment.py", line 62, in get_function
    function_name = segment['function']
KeyError: u'function'

The quickest solution is to take the new default config files and dump them in your ~/.config/powerline directory.

The Mohu Leaf worked so well, I upgraded to a Mohu Sky

Ok, I had the Mohu Leaf working for almost the entire house using the DirecTV cable in and with 2 indoor antenna amplifiers on the HDTVs. The signal was almost strong enough just by putting it against the side of the house facing the station antennae (according to AntennaWeb, even though we’re about 20 miles out from the station broadcasts. One downside was that the paper thin design was too prone to being blown around by storms.

Decided to upgrade to the Sky and have it “mounted” on the inside of our privacy fence (with open air in the direction of the antennae). I plugged the amp into the 4-way splitter and removed all other amps. We’re now even getting the obscure channels.

Refinements in Ruby: in map: super: no superclass method

I was trying out refinements to see if they would help clean up some parsing code. I liked defining a couple of methods for the String class to respond to, but really didn’t want them as permanent monkey patches on String.

And so, I had a pipe mapping module with refinements:

module PipeMapping
  refine String do
    def only_lines_with_pipes
      self.lines.select { |s| s =~ /\|/ }
    end
    def pipes_to_array
      self.split('|').map(&:strip)
    end
  end
end

I added the following to my class to allow it to load itself:

  using PipeMapping
  def self.initalize_mappings
    data_to_load.only_lines_with_pipes.map(&:pipes_to_array).each do |mapping|
      # do stuff
    end
  end

I got the following output:

...in `map': super: no superclass method `pipes_to_array' for "A|B|C\n":String (NoMethodError)

The problem is that Symbol#to_proc will end up operating outside of the scope of the refinement using invocation, and will, therefore, have no knowledge of the method.

A quick change to a block works:

  using PipeMapping
  def self.initalize_mappings
    data_to_load.only_lines_with_pipes.map{|s| s.pipes_to_array}.each do |mapping|
      # do stuff
    end
  end

I’m still trying to decide if this is a satisfactory trade-off.

rails (4) generate migration behaviors I forget to use

When I’m generating a migration, I usually don’t go any deeper than specifying column_name:data_type on the command line, and often I only use the command line to generate the file itself.

I don’t know that the other options really save all that much typing, but stopping to think about the other options for a few seconds might just help avoid having to go back later and add things.

Elementary things I don’t make enough use of:

  • rails g migration AddXXXtoYYY automatically creates an add_column for table YYY for every column name specified.
  • rails g migration RemoveXXXtoYYY automatically creates a remove_column for table YYY for every column name specified.
  • Specifying column_name:data_type:index¬†also adds an index to the new column.
  • rails g migration CreateJoinTableXXXYYY will produce a join table.

Applescripts to Mute or Unmute Lync

In preparation for hooking up Lync muting and unmuting to separate hotkeys, I wanted to make sure that my scripts no longer toggled the mute button, but only muted or unmuted.

For that to work, I needed to retrieve the current state of the checkbox.

set theCheckbox to checkbox 5 of splitter group 1 of aWindow
tell theCheckbox
  set checkboxStatus to value of theCheckbox as boolean
  if checkboxStatus is true then click theCheckbox
end tell

In this case, I store off the checkbox into a variable theCheckbox and then later the checkbox status into a variable, allowing me to unset the checkbox if it is true.

This results in the following script for unmuting:

tell application "Microsoft Lync"
	activate
end tell
tell application "System Events"
	tell process "Microsoft Lync"
		repeat with aWindow in (get every window)
			set aName to get the name of aWindow
			set initialName to ((characters 1 through 12 of aName) as string)
			if (initialName = "Conversation") then
				activate aWindow
				set theCheckbox to checkbox 5 of splitter group 1 of aWindow
				tell theCheckbox
					set checkboxStatus to value of theCheckbox as boolean
					if checkboxStatus is true then click theCheckbox
				end tell
			end if
		end repeat
	end tell
end tell

And for muting:

tell application "Microsoft Lync"
	activate
end tell
tell application "System Events"
	tell process "Microsoft Lync"
		repeat with aWindow in (get every window)
			set aName to get the name of aWindow
			set initialName to ((characters 1 through 12 of aName) as string)
			if (initialName = "Conversation") then
				activate aWindow
				set theCheckbox to checkbox 5 of splitter group 1 of aWindow
				tell theCheckbox
					set checkboxStatus to value of theCheckbox as boolean
					if checkboxStatus is false then click theCheckbox
				end tell
			end if
		end repeat
	end tell
end tell

These scripts (and hopefully, others soon) are available on GitHub

Toggling the mute button in Microsoft Lync for Mac via Applescript

Through liberal use of the dictionary for Microsoft Lync, the Accessibility Inspector, and a few web links, I’ve come up with this script which toggles the mute button in Lync for Mac.

tell application "Microsoft Lync"
  activate
end tell
tell application "System Events"
  tell process "Microsoft Lync"
    repeat with aWindow in (get every window)
      set aName to get the name of aWindow
      set initialName to ((characters 1 through 12 of aName) as string)
      if (initialName = "Conversation") then
        activate aWindow
        click checkbox 5 of splitter group 1 of aWindow
      end if
    end repeat
  end tell
end tell

I still want to hook it up to a hotkey, and ideally, have a different hotkey for mute and unmute, but that will have to be left for another session. I will hopefully update this post with more details as I figure out how to explain them.