Agile and Hill Climbing
Hill Climbing is a mathematical process to find the top of a curve, or “hill”. The basic algorithm is as follows:
Hill Climbing is a mathematical process to find the top of a curve, or “hill”. The basic algorithm is as follows:
I recently met with a junior developer who was seeking web development career advice. When we met, she had clearly done her research on me, knowing my educational background and my general career path. It had been years since I Googled myself, and I became curious what info arises for my name. I’ve successfully avoided social media for the most part, but I have been working on and writing for my personal site, AlexBrinkman.com, since 2006, and EnlightenedPixel (this site) since 2010. I assumed could be found if using my full name. I was wrong, and it pissed me off.
When learning a new programming language, I like the idea of having a familiar program or algorithm to reimplement in the new language. My personal favorite is a little game that I prosaically call 543. I have no idea if there is an actual name for this game as it was taught to me in a bar. 543 is a two-player deterministic board game with very simple rules. It is perfect for the minimax algorithm - there’s enough complexity in minimax to use a fair amount of a language, but it can be written in a few hours if so motivated.
Abraham Maslow’s Hierarchy of needs is a valuable mental model describing the progression of needs, which he classically applied to psychology. The idea behind Maslow’s Hierarchy is that one can only work on obtaining a higher level of need when the needs of a given level (and the levels below) are fully met.
I wrote a little code to analyze technologies in demand with new startups. I used the AngelList job board as my source and was able to pull about 1100 startup job postings. AngelList shut down their API a while back. I created the data files from a simple jQuery selector, once I had manually loaded all of the posts they would allow. Note that this behavior caused my AngelList account to be flagged for scraping and disabled, and they won’t re-enable it.
bundle outdated
. It’s wise to update gems one at a time, running the test suite
in between. I also find it worthwhile to check the gem’s release notes for what is
new, or fixed in the latest version.select
for a model association, which I got to work, but required some manual wire up in the
controller. I finally switched to a collection_select
, even though the user was only
able to select one option, and it really cleaned up my code. I need to spend some
time going over all of the different form_helpers and appropriate use for each.belongs_to
association is required by default in Rails 5. If I have a User/Profile relationship, I cannot create a Profile that doesn’t belong to a User (by default). I can make the association not required by declaring belongs_to :user, required: false
. I have mixed feelings about this. Having the parent record be required for a child makes logical sense, and is almost always the behavior I want, but it makes testing harder. For example, if I want to test some model methods on my Profile model, I have to create an associated User model too, which makes the test build-up harder to configure, and slows down my test suite. I’m going to dig more into this to find the right balance.ApplicationRecord
instead of ActiveRecord::Base
. This seems to simply add a thin layer in which functionality can be mixed-in for only the parent application and kept out of related engines, etc.spec_helper.rb
file which is itself required by rails_helper.rb
. I simply moved the SimpleCov statements to the top of rails_helper.rb
and the stats appear much more accurately.bundle clean --force
visibility: hidden;
. I first tried display: none;
, but the browser still interpreted that as the open quote not being closed.Much of the buzz around AI centers around the AI’s ability to be creative. The recent AlphaGo victory over grandmaster Lee Sedol was not only a triumph of Computer Science in a realm previously thought impossible, but more importantly, and impressively, it showed creative problem solving capabilities by an otherwise extremely analytical AI. The now famous 19th move of Game Two was shocking to Go grandmasters, including Lee Sedol himself. Those in the know describe the move as “creative” and “unexpected”.
2016 was a fantastic year! I made my goal of writing 25 blog posts, which I’m quite proud of as I had fallen short several years running.
This is Part 1 of my Soft Skills of Development series.
# From project-a
git remote add project-b git@github.com:project-b.git
git fetch project-b
git cherry-pick <SHA-from-project-b>
# Merge conflicts and done!
A great way to improve as a developer is to spend time with quality code. See how other developers solve issues. Dig into code you don’t understand, figure out how it works. Find elegant solutions to problems you’ve solved before.
Count me as a developer that knew there was a difference between control-c and control-z, but couldn’t tell you the details of the difference. If I have a non-responsive process, I generally try control-c first. But if that doesn’t work, I resort to using control-z, followed by the kill command to end the process by id.
Is it not the height of conceit to think that your app is changing the world?
I’ve been spending time lately developing better processes for how to think about my job, how to think about the products I’m building, and how to prime myself to come up with better ideas. The topic of how to “ideate” has been written about ad nauseam, and I’ve read and listened to much of the advice. There’s a lot of good information, and some bad information out there. I think much of the advice is personal, what works for one person may not work for another. Having tried many different methods with varying results, one thing is clear to me - giving my mind space to process and make new connections that lead to new ideas is extremely important.
One of the most important questions to ask yourself as a web developer is if you enjoy working on a single product, or across multiple products. There is no right answer to this question. However, there is a right answer for you.
It’s our best iPhone ever! No kidding. Was there ever a question? Is there a chance that the newest model of anything will be worse than the previous version? As consumers, we assume that it will be better, we’re expecting it, now just tell us how.
I often hear the terms computer scientist and developer or programmer used interchangeably. They’re actually quite different. I think developer and programmer are synonymous, but both are very different from a computer scientist.
The biggest objection I hear from developers that aren’t on the TDD bandwagon is that writing tests takes too much time.
Here’s a little testing trick I use while working in Rails. When I’m trying to find areas of code that are missing test coverage, I like to individually run the different types of tests, then check the coverage for that type. So instead of simply running rspec
, I’ll first run each of the following:
My wife asked me a question that got me thinking about my skills as a developer. She said, “My co-worker’s son is really good at programming as a 15 year old, does that worry you?” She’s implying that there’s a good chance that he will be better than I am at my craft because he started so early, perhaps pushing me out of the market like a young hot shot athlete causing the older veteran to retire. My answer is unequivocally, “No, it doesn’t worry me.”
There’s a trend in the programming world that bothers me. A technology or product will get popular because it solves a problem well. Then, as something new and more exciting comes out, we relentlessly mock the old technology as if it never belonged in the world. This trend plagues Java.
/search?q=term
and the use then chooses to switch locales - /?locale=es
. Ideally the search term would be preserved and the final result would be something like /search?q=term&locale=es
. This can easily be done with the url_for
method and merging the existing params: url_for(request.parameters.merge(locale: "es"))
ActionDispatch::ExceptionWrapper.rescue_responses
method. If you run this method in your console, you’ll see the mapping:{ "ActionController::RoutingError" => :not_found,
"AbstractController::ActionNotFound" => :not_found,
"ActionController::MethodNotAllowed" => :method_not_allowed,
"ActionController::UnknownHttpMethod" => :method_not_allowed,
"ActionController::NotImplemented" => :not_implemented,
"ActionController::UnknownFormat" => :not_acceptable,
"ActionController::InvalidAuthenticityToken" => :unprocessable_entity,
"ActionController::InvalidCrossOriginRequest" => :unprocessable_entity,
"ActionDispatch::ParamsParser::ParseError" => :bad_request,
"ActionController::BadRequest" => :bad_request,
"ActionController::ParameterMissing" => :bad_request,
"ActiveRecord::RecordNotFound" => :not_found,
"ActiveRecord::StaleObjectError" => :conflict,
"ActiveRecord::RecordInvalid" => :unprocessable_entity,
"ActiveRecord::RecordNotSaved" => :unprocessable_entity }
I’ve been working a bit with Rails Internationalization (I18n) this week, here’s what I learned:
date_field
helper falls back to just a textbox on Firefox and Safari (and IE?).git fetch -p
(prune). I find pruning helps prevent non-obvious branch name conflicts if you happen to reuse a name that once existed on the remote. Plus, I find just find it satisfying.main_app.whatever_path
. Likewise, if you want to link to a route within the engine, the syntax is engine_name.whatever_path
.Time.zone
everywhere. Note that Rubocop also recommends the Time.zone
methods, providing a nice way to catch missed instances.whereami
command in pry prints out the code view. This is very helpful if you’ve recently outputed a screen’s worth of data hiding what the next command would be. I use this almost daily. RailsEngineIDontOwn::SomeController.include MyCode::OverrideMethods
<%= sanitize html.body, attributes: %w(href target) %>
git checkout feature_branch
git checkout - # Back on master branch
git checkout - # Back on feature_branch
The SOLID principles of object-oriented programming define a set of guidelines that help produce well-written, maintainable software.
The last several years I have set goals, some of which I met, and some of which I did not. I like the practice of setting goals for the year ahead - it seems healthy. Though my goals are not at the front of my mind on a day-to-day basis, I like to think that they work on a subconscious level.
2015 was a wild ride. I took a new job as a Rails Developer with Commerce Kitchen, and became a father for the first time. Looking back on the goals I set for 2015, while they may have been appropriate at the time, they became out-of-date the moment I took the new job, and unattainable the day my little man was born. Hitting yearly goals has been hard in years past too, but my excuses are more pronounced this year. Part of 2016 will be to evaluate what yearly goals mean to me, and how to set more realistic and beneficial goals. Regardless, here are the goals I set for 2015:
I like coding style guides. Having a consistent style removes that little bit of friction that writing code in multiple styles creates. This article is a quick tutorial on how to get Rubocop - a static code analyzer for Ruby - up and running.
Today was my final day at Colorado PERA, my employer for the past 5 years. I’ve decided to take a position with Commerce Kitchen as a Rails developer, which I am very excited about. However, leaving is hard.
As someone who loves Ember but doesn’t get to use it on a daily basis, I find myself relearning concepts frequently. Here is my list of helpful hints when diving back into the framework, or when taking the next steps after learning the basic concepts.
I like fast sites. I also like to keep track of how changes to my code affect the page load time.
For Jekyll sites, here’s how I approach including the Google Analytics script in production, but not development.
2014 was the first year where I religiously tracked where I spent my freelance time, which includes nights and weekends work, outside of my full-time job.
Once again, the new year is upon us and it’s time to layout my professional goals for the year ahead. As I like to say, this is my time to prune the old and irrelevant, expand on what is solid and good, and gain exposure to the new and exciting. Here are my goals for 2015.
This post is a reflection on my 2014 goals, where I succeeded, and where I came up short. I worked harder in 2014 than in any other year in my life, and I accomplished some of the goals I set back on New Year’s Eve 2013. Here are the goals I set for 2014:
I believe that writing is an essential skill. Like writing code, pure writing is a skill to be worked on continuously. Clear writing indicates clear thinking.
As a web developer, most of my work is not only completely digital, but it’s ephemeral - lasting only a few years, if I’m lucky. At times this wears on me, as if my entire career is building something that will be simply overwritten in the next version.
While a static site is a perfect fit for the combination of my skill set, and the requirements of enlightenedpixel.com, it certainly isn’t a fit for every site, nor every site owner. Here’s why it is a fit for me, and why it may or may not be a fit for you.
I recently converted this site, enlightenedpixel.com, from WordPress to a Jekyll static site, and I’m very, very happy with the result.
Stripe is a payment processing API built for developers. Their API is a wonderful example of a clean and understandable API, with very good documentation.
One of my goals for this year was to give a talk at a meetup. At the time I set my goals, I was attending several different groups, including the local Ruby on Rails, EmberJS, and HTML groups, but always as a spectator, never as a contributer. I wanted to change that.
I recently had the opportunity to sit at the other end of the table and interview six different web design and development firms. As the owner of a little web development shop, I'm usually the one being interviewed for a web development job, trying to convince the potential client that I'm the right person for their needs. To be the client for once was a flip in mindset, and was a very educational process. What I learned probably sounds like common sense, but of the six firms that we interviewed, only one nailed every point. Here are my take aways, a list that I'll adhere to as Enlightened Pixel continues to grow:
This post is a complete and honest look at who I am as a developer, something I find hard to express in a cover letter or resume. I have strengths and I have weaknesses, and I'm happy to tell you about them both.
This post is my complete work history, from my first page as a student, through my professional jobs, freelance jobs, and personal projects.
Technology moves fast. Each year I try to take some time to evaluate my own skill set and prune skills that are no longer relevant to make way for the new and more promising. I write this article through the lens of a freelance, full-stack developer, which means that I need to know, and be proficient in, many different technologies, and be able to choose the best one for the situation. Certainly, there are many different types of web developers, and many different levels of specialization amongst those developers. This list applies to my specific situation. However, my situation is fairly common and I believe it applies to many others as well.
I've spent a significant amount of time evaluating the different JavaScript frameworks over the past several months. Like many others, I weighed the pros and cons of both Angular and Ember, finally settling on EmberJS. Making a choice between frameworks is a decision with deep and long-lasting implications, so it's not one that I take lightly. Attached to the decision are hours of time learning new skills, not just for me but for every developer on my team. Choosing a framework is choosing a side - you get all the good and all of the bad.
New Year's Eve is a natural and fantastic time to reflect on the past year's goals, and to derive goals for the year to come. This is increasingly important as technology continues to change at an ever increasing pace. Learn to prune the old and irrelevant, expand on the solid and good, and gain exposure to the new and exciting. Here are my goals for 2014.
For the past several months, I've been working on a Rails application called MyTennisStats that offers data visualization and analysis of tennis matches captured from a mobile device. We have many different types of graphs and charts, and I've made heavy use of Morris.js, which has been fantastic.
For the past several months, I've been working on a Rails contract for a membership site that provides analysis of tennis matches captured from a iPhone app. The heart of the site is a dashboard of stats and charts of one or more tennis matches, and is heavy on the JavaScript side of things.
I love Test Driven Development. I love how it naturally improves my code by forcing me to write testable functions, and clear interfaces. I love how tremendously satisfying it is when a new feature request comes in for a section of code that has solid test coverage, knowing that as long as I can produce and satisfy a test that mimics the new feature, without breaking other tests, I have reasonable assurance I'm not breaking something else. The same thing goes for bug reports.
Chad Pytel is the CEO of thoughtbot, and was recently interviewed on Founders Talk with Adam Stacoviak.
Today I came across a large reference book from 1994 titled, The Internet Complete Reference. The book was an attempt to enumerate every available resource on the web: Usenet groups, Gopher sites, email addresses, and FTP sites (with username and password). Surprisingly few listings had a URL. This book was Google before Google, in printed form, Yellow Pages style.
Today was not my best day. For several weeks I've been working on some significant changes to a large and heavily used member site for the company that I work for. I added a new responsive layout, a cleaner and sharper UI, integrated a new web service, rethought the main landing page with more useful information, and made it much easier for the user to update some key information.
As a web developer, I spend an incredible amount of time keeping up with the industry. I watch talks online, go to conferences, attend meetups, listen to podcasts, read books and articles. It's a daily devotion to (attempt to) stay current in this field. Rarely do I feel as challenged as I did from watching Paul Irish's "The Mobile Web is in Trouble" given at Breaking Development, April 2013.
I use my bank’s ATMs for a few things - I pull out cash, and I deposit checks. When I get cash, it’s always the same amount. When I deposit a check, I always choose to deposit in my checking account, and email me a receipt. It used to be that when going to the ATM, I pick from the options my same choices over and over, which was fine, I never thought otherwise, until.. One day the ATM remembered my choices from the previous time, and thought to ask, “Hey Alex, do you just want to deposit this check in your checking account and send a receipt to this particular email address?” It was a pleasant little surprise, to which I answered, “Why yes, that is what I’d like to do, thank you.”
I graduated college in 2003 and my first job out of school was a combination of development and IT. Of the development I did, only a portion could have been considered web development. My second job was also a mix. Finally, my third job has been 100% web development, which is where I'd like to stay for many years. I consider myself having about 5 years of solid web development experience, though I've been building sites since 2000.
This video is a great example of a simple idea done well, love it.
Responsive sites adjust fluidly to different screen and viewport sizes - from the phone, to the tablet, to your 27 inch iMac. It's both an art and a science. There are hundreds of examples of well-done responsive sites on the internet, but these are currently my favorite five.
It takes some serious creativity to capture snowboarding in a new way. Jacob Sutton nails it.
It’s often said that the fastest input device is still the keyboard. I thought I’d share a use-case where the iPad is actually a faster input device than the keyboard.
I love listening to podcasts. They are a tremendous tool in the ever present battle to keep up with the craft of programming. Podcasts help me keep up with industry news, learn about new patterns and technologies, and hear about what others are creating on the web.
Tonight I pushed out my first app. Normally I would disqualify and cheapen the accomplishment by saying that it's no Angry Birds, or that the UI could be better, or that it could still use some tweaking, etc, etc, blah, blah. But not this time, in fact, I'm damn proud of the little game. Even if it gets installed by 3 users, all of which are relatives, it would still be a success.
Recently I've had the opportunity to implement ecommerce solutions for two small companies in the Denver area. Both companies had an existing ecommerce platform with limitations in functionality, performance, and reliability, and it was time to move onto a more professional platform. The clients that I work with generally don't have an IT department to handle server maintenance, so I was solely interested in hosted solutions with live support.
I was listening to an interview with Aaron Walter from Mailchimp and he said something that really struck a chord with me. He drew an analogy between gardening and the creative process.
My trademark strength has always been the ability to play in both the technical world, and the business development world.
“What is an enlightened pixel, is that some kind of web thing?” says the teller at my local business bank. I didn’t have a clever reply, so I simply said, “yes.”
One of the main projects that I have been working on is the conversion of Adobe Flex/Flash applications into a standards based approach with HTML/CSS/Javascript/Ajax. I’ve been using jQuery heavily along with jQuery UI.