Apr 27 2014

Zurb Magellan Navigation

Love the Zurb Foundation stuff. Love that they freely open-source these cool tools and provide documentation to the community. So, it is hard to complain about “free.” But, in the spirit of community, I think our frustration is often due to being excited about trying out a new, cool, thing, and getting bummed out when running into small roadblocks. (Especially for me, a hacker, who is not really qualified to jump in and discover some crazy cascading javascript or CSS explanation for the odd behavior.)

The disjointed and terse example on the Magellan docs page does leave one asking for more details.

Disjointed example:

  • Arrivals (build, js)

  • Destinations (arrival, destination)
   
  

Arrival

Destination

I had a great deal of trouble to get the nesting correct on my page that also included the topbar element. There seemed to be conflicts with having the topbar being contain-to-grid and fixed.

From what I have gleaned by looking at the page source and doing a lot of trial and error (:boom:), I got something to work “good enough” (as I got tired of the trial and error):

  • In one div, define the arrivals
  • Later in the page, define the matching destinations
  • And fiddle around with divs, nesting, classes, until it works the way you like

An example in haml (sorry for not doing it in HTML, but this is ripped from an app I am writing — modified slightly for this post):

- structure_elements = %w(Access Interior Roof Shutoff Drain FloorPlan SiteDetails)
- structure = @structure

%div{"data-magellan-expedition" => "fixed"}
  %dl.sub-nav
    - structure_elements.each do |element|
      %dd{"data-magellan-arrival" => element}
        = link_to element, "##{element}"
%article#structure
  %h4
    = link_to structure.name, edit_structure_path(structure)
    = link_to fa_icon('pencil'), edit_structure_path(structure)
%hr
= render partial: 'photos/photos', locals: {context: structure, preplan: preplan}
- structure_elements.each do |element|
  %a{name: element}
  %h3{"data-magellan-destination" => element}
    = element
  %div.panel
    ="#{Faker::Lorem.paragraphs(3).join(' ')}"

I hope this helps :heart_eyes_cat:

 


 

Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Mar 11 2014

When Should You Think Doing Software?

Uncle Bob has a nice post titled “When Should You Think?

Here’s my long-winded answer.

Always.

 

Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Feb 15 2014

Kaminari Paging and Zurb Foundation

I am using Kaminari paging gem and Zurb Foundation 5, and here is what I did to make them work together in HAML fashion:

If you generate the theme (it might not matter which one), for example:

rails g kaminari:views bootstrap

You can see all of the “machinery” in the views\kaminari\ folder. Here is my “hack” to get Foundations Pagination working with Kaminari:

I tweaked _paginator.html.haml to reflect the Foundation class on the %ul tag:

= paginator.render do
  %ul.pagination
  ...

And I tweaked _page.html.haml to reflect Foundations current class (instead of Kaminari’s active class):

%li{class: "#{'current' if page.current?}"}

And then it just worked!

Kaminari and Foundation Paging

Kaminari and Foundation Paging


Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Jan 15 2014

A Fool with a Tool

One of my quips that people seem to get a kick out of is:

“A fool with a tool is still a fool”

My point is simple: woodworking tools in the hands of craftsmen can produce fine furniture or musical instruments. But merely the availability of great tools “doth not a masterpiece make.” Not to take the woodworking analogy too far, but power tools can also make it easier for the amateur to get hurt.

The reason a quality piece can be turned out more efficiently with a tool is the ability for the craftsmen to more quickly realize the design and architecture. In addition, tools can help make patterns easier to replicate. From actual patterns (like certain cross-section shapes on molding), to templates (like violin bodies), to connectors (like Kreg pocket hole jigs). A woodworking shop will also make good use of building components to put into larger assemblies.

So, tools in the hands of experts can help realize the design. Tools that are able to help apprentices produce parts designed by the masters, can help produce more output and help train the apprentices.

But put me in a room with the most awesome woodworking tools, and I will not be producing Stradivarius-esque violins any time soon (or ever, most likely).

Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Nov 06 2013

A Java Developer’s Switch to Rails

As I read this account of transitioning from Java EE to Ruby on Rails,”Java Web Apps to Rails, A Developer’s Experience,” I thought the following:

Regarding the lack of a good Ruby/Rails IDE:

When it was time to look at the code, I was a bit disappointed.  TextMate looked like a popular choice but it fell short in many ways.  I struggled to navigate the code, link the methods across files and follow the code. Grep was my only savior.

I am surprised he did not find RubyMine. JetBrains makes awesome IDEs (IntelliJ IDEA for Java, too). I have to admit at being very impressed that the underlying model of the ruby code within the RubyMine IDE is amazingly capable of giving you the same sort of features that it can for a “compiled,” or more type-centric language like Java.

Ruby

Next he mentioned about learning the language…

My approach to learning Ruby was to start looking at code and figuring out pieces of syntax that did not make sense.  That turned out to be a bad idea. Constructs like “do |x| x+1” threw me off. … I found it very important to understand the motivation behind creating the new language.

There are some good books out there, and other resources…

Another comment rang true with me:

I found it very important to understand the motivation behind creating the new language.

More about the motivation behind Ruby… or at least, how I interpret things.

Ruby treats you like an adult. It doesn’t baby you, or hold your hand, or make you type all sorts of (obfuscating, in my opinion) fluff that a compiled language needs. Your code is more compact and obvious and “dense with meaning,” leading to less need for things like method return types and method parameter data types. Or semicolons.

However, I miss parameters list, curly braces, return statements, camel case naming conventions…

Be patient… soon you will grow weary of having to read all that extra stuff when you go back to Java. If you write well-formed classes, and very small, compact, and obvious methods, you don’t need the extra frills. You will run across the concept of “duck typing” which really means that classic C++/Java/C# style interfaces are not needed. If you create a method that expects a passed-in object to respond to a method call (e.g., “torque”), any object of any class will do — as long as it has that method call! And if you pass in an object that does not have that method, Rails will kindly throw an exception.

The concept of ‘open classes’ that allow developers to go in and change a base class sounds scary.

Go back to my opening statement. “Ruby treats you like an adult.” If you are naive, you can blow your code up and break stuff. If you do everything the Ruby way, you’ll be fine — because you will catch it with tests (right?). There are good rules of thumb for how and why and when you should consider adding to an existing class — or worse, monkey-patching. In Ruby you can actually alter the behavior of an existing method of an existing class. Do it poorly, and you will pay the price. And maybe not for a year or two. Mwahahahaha.

Ruby’s metaprogramming is incredibly powerful (even if the syntax takes a bit of getting used to).

Rails

Rails is incredibly opinionated about how the MVC code should look. It is basically a model-driven architecture approach. The framework expects the MVC stack to have a model, a view, and a controller for each domain concept. (As a long-time domain modeler, and UML guy, this is a real treat.) You can use the default rails generators (interesting when first starting, or for banging out a quick prototype), or write your own twist on a generator. Instead of focusing on the boring framework bits with repetitive, template-like code for each domain object, you can focus on quickly creating features that people want to use and pay for :-)

Supporting Cast

Ruby on Rails has a great ecosystem of wonderfully talented folks providing 1000s of gems to do all sorts of useful things. For example:

The ecosystem of supporting tools is incredible. Some of my favorites:

These all make it so easy to “do the right thing” and write code with BDD/TDD to provide quality from the start.

Personally, my switch from J2EE to Rails (not to mention SQL to NoSQL/MongoDB) has been one of pure pleasure. The kinds of rich functionality and the ability to build stuff faster is imprerssive. I only wish I were better at writing kick-ass Ruby, Rails, CSS, Javascript, MongoDB…

Is it perfect? Of course not. There are other cool things to look at as well… Meteor, Node.js, MEAN, etc. So much to explore, so little time.

Back to my continuous learning!

 


Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Oct 30 2013

Measuring Effectiveness: The Software Industry’s Conundrum

On “Measuring Effectiveness”

I’ve been saying for seemingly decades, this is (one of?) our nascent software industry’s biggest conundrums (maybe even an enigma?).

Just how do you prove a team is “doing better?” Or that a new set of processes are “more effective?”

My usual reaction when asked for such proof:

“Ok, show me what you are tracking today for the team’s performance over the past few years, so we have a baseline.”

Crickets…

But seriously, wouldn’t it be awesome if we could measure something? Anything?

For my money:

Delivering useful features on top of a reasonably quality architecture, with good acceptance and unit test coverage, for a good price, is success.

Every real engineering discipline has metrics (I think, anyway, it sounds good — my kids would say I am “Insta-facting™”).

If we were painting office building interiors, or paving a highway, we could certainly develop a new process or a new tool and quantitatively estimate the expected ROI, and then prove the actual ROI after the fact. All day long.

In engineering a new piece of hardware, we could use costing analysis, and MTBF to get an idea on the relative merits of one design over another.

We would even get a weird side benefit — being relatively capable at providing estimates.

In software, I posit this dilemma (it’s a story of two teams/processes):

Garden A:

  • Produces 15 bushels (on average) per month over the growing season
  • Is full of weeds
  • Does not have good soil management
  • Will experience exponential (or maybe not quite that dramatic) production drop off in ensuing years, requiring greater effort to keep the production going. Predictability will wane.
  • Costs $X per month to tend

Garden B:

  • Produces 15 bushels (on average) per month over the growing season
  • Is weed free and looks like a postcard
  • Uses raised bed techniques, compost, and has good soil management
  • Will experience consistent, predictable, production in ensuing years
  • Costs $Y per month to tend

I could make some assertions that $Y is a bit more costly than $X… Or not. Let’s assume more costly is the case for now.

To make it easier to grok, I am holding the output of the gardens constant. This is reflected by the exorbitant rise in cost in the weedy Garden A to keep producing the same bushels per month… (I could have held the team or expense constant, and allowed production to vary. Or, I could have tried to make it even more convoluted and let everything vary. Meh. Deal with this simple analogy!)

 

Year 1 2 3 4 5 6 7 8 9 10
Garden A 100 102 105 110 130 170 250 410 730 1600
Garden B 120 120 120 120 120 120 120 120 120 120

If we look at $X and $Y in years 1 through 10, we might see some numbers that would make us choose B over A.

But if we looked at just the current burn rate (or even through year 4), we might think Garden A is the one we want. (And we can hold our tongue about the weeds.)

But most of the people asking these questions are at year 5-10 of Garden A, looking over at their neighbor’s Garden B and wanting a magic wand. The developers are in the same boat… Wishing they could be working on the cooler, younger, plot of Garden B.

What’s a business person/gold owner to do? After all, they can’t really even see the quality of the garden, they just see output. And cost. Over time. Unless they get their bonus and move on to the next project before anyone finds out the mess in Garden A. Of course, the new person coming into Garden A knows no different (unless they were fools and used to work in Garden B, and got snookered into changing jobs).

Scenario #2

Maybe we abandon Garden A, and start anew in a different plot of land every few years? Then it is cheaper over the long haul.

Year 1 2 3 4 5 6 7 8 9 10
Garden A 100 102 105 100 102 105 100 102 105 100
Garden B 120 120 120 120 120 120 120 120 120 120

I think the reason it is so challenging to get all scientific about TQM, is that what we do is more along the lines of knowledge work and craftwork, compared to assembly line.

The missing piece is to quantify what we produce in software. Just how many features are in a bushel?

I submit: ask the customer what to measure. And maybe the best you can do is periodic surveys that measure satisfaction (sometimes known as revenue).

Matt Snyder (@msnyder) tweeted me a nice video: Metrics, Metrics, Everywhere – Coda Hale


Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Oct 28 2013

Regex to Exclude Multiple Words

For Google Analytics, I wanted to create some chainable filters to deal with a set of subdomains that can occur on alpha, beta, and production, etc. So I needed to find a way to say “Give me all of the production subdomains, and none of the alpha/beta variants, or preprod.”

Here are the sample URLs that I want to filter out the alpha/beta/preprod from:

acme.domain.com
acme.beta123.domain.com
acme.alpha123.domain.com
wyle.alpha.domain.com
wyle.showme.domain.com\cool_stuff.html
acme-two.domain.com
acme-two.preprod.domain.com

Here is the resultant regex:

^\w+-*\w*\.(?!(?:alpha(123)*\.|beta(123)*\.|preprod\.)domain\.com).*$

And here is what Rubular looks like:
Rubular Multi Word Exclude URL Regex

Big shout out to Rubular.com, an awesome place to test out regex!

Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Aug 19 2013

Don’t be the Frog!

Ever hear the muse about the frog and the boiling water?

I use it to describe the behavior where we innocently allow otherwise really odd things to happen to software products over time. “Oh, it’s been like that for 10 years!” It is never a single, discreet moment in time; instead it kind of “sneaks up” on you if you are not paying attention.

For example:

  • Code that is hard to unit test without bringing in all sorts of dependencies (even mocking barely helps)
  • That javascript error that happens in (unsupported) Firefox, but not in (supported) IE or Chrome
    • Instead of being more compatible with all modern browsers via a simpler and more consistent UI framework.
  • Context menus (right-click) that have everything but the kitchen sink in them
    • Instead of more clearly articulating the commonly-used vs the rare menu choices
  • A UI that nearly defies Cucumber/Capybara testing
  • A “Save As” dialog that also offers up to the user the ability to control the next landing page, to deactivate the item, to create a new item under a new parent, and to generate the PDFs for the item All under Save As!
    • Instead of making the UX more clear and solving the real problem: undesirable workflow.
    • We have Save. We have Save As. But wait! There’s more! You can Save As, give a new name, and choose from 3 different pages to go to next!

I often think it stems from a few common shortfalls:

  • The real problem was not solved, but simply masked
  • Complexity begets more complexity
  • The domain is not understood, so incompatible fixes are tacked on in the wrong spots
  • We didn’t have time to do it right, so we just got something that would work shipped
  • The customer(s) wanted it built like this
  • There is no overriding vision for the type of user experience we want to convey
  • There is no hard-ass product owner putting their foot down

Don’t let this discourage you if you are still outside the pot looking in at friends and colleagues who are in the hot water. It’s an opportunity to improve, clean up, straighten things out, and start anew.

Don’t be the frog!

 


 

Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Aug 19 2013

Best way to Learn Authentication?

This was a question posed on the Rails Studio mailing list…

My initial reply to a suggestion to check out Railscasts was…

And then, once you are happy with your learning, throw away all of your Auth code and get the Devise gem loaded and working :-)

To which, the OP replied:

Hmm, I would think your own custom solution would always be smoother than using someone else’s code. Why use Devise?

Here is my reply:

One day, in a galaxy far away, I needed to have millisecond resolution timing on the PC to do some reaction time experiments with subjects as they were exposed to various shapes and colors (eventually used to improve HUD symbology for fighter aircraft display). Since the computer timer chip could only get down to 54ms, I was on the prowl for a better way. Lo and behold, I found some assembly code techniques I could use to over clock the timer chip. Problem solved. I hated writing assembly code… But I had to. Must. Not. Be. Blocked.

Product went into production, and was used by the researchers…

A month or two later, I found an awesome timer package for $50. It did what I needed and more, by a guy who specialized in this.

As fast as I could, I ripped out my code and dropped in the new library. I never looked back. You see, timing was not core to my research app, but rather contextual (like printing or graphing). (As an aside, the module grew and grew and kept up with hardcore CPU vagaries… it was able to tune itself in spite of processor logic becoming much less predictable as it went from 286 to 386 to 486 to 586. I was glad I didn’t have to keep up with the CPU technology! I used this same core functionality on apps that I wrote to control missiles in real-time.)

So, if your business is all about writing an authentication module, then that is what is “core” for your work, and you should craft your own and hone it to perfection.

Or, if you just want to do it as a learning exercise, that is great! Learn, and then pitch your code.

But for me, I am all too happy to drop in some other folks’ gem that gets a set of functionality up and running quickly, so I can get on with my core functionality and not be distracted.

YMMMV

Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Aug 13 2013

uTest Interview

I “ran” into the nice folks at uTest, and they asked me a handful of questions.

I answered… in a shocklingly (for me) succinct way.

Read more on:

Testing the Limits With Jon Kern, Agile Manifesto Co-Author

 


Share this:
Share this page via Email Share this page via Stumble Upon Share this page via Digg this Share this page via Facebook Share this page via Twitter

Older posts «