fbpx

Increase Productivity On Your Mac

Today I learned about a tool to help with workflows on your mac. The Better Touch Tool allows the user to create custom workflows, keyboard shortcuts and snap areas.

The custom keyboard shortcuts can be set to individual apps or to be enabled in certain circumstances. In addition to special keyboard shortcuts, the app also allows you to customize actions based on gestures input through the trackpad.

A feature I have started using is setting up custom snap areas. The basic level of this feature adds in the functionality found default in modern Windows environments. When dragging an app to the edge or top of the screen it will snap to take up half or a corner of your screen. The advanced functionality of this features allows you to set multiple drag zones that will allow you to size a window down to the specific pixel dimensions that work for you, then create a keyboard shortcut or drag zone to replicate these dimensions.

Finally, if you have a favorite mouse whose auxiliary buttons and features do not work natively with your mac, you can map the desired functions with this app.

The Power of 3 [micro team edition]

Today I learned that we need to keep doing something that we have found really works: At Trim, we believe that a lean, cross-functional team of three can build a product. To us, that team of three is made up of one product design lead, one product development lead, and one product strategist. We call this a micro team, and each team member’s role is required.

We have [all] seen how greatly velocity can be impacted when teams invest too much human capital on a project. It is business law that your output does not grow at the same multiplier of “personnel” on a project. At some point, often said to be over 6 people on any team, you begin to see clear diminishing return as more and more team members contribute to one single business unit. On any given sprint, we will augment a team with more resources only if necessary, as we try to keep our efficiency as high as possible.

Our formula is to hire consultants that embody the skill and the empathy to make decisions in their domain and align with the value and core mission of the product owner’s feature set. Our developers need to flag designs that will double the scope versus an alternative solution, our designers need to flag a work-flow that strategy has over-complicated, and we all need to be able to assemble as often as needed to align with those pivots.

Environment Variables in Webpack

Diving into webpack module loader can often seem like a confusing and daunting task. Luckily, setting environment variables is rather straight forward.

At the top of your webpack.config.js file define your environment variables like so:

/**
 * Example Constants
 */
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const API_URL = process.env.API_URL = 'http://localhost:3000';
const METADATA = {
  API_URL: API_URL,
  ENV: ENV
};

Then in the plugins array use DefinePlugin method to define global variables configured at compile time:

/**
 * Make Webpack Constants Available Globally
 */
   new webpack.DefinePlugin({
     'ENV': JSON.stringify(METADATA.ENV),
     'API_URL': JSON.stringify(METADATA.API_URL),
     'process.env': {
       'ENV': JSON.stringify(METADATA.ENV),
       'NODE_ENV': JSON.stringify(METADATA.ENV),
       'API_URL' : JSON.stringify(METADATA.API_URL),
     }
   }),

Re-compile and now your variables will be globally available.

Module Decorators

Why decorate objects instead of using inheritance?

It’s a more dynamic, flexible and transparent alternative to subclassing. There’s several different ways of using the decorator pattern in Ruby, but I’m just going to show the module/extend approach. You can read about other decorator techniques in Dan Croak’s blog post.

Use a module and extend to add instance methods on an object. This will still maintain the ability to use super as demonstrated in this trivial example:

class Report
  def number_of_pages
    10
  end
end

module CustomerAdmendment
  def number_of_pages
    super + 5
  end
end

module AdminAdmendment
  def number_of_pages
    super + 1
  end
end

report = Report.new
report.number_of_pages # => 10
report.extend(CustomerAdmendment).number_of_pages # => 15
report.extend(AdminAdmendment).number_of_pages  # => 16

With the module/extend technique we can maintain the original interface and delegate through all the decorators.

Today I learned how to connect Slack with Email

Today I learned about a few new workflow ideas to improve communication with clients. Being the technologists that we are, the value of modern communication tools like Slack is very clear. Many clients or business partners, however, may not be interested in learning a brand new tool or workflow.

Slack is a powerful asynchronous communication tool that allows teams to communicate efficiently without interrupting each other’s focus. It is like text messaging when communicating directly with another team member. It can also be used like a group text or chatroom when communicating with a relevant team or micro-team.

Email is still king in the sense that it is so ubiquitous. Almost everyone is comfortable with email these days. The problem with email is that it is easy for messages to get lost in the noise. Communication with a group of people or carrying on a long thread of messages can get messy.

If 3-5 team members are CC’d in an email to a client, and they respond with Reply, instead of Reply-All the rest of the team is left out of the conversation.

If a team member sends a question to the client and forgets to CC everyone, communication also breaks down.

I found a few potential solutions to this communication conundrum. So that client emails are made visible to the team, Slack provides for the creation of a “Channel Email Address”. This can be shared with the client as THE email to use with the team.

What if the client still emails an individual instead of the Channel Email Address? No problem, just setup a Gmail filter to auto forward messages from a particular person to your special email address.

Awesome, so we have the ability to capture incoming emails in slack. What about sending messages to said person’s email?

I found a solution for that too.

There is a service by the name of mailclark.ai that allows you to setup a Slack email channel that will forward messages communicated in slack to the desired email address(s).

CSS & SVG Based Tooltips

While working on a quick cleanup sprint I ran into an issue with a tooltip-box. The original design was using a raster-based image as a CSS background and it wasn’t meeting our needs. Googling revealed the problem had been solved but still didn’t give me a shadow on the arrow tip. Below is the quick and dirty structure of a CSS & SVG based tooltip box.

See the Pen CSS-Only Tooltip w/ Shadow by Ryan Stone (@ryanstone) on CodePen.

Simple Sprint Retrospective

At the end of every sprint, it is a good idea for the team to conduct a retrospective.

The sprint retrospective gives the team the opportunity to reflect on the process of the past week. The simple and effective retrospective processes used by one of the leaders in Agile education is a great place to start and even stay when it comes to reflecting and improving your process.

The Start / Stop / Continue Retrospective. 

There are many ways to gather creative ideas using this method, the simplest is letting the team shout out ideas.

The continue items are often ideas that the team is reminded to keep working on and can be included in a display of the previous weeks retrospective results.

The stop items are processes or events that lead to blockers or other inefficiencies.

The start items are new ideas that the team can do to improve the processes.

After the ideas are collected and compiled, it is time to vote.

By focusing on a single item (or a short few), it allows the team to find an area of focus that the team as a whole agrees is an important idea. By focusing on a single, or short list of items the team can choose a focused direction as a theme for the following week.

 

Git and GitHub Tutorials

Basic courses on git

  • Try Git allows the beginner to try out commands using the dreaded command line without fear. This interactive web app walks you through the basics of using Git.
  • The Introduction Series in the GitHub & Git Foundations is a collection of several videos covering a wide range of beginner to intermediate Git tasks.

More advanced course created by Upcase

When you have mastered the basics of Git and GitHub, Upcase provides advanced tutorials and workflows to bring your skills to the next level.

Immutable Objects using Object.assign

Is immutability important? Mutating data can produce code that’s hard to read and error prone. But we can avoid this mess using vanilla javascript’s ES6 feature Object.assign!

Let’s look at the problem….

var obj1 = { key: 'some value' };

var obj2 = obj1;
obj2.key = 'another value';

console.log( obj1 === obj2) // true
console.log( obj1.key ) // 'another value'

When we changed obj2’s key property, it also changed obj1’s key property. No bueno! The solution:

var obj1 = { key: 'some value' };

var obj2 = Object.assign( {}, obj1, { key: 'another value' });

console.log( obj1 === obj2) // false
console.log( obj1.key ) // 'some value'
console.log( obj2.key ) // 'another value'

As you can see we changed obj2’s key property and it left obj1’s state intact! Now that’s immutable! Object.assign takes objects as its parameters and passing in an empty object as the ‘target’ keeps our ‘source’ objects intact.

Object.assign is widely supported by desktop and mobile browsers, please check Mozilla for more info.

CSS Image Masking

Today I learned a very efficient way to create triangular cutouts using solid colored and transparent css borders.

The angle of the triangle cutouts can be changed by adjusting the widths of the borders and the height of the mask div.

For best view of Results, click “Edit On CodePen”

See the Pen CSS Triangle Image Mask by Miguel Lozano (@MiguelDotL) on CodePen.

Ruby’s Safe Navigation Operator

nil‘s in Ruby can be annoying. Thankfully, Ruby version 2.3.0 gave us a safe navigation operator, something that other languages like C# and Swift already had. It’s very much like ActiveSupport’s try method, which checks if a receiver responds to a method before calling that method. If the receive doesn’t respond to the method, nil is returned.

Usage

Here is a trivial example to demonstrate how this works. Let’s say you need to call upcase an object attribute that may or may not be defined. At some point, this might happen:

person = Struct.new(:first_name)
bob = person.new
=> #<struct first_name=nil>

bob.first_name.upcase
# => undefined method `upcase' for nil:NilClass

Before Ruby 2.3.0, we might have solved this problem with something like:

bob.first_name.upcase if bob.first_name
=> nil

Using the Safe Navigation Operator (&.) we can do this:

bob.first_name&.upcase
=> nil

In this example, calling first_name on the bob instance returns nil, so &. halts the method chain right there.

Apprenticeship: Week 1 Complete

The longest week. The shortest week.

Any time one is exposed to a brand new experience, time often feels broken. The week flew by to seem that we just started this morning, yet it feels as though we have been here for weeks. I have been overwhelmed with excitement and energy with the new opportunity yet left exhausted and dizzy from learning the new processes and procedures.

I know nothing. I know something.

The most frustrating part of being new is the feeling that you are slowing down the team. Of course, I know there is a learning curve with everything, but the internal pressure to contribute can feel overwhelming. The key, I believe, is patience. When starting your first week, keep the following in mind. Know that such feelings are normal among others in your position. Learn something every day and you will be surprised with your progress. Before you know it you will be contributing.

Team Trim.

The support and guidance I have received from the team have been second to none.

I am extremely impressed with the knowledge and progress of the mentoring developers. Developers who started as apprentices just one year ago demonstrate the knowledge and experience of seasoned engineers.

I am very thankful for the opportunity to be a Trim Apprentice and look forward to seeing where 2017 takes us.

What is Demo Day? What is a blocker?

Today I learned that we need to establish some critical structure, largely that we hope is going to come with the addition of a dedicated scrum master at Team Trim. As we all grow to becoming ‘agilelists,’ we have identified the need to define two critical functions of our sprint activity:

1. We need a Demo Day structure so that each of our team members and micro teams are covering the same material, tooling, nomenclature, and process with our product owners.

2. We need to continually define and celebrate “the blocker.” The blocker is not a bad word, and we aim to grown comfortable with identifying problems that other team members can solve. We fully understand that sometimes, there is someone on the team that is blocking another team member, but this is what we hope to grow comfortable in talking through.