0

Things and Pomodoro

Posted by admin on Aug 31, 2010 in Uncategorized

For the last two years, I’ve been a loose GTD-er, using Cultured Code’sThings” to dump my brain and keep track of tasks to do. I never got into the “project” side of GTD–planning out every project and asking why… I’m sure it has value, but that was never the problem I was trying to solve with GTD.

I just wanted to keep up with all the stuff everyone wanted me to do and I was tired of having things so easily slip through the cracks.

Well, 2+ years later and I’ve gotten very used to capturing, scheduling, prioritizing and crossing off items from my master list that isn’t in my brain. Things has been great for this, if only for the “Today” feature. For those of you looking for a great GTD app, I’d still recommend Things even though it doesn’t have OTA sync yet and there are many performance issues. It’s a simple app that does a simple thing.

Now, though, I’ve discovered that I have a problem getting motivated to do items on my list. Motivation is always difficult, but I tend to be paralyzed when I’m not sure how I will complete something. It makes me fail to even get started. Enter the Pomodoro Technique. I read this over the weekend and it made a huge difference on the first day. If you struggle with motivation and procrastination, this is the technique for you.

I’ve got 2 years worth of data in “Things” and my Pomodoro Technique is pretty new, so my first big question was how to use them TOGETHER. While this is neither pure GTD nor pure Pomodoro, I think I already have a great way to use Things better than I ever have and to stay motivated. If you’d like to try it, read on.

Read more…

 
0

A Ruby Scoping Gotcha?

Posted by admin on Aug 27, 2010 in Uncategorized

Let’s take this basic class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class TestClass
  attr_accessor :one
 
  def my_method(branch=true)
    if branch
      puts "Do nothing to modify `one`"
    else
      puts "Modify `one` but it's a local variable"
      one = "test"
    end
   
    one # local variable
  end
 
  def my_non_modifying_method(branch=true)
    if branch
      puts "Do nothing to modify `one`"
    else
      puts "Do nothing to modify `one` either"
    end
   
    one #method call
  end
end
1
2
3
4
5
6
7
8
9
10
11
o = TestClass.new
o.one = "Value"

puts o.my_method
 => nil #might expect 'Value' if you're not paying attention
puts o.my_non_modifying_method #expects "Value"
 => "Value"
puts o.my_method(false)
 => "test"
puts o.my_non_modifying_method(false) #expects "Value"
 => "Value"

So remember, if you create any local variables anywhere in your method, even if they’re not called, they override the accessor methods and will give you results you’re not expecting. To get around it, make sure you always use self.accessor= to assign values when there is ambiguity.

 
0

Optional Heirarchal Checkbox Selection with Nested Attributes in Rails

Posted by admin on Jun 4, 2010 in Uncategorized

I had a process where I wanted users to fill out a survey which had hierarchal categories AND be able to specify some additional data for specific capabilities that the user had.

Now, you could easily do this for a small subset and hand-code every item, but I wanted a flexible survey system that allowed true hierarchy and generalized code.

Let’s start off with the basic survey and capabilities models and relationships:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# ./script/generate model Survey name:string
# app/models/survey.rb
class Survey < ActiveRecord::Base
  has_many :survey_capabilities
  has_many :capabilities, :through => :survey_capabilities
end

# ./script/generate model Capability name:string parent_id:integer question:string
# app/models/capability.rb
class Capability < ActiveRecord::Base
  has_many :survey_capabilities
 
  belongs_to :parent, :class_name => 'Capability'
  has_many :capabilities, :foreign_key => 'parent_id'
end

# ./script/generate model SurveyCapability survey:references capability:references answer:string
# app/models/survey_capability.rb
class SurveyCapability < ActiveRecord::Base
  belongs_to :survey
  belongs_to :capability
end

Your first attempt at making a survey map to many capabilities will be something like this (formtastic):

1
<%= f.input :capabilities, :as => :check_boxes %>

But while that works on a basic level, it doesn’t work for capabilities that have a hierarchy and it doesn’t allow the user to specify additional data (i.e. answer a question about the capability).

So we’re going to need to accept nested resources. So we add this line to survey.rb:

1
accepts_nested_attributes_for :site_capabilities, :reject_if => lambda { |a| a[:capability_id].blank? || a[:capability_id].to_i == 0}, :allow_destroy => true

Now we need to recursively display hierarchal capabilities (If you show videos on your site, you might allow the user to invoke it, or require the user to invoke it, but if you don’t show videos, we don’t care about your invocation restrictions):

First, let’s make a quick way to show/hide enable/disable elements within a div:

1
2
3
4
5
6
7
8
9
10
11
12
# public/javascripts/application.js
function toggle_fields(element_id, value) {
  if (!value) {
    Effect.SlideUp(element_id, { duration: 0.1 })
  }
  $(element_id).select('input').each(function(element) {if (value) { element.enable() } else { element.disable() }})
  $(element_id).select('select').each(function(element) {if (value) { element.enable() } else { element.disable() }})
  $(element_id).select('textarea').each(function(element) {if (value) { element.enable() } else { element.disable() }})
  if (value) {
    Effect.SlideDown(element_id, { duration: 0.1 })
  }
}

Now let’s create a helper that will set up the capabilities checkboxes and nested inputs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# app/helpers/survey_helper.rb
def select_capabilities(f, collection)
    html = ""
    collection.each do |capability|
      survey_capability = f.object.survey_capabilities.select{|obj| obj.capability_id == capability.id}.first
      selected = !!survey_capability
      survey_capability ||= f.object.survey_capabilities.build(:capability_id => capability.id)
      f.fields_for :survey_capabilities, survey_capability  do |cap_form|
        html += cap_form.input :capability_id, :as => :boolean, :label => capability.name,
          :input_html => {:onclick => "toggle_fields('capability_#{capability.id}_details', this.checked);$('capability_#{capability.id}_delete').value = (!this.checked ? '1' : '0')"},
          :checked => selected, :checked_value => capability.id
        html += cap_form.input :_delete, :as => :hidden, :value => "0", :id => "capability_#{capability.id}_delete"
        html += content_tag :div, (capability.question.blank? ? "" : cap_form.input(:answer, :label => capability.question)) + (capability.capabilities.any? ? select_capabilities(f, capability.capabilities) : ""), {
            :id => "capability_#{capability.id}_details", :class => "details",
            :style => "display:#{selected ? "block" : "none"}"
        } if capability.capabilities.any? || !capability.question.blank?
      end
    end
    html
  end

There is a lot going on here. Let’s step through.

Keep in mind that we’re recursive, so first off, we’re passing in the collection of Capabilities we’re dealing with through the “collection” parameter, but that isn’t what we need to create in terms of nested form attributes–we need SurveyCapability objects for that, so we have to find or build them:

1
2
3
      survey_capability = f.object.survey_capabilities.select{|obj| obj.capability_id == capability.id}.first
      selected = !!survey_capability
      survey_capability ||= f.object.survey_capabilities.build(:capability_id => capability.id)

Then we create the fields_for section for nested form attributes and pass in the SurveyCapability we just created. Since we can specify that we want checkboxes here and specify the value, we make the checkbox the capability_id and make sure the ‘checked_value’ is the capability.id (it is ‘1′ by default).

1
2
  html += cap_form.input :capability_id, :as => :boolean, :label => capability.name,
                :checked => selected, :checked_value => capability.id

And while we’re at it, we’ll create a way to remove the relationship altogether if they uncheck the capability

1
   html += cap_form.input :_delete, :as => :hidden, :value => "0", :id => "capability_#{capability.id}_delete"

Finally, we build up the optional sub-question in the case of a click:

1
2
3
4
  html += content_tag :div, (capability.question.blank? ? "" : cap_form.input(:answer, :label => capability.question)) + (capability.capabilities.any? ? select_capabilities(f, capability.capabilities) : ""), {
            :id => "capability_#{capability.id}_details", :class => "details",
            :style => "display:#{selected ? "block" : "none"}"
        } if capability.capabilities.any? || !capability.question.blank?

And now we can add the :onclick option to the original checkbox so that appropriate inputs are toggled on click:

1
   :input_html => {:onclick => "toggle_fields('capability_#{capability.id}_details', this.checked);$('capability_#{capability.id}_delete').value = (!this.checked ? '1' : '0')"},

After we’ve got all that going on, we simply have to place it in the _form view:

1
2
3
4
# app/views/surveys/_form.rb
<% semantic_form_for @survey do |f| %>
  <%= select_capabilities f, Capability.find(:all, :conditions => {:parent_id => nil}) %>
<% end %>

Instead of doing Capability.find…, let’s add a named scope to the Capability class:

1
2
3
4
class Capability
  named_scope :top_level, :conditions => {:parent_id => nil}
  ...
end

Yeah! Now you don’t have to change your controllers at all and you can have optional, hierarchal selection of checkboxes with nested attributes!

 
0

How and Why to Stop Multitasking – Peter Bregman – Harvard Business Review

Posted by admin on May 27, 2010 in Uncategorized

A study showed that people distracted by incoming email and phone calls saw a 10-point fall in their IQs. What&apos;s the impact of a 10-point drop? The same as losing a night of sleep. More than twice the effect of smoking marijuana.Doing several things at once is a trick we play on ourselves, thinking we&apos;re getting more done. In reality, our productivity goes down by as much as 40%. We don&apos;t actually multitask. We switch-task, rapidly shifting from one thing to another, interrupting ourselves unproductively, and losing time in the process.

via How and Why to Stop Multitasking – Peter Bregman – Harvard Business Review.

 
0

9GAG – Making an iPad stand from its own packaging

Posted by admin on Apr 27, 2010 in general computing

9GAG – Making an iPad stand from its own packaging.

iPad Stand

Geeky and efficient.  Couldn’t resist.

 
0

Who Is A Good Tester?

Posted by admin on Apr 14, 2010 in test

A good software tester…

  • Constantly asks, “What is the best test I can execute right now”.
  • Can log unambiguous bugs with clear repro steps that make the main problem obvious with few words.
  • Is not distracted by their understanding of developer decisions. Just because the tester may understand certain technology constraints motivating dev solutions, the tester’s mission is never to defend the AUT see my post, What We Can Learn From Dumb Testers. It is to communicate how the AUT currently works, in areas that matter right now.

via Test This Blog – Eric Jacobson’s Software Testing Blog: Who Is A Good Tester?.

 
0

Rails Controller Specs with users, roles and nested routes

Posted by admin on Mar 3, 2010 in rails, ruby, tdd

I’ve long put off testing my controllers because of user authentication and nested controllers, dealing with stubs, etc.

But today, a fully working test!

As background, Advertisers have many trackers and the routes look like this:

1
2
3
4
5
6
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
  map.resources :advertisers do |advertisers|
    advertisers.resources :trackers
  end
end

To set everything up in the specs, I included all the files in the spec/support directory and used Mocha as my mock framework

1
2
3
4
5
6
# spec/spec_helper.rb
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}

Spec::Runner.configure do |config|
  config.mock_with :mocha
end

Then I set up my factories (rather than fixtures) using Factory Girl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# spec/factories.rb
Factory.define :user do |user|
  user.sequence(:login) { |n| "username#{n}" }
  user.password 'password'
  user.password_confirmation { |u| u.password }
  user.sequence(:email) { |n| "email#{n}@example.com" }
  user.first_name "Mama"
  user.last_name "Foo"
end

Factory.define :advertiser do |advertiser|
  advertiser.name 'Advertiser 1'
end

Factory.define :tracker do |tracker|
  tracker.name 'Tracker 1'
end

Now we get down to brass tacks. In order to make my tests DRY (appropriately) and allow for all my controllers to test if someone is logged in and has access, I set up this shared context

1
2
3
4
5
6
7
# spec/support/user_authentication.rb
describe "an admin is logged in", :shared => true do
  before(:each) do
    controller.stubs( :login_required => true)
    controller.stubs( :current_user => Factory.build(:user, :login => 'admin', :roles_list => ["super"]))
  end
end

From there, all we need to do is put it all together, setting up trackers parent @advertiser and the @tracker we’ll be using and stubbing the ActiveRecord find so that it always returns @advertiser

1
2
3
4
5
6
7
8
9
10
# spec/controllers/trackers_controller.rb
describe TrackersController do
  it_should_behave_like "an admin is logged in"
  integrate_views
 
  before(:each) do
    @advertiser = Factory.create(:advertiser)
    @tracker = @advertiser.trackers.create(Factory.attributes_for(:tracker))
    Advertiser.stubs(:find => @advertiser)
  end

Now we simply specify the part of the path that is needed to find the nested route by using :advertiser_id => @advertiser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# spec/controllers/trackers_controller.rb
  it "index action should render index template" do
    get :index, :advertiser_id => @advertiser
    response.should render_template(:index)
  end
 
  it "show action should render show template" do
    get :show, :advertiser_id => @advertiser, :id => @tracker
    response.should render_template(:show)
  end
 
  it "new action should render new template" do
    get :new, :advertiser_id => @advertiser
    response.should render_template(:new)
  end

  it "create action should render new template when model is invalid" do
    Tracker.any_instance.stubs(:valid?).returns(false)
    post :create, :advertiser_id => @advertiser
    response.should render_template(:new)
  end

  it "create action should redirect when model is valid" do
    Tracker.any_instance.stubs(:valid?).returns(true)
    post :create, :advertiser_id => @advertiser
    response.should redirect_to(advertiser_tracker_url(@advertiser, assigns[:tracker]))
  end
 
  it "edit action should render edit template" do
    get :edit, :advertiser_id => @advertiser, :id => @tracker
    response.should render_template(:edit)
  end
 
  it "update action should render edit template when model is invalid" do
    Tracker.any_instance.stubs(:valid?).returns(false)
    put :update, :advertiser_id => @advertiser, :id => @tracker
    response.should render_template(:edit)
  end
 
  it "update action should redirect when model is valid" do
    Tracker.any_instance.stubs(:valid?).returns(true)
    put :update, :advertiser_id => @advertiser, :id => @tracker
    response.should redirect_to(advertiser_tracker_url(@advertiser, assigns[:tracker]))
  end
 
  it "destroy action should destroy model and redirect to index action" do
    delete :destroy, :advertiser_id => @advertiser, :id => @tracker
    response.should redirect_to(advertiser_trackers_url(@advertiser))
    Tracker.exists?(@tracker.id).should be_false
  end
end

Works! And works great! A minimal and excellent way to test your controllers, especially for access. You can easily create additional shared contexts with different user permissions and extend out the tests to make sure users that don’t have access can properly access them.

 
0

An Interesting Way to Publish a Blog

Posted by admin on Feb 27, 2010 in ruby

Peepcode has a blog and it is managed in a very efficient and unique way.  Everything is checked into git and pushed, no database involved–it’s kindof incredible.   Check out the stack here:

About this Blog | Free PeepCode Blog.

 
0

Simplicity

Posted by admin on Feb 23, 2010 in Uncategorized

I’ve read quite a bit lately about simplifying our lives–mostly from a personal perspective, i.e. having less stuff, doing fewer things, focusing on the right things. It made me wonder how that translates to the professional level.

Apple, 37 Signals and many other companies make a living making software simple AND effective to use. That’s one way that it translates–on the macro level, but how about on the micro level? What is your absolute minimum work setup where you are free from distractions and free to do everything you need to do? Are there things that initially seem like “extras” that are actually a big deal? Are there things that you have in your workspace that you could easily do without now?

I thought about these things for my job and realized that my minimum workspace is deceptive: My MBP + my iPhone + a chair + a desk. At first it seems simple, but those first two items pack so much punch and are so high end that while they are simple, they are not as “minimalistic” as they sound as the list sounds at first. Within the iPhone I have apps upon apps that help me stay on top of things. Within my Mac, I have my workspace tuned nearly to the pixel on 6 spaces that are specifically arranged–all for efficiency and separation. But I can do 100% of my job from only these tools. Sure, a second monitor helps. Sure, a backup drive is dumb to be without for long. Sure, I like my digital picture frame–but in reality, these items are nice-to-haves–even the backup since DropBox came on the scene–not criticals.

I know several people that this list would be incomplete for. My coworker simply could not be effective without a whiteboard. Another coworker would be rendered useless without the filing cabinets she has.

What is on your list of criticals for your job?

 
0

Python vs. Ruby – A Fight To The Death

Posted by admin on Feb 21, 2010 in python, ruby

When you’re discussing efficiency, a lot of what comes up is the details.  There is something to be said for the “beauty” of limitation and the “efficiency” of beautiful things–especially the efficiency of our brains processing it.

A talk about the Zen of Python, monkey patching (several times), the Ruby community&apos;s reckless hastiness, the syntax of RSpec and cucumber, beauty and ugliness in languages and testing tools, the complexity of the languages&apos; grammars, syntactic vs. semantic complexity, the relative taste of grasshoppers and tree bark, etc., etc.

<object width=”400″ height=”225″><param name=”allowfullscreen” value=”true” /><param name=”allowscriptaccess” value=”always” /><param name=”movie” value=”http://vimeo.com/moogaloop.swf?clip_id=9471538&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1″ /><embed src=”http://vimeo.com/moogaloop.swf?clip_id=9471538&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1″ type=”application/x-shockwave-flash” allowfullscreen=”true” allowscriptaccess=”always” width=”400″ height=”225″></embed></object><p><a href=”http://vimeo.com/9471538″>Python vs. Ruby: A Battle to The Death</a> from <a href=”http://vimeo.com/user1043515″>Gary Bernhardt</a> on <a href=”http://vimeo.com”>Vimeo</a>.</p>

via Extra Cheese.

Copyright © 2010 Autoficiency All rights reserved. Theme by Laptop Geek.