Friday, July 31, 2015

30 Days Paleo: Lessons Learned

I finished my 30-day paleo challenge last week, technically last Monday, but because I took some liberties on the weekend before, stretched it until Friday.  The results are in...

Over the course of the ~5 weeks, I lost 10 pounds and some of my pants don't fit well anymore (had to go down one notch on the belt).  Part of that may have been to a 3-hour long "cardio tennis" session during the last week.  I didn't feel as sore in the mornings, and was able to work out 5+ times per week and still function.  I noticed a *slight* improvement in athletic performance, more in endurance than raw physical strength.

The 5 weeks ended up being a different experience compared to my prior strict-paleo experience.  Here are some things that I found:

  • Having the pre-made meals made staying on track much easier.  Zero prep time meant there was no excuse for eating something bad-but-quick.
  • Conversely, when not having the pre-made meals, it was much harder to eat right.  Restaurants, cafeterias at work, etc. have very few truly paleo options, and I had to go with salads.
  • Having something sweet / dessert-ish took a lot of the harsh drudgery off of eating strict. Making paleo pies every week was our trick -- we tried coconut cream, key lime, blueberry, peach, and cherry pies.  They all turned out surprisingly good -- like, I'd-eat-this-even-not-on-strict-paleo good.
  • I found my true enemy: Sugar.  Finding sugar-free but yummy food was challenging, but it meant not having big swings in hunger pangs, and not feeling crappy an hour after snacks.  I also learned there is a *ton* of sugar in fruit (apples!), so I stopped drinking OJ and cut down how many fruits I was eating as snacks.
  • Limiting my alcohol consumption, especially at night, probably had a bit part to play in the weight loss but I'm in denial on this one :)
In the end, I feel much better on a daily basis, look trimmer around the gut -- and the challenge wasn't hell, thanks to cheat days and paleo treats.  As a result, I'm going to keep at it for the foreseeable future.

Now, I just need to discover a paleo beer...not sure if I can switch over to sugary ciders...

Tuesday, June 30, 2015

9 Days Paleo

Now that I've gone through most of 9 days on strict-ish paleo, I feel great, energized, and awake.  I checked this morning and I'm down ~5 pounds, but I don't know if that's just water weight.  I feel like I could easily lose another 7, based on my my compression shirts fit.  Still, feeling better is worth it.

Hunger issues are much better the last week.  I was able to make it past the 2-3 PM wall without craving sugar.  Almonds and apples have come in handy, but it's hard to stay full without consuming lots of additional fructose / fat.

Finding paleo foods at lunch is still kind of a challenge, even if it's outright free, much of it is covered in sauces with wheat, dairy, or sugar.  I can have a salad, and there's usually a protein or two that I scrounge up like avocados or hard boiled eggs.  We do have a few pretty paleo salad dressings, which makes the salads much more palatable.  I would bring my own chicken breast, but there are no microwaves anywhere (a downside of having a place that gives you free food.)  At home, we've been eating power supply which is both tasty and useful to have right on hand.

Coffee and tea are rough without milk, and most of the almond milk I can find is laden with sugar or sugar substitutes.  So we've been trying some coconut cream and it's pretty close.  So far, our favorite paleo food has been a coconut cream pie, drizzled with a little lime flavor.  Score!

I haven't seen a significant difference in my workout performance yet, but that may be because the workouts vary so much, and we haven't done any benchmark workouts.  But I am feeling much less soreness than usual.

9 days down, another 23 to go!

Monday, June 22, 2015

1 Day Paleo

Day 1:  Got through the first day, which is always the hardest!

  • Lunch was my biggest concern, since most of the food in the cafeteria is not paleo.  Instead, I had a salad with lots of greens and a bug chunk of avocado (not my favorite, but I'll eat it for the challenge.)
  • I found that I went strong through most of the day, but hit a wall at 2-3 pm, when I got very hungry.  I ate almonds and an apple, and still it didn't feel like enough.
  • Paleo cookies are great, but get addictive as a food to fill up on when I'm hungry.  I end up having 3 instead of 1.  I learned to eat lots of good stuff before I have any.
  • Raw almonds are easy to choke on without water.
On to day 2!

Start of the 30 day paleo challenge

Tomorrow, the wife and I will be embarking on another 30-day challenge: to eat only strict paleo for 30 days.  There are several reasons for wanting to try this, including trying to lose some weight, feel better and more awake, and cut down on bad behavior (for me, drinking so much.)

The goal is pretty straightforward:  eat only paleo food for a month.  The only exceptions are one cheat meal per week, and one floating cheat meal (5 total in 30 days) -- the fourth of July weekend excluded since we'll be on vacation, so that will be one, three-day-long, continuous cheat meal.  No dairy, no wheat, no sugar, etc. -- we're allowed one 6 oz glass of red wine per day (replaceable with an ounce of chocolate if we want to trade).  For me, no beer, which is a big change.  If we complete the challenge, we each get to go on a trip-vacation of our own devising.

I'm excited to start, mostly because this week has been a binge week of eating and drinking up all the bad stuff in the fridge (I had what seemed to be an entire keg of beer to drink).  So every morning, I've felt queasy, tired, unmotivated, but frankly really looking forward to not eating bad anymore.

My goal for myself is three-fold:

  1. Look better in the mirror.  On the eve of the challenge, I weigh 179.4 pounds, and would like to hit 170.
  2. Raise my endurance and physical performance.  Some measure this in benchmark workout times and weights, but for me, it's probably more like regularly performing near the top of my class, 5 days a week.  My 400m/800m times would probably be the benchmark I care about most.
  3. Stop drinking as much.  I love beer, and it probably shows :)
Anyways, I plan to use this blog to document how I'm feeling, what recipes we're using, what we're finding difficult, etc.  Wish us luck -- in 30 days, we'll hopefully be much stronger!

Tuesday, February 17, 2015

Enterprise Management: User-Agent Switcher for Chrome

When I first wrote the User-Agent Switcher for Chrome, I imagined that it would be useful for administrators who wanted their users to use Chrome, but hack around legacy web apps that expected and required ancient browser versions.  Anyone using the steaming turd that is Outlook Web Access knows what I'm talking about.

However, Chrome didn't offer a way to manage extensions' settings -- only policies for managing itself...until recently.  With policy for extensions, Chrome now allows administrators to send policy settings directly to extensions -- not only can you deploy this extension, you could also deploy all the user-agents and permanent spoofs.

Setting policy for extensions is similar to setting policy for other applications on the target OS: the registry on Windows, a protected directory on Linux, Workgroup Manager on Mac, etc.  Chrome looks for these policies and then applies them to the extension (but only if they are crafted correctly -- more on that later.)

In version ~1.0.38, I added support for policy in the extension: I added the ability to set the user-agents, permanent spoofs, and a few of the other settings...and I hope to add more controls in the future.

To take advantage of this, you'll need to follow the steps below.  Unfortunately, every OS has its own format and own way of handling admin policies, so you may have to follow several of these to get coverage on your entire fleet.

Side note: I often found that any misspelling, or slightly-off structure of JSON or XML would cause policy to silently fail (*cough* broken user journey *cough*), so be sure your structure is correct.  Some debugging tips are at the very end of this post.

What Policies Are Supported

I added support for the most typical things an admin would change -- if you peek down at some of the sample policy files below, the structure should make some sense.  The policies currently supported include:
  • UserAgents -- a list of user-agent strings available for the user.  This is a List of Dictionaries/Hashes that contain the following values:
    • title [string] - the name of the user-agent ("Chrome 41")
    • ua_string [string] - the value of the user-agent string
    • vendor [string] - the value of the "navigator.vendor" field
    • badge [string] - the couple of letters that show up over the icon when spoofing
    • append [boolean]- whether the ua_string value should be appended to Chrome's user-agent (false means replace it)
  • PermanentSpoofs -- a list of permanent spoofs.  This is a List of Dictionaries/Hashes that contain the following values:
    • domain - [string] the domain regular expression to match.
    • user_agent - [dictionary] - this is a full UserAgent object (see above).  This is the user-agent to use with the permanent spoof.
  • EditRights -- several one-off settings for defining what users can edit.  This is a Dictionary.  Regardless of what you set here, users cannot modify user-agents or spoofs provided via policy.
    • user_agents [boolean] - whether the user can edit/add/delete user_agent strings.
    • permanent_spoofs [boolean] - whether the user can edit/add/delete permanent spoofs.
  • Other Settings -- more one-off settings representing the "Other Settings" section in the options screen.  This is a Dictionary of values.
    • hotlist_enabled [boolean] - Whether the user can switch the spoofed user-agent on the fly.
    • spoof_override [boolean] - Whether the on-the-fly spoof user-agent overrides permanent spoofs.
    • spoof_per_tab [boolean] - Whether the on-the-fly spoof applies only to the current tab.

Setup on Chrome OS / Google-managed Chrome

The Admin console has a place to manage extensions' settings (more info here.)  When you find the part of the admin console for setting extensions' policies, you can use JSON of this form:

{ "UserAgents": { "Value": [ {"title": "1", "ua_string": "ua_1", "vendor": "v_1", "badge": "A1", "append" : false}, {"title": "2", "ua_string": "ua_2", "vendor": "v_2", "badge": "A2", "append" : false}, {"title": "3", "ua_string": "ua_3", "vendor": "v_3", "badge": "A3", "append" : true} ] }, "PermanentSpoofs": { "Value": [ {"domain" : "foo.com", "user_agent": {"title": "4", "ua_string": "ua_4", "vendor": "v_4", "badge": "A4", "append" : false}}, {"domain" : "bar.com", "user_agent": {"title": "5", "ua_string": "ua_5", "vendor": "v_5", "badge": "A5", "append" : true}} ] }, "EditRights": { "Value": [ {"user_agents" : false, "permanent_spoofs": false} ] }, "OtherSettings": { "Value": { "hotlist_enabled" : false, "spoof_override": true, "spoof_per_tab": false } } }


Setup on Windows

Full disclosure: I haven't tested this at all, since I don't have any Windows machines to work on anymore, but I *think* this is the right structure.  Feedback is greatly appreciated on whether this works or not.


[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\UserAgents\1
"title"="Test"
"ua_string"="Test UA 1"
"vendor"="Testing"
"badge"="aaa"
"append"=false

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\PermanentSpoofs\1
"domain"="foo.com"

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\PermanentSpoofs\1\user_agent
"title"="Test 2"
"ua_string"="Test UA 2"
"vendor"="Testing 2"
"badge"="bbb"
"append"=true

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\EditRights
"user_agents"=false
"permanent_spoofs"=false

[HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\3rdparty\extensions\jhefaickifmkaeoijafmdniimnjfohef\policy\EditRights
"hotlist_enabled"=false
"spoof_override"=false
"spoof_per_tab"=false

Again, I'm not totally sure this is exactly right since I don't have a good way to test it, but please post in the comments if it does.


Setup on Mac

Mac devices use "plist" (policy list?) files to distribute settings -- these are glorified xml text files.  The format for this extension looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.google.Chrome.extensions.jhefaickifmkaeoijafmdniimnjfohef</key>
  <dict>
    <key>UserAgents</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <array>
        <dict>
          <key>title</key>
          <string>mac_plist_1</string>
          <key>ua_string</key>
          <string>mac plist 1</string>
          <key>vendor</key>
          <string>mac vendor 1</string>
          <key>badge</key>
          <string>aaa</string>
          <key>append</key>
          <false/>
        </dict>
        <dict>
          <key>title</key>
          <string>mac_plist_2</string>
          <key>ua_string</key>
          <string>mac plist 2</string>
          <key>vendor</key>
          <string>mac vendor 2</string>
          <key>badge</key>
          <string>bbb</string>
          <key>append</key>
          <true/>
        </dict>
      </array>
    </dict>
    <key>PermanentSpoofs</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <array>
        <dict>
          <key>domain</key>
          <string>www.foo1.com</string>
          <key>user_agent</key>
          <dict>
            <key>title</key>
            <string>mac_plist_3</string>
            <key>ua_string</key>
            <string>mac plist 3</string>
            <key>vendor</key>
            <string>mac vendor 3</string>
            <key>badge</key>
            <string>ccc</string>
            <key>append</key>
            <true/>
          </dict>
        </dict>
        <dict>
          <key>domain</key>
          <string>whatsmyuseragent.com</string>
          <key>user_agent</key>
          <dict>
            <key>title</key>
            <string>mac_plist_4</string>
            <key>ua_string</key>
            <string>mac plist 4</string>
            <key>vendor</key>
            <string>mac vendor 4</string>
            <key>badge</key>
            <string>ddd</string>
            <key>append</key>
            <false/>
          </dict>
        </dict>
      </array>
    </dict>
    <key>EditRights</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <dict>
        <key>user_agents</key>
        <true/>
        <key>permanent_spoofs</key>
        <true/>
      </dict>
    </dict>
    <key>OtherSettings</key>
    <dict>
      <key>state</key>
      <string>always</string>
      <key>value</key>
      <dict>
        <key>hotlist_enabled</key>
        <true/>
        <key>spoof_override</key>
        <true/>
        <key>spoof_per_tab</key>
        <false/>
        <key>send_errors</key>
        <false/>
      </dict>
    </dict>
  </dict>
</dict>
</plist>



Take this content, save it in a file with a name like "abc.plist".  You'll obviously want to update this to adjust to the settings you want -- these are just my test settings.  Mac administrators can deploy this file via Workgroup Manager, with some guidance on how to do this on the Chromium site.


Setup on Linux

I've never tested this on Linux myself, but I surmise that if you use JSON of the same structure as the Chrome OS policy, and put it in a JSON file in the right location (some basic instructions here.)


Why Isn't It Working / Debugging 

In my development and testing, I found it very common for the policies I was trying to set to not appear at all.  Here's a couple of tricks I used to debug issues with getting policies picked up:


  • http://about:policy is a huge help: it shows if the browser is picking up policies for extensions.  If it's not appearing here, it's not getting to the browser.
  • Any misspelling, missing comma (JSON), using true instead of , etc. will make the OS and the browser just ignore the policy.  If the policy isn't appearing in about:policy, or in the OS's policy viewer, there is a good chance the structure is off.
  • When encountering #2, I found it helpful to get just one *very* basic policy working, then build up the other necessary policies one at a time.


Final Thoughts


I'm hoping that some admins out there who are trying to hack around some legacy systems' problems will find this useful.  Not every setting has a corresponding policy, so there's more work for me to do.  I also need to test on more systems, but I think this should work.

Feedback is greatly appreciated -- feel free to leave it here, or on my G+ page.

Tuesday, January 27, 2015

The Web's Death has been Greatly Exaggerated

Over the past several years, developers and pundits started buzzing about users' shift from mobile to desktop.  And they have good reason to think this way: smartphone shipments are hundreds of millions of units per quarter, a majority of the world's population has access to one, and mobile now accounts for more web usage than desktop.  With both the potential upsize of getting a smartphone in billions of new hands over the next few years, and the rapid overtaking of desktop web usage and PC shipments, how could observers not think that "Mobile is eating the world"?

Many believe this to be a troubling trend for the "open web": users are spending 86% of their time in native apps, and only 14% in mobile web.  Native apps are considered "walled gardens" in that they can't typically be crawled by third parties, like search applications, and the data you generate in them is not typically discoverable outside of the app.  The app developer has complete control over the data they generate and access to that data.  Good luck Googling on your phone for your Instagram photos or your Uber history -- it even sounds silly.

Simultaneously, there's been a rush for developers to make all kinds of apps.  These are developers that could have been out developing innovative web applications but chose to make mobile apps instead.  Many theories persist as to why they choose to make mobile apps instead of web apps, all of which may have a grain of truth:

  • Mobile apps have a built-in monetization method (users are 'conditioned' to pay for apps)
  • Mobile apps have native UI toolkits that make them look much slicker
  • IDEs and tooling around web application development are sub-par compared to Xcode 
  • Javascript and CSS are really hard.  Objective-C, C/++ and Java are easier (related to #3)

This is also very concerning to the "open web": if fewer developers are developing compelling things on the web because they're making walled garden native apps, won't the web wither and die from a lack of innovation?  Isn't the web dying because of the fundamental shift to mobile, and more specifically, mobile apps?

What Are Users Doing In Apps That Is So Valuable?

Let's look at the data to see if the web is really dying.  First, what apps are users using?  Per Flurry's analysis, this is where they spend their time:



Let's break it down in terms of where developers are spending their time:

  • Games.  There's enough to talk about in games, it has its own section below.
  • Facebook --  There are only so many developers working on this app, and they all work at Facebook.  It would be great if the data were open, but it's not a stretch to imagine why it is not.
  • Social Messaging -- people texting each other, sending each other short videos or self-destructing images.  Maybe these could have been developed on the web...as valuable as it is for the open web to have access to everyone's "lol"s and poop emojis.
  • Twitter, YouTube, News -- almost all have web equivalents that are "open".  Except in Spain
  • Utilities -- Flashlights and data usage counters.  Web equivalents of these probably don't make sense to build in the first place, but never say never.

Is there anything that the web is really missing here?  It's possible that instead of spending time making web access points for data really shine, developers are spending time making the mobile apps shine.  However, that's not where users are spending their time.

Maybe that was just a misleading chart.  Instead of looking at people's time spent, look at the top Apps by users in the US:



  • 15 of the top 25 apps are owned by four companies.  (Oh, Snapchat -- maybe you could have been #16.)   8 of the apps are provided by the platform owners Google and Apple.
  • 21 of the top 25 apps have web equivalents that are just another face on the same set of underlying data -- data which is arguably the value to the user, not the app "shell" itself.
  • 24 of the top 25 apps are free.  Technically, the Netflix app is free but really requires a subscription, so I didn't count it as free.  It's totally worth it though -- if you haven't seen House of Cards, it's worth every single cent of your subscription.
Most of the top apps, and apps where users spend the most time, are just another view of data already available on the web in some form.  Moreover, most of the top apps are built and controlled by a small number of large tech companies -- those companies developing these apps is not likely to present an opportunity cost to the web, because they also have a large number of developers also working on web applications.  Perhaps those efforts could have been focused on really making the web version better, but are any of them in a terrible state of disrepair?  


Every one of these apps is free, which flies in the face of the conventional thinking that users are ok paying for apps.  When taken by time used, games, Facebook, social messaging (mostly), YouTube,  Twitter, and news apps are all free (with ads) or make their money off of freemium models.  Users are spending all of their time in free apps!  Guess what else is mostly free, freemium, or ad-supported?  The web.

What About Games?

Games, which constitute the largest chunk of mobile users' time, are obviously a draw for app developers.  Of the roughly 1 million live apps in the App Store, 21% are games.  What's up with so many games, and why do so many get created every month?

A few hypotheses:

  • Games are fun for developers to make, more so than another calculator app.
  • Several high profile mobile game companies got popular fast and had very large exits -- get a few hundred thousand users and then get bought out.
  • People love wasting time on their phone, as evidenced by spending 32% of their time doing so.
Most games are freemium -- very few are paid up front.  They often rely on addictive progression, coupled with social sharing components to get "whales" addicted and shelling out big bucks to get ahead.  In the meantime, the other 98.5% of users get advertising, commonly a very effective kind of advertising called "cost per install" (CPI) advertising.  In CPI, app creator A pays app creator B for every user who clicks one of their ads and installs their app.  CPI is known to be very financially beneficial for the publisher (but only so-so for the advertiser) because even though they set their own install price target, the users they get this way don't stick around and become whales.  So the advertiser has to cram in more ads into their own app to increase lifetime customer value and make the install price worth it.

What does this lead to?  Free games that have CPI ads for other free games -- that have CPI ads for other free games -- etc.  A bunch of money going around in a circle.

Regardless of how un-sustainable that monetization model sounds, how big of a loss is it that the information contained within these games isn't openly accessible?  Arguably, the data within games has some tiny smidgeon of value, and it would be great if the open web could find and discover that.  However, does not having your high scores in Angry Birds be searchable online going to be the nail in the coffin of the web?

Picks and Shovels

There is a famous investing adage that, during the California gold rush of 1849, none of the prospectors who went hunting for gold got rich.  However, people who sold them picks, shovels, blue jeans, and chocolate did get rich.

Mobile apps are having their gold rush -- if a relatively simple flashlight utility app becomes the top popular install, the developer could put a bunch of ads on it and make a decent amount of money.  However, there's only going to be one most popular flashlight app, and one most popular calculator, and one Facebook.  It's reasonable to think that there are some innovative, unique app opportunities not already taken -- but many of the opportunities are.   The marketplaces are entirely owned and controlled by large tech companies: they are the pick and shovel makers, who also happen to be putting big bets on the web.

The shift to mobile is a fundamental change in how users access information, communicate, and spend their spare brain cycles.  Its rise has been meteoric, and anyone who does not respond will certainly be lapped by competitors.  However, the rise of mobile usage has not been to the detriment of desktop usage.

Declaring the web as "dying" is silly -- developers are making free apps for convenience or to fill time, and take advantage of being anywhere -- not replacing what people normally do on laptops or desktops (try to write a book on a phone.)  Once the gold rush of app development is over, the smoke will clear and valuations of mobile apps will come back to Earth.  Would it be better for the open web for all developers to be developing web apps and not mobile apps?  Of course.  But the mobile apps they are building are not apps that make sense for the web, and often have data that isn't that useful or is already available on the web.

Maybe mobile will kill the web at some point in the future -- never say never -- but it hasn't killed it yet.