Learning Photography the Slow Way

I wrote about Instagram 5 years ago. I liked how it encouraged bite-sized daily creativity. I’ve continued to slowly learn about photography in bits and pieces. What started with an app 5 years ago lead to me buying a nicer camera (Sony RX100) and now a full-fledge amateur photographer camera (Nikon D3200 with 300mm lens – used on ebay). Yesterday, I walked around the park adjusting shutter speed and aperture while manually focusing – OMG photo poser! At least I’m not developing prints, yet.

I still love Instagram. Many people don’t like it. Obsessing over “Likes” rubs some the wrong way. I’ll admit likes are pretty meaningless – easy to give. But in terms of a feedback loop, they’re priceless. Similarly, some would say that with the apps and filters available these days it is all-to-easy to make something out of nothing – to be an artist with no “skill.” This is an issue with photography generally – it’s easy to get started. How much credit should the photographer get if they happen on a beautiful scene? How can we make feedback as easily available for playing piano or guitar?

I still use Instagram as a test bed for a tiny slice of daily creativity. Other people use Instagram to document their life. They share day-today experiences framed for their personal significance (“I had sushi for lunch,” or “arrived in Hawaii”) – not micro-works of art – except in the context of someone’s life.

It seems like almost everyone goes through a photography phase in their life. That’s not a bad thing. Every slice of creating instead of consuming should be praised. We should be reward for cultivating our creativity. The next goal for me is to work on telling stories, creating interesting compositions, not just recognizing them or capturing them by luck.

Here are some updates to the favorite photo apps I’ve written about previously. What are your favorite cameras and apps? Please leave a comment below.

  • Instagram – still a winner. Hashtags are the secret to exposing your photos to a wider audience. I love that I have a different followers there than on Facebook. I still only post my best photos (one or two a week). It’s not just for phone photos, I publish photos taken with my other cameras too.

    #kiteboarding #summer #washington #juandefuca #dungenessspit #sequim

    A photo posted by Adam Loving (@adamloving) on

  • Aurora HDR – easy to use. Now HDR is built in to the iPhone’s camera, but Aurora is great to use on your computer. The RX100 does automatic exposure bracketing, so you can combine the best of two images into one.screen-shot-2016-09-18-at-6-48-02-pm
  • TiltShift: it was a fad (now built into Instagram). However, I recently discovered linear gradient filters in Adobe Lightroom. It gives you great control over tweaking your photos. It seems to be what most serious amateurs are using these days. Please leave a comment and let me know what you’re using.
  • Same for re-touching (Lightroom on the desktop).
  • 360 degree photos haven’t quite caught on yet, but I be they will as VR takes hold. I just use the panorama function on my phone and camera
  • For selfies, the Facetune and Microsoft Selfie apps are the current champions.
  • Prisma has won the simulated drawing and painting wars – for now.

    Man and dog computer Kandysky #mlvch

    A photo posted by Adam Loving (@adamloving) on

Another Ruby on Rails cheat sheet

This blog post is an experiment. I’ve shared some phrases I searched for below, with the abbreviated solution I was searching for. I’m hoping that this blog post will replace the other results.

rails test error stack trace

  • fixtures implicit conversion of Fixnum into String
  • rails TypeError: no implicit conversion of Fixnum into String

Solution: Fixture names should not be numeric

rails rake test stack trace

Rails.backtrace_cleaner.remove_silencers!

rails update_attributes

 my_model.update({ field1: ‘a’, field2: ‘b’})

html anchor disabled

  • javascript a click cancel
<a onclick=“e.preventDefault()”>

javascript array compact

 [1,2,3].filter(function(n) { return n > 2 })

undefined method column for Foreigner

foreigner is deprecated

rails parse integer with comma

 string.gsub(/\D/, ‘’).to_i …

That is, remove everything that isn’t a digit.

 s.gsub(/[^\d\.]/, '').to_f.round.to_i

find local path of gem

 gem environment

require actionview helpers

  • require view helpers
include ActionView::Helpers::NumberHelper

active record where less than

Post.where(“date < ?”, DateTime.now)

Ruby on Rails Cheat Sheet

Here are some of my actual Google searches from the last few days with the code fragments I was looking for.

rails format number with commas

number_to_currency(1234567890.506, precision: 3)

rails date from datetime

DateTime.new.to_date

ruby is numeric

12.is_a? Numeric

ruby 1 month from now

1.month.from_now

ruby hash delete key

{a: 1}.delete(:a)

ruby hash key order

Keys are preserved in the order inserted.

savon gyoku unwrap

Savon.client(unwrap: true)

rails before_action admin

before_filter do 
  redirect_to root unless current_user.admin?
end

rails controller require admin

before_filter do 
  redirect_to root unless current_user.admin?
end

rails routes require admin

Routes are created before the request is handled, so you can’t dynamically create routes based on the user.

rails route require user

authenticate :user do
   get 'dashboard' => 'dashboard#show'
   ...

rails devise admin role

class AddAdminToUsers < ActiveRecord::Migration
 def change
   add_column :users, :admin, :boolean, default: false
 end
end
if current_user.admin?
  # do something
end

nokogiri pretty print

Nokogiri::XML('<myxml/>', &:noblanks)

rails pretty print xml

Nokogiri::XML('<myxml/>', &:noblanks)

ruby strftime

Time.now.strftime('%a, %b %-d %H:%M:%S')

rails migration rename table

rename_table :bank_settings, :bank_accounts

React Native Notes

I just finished a one month React Native iOS project. The app was accepted into the app store yesterday – hooray! The app integrates Ustream live video with Firebase realtime chat and Braintree payments.

I chose React Native for a couple reasons.

1) The flex based layout system is a huge simplification (productivity and complexity) win over the native iOS contraint-based approach.

2) The simplicity of re-using our real-time javascript client code was really appealing.

Lastly, while prototyping I found it straightforward to make Javascript code interoperate with Swift and ObjectiveC. That gave me the confidence to proceed.

One of the first realizations I had was that I couldn’t actually re-use much of the code without changing it. There was copy and paste re-use, but our website didn’t have enough separation between component, model, and store. You obviously can’t re-use React component code designed for the web on the phone, but you can re-use the pattern, which counts for a lot.

The app got complex when I implemented deep linking from the web. The complexity came about when the UI state started to differ from the application (data) state. At that point, I had to implement “store” or “dispatcher” patterns. Data store classes load and cache data, and signal changes to the UI components via events (as opposed to the UI loading the data it needed when users tap).

Packaging app dependencies with React Native is awkward. There are several ways to do it, and package contributers have yet to standardized on a single method. Depending on the package, you may need to use npm, rnpm, cocoa pods, or manually drag code into the project. Experience with Objective-C and Swift projects (and C/C++ for that matter) was very useful here. If you were coming at this as a Javascript web developer, adding header and linker search paths would be confusing. Even adding fonts is a tricky three step process with xcode.

Some other notes: The react-native-device-info project needs to be updated so that it doesn’t depend on the React Native cocoa pod. I added this library to get at my app version number, and to access a unique ID for the device. Device info should be supported by React Native itself. As it stands, it device info project compatible with the latest version of React Native (due to the cocoa pod issue).

I didn’t quite make the leap (or implement it myself), but a library that supports percentage-based styles will be useful. In practice, hard coded view sizes were sufficient to work on all the devices we wanted to support. react-native-extended-stylesheet is one package that I considered adding but didn’t.

Also, I may look at trying either https://apphub.io or https://buddybuild.com for web-based app updates in the future.

The biggest snags I ran into were a babel conflict (conflicting .babelrc files) and verifying Google Analytics events (they were there, just very difficult to find until I created a separate property).

I’d like to spend another day building for Android. I’d like to learn Android deployment in order to be able to estimate the cost of Android projects.

Here are the packages I actually used for the project.

  •     babel-preset-react-native (for ES6)
  •     firebase (significantly, this is the Firebase Javascript SDK, not the iOS SDK)
  •     moment (date conversion)
  •     react-native-communications (for sending an email)
  •     react-native-facebook-login
  •     react-native-google-analytics
  •     react-native-linear-gradient (pretty backgrounds)
  •     react-native-orientation (for phone orientation changes)
  •     react-native-vector-icons (gives you access to 8 icon libraries)

Seattle Node and Swift Freelance Developer

summer

I worked on several cool projects this summer, but also had some challenging tests of my skills as a freelancer.

The challenges of being a freelancer

Just a few of them…

  • Scrambling to find new clients when a long-term project ends unexpectedly.
  • Wanting to say yes to a position referred by a friend for fear that offers will stop coming if you say no.
  • Taking a short job to bridge to a longer-term job, then having the longer-term job come through too quickly.
  • Balancing expectations on availability with clients
    • “I’ll be available next month”  doesn’t mean “I’ll start next at the beginning of next month”
    • “I’m available for four weeks”  doesn’t mean “until the end of next month”

As a freelancer, it’s hard to be strict about exactly what work you want to do and can-do. A good goal is to charge enough so that you can say no to all but the best-fit clients.

There’s a fine line between no projects (or too little work) and too much work. In one case I was trying to work while sick to keep the client happy (not that they asked). I didn’t get better, and I barely ended the project on a positive note. It would’ve been much better to just take the time off up front that I needed to not get sick.

Haiku Deck

I worked at Haiku Deck on an awesome product with a fun team for 2 years. Even though I knew funds were tight, it came as a little bit of a surprise to learn that the budget for my time was used up. The ensuing restructuring made for a chaotic week. As a freelancer (unlike salaried employees), I actually like this dynamic change. It’s a challenge to find fresh problems to sole.

The main issue for me, was that I hadn’t been doing a lot of networking. I had gotten lazy about participating in community events. So when my job dried up, I didn’t have another one to jump to. Or, even a clear definition of what I wanted to the next. I did have a lot of side projects I to work on. So I started work on those and tried to get a quick job through Upwork (previously oDesk) to pay the bills.

Scality via Upwork

I’ve always been enticed by the prospect of finding small projects online that are paid hourly. I love the idea of working remote and on my own time. Someday, I’d like to do this while traveling. I had used oDesk as a client before – hiring writers and developers. But I never signed on as developer to get paid for a project.

I applied to about 10 projects. The application process was time-consuming. I tried to write enough and ask enough questions to distinguish myself from the other applicants. I had to explain why I charge 5 times as much as the other developers. I found a good project that was very clearly specified, the unit tests were even provided.

I landed the project and started work – albeit at 2/3rds my normal rate. Unfortunately, the unit tests did not cover a very important and complicated part of the new functionality. So there were a couple very late nights getting things done in a timely fashion for the client. The project was using node to transfer giant files. I wrote up some of my learnings about subclassing node streams.

I expected starting out with Upwork that I would have to discount my rate. What I didn’t account for was that every minute is logged. I don’t mind the invasion of privacy, my assumption is that as I gain trust with my clients – they will pay less attention to my hours. However, I didn’t account for the loss of “soft” billable time. I couldn’t charge for meetings. Every time I went to the bathroom,  took lunch, or researched something, I felt like I needed to clock out. This meant that 40 billable hours required about 50 hours of time. It was intense. Especially when trying to impress the client by meeting the deadline.

Of course, once I did a good job, client offered more work at a higher rate. Which is awesome. It was a great way to discover a new client that I wouldn’t have met through my Seattle network. However, At that point in the summer I wasn’t ready to “drink from the fire hose.”

I’m not sure I will return to Upwork because I think I would be more efficient pitching my skills in person (or on the phone), and finding more interesting projects through my network.

Moment

I wanted to work for Mark Barros because he’s an awesome CEO. But also I wanted to work for him because he pulled me up the half pipe during Tough Mudder. I got to help Moment for a few days with a product launch. Specifically, I worked on an order fulfillment system for cool new phone cases and camera lenses.

The interesting thing about working for moment is that it is primarily hardware company. Turns out that’s not a good fit for me. I’ve mostly worked for companies where software is the main product. For a business like Moment, hardware is the product. They rightfully use whatever software necessary to sell and deliver it. In this case it was WordPress with WooCommerce. A frustrating choice for me as a developer – but a logical one for Moment.

Uberhuman

TA McCann wrote a great blog post about his experience killing this startup right before the seed round. It inspired me to write this post. I thought it would be fun to share my perspective.

With a few extra hours during the summer, I joined TA with a couple other developers and designers at his home. We discussed and coded an initial prototype. My job was writing the Node API to send faxes requesting medical records from doctors. Few providers responded. As it turns out, providers have no incentive (despite the law) to share medical records with their patients.

T.A. and I have a great working relationship. I can show up, ask a few questions, and then implement an experiment. It was worth the investment of free time for the possibility of working together. Sadly, we decided not to pursue it and it’s back to being a side project for me.

Photo app

Another great project that I spent considerable time on over the summer was a viral photo app. It is sort of like a Photo booth with a twist. A friend of a friend and I had a similar idea and the three of us started working on it. As I got the prototype going, we narrowed in on an MVP feature set. A big part of this was negotiating ownership of the project. It will hopefully yet see the light of day.

The project was excellent experience with Swift development. I am impressed by how well documented the iOS APIs are. I was also relieved to be writing code that compiled after lots and lots of JavaScript.

Retirement Calculator and Portfolio Creator

To prove my credentials as an iOS developer, I wanted to get an iOS app in the app store. A close relative is a financial advisor. After seeing his website, I realized it would make a straightforward iOS app. I scoped it out and talked to him. Within about 10 days of work we had Retirement Calculator and Portfolio Creator in the App Store.

I was pleasantly surprised that there was zero pushback from Apple. The release process was smooth. As a marketer, the project reinforced the importance engagement for mobile apps. We have new users that have committed valuable megabytes of their phone. We want to keep them using our app. This is a small insight for me – more obvious in mobile than on the web. Orphaned registered users seem that much closer when your code is in for installed on their phone.

Freeway

The project that I’m most excited to be working on is building tools for freelancers. We’re also matching freelancers to projects. I’m going to skip writing about this now because we’ve got some cool stuff in the works. But I did want to share this call I had with freelancers. We’ve been following up with everybody and I’ll have more on this by the end of the year.

Ookla/Formidable

I worked with Per Nilsson and Anna Luisa West from Formidable Labs at Haiku Deck. They were great. I wanted to work with Formidable again. Formidable offered a great project that I couldn’t refuse, helping Ookla launch a data portal.  You’ve probably used speedtest.net – we helped them report on all that great data. The result was a killer product for their clients.

Related

Recovering from a dislocated shoulder

IMG_2157

Bikers: If you get nothing else from this post, watch this video Showing Kocher’s method for putting your shoulder back in (I paid a very nice ER doc $800 for a live demonstration). Of course, you should see a doctor as soon as you can, but maybe it will spare you a scary hike.

One Sunday (July 25, 2015) when I was bored with riding on the road, I took off for a trail ride. It was an amazing 45 minutes before I got into trouble. I started on the beginner trails at Duthie Hill. Even though it was a damp morning, the trail was so nice I kicked myself for not going up there once a week all summer.

I started slowly and cautiously. I’ve had bad luck falling off my mountain bike – a couple times since I got it last year. After the beginner trail, I went to another nearby Grand Ridge trail which is more difficult (see photo above). I rode a ways out before turning around. Unfortunately on the way back I hit a loose patch of gravel on the outside of a narrow turn. My front wheel washed out to the right and I flew like superman into the ground – landing mostly on my chest. I landed with just the right forced to dislocate my left shoulder.

A nice young lady came along two minutes later. I asked her “This doesn’t look normal does it?” showing her my shoulder. “No,” she said. She graciously pushed both of our bikes out while I hiked. I carried the weight of my left arm in my right-hand. Surprisingly, it was not that painful. I didn’t relax until we hiked / jogged for about 20 minutes out to the road.

I’m writing this post to share some of the supplements I found trying to accelerate my recovery. Unfortunately, it’s been very slow. Over a hundred days now. I was able to get back on my bike after about 2 1/2 months, but I completely missed the last month of the race season. Luckily, it was only about two weeks that my arm was in a sling and I couldn’t type. It seems like my shoulder will be back to normal around the end of the year (5 months total).

Here are some of the supplements I that I tried.

  • Glucosamine
  • MSM
  • Gelatin (collagen) – (helps re-grow tissue)
  • Fish oil
  • Daily vitamin
  • Cissus quadrangularis (helps joint healing)
  • Magnesium (relaxes muscles)
  • Ginger tea (reduces inflammation)
  • Vinegar Apple cider  – forget why I started, but I drink this now to when my stomach is out-of-whack.

It’s really only Advil that I can definitively point to as helping my recovery. I should’ve taken more sooner in order to sleep better and heal faster, but I didn’t like the idea of numbing the pain. I think the nice snugness of my newly reformed shoulder capsule is due to many of the supplements that I took (primarily the Gelatin).

I also used a heating pad, stability ball, foam roller, and tennis ball in a sock to release tight back muscles.

I did a number of exercises recommended by a physical therapist. Other than slowly strengthening and stretching my shoulder, it’s hard to say which helped the most. So I won’t list them here.

The big lesson from this is that I need to keep working on my skills. The Total cost of the accident: a $2,000 trip to the ER, and a $1,000 chipped tooth.

Update: day 87 (12.5 weeks)

Motion continues to increase slightly every day. I’ve started doing Tony Horton’s Shoulder rehab workout.

Update: day 102 (14.5 weeks, 5 November 2015).

I was still having trouble sleeping last week. I can’t get used to sleeping on my back. A cold I got earlier in the summer came back. I’m pretty sure it’s because I wasn’t getting enough sleep (5 hrs a night). On a doctor’s recommendation, I’m back doing three Advil an hour before bed. It’s made a big improvement in my sleep.

Related

Should I write unit tests for node code?

A friend (learning node development) just asked:

Hey, another developer is encouraging me to do some unit testing using a testing framework called Mocha and Chai. What are your thoughts: must do, nice to have, or good hygiene (like pushing to GitHub and production every day)? Thanks in advance for your advice!

My answer: Must do, but it’s Level 2. In other words, as soon as you’ve grasped the basics (shipped your first app or site) – you should learn to write tests.

It’s more than just good hygiene. As your code base gets more complicated, automated testing will catch bugs that hand-testing won’t catch. You don’t have to go crazy, I’d suggest just starting with tests for the parts of your code that are hard to test by hand.
 
I like mocha. Chai is a little over-complicated. You can also just use “assert.” Other npm libraries I use for code testing:
  • Istanbul (coverage)
  • Sinon
  • Nock
  • Supertest

Longer answer: Automated testing is often required to know that your code is working. Once you’ve got a good suite of tests, you can change things with confidence and quickly verify that you haven’t broken something unexpectedly. However, It won’t guarantee that your code has no bugs (after all, tests can contain bugs too). Lastly, writing tests first (AKA “test driven development”) will help you organize your code better and write better interfaces.

How to win a bike race

Screen Shot 2015-11-25 at 12.10.14 PM

I finally won a Cat 4/5 criterium – in a race I’ve been doing off and on since the mid-1990’s. It’s 4 days later as I write this, and I’m still reveling in it. As I wrote in my 4 hour bike racer post, I set this goal because I previously upgraded my cycling license without ever winning. There’s a million reasons why winning this particular race was no big deal, but I made it the cornerstone of my mid-life crisis. I didn’t want to go to my grave without ever having won. It feels a little boastful to write this, but it’s my blog dammit. I write it for me, and I’m pretty satisfied with myself.

This was the actual race, Seattle’s weekly Seward Park Criterium. It’s open to young and old, male and female racers.

A few keys to winning:

  • Showing up week after week (a couple of the people that usually win weren’t there the night I won)
  • Counting lapsto get in position at the right time. Hint: 2 laps to go is too soon
  • Locking down the inside lane. I learned this from another guy in the race. If you keep near the curb, there’s only one direction people can attack you from.

Two weeks ago, after being aced out in the sprint yet again, I wrote down these tips for myself:

  • You have to come-around sometime in order to win. If the lead-out is not there, just go.
  • Carry momentum. If you’ve got it, just go.
  • Attack when it hurts. Don’t take your foot off the gas when others are hurting also.

Another thing that helped was analyzing the lap times and taking a few timed practice loops around the course. In practice, I could get around in maybe 1:50, but in the race our lap times are between 1:30-1:45, so I knew there was no chance of a solo breakaway.

As it happened, there were only slow wheels to be had – so I went from the middle of the hill 300m or so from the finish. Normally, I would’ve thought that was too soon – but I managed to hold everyone off. I remember thinking – “you may never get this chance again.”

Of course, acquiring the best bike money can buy was a big part of my success.

2015 Pinarello Dogma F8 Naked Red with Shimano Dura Ace C-50 wheels

But more importantly, I think there was a philosophical reason for winning. In the past 4 years, I’ve changed the way I think about fitness. I’m no longer a weekend warrior like I was in my 30s. I can’t coast on decent DNA any longer – I have to workout to survive. The best I can hope for is to cause my own pain (or “steady discomfort” as they say).

The thing is, when you do 30 minutes of exercise per day (OK, some days it’s 5 minutes) – you can do a half marathon without training for it. I workout less now. I don’t ride massive miles, but do try to make my short workouts intense.

Remember that startup I mentioned in my earlier post about habit formation? One of the best quotes I’ve hung on to is:

“You want to know how to paint a perfect painting? It’s easy. Make yourself perfect and then just paint naturally.” Robert M. Pirsig, Zen and the Art of Motorcycle Maintenance

 

Or, as I read this morning…

“Winning is not a moment of triumph – it is a habit of discipline and a process of becoming” – Métier

Turns out, if you want to win a bike race, you make yourself into a bike racer then ride naturally.

But I digress. Here are some hacks that worked for me. They’re important too.

  • Caffeine: correlates with better performance, what can I say?
  • Creatine: also seems to increase my work threshold, especially when coupled with caffeine
  • A good night’s sleep, or a nap if you can afford it, before the race has helped me too.
  • Soylent: great recovery and every meal drink. Rice protein not whey (though version 1.5 is giving me reflux and gas despite taking stomach enzymes with it).

New goals for 2016

  • Get to know more riders and get on a team
  • Help support racing however I can – heard a youngster speculating about how he could be win this race – and that’s what it’s all about (motivation and experimentation, not winning).
  • Do more mountain biking

Updates from Four Hour Cyclist 

  • It took 4+ years, not 6 months like I hoped.
  • Interval training (and high intensity intervals) did work, including for training for a marathon with minimal running.
  • I never did the track class, I’d still like to.
  • I acquired an olympic size deadlift bar, and about 2x my weight. I only ever made it to 1x my weight due to my lack of persistence (The 4HR body suggested 3x as the goal). This may be simply because I had it in the wrong room of my house – the garage and basement where it is hard to move around without hitting my head.
  • I never got a power meter, though prices are getting down a lot closer to $500. I traded my rollers for a Wahoo Kickr trainer (with power meter) and took a CycleU class – both helped me establish my Functional Threshold Power which was critical to doing effective computer-guided workouts during the winter.
  • For some reason, sprint workouts on the road require a lot of discipline. you have to head to a patch of road without too many cars, and you have to have the discipline to go back and forth putting yourself in a world of hurt. Doing this with others would definitely help.
  • My 2006 Dogma was stolen from my garage, but luckily my insurance covered the replacement cost of the 2015 version (pictured above) – a freakin superbike.
  • I drank so much whey protein I became lactose intolerant. Now I drink rice protein (primarily in Soylent).
  • I save Magnesium for the evening after a workout – helps relax the legs. During a hard  workout or race, I put creatine in my water – a recommendation from the 4HB.
  • Of course, to be an old-guy bike racer like me, you need full body fitness. Just 2 months prior I was not riding outside due to neck and back pain. I’d fallen off my mountain bike (at 0 miles per hour) knocking a rib was out of place. It was made worse by years of computer work. It took several weeks of chiropractic care and acupuncture to get everything loosened up so the ribs would stay in place. I immediately started strengthening. I used the exercises in my 4 Hour Body Cheat Sheet, and an old (fairly basic) Carmichael core training for triathletes video.

Related