<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Jiaaro</title>
        <description>Jiaaro (on life, the universe, and everything)</description>
        <link>http://www.jiaaro.com</link>
        <atom:link href="http://www.jiaaro.com/feed.xml" rel="self" type="application/rss+xml" />
        
            <item>
                <title>Why not Facebook?</title>
                <description>&lt;p&gt;They don’t respect your privacy. They’re irresponsible. And they’re dishonest.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Facebook collects more information about you than they lead you to believe.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://techcrunch.com/2019/01/29/facebook-project-atlas/&quot;&gt;Facebook pays teens to install VPN that spies on them&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.wsj.com/articles/you-give-apps-sensitive-personal-information-then-they-tell-facebook-11550851636&quot;&gt;You Give Apps Sensitive Personal Information. Then They Tell Facebook.&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://gizmodo.com/facebook-was-fully-aware-that-tracking-who-people-call-1830884585/amp&quot;&gt;Facebook Well Aware That Tracking Contacts Is Creepy: Emails&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Facebook shares specific personal details about you with third parties without asking your permission or telling you.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://gizmodo.com/facebook-is-giving-advertisers-access-to-your-shadow-co-1828476051&quot;&gt;Facebook Is Giving Advertisers Access to Your Shadow Contact Information&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://theintercept.com/2019/05/20/facebook-data-phone-carriers-ads-credit-score/&quot;&gt;Facebook’s Work With Phone Carriers Alarms Legal Experts&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.nytimes.com/2019/09/20/technology/facebook-data-privacy-suspension.html&quot;&gt;Facebook’s Suspension of ‘Tens of Thousands’ of Apps Reveals Wider Privacy Issues&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.fastcompany.com/90314763/now-facebook-is-allowing-anyone-to-look-you-up-using-your-security-phone-number&quot;&gt;Now Facebook is allowing anyone to look you up using your security phone number&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://daringfireball.net/linked/2018/12/19/facebook-microsoft-amazon&quot;&gt;Facebook Shared Personal Information With Amazon, Microsoft, Netflix, and Others&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When Facebook gets caught doing things they shouldn’t, Mark Zuckerberg apologizes. As part of the apology he offers an explanation and an estimate of how many users were affected (so far so good). But, this estimate is always lower than the real number. Once they are no longer the center of attention Facebook revises the number of people affected to a much higher number.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.businessinsider.in/Facebook-says-it-unintentionally-uploaded-1-5-million-peoples-email-contacts-without-their-consent/articleshow/68930320.cms&quot;&gt;Facebook says it ‘unintentionally uploaded’ 1.5 million people’s email contacts without their consent&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.recode.net/2019/4/18/18485528/facebook-instagram-passwords-stored-unencrypted-security-issue&quot;&gt;Facebook stored millions of Instagram passwords unencrypted&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://krebsonsecurity.com/2019/03/facebook-stored-hundreds-of-millions-of-user-passwords-in-plain-text-for-years/&quot;&gt;Facebook Stored Hundreds of Millions of User Passwords in Plain Text for Years&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.nytimes.com/2018/04/04/technology/mark-zuckerberg-testify-congress.html&quot;&gt;Facebook Says Cambridge Analytica Harvested Data of Up to 87 Million Users&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Facebook misleads users by offering privacy tools and settings which do not provide complete information, nor full protection. Regardless of how carefully you use them they still allow Facebook to continue using your data and personal information however they want. And Facebook regularly works around or disallows privacy tools provided by third parties.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.wired.com/story/facebook-privacy-setting-doesnt-do-anything/&quot;&gt;The Facebook Privacy Setting That Doesn’t Do Anything at All&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.washingtonpost.com/technology/2019/08/20/facebook-unveils-long-promised-tool-remove-data-it-receives-third-party-apps-websites/&quot;&gt;Facebook’s ‘Clear History’ tool arrives with ambiguous data privacy controls&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.propublica.org/article/facebook-blocks-ad-transparency-tools&quot;&gt;Facebook Moves to Block Ad Transparency Tools — Including Ours&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Facebook promotes content that is extreme – including reporting that is verifiably false or fabricated – and leads users to adopt more extreme beliefs over time.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.propublica.org/article/facebook-enabled-advertisers-to-reach-jew-haters&quot;&gt;Facebook Enabled Advertisers to Reach ‘Jew Haters’&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://lithub.com/how-the-algorithm-rewards-extremism/&quot;&gt;How the Algorithm Rewards Extremism&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.nytimes.com/2018/04/25/world/asia/facebook-extremism.html&quot;&gt;How Everyday Social Media Users Become Real-World Extremists&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A side effect of Facebook promoting progressively more extreme content is that all the bad PR has all but forced them to hire moderators. Moderators who tamp down the &lt;em&gt;most&lt;/em&gt; extreme stuff. Truly horrific things. Unsurprisingly, &lt;a href=&quot;https://www.theverge.com/2019/2/25/18229714/cognizant-facebook-content-moderator-interviews-trauma-working-conditions-arizona&quot;&gt;being a Facebook moderator is not good for your mental health&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;And finally, pretty much all reporting indicates Facebook is run by morally questionable people. And &lt;a href=&quot;https://www.nytimes.com/2018/03/19/technology/facebook-alex-stamos.html&quot;&gt;people with integrity eventually get pushed out&lt;/a&gt;.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.wired.com/story/facebook-mark-zuckerberg-15-months-of-fresh-hell/&quot;&gt;15 Months of Fresh Hell Inside Facebook&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.businessinsider.com/facebook-old-posts-mark-zuckerberg-disappeared-2019-3&quot;&gt;Old posts by Mark Zuckerberg have disappeared&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.revealnews.org/blog/a-judge-unsealed-a-trove-of-internal-facebook-documents-following-our-legal-action/&quot;&gt;Facebook’s internal documents about how it made money off children to be released&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;but-instagram&quot;&gt;But Instagram…&lt;/h2&gt;

&lt;p&gt;These issues are &lt;em&gt;not&lt;/em&gt; isolated to the Facebook app. Facebook, as an institution, uses whatever means available to pursue their goals. Instagram and WhatsApp can snoop through your contacts and photos, or log your location history just as well as any other Facebook property.&lt;/p&gt;

&lt;p&gt;Also, Instagram is younger in its product lifecycle. You’ve probably noticed the increasing number of ads. It’s heading the same direction as Facebook proper, just 5 years behind. And the money they make on Instagram will fund other Facebook projects (like their cryptocurrency) and anticompetitive activity (like lobbying or acquiring competitors, e.g., Instagram and WhatsApp).&lt;/p&gt;
</description>
                <pubDate>Fri, 27 Sep 2019 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/why-not-facebook</link>
                <guid isPermaLink="true">http://www.jiaaro.com/why-not-facebook</guid>
            </item>
        
            <item>
                <title>Twitter vs Facebook</title>
                <description>&lt;p&gt;The difference between Twitter and Facebook isn’t that Twitter is a better company, a better product, or that they treat their users better (they aren’t, it’s not, and they don’t). It’s that after reading twitter I feel (you know, ever-so-slightly) happier and more relaxed. And after using Facebook I miss old friends, and generally feel anxious and melancholy.&lt;/p&gt;

&lt;p&gt;If that’s how it feels to “stay connected”, I’ll pass. Email, text, snapchat, and twitter are still good :)&lt;/p&gt;

&lt;p&gt;Twitter requires you to curate who you follow, and that’s real work. I appreciate that. I’m also not the target of the bizarre pile-on attacks twitter is sometimes associated with. I’m sure that would ruin it for me. But, Facebook doesn’t have that problem (as far as I know) and it’s already baseline negative so… ¯\_(ツ)_/¯&lt;/p&gt;

&lt;p&gt;Also, friends, if you publish anything anywhere (blog, soundcloud, university website, etc.) please — PLEASE — let me know how to subscribe for updates. I am seriously interested in the work you do!&lt;/p&gt;

&lt;p&gt;It’s easy. Just &lt;a href=&quot;mailto:me@jiaaro.com&quot;&gt;write an email&lt;/a&gt; to me and say “Hey your blog post says to tell you that I am publishing my work at …”&lt;/p&gt;

&lt;p&gt;Please do it!&lt;/p&gt;
</description>
                <pubDate>Thu, 01 Jun 2017 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/twitter-vs-facebook</link>
                <guid isPermaLink="true">http://www.jiaaro.com/twitter-vs-facebook</guid>
            </item>
        
            <item>
                <title>Tyranny of the Majority</title>
                <description>&lt;p&gt;Many people, especially liberals, are concerned about the “tyranny of the majority” and spend much time thinking and discussing how we might make things better and more fair. Specifically, how to put a check on the power of the majority. A noble goal.&lt;/p&gt;

&lt;p&gt;The problem: If you give minorities – say we aim to help transgender people – a check on the power of the majority, then what happens to that other famous minority, millionaires? It’s not like the millionaires have had a hard time advocating their interests up until now.&lt;/p&gt;

&lt;p&gt;Compared with other minority groups, the millionaires are better organized. They have resources. They’re connected. You’d better believe they will take full advantage of any systems designed to empower the other minority groups, no matter how noble the intent. This isn’t theoretical; look no further than the electoral college and the tax code.&lt;/p&gt;

&lt;p&gt;Of course, we can make targeted changes to benefit a specific minority each time there’s a need. Which &lt;em&gt;does&lt;/em&gt; work — if you can make it happen. That plan relies on the majority though, to notice and accept the specific minority actually has a need. Which, historically, hasn’t been reliable.&lt;/p&gt;

&lt;p&gt;I don’t have solutions, but I find this concerning.&lt;/p&gt;
</description>
                <pubDate>Fri, 11 Nov 2016 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/tyranny-of-the-majority</link>
                <guid isPermaLink="true">http://www.jiaaro.com/tyranny-of-the-majority</guid>
            </item>
        
            <item>
                <title>What Makes a Good Game?</title>
                <description>&lt;p&gt;Fun is number one. Gaming is entertainment. Not a lifestyle, not a subculture.&lt;/p&gt;

&lt;p&gt;Call me a filthy casual if you want. But do it quick, I heard Destiny raised their level cap again. Or can you skip the grinding with an in-app purchase now?&lt;/p&gt;

&lt;p&gt;My other values largely follow from that.&lt;/p&gt;

&lt;h3 id=&quot;story-telling&quot;&gt;Story Telling&lt;/h3&gt;
&lt;p&gt;Do it well or don’t do it at all. Script, voice-acting, and themes will be evaluated against the best from hollywood.&lt;/p&gt;

&lt;p&gt;Yes, games require exponentially more content, and that is hard. But that’s not my problem. The story doesn’t care that the medium is expansive. It can be done, I’ve &lt;em&gt;seen&lt;/em&gt; it done.&lt;/p&gt;

&lt;p&gt;But, not all games need story. If the game is great fun without story, then toss it. Tacking on a crap story will only hurt the game.&lt;/p&gt;

&lt;h3 id=&quot;difficulty&quot;&gt;Difficulty&lt;/h3&gt;
&lt;p&gt;Should match the player’s ability. Where possible it should dynamically adjust. Challenges should be achievable but, you know, challenging. If it’s too easy it’s boring, if it’s too hard it’s disenchanting.&lt;/p&gt;

&lt;h3 id=&quot;grinding&quot;&gt;Grinding&lt;/h3&gt;
&lt;p&gt;If the grind is fun, then the grind &lt;em&gt;is&lt;/em&gt; the game (and, I’d say, it’s unfair to call it grinding probably). If the grind is not fun, then it’s unforgivable.&lt;/p&gt;

&lt;p&gt;For those who only care about the trajectory of the story, you should be able to continue through the game without grinding, but of course there has to be some reward for doing the grind. That’s a balance that must be achieved.&lt;/p&gt;

&lt;p&gt;In Borderlands 2 you can grind for better gear and stats, but you can also just power through without worrying much about it on an easier difficulty setting. That design worked pretty well (along with many other complementary game elements).&lt;/p&gt;

&lt;h3 id=&quot;novelty-gimmicks&quot;&gt;Novelty, gimmicks&lt;/h3&gt;
&lt;p&gt;Novelty is worth something. I won’t dismiss a game because it has a gimmick. Novelty wears off though.&lt;/p&gt;

&lt;h3 id=&quot;franchises&quot;&gt;Franchises&lt;/h3&gt;
&lt;p&gt;I appreciate the value of a deep universe and lore, but each game must stand alone. I not going to watch every Star Trek movie ever made before seeing this year’s blockbuster, and I won’t play all of a games predecessors before I start on it either. I just won’t.&lt;/p&gt;

&lt;p&gt;If the game is great I may play the predecessors afterward. There may be spoilers in the sequels. I understand the risks.&lt;/p&gt;

&lt;h3 id=&quot;prices&quot;&gt;Prices&lt;/h3&gt;
&lt;p&gt;Truly free games make me suspicious - I need to know why someone invested that much effort for no financial reward.&lt;/p&gt;

&lt;p&gt;Free-to-play games should be free-to-win. Without a level playing field we’re really just playing a game of “who’s willing to spend the most money on a false sense of superiority?”&lt;/p&gt;

&lt;p&gt;But, really, one way or another, I want to pay for games.&lt;/p&gt;

&lt;p&gt;If you like games (check), and you want games to keep being made (check!), then the people who make games need a reward for their effort (e.g., to get paid).&lt;/p&gt;

&lt;p&gt;It doesn’t matter if you, specifically, pay for games. Because guess what? The game makers who get rewarded will be the ones who make games for the people who pay.&lt;/p&gt;

&lt;p&gt;The more you (and people like you) spend on games, the more developers are going to make games for people like you.&lt;/p&gt;

&lt;p&gt;That also applies to in-app purchases. Every dollar you spend in Farmville is a vote for more games like Farmville (whether that’s good is up to you!)&lt;/p&gt;

&lt;h3 id=&quot;execution-beats-ideas&quot;&gt;Execution beats ideas&lt;/h3&gt;
&lt;p&gt;Really. Execution above all else. This is not exclusive to games, but it’s just as true for games as for all other products.&lt;/p&gt;

&lt;p&gt;A good idea badly executed is still a bad game. A bad idea executed terrifically can sometimes reveal the idea to be quite good. Some ideas really are bad. You need both.&lt;/p&gt;
</description>
                <pubDate>Fri, 02 Sep 2016 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/gaming-values</link>
                <guid isPermaLink="true">http://www.jiaaro.com/gaming-values</guid>
            </item>
        
            <item>
                <title>Maintainable CSS (or CSS the good parts)</title>
                <description>&lt;p&gt;CSS is kind of terrible. Everything affects everything. It’s impossible to refactor. Code is spaghetti from day one.  And selectors are used to identify elements in scripts as well as applying styles, not to mention the semantic meaning of html tags themselves.&lt;/p&gt;

&lt;p&gt;So. Some proposals…&lt;/p&gt;

&lt;h3 id=&quot;element-id&quot;&gt;Element ID&lt;/h3&gt;
&lt;p&gt;Don’t use ID. Don’t use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getElementByID()&lt;/code&gt;. Don’t use element IDs in your CSS selectors. Just don’t. ID has no benefit over classes for use in CSS or JavaScript.&lt;/p&gt;

&lt;p&gt;There is virtually no case where you can be 100% certain that a style will only ever need to be used on one element in the whole page. Even if you &lt;em&gt;were&lt;/em&gt; certain, a class would work just as well!&lt;/p&gt;

&lt;p&gt;There is only one acceptable use for id: to enable deep-links to specific elements (with the scroll behavior that entails).&lt;/p&gt;

&lt;h3 id=&quot;tag-selectors&quot;&gt;Tag selectors&lt;/h3&gt;
&lt;p&gt;Don’t use tag selectors in javascript. In CSS only use them to provide the most basic reset and baseline styles. Never mix tag selectors with class selectors.&lt;/p&gt;

&lt;h3 id=&quot;one-class-selectors&quot;&gt;One class selectors&lt;/h3&gt;
&lt;p&gt;No nesting. If you need more behaviors on an element, add another class. If you need only some of the behaviors of a parent class and you want to override others, your parent class is probably doing too much. Try giving it less responsibility, or if you really can’t – no way, no how – just define a new class.&lt;/p&gt;

&lt;p&gt;Really consider giving the parent class less responsibilities though. If you have to think about the order of the rules in a style block, there are probably too many.&lt;/p&gt;

&lt;p&gt;Good:&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.my-class&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not great (but sometimes necessary):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.my-container&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.my-class&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Bad (just create a third class):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.my-class.other-class&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Very Bad (fully engaged in the precedence war):&lt;/p&gt;

&lt;div class=&quot;language-css highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;.container&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;.sub-element&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.special-link.active&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;use-naming-conventions&quot;&gt;Use Naming conventions&lt;/h3&gt;
&lt;p&gt;You should be able to tell roughly what a class is for (and you’re only using classes right?) by the name.  Establish – at a minimum – a convention for classes that control layout, text styles, and javascript hooks.&lt;/p&gt;

&lt;p&gt;JavaScript should not use the same classes as css.&lt;/p&gt;

&lt;p&gt;That would be mixing presentation with logic.&lt;/p&gt;

&lt;h3 id=&quot;use-rem-root-em-units&quot;&gt;Use rem (root em) units&lt;/h3&gt;
&lt;p&gt;em units are kind of crap because if they are nested they compound. Still, it’s great to set the font-size on the body and have everything work from there. And, rems are well supported (IE 9+).&lt;/p&gt;

&lt;h3 id=&quot;use-lots-of-css-files&quot;&gt;Use lots of CSS files&lt;/h3&gt;
&lt;p&gt;You should have one main css file which uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@import&lt;/code&gt; to bring in everything else it needs. Break up your css so that each logical unit is in it’s own file. Got a custom dropdown widget? super-dropdown.css. What about persistent navigation at the top of each page? header-navbar.css. Login form? login-form.css.&lt;/p&gt;

&lt;p&gt;If you have less than 5 CSS files you’re probably doing it wrong. If you have exactly &lt;em&gt;one&lt;/em&gt; CSS file you almost definitely are.&lt;/p&gt;

&lt;p&gt;ok, ok, ok. I know what you’re thinking: “James, I’ve been doing lots of these ‘wrong’ things and it’s been working fine for me.”&lt;/p&gt;

&lt;p&gt;You see, it seems that way at first. IDs, specific selectors, using a class for styles and javascript. These things seem useful and “clean”. Why use two classes when one will do? Because you will not be able to refactor your code. That’s why. And if you let it go on long enough you won’t even be able to change your code without a full round of manual testing.&lt;/p&gt;

&lt;p&gt;Most CSS code being written today is technical debt from the moment it’s created. And it’s the worst kind of technical debt: the kind you don’t know you have.&lt;/p&gt;
</description>
                <pubDate>Tue, 07 Jun 2016 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/maintainable-css</link>
                <guid isPermaLink="true">http://www.jiaaro.com/maintainable-css</guid>
            </item>
        
            <item>
                <title>A Path to Fluency</title>
                <description>&lt;p&gt;Learning a language is a Good Idea. It makes you &lt;a href=&quot;http://www.lifehack.org/316041/research-finds-that-bilingual-people-are-smarter-more-creative-and-empathetic&quot;&gt;smarter, more creative, and empathetic&lt;/a&gt;, and more likely to &lt;a href=&quot;http://www.sciencealert.com/bilingual-people-are-twice-as-likely-to-recover-from-a-stroke-study-finds&quot;&gt;recover from a stroke&lt;/a&gt;. Thinking it’s good idea doesn’t make it easy. The payoff is too far off, too abstract.&lt;/p&gt;

&lt;p&gt;Recently though, I’ve been making some headway after giving up lots of times in the past. Some observations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning a language because it’ll be “useful” probably won’t work out.&lt;/strong&gt;&lt;br /&gt;
If you haven’t encountered any Chinese in the last 20 years, odds are you won’t in the next 20 years either. Any language is worth knowing, but, like exercise, most people run out of motivation before reaching their goals.&lt;/p&gt;

&lt;p&gt;My advice? Pick one you have a personal reason for. I have Spanish-speaking family (including my wife), Mexico is right next door, and there’s Spanish language TV here in New York.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Duolingo is amazing.&lt;/strong&gt;&lt;br /&gt;
If you’re not using &lt;a href=&quot;https://www.duolingo.com&quot;&gt;Duolingo&lt;/a&gt;, you’re missing out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entertainment: You can trick yourself into learning.&lt;/strong&gt;&lt;br /&gt;
Spanish tech news on twitter and RSS make it easier to practice every day without it feeling like work. I also picked up some &lt;a href=&quot;http://amzn.to/1XdgCCa&quot;&gt;translated graphic novels&lt;/a&gt;. Comics, graphic novels, and manga make it &lt;em&gt;much&lt;/em&gt; easier to get the gist of the story without struggling too much. There are also &lt;a href=&quot;http://amzn.to/1TfLbTd&quot;&gt;“side-by-side” readers&lt;/a&gt; which have the same text in two langauges – English on the left, Spanish on the right.&lt;/p&gt;

&lt;p&gt;Be careful of things that are too difficult for you. Feeling like you’re in over your head makes it hard to stay focused and it’s demoralizing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TV and Movies are a siren song.&lt;/strong&gt;&lt;br /&gt;
At least early on; I’m still not able to keep up. They seem like a great way to practice, but the pace is too fast and there are a lot of idioms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional methods don’t work (for me).&lt;/strong&gt;&lt;br /&gt;
Stuff like Rosetta Stone, “Learn Spanish” books, podcasts, etc bore me to death. Motivation is as important as the information and exercises. You definitely won’t learn the language if you quit. And “I’ll know Spanish if I do this hard-ass work,” is not enough on it’s own.&lt;/p&gt;

&lt;p&gt;Honestly, I don’t know how &lt;em&gt;anyone&lt;/em&gt; learns language that way. ¯_(ツ)_/¯&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visiting Mexico was a huge motivator.&lt;/strong&gt;&lt;br /&gt;
Really. Nothing makes me want grind through Spanish lessons like being surrounded by native speakers.&lt;/p&gt;

&lt;p&gt;You can fly to Cancun for just over $150 each way on Jet Blue:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/f7cfab39e36dbbfa6d82678c1ac2f8a8.jpeg&quot; alt=&quot;JFK to CUN for $315&quot; class=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;…and rent a lovely place in Puerto Morelos for $220/mo (4000 pesos):&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;Puerto Morelos Apartment for $220/mo&quot; src=&quot;/img/07da2395f08409e8d2dcf36a587fb956.jpeg&quot; class=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;note: I haven’t done that, I just took that photo of the apartment listing when I was in Cancun a few years ago.&lt;/p&gt;

&lt;p&gt;That’s all I’ve got for now. Wish me luck!&lt;/p&gt;
</description>
                <pubDate>Sun, 15 May 2016 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/a-path-to-fluency</link>
                <guid isPermaLink="true">http://www.jiaaro.com/a-path-to-fluency</guid>
            </item>
        
            <item>
                <title>Blocking Content Blocking</title>
                <description>&lt;p&gt;I can’t help but chuckle about all the hand-wringing over content blockers in iOS 9. Ad blockers have existed for some time. Not many people use them (as a percentage of overall web users). Plus, native advertising is mostly immune to content blocking anyway, and that’s where a lot (most?) of the money was going to end up anyway.&lt;/p&gt;

&lt;p&gt;That’s old news. My favorite part is: it’s really not that hard to make nearly unblockable ads. If the publishers and ad networks worked together they could mostly nullify the effects of ad blockers in lots of ways.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;They could insert the ads server-side in a way indistinguishable from content. Then load the ad network’s javascript purely to mark the ads as “sponsored content” and handle tracking. This would make it so that people using ad-blockers would have more trouble telling where the ads are, but everyone would see the ads.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ad networks could build CDN-like infrastructure and insert their ads in pre-specified parts of the page (like how Vagrant builds pages). This approach lets everything come down from one domain but takes care of publisher accountability (publishers can’t screw the ad network).&lt;/p&gt;

    &lt;p&gt;Alternatively, an actual CDN (like CloudFront) could provide hooks for publishers and Ad networks (again, like Vagrant) to insert ads into pages within the same domain, and do impression/click tracking on the same domain as well. This variant solves some of the incentive issues (publishers don’t have to trust the ad networks either) by moving trust on a third-party (the CDN). I prefer this variant in terms of incentives, but it requires more coordination, so it might be harder for a CDN to succeed in the marketplace with this approach.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ads can be sold on an average-traffic or pay-per-click basis (i.e. the Deck), but without any 3rd party javascript. The markup inserted by publishers is just a clickable hot linked image, and the ad is rotated by just changing the image served at that url, and changing the destination of the link’s redirect. Publishers would just have to insert a unix timestamp in the querystring of the image and link to invalidate caches, deal with fast ad rotations, and all sorts of other issues. This method is relatively blockable, but easily pairs with a CDN-like approach.&lt;/p&gt;

    &lt;p&gt;What I like about this is the simplicity, and the fact that it represents a line in the sand. You can easily say, ads served as third-party images are OK, but not ads served as 3rd party javascript or 3rd party iframes.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Anyway, there are lots of details around all these approaches that would have to be worked out. And plenty of pros and cons of each one as well (for all parties involved, consumers, advertisers, publishers, and ad networks. And CDNs should they choose to get in the middle of all this.)&lt;/p&gt;
</description>
                <pubDate>Tue, 06 Oct 2015 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/blocking-content-blocking</link>
                <guid isPermaLink="true">http://www.jiaaro.com/blocking-content-blocking</guid>
            </item>
        
            <item>
                <title>The Shortest Apple Watch Review</title>
                <description>&lt;p&gt;If you’re into two or more of these (or &lt;em&gt;really&lt;/em&gt; into one), you should check out the Apple Watch:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Personal fitness&lt;/li&gt;
  &lt;li&gt;Watches&lt;/li&gt;
  &lt;li&gt;Apple products&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it. Review complete.&lt;/p&gt;

&lt;p&gt;It’s an interesting product - I still need time to form a more nuanced opinion.&lt;/p&gt;

&lt;p&gt;One thing I will say though: the Sport is nice. It’s as nice and well built as the iPhone 6.&lt;/p&gt;

&lt;p&gt;Don’t feel like you need to buy the Steel version unless the &lt;em&gt;look and feel&lt;/em&gt; of the steel itself is what you’re interested in. Especially if fitness tracking is an attractor for you; the Ion-X glass on the Sport is &lt;strong&gt;more&lt;/strong&gt; resilient to impact than the Sapphire screen of the Steel and Gold versions (the glass scratches more easily, but who cares about scratches if you shatter the sapphire screen playing sports).&lt;/p&gt;
</description>
                <pubDate>Mon, 27 Apr 2015 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/shortest-apple-watch-review</link>
                <guid isPermaLink="true">http://www.jiaaro.com/shortest-apple-watch-review</guid>
            </item>
        
            <item>
                <title>Social Skills Education</title>
                <description>&lt;p&gt;In my post, “&lt;a href=&quot;http://www.jiaaro.com/Why-we-got-140-characters-instead-of-flying-cars/&quot;&gt;Why we got 140 characters instead of flying cars&lt;/a&gt;,” I made a throwaway comment about how enterprising individuals should focus on communication &lt;em&gt;skills&lt;/em&gt; instead of &lt;em&gt;delivery&lt;/em&gt;. My &lt;a href=&quot;http://www.bizvsdev.com&quot;&gt;podcast&lt;/a&gt; cohost &lt;a href=&quot;https://twitter.com/MikPozin&quot;&gt;Mik&lt;/a&gt;, was &lt;a href=&quot;http://mikhail.svbtle.com/140-character-vs-red-white-and-blue-space-jockeys&quot;&gt;disappointed&lt;/a&gt; that I was writing about economics and not communication. So today I’ll talk about the economics of education instead =P&lt;/p&gt;

&lt;p&gt;I’ll cut to the chase. Teaching communication skills is not a very good idea for a startup.&lt;/p&gt;

&lt;p&gt;This isn’t news. I said it in the last post too. Communication skills are valuable, but capturing that value is difficult. Education startups aren’t debuting to multi-billion dollar IPOs. Not &lt;a href=&quot;http://www.forbes.com/sites/michaelnoer/2012/11/02/one-man-one-computer-10-million-students-how-khan-academy-is-reinventing-education/&quot;&gt;Learn-to-code startups&lt;/a&gt;. Not Learn-to-write startups. Not learn-a-new-language startups. Not even learn-to-make-friends or learn-to-influence-people startups.&lt;/p&gt;

&lt;p&gt;People just don’t value education in that way. Universities have managed to jack up the price, but even &lt;em&gt;they&lt;/em&gt; focus on prestige, job prospects, facilities, and connections.&lt;/p&gt;

&lt;p&gt;Conspicuously absent: the stuff you will know when you graduate.&lt;/p&gt;

&lt;p&gt;In fact, those parts seem to be losing prominence as a larger trend in education. The focus is on opportunity, not knowledge.&lt;/p&gt;

&lt;p&gt;And selling knowledge is getting harder. The Internet is &lt;a href=&quot;http://www.meltingasphalt.com/personhood-a-game-for-two-or-more-players/&quot;&gt;socializing us&lt;/a&gt; to believe &lt;a href=&quot;http://en.wikipedia.org/wiki/Information_wants_to_be_free&quot;&gt;information should be free&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So… where does that leave you, the social entrepreneur?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Delivering&lt;/em&gt; communications – no matter how inane the content – at least has a business model: insert extra communications (ads) into your pipe in exchange for cash.&lt;/p&gt;

&lt;p&gt;I hate that business model, but c’est la vie.&lt;/p&gt;

&lt;p&gt;Some education startups have innovated in the business model department. &lt;a href=&quot;https://www.duolingo.com&quot;&gt;Duolingo&lt;/a&gt; teaches you a language, and when their students become advanced they translate documents for practice. They sell translation services.&lt;/p&gt;

&lt;p&gt;At first blush, you’d expect a high-value skill like computer programming to be something where you can sell education for a high price. If a professional programmer can earn $100k/year for the next 10 years – that’s a &lt;em&gt;million&lt;/em&gt; bucks! – surely you can charge $5k to teach someone that skill. After all, that’s only half a percent of the earnings.&lt;/p&gt;

&lt;p&gt;But that math only works if you assume that you’ll only want/need to learn one career skill. That you’ll like the first one you learn. That the skills will remain valuable for a long time. That’s not how people work.&lt;/p&gt;

&lt;p&gt;If you’ve never tried computer programming, you really have no idea what it’s like to be a programmer (take it from me). Would &lt;em&gt;you&lt;/em&gt; simultaneously choose a career you know nothing about &lt;em&gt;AND&lt;/em&gt; hand over $5k to someone whose expertise you are completely unable to evaluate? I wouldn’t. Even &lt;em&gt;without&lt;/em&gt; the risk of some asshole running off with my five grand.&lt;/p&gt;

&lt;p&gt;Could a learn-to-communicate startup work (be profitable)? Maybe. First they’d have to settle on an approach. Will they teach people to write? to speak? to unravel the mind of their audience?&lt;/p&gt;

&lt;p&gt;So far these sound like classical academic topics – literature, theater, psychology – and not exactly a bunch that are &lt;a href=&quot;http://fivethirtyeight.com/features/the-economic-guide-to-picking-a-college-major/&quot;&gt;associated with high-paying careers&lt;/a&gt; either.&lt;/p&gt;

&lt;p&gt;Much like technology, these things &lt;em&gt;can&lt;/em&gt; be tremendously valuable when used in conjunction with another skill. It almost doesn’t matter what that other skill is. But that makes the value proposition even &lt;em&gt;harder&lt;/em&gt; than the computer programmer one. “Want to learn a skill which will make you marginally more successful in whatever &lt;em&gt;other&lt;/em&gt; career path you choose? I’ll teach you, that’ll be five grand.”&lt;/p&gt;

&lt;p&gt;Now add the fact that people generally don’t think of themselves as poor communicators, and generally underestimate the benefits of good communication skills. How are you going to sell that?&lt;/p&gt;

&lt;p&gt;Back to the drawing board. Each education startup will have to find a purpose-made way to capture value (a la duolingo).&lt;/p&gt;

&lt;p&gt;And if they can’t? Screw it. Slap an ad on top and IPO.&lt;/p&gt;

</description>
                <pubDate>Mon, 03 Nov 2014 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/social-skills-and-education</link>
                <guid isPermaLink="true">http://www.jiaaro.com/social-skills-and-education</guid>
            </item>
        
            <item>
                <title>Hard problems and Sex appeal</title>
                <description>&lt;p&gt;My Biz vs Dev cohost, &lt;a href=&quot;http://mikhail.svbtle.com/140-character-vs-red-white-and-blue-space-jockeys&quot;&gt;Mik Pozin&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Yes, the problems that aren’t 140 characters are the really hard ones. But we now have to make &lt;em&gt;that&lt;/em&gt; be the sexy thing. We have to make solving hard problems sexy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hard problems &lt;em&gt;are&lt;/em&gt; sexy. Solving hard problems makes you a god damn super hero. My nascent interest in writing software was kickstarted by an intense curiosity to understand, “What is this sorcery and how does it work?”&lt;/p&gt;

&lt;p&gt;Google Search is sexy. The iPhone is Sexy. SpaceX Rockets are sexy.&lt;/p&gt;

&lt;p&gt;I want us to get there too, I think we’re in complete agreement on that. But saying that everyone is working on meaningless crap instead of solving real problems just isn’t true. There are a few people working on things like twitter, and a small cult of wannabe entrepreneurs following what &lt;em&gt;looks&lt;/em&gt; like easy money.&lt;/p&gt;

&lt;p&gt;But it’s not easy money. You can count the number of truely successful social networks on one hand. Social networks are an intensely hard problem themselves, but the hard part is the business model.&lt;/p&gt;

&lt;p&gt;Innovating on business models is an underappreciated art. Business models are the difference between Android and iOS. Farmville and Minecraft. Gillette and Harrys.&lt;/p&gt;

&lt;p&gt;Nobody is going to Mars until there’s a business model. And it’ll need to be a new one; I don’t think &lt;a href=&quot;http://en.wikipedia.org/wiki/Indentured_servant&quot;&gt;indentured servitude&lt;/a&gt; is going to cut it this time.&lt;/p&gt;
</description>
                <pubDate>Thu, 02 Oct 2014 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/hard-problems-and-sex-appeal</link>
                <guid isPermaLink="true">http://www.jiaaro.com/hard-problems-and-sex-appeal</guid>
            </item>
        
            <item>
                <title>Mailbox for Mac</title>
                <description>
&lt;hr /&gt;

&lt;p&gt;I tried Mailbox for mac recently.&lt;/p&gt;

&lt;p&gt;It’s nice. Excellent design.&lt;/p&gt;

&lt;p&gt;I was surprised to find that I had a slight, subconscious distrust of dropbox. When I found out the app was made by dropbox I briefly reconsidered whether to even try it. I’m glad I did. I owe &lt;a href=&quot;https://twitter.com/PCrysdale&quot;&gt;Peter Crysdale&lt;/a&gt; for the beta invite (and for &lt;a href=&quot;http://www.bizvsdev.com/Ep24/&quot;&gt;coming on my podcast&lt;/a&gt;!)&lt;/p&gt;

&lt;p&gt;I’ve been a long-time user of Gmail + Mail.app, which… aren’t the best integrated pair of apps. In fact, I’ve tried a &lt;em&gt;lot&lt;/em&gt; of different email setups. Juno, AOL, vanilla POP3 and IMAP with Outlook, Thunderbird, then back to Outlook, then terrible web-based email (squirrel I think) provided with web hosting. Finally ending up with 2 Gmail accounts and iCloud account.&lt;/p&gt;

&lt;p&gt;Being able to send email using the appropriate address is important, it’s not super professional to have people emailing my business address and getting a reply from my personal Gmail account. Doing everything through the Gmail web interface is a bit of a non-starter. I’m not going to switch between 2 Gmail accounts all day. It’s a pain, and it means I don’t see new stuff for a lot longer if I forget to check each one. Every time.&lt;/p&gt;

&lt;p&gt;I also just don’t like the new Gmail interface. Leaving me with one option: a third-party mail client.&lt;/p&gt;

&lt;p&gt;Mail.app served me well for a long time, but it’s never been a great companion to Gmail. The way Gmail does email simply doesn’t fit the IMAP mold very well. That impedance mismatch has been the cause of much unpleasantness. Mail I meant to archive ended up in the trash (and was deleted). Searching my archive has really only ever worked from the Gmail web interface. I’m still not sure what happens when I flag something as spam in Mail.app – does Gmail get the memo, or not?&lt;/p&gt;

&lt;p&gt;Don’t get me started about filters and rules - that all has to live on the Gmail server, and I have a set of rules for each Gmail account. And the iCloud account? Well I’ve just stopped giving out that address due to useless search, lack of filters, and having to use an “@icloud.com” address. Luckily I don’t get much email that way.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&quot;https://en.wikipedia.org/wiki/Mailbox_(application)&quot;&gt;Mailbox&lt;/a&gt;…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/mailbox-for-mac.png&quot; alt=&quot;Mailbox for Mac&quot; class=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Hooks into all three email accounts (supports Gmail and iCloud)&lt;/li&gt;
  &lt;li&gt;Clear, understandable interface (and bonus: beautiful)&lt;/li&gt;
  &lt;li&gt;Supports keyboard-only workflows&lt;/li&gt;
  &lt;li&gt;First-class support for archive/delete/mark-as-spam&lt;/li&gt;
  &lt;li&gt;Free download for Mac, iPhone, iPad, and Android&lt;/li&gt;
  &lt;li&gt;Lists that are actually useful&lt;/li&gt;
  &lt;li&gt;“Snooze”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, I haven’t had an empty inbox in years. Those last 2 are a much bigger deal than you’d first think.&lt;/p&gt;

&lt;p&gt;Gmail “tags” are weird. Many of them are hidden in the web UI, and using tags as an organizational tool is clunky. So I’ve more or less settled on starring everything important and leaving anything that still requires action in my inbox.&lt;/p&gt;

&lt;p&gt;Now I have 5 main lists where I put things I would have starred:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Photos” (family pictures, etc)&lt;/li&gt;
  &lt;li&gt;“Tax” (liberally - anything related to finances really)&lt;/li&gt;
  &lt;li&gt;“receipts”&lt;/li&gt;
  &lt;li&gt;“travel” (itineraries, reservations, tickets, etc)&lt;/li&gt;
  &lt;li&gt;[Work] - Ok I cheated this last one is actually one additional list for each work project where I put business related email chains I may need to reference in the future.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now I keep my inbox nearly empty. The [Work] lists are my todo list. Anything I want to spend more time on, but not right now gets “snoozed.”&lt;/p&gt;

&lt;p&gt;Snooze works just like your alarm clock. Makes the message go away for a little while, then return to the top of your inbox. How long can be “later” (3 hours), “tonight” (6 pm), tomorrow, this weekend, next week, among other options. Almost all of them are configurable. Snooze is simple. Snooze is great. Snooze is why my inbox is now empty.&lt;/p&gt;

&lt;p&gt;I’m was surprised that Mailbox is a Dropbox product. I’m concerned about their motivation; how do they make money on this? They’ve made versions for iPhone, iPad, Mac, and Android, which is an impressive level of dedication. But is automatic dropbox integration for attachments enough to keep this going?&lt;/p&gt;

&lt;p&gt;Still, I think I’ll keep it. For now.&lt;/p&gt;
</description>
                <pubDate>Thu, 28 Aug 2014 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/Mailbox-for-mac</link>
                <guid isPermaLink="true">http://www.jiaaro.com/Mailbox-for-mac</guid>
            </item>
        
            <item>
                <title>Why We Got 140 Characters Instead Of Flying Cars</title>
                <description>&lt;p&gt;For entrepreneurs aiming to solve humanity’s communication problems, here’s some free advice: give people communication &lt;em&gt;skills&lt;/em&gt;, not another way to distribute their half-baked thoughts. We’ve got plenty of ways to send text around the internet. But communication skills – they haven’t improved much since the proliferation of the internet (if at all).&lt;/p&gt;

&lt;p&gt;The problem is that it’s not easy to monetize someone else’s communication skills (who will fund you?). Aside, of course, from hiring them to solve some pressing communication problem. But we can’t &lt;em&gt;all&lt;/em&gt; work in PR.&lt;/p&gt;

&lt;p&gt;It’s easy to see how we got 140 characters. Advertising. But where are our flying cars? You can barely spend 10 minutes reading or talking about startups and technology without a reference to &lt;a href=&quot;http://www.foundersfund.com/the-future&quot;&gt;how we &lt;em&gt;still&lt;/em&gt; don’t have flying cars&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We wanted flying cars, instead we got 140 characters&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I appreciate the sentiment, but the problems we really need to solve to get flying cars are economic ones. Flight uses a lot of energy. Energy is expensive. The real obstacle is the cost of flying cars – we’ve already figured out air travel – it just costs too much to be practical for day-to-day use.&lt;/p&gt;

&lt;p&gt;I have a hard time imagining the founders of twitter thinking to themselves, “Let me go work in BP’s research division so we can eventually have flying cars.” But that’s the reality of it. That or find a way to break the laws of physics, but the prospects aren’t looking good for that. There’s a Nobel Prize waiting for you if you succeed on that front though.&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;Let’s focus on the hard problems&lt;/em&gt;.” Yes, let’s! But let’s also be honest with ourselves: the hard problems we need to solve are in energy, agriculture, and biology. And hey! What do you know‽ We, as a global society, are spending a &lt;em&gt;lot&lt;/em&gt; of resources in those areas. The problems are just &lt;em&gt;really&lt;/em&gt; hard.&lt;/p&gt;

&lt;p&gt;I don’t mean to say everything is fine or that there aren’t other things to improve  (as a species, I disdain nationalism), but I think the problem is overstated.&lt;/p&gt;

&lt;p&gt;It’s great that &lt;a href=&quot;http://spaceindustrynews.com/elon-musk-and-spacex-to-send-humans-to-mars/&quot;&gt;SpaceX is trying to get us on Mars&lt;/a&gt;, but again, a huge factor in why there isn’t much investment in that area is cost. Before any number of people are going to go off and colonize mars, we need to reduce the cost to a level that is affordable at scale.&lt;/p&gt;

&lt;p&gt;Musk understands this well:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Elon states that he wants to make a trip to the Red Planet affordable for an average American Family. Affordable, he later said,  is “no more than half a million dollars”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because as long as it costs millions (billions?) of dollars – which we could otherwise  spend &lt;strong&gt;saving lives here on earth&lt;/strong&gt; – a mission to colonize Mars is going to be unpalatable. Same for those fancy flying machines you’re yearning for.&lt;/p&gt;

</description>
                <pubDate>Fri, 09 May 2014 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/Why-we-got-140-characters-instead-of-flying-cars</link>
                <guid isPermaLink="true">http://www.jiaaro.com/Why-we-got-140-characters-instead-of-flying-cars</guid>
            </item>
        
            <item>
                <title>Safari Web Content using all my CPU and RAM</title>
                <description>&lt;p&gt;This post is a bit of a departure from my normal style, but it took me hours of searching to finally nail this down and resolve the issue.&lt;/p&gt;

&lt;p&gt;I’m using OS X 10.9.1 on a Mid-2010 MacBook Pro, Safari is version 7.0.1.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2014-01-16-activity-monitor.png&quot; class=&quot;screenshot&quot; alt=&quot;Activity Monitor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt;: I’ve also experieced this issue now on OS X 10.8.5 on a Mid-2010 iMac, in Safari 6.1 (Pretty much the same version of Safari)&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;At some point a few days ago I noticed that my CPU fan was blasting for what seemed like no reason at all. So I did what any rational person would do. I opened Activity Monitor.&lt;/p&gt;

&lt;p&gt;Safari Web Content was using 100% CPU over 1GB of RAM and was “Not Responding”.&lt;/p&gt;

&lt;p&gt;I tried killing the little bugger, but to no avail. Every time I  went back to using Safari the problem resurfaced.&lt;/p&gt;

&lt;p&gt;I found a very helpful, but unfortunately also very long &lt;a href=&quot;https://discussions.apple.com/thread/3190569&quot;&gt;thread on Apple’s Support Community&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Turns out this is a side effect of things going badly with Top Sites.&lt;/p&gt;

&lt;h2 id=&quot;solutions&quot;&gt;Solutions&lt;/h2&gt;

&lt;p&gt;You can disable Top Sites all together:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Go to “Safari” &amp;gt; “Preferences” &amp;gt; “General” and change new windows and new tabs to open with a blank page (or anything besides Top Sites)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Try to figure out which of your top sites is causing the issue. I suspect that if there is one with no preview (having the black background with a grey safari icon overlaid instead) it is probably the culprit, but I can’t verify that. &lt;strong&gt;[update]&lt;/strong&gt;: I have confirmed this to be the case.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/img/2014-01-16-Top-Sites.png&quot; alt=&quot;Safari Top Sites&quot; class=&quot;screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Another theory I have about which sites to remove from Top Sites is ones that use a lot of JavaScript or Flash.&lt;/p&gt;

&lt;p&gt;Safari has to run and render all code in the website in order to generate the preview. The more code it has to run, the more potential for problems.&lt;/p&gt;

&lt;p&gt;Anyway hope this helps some poor person with this problem :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;edit:&lt;/strong&gt; I’ve just discovered that if you hover over the “Safari Web Content” item in Activity Monitor, the hover text will show the url of the page being rendered!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;edit 2:&lt;/strong&gt; The trick mentioned in the previous edit is nice, but doesn’t work on the Safari Web Content process that hangs, only the ones spawned for browser tabs. Doh!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;edit 3:&lt;/strong&gt; OSX 10.10 Yosemite has &lt;a href=&quot;http://arstechnica.com/apple/2014/10/os-x-10-10/24/&quot;&gt;greatly improved Activity Monitor’s reporting&lt;/a&gt; of Safari processes&lt;/p&gt;
</description>
                <pubDate>Thu, 16 Jan 2014 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/safari-web-content-cpu-ram</link>
                <guid isPermaLink="true">http://www.jiaaro.com/safari-web-content-cpu-ram</guid>
            </item>
        
            <item>
                <title>Machine Learning for Humans: K Nearest-Neighbor</title>
                <description>&lt;p&gt;&lt;a href=&quot;http://amzn.to/16UaKU2&quot;&gt;&lt;img src=&quot;/img/MLIA.jpg&quot; alt=&quot;Machine Learning in Action - cover&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve been reading Peter Harrington’s “&lt;em&gt;&lt;a href=&quot;http://amzn.to/16UaKU2&quot;&gt;Machine Learning in Action&lt;/a&gt;&lt;/em&gt;,” and it’s packed with useful stuff! However, while providing a large number of ML (machine learning) algorithms and sufficient example code to learn how they work, the book is a bit dry.&lt;/p&gt;

&lt;p&gt;So I’ve decided to make my contribution to democratizing ML by posting simple explanations of these algorithms.&lt;/p&gt;

&lt;h2 id=&quot;why-python&quot;&gt;Why Python?&lt;/h2&gt;

&lt;p&gt;Pure Python isn’t the most (computationally) efficient way to implement these algorithms, but that isn’t the purpose here. The goal is to help &lt;em&gt;humans&lt;/em&gt; understand how these algorithms work. Python is great for that. That’s why the book uses Python as well.&lt;/p&gt;

&lt;p&gt;But Harrington takes the alternate route of using the (very powerful) numpy from the get-go, which is more performant, but much less clear, at the expense of the reader.&lt;/p&gt;

&lt;p&gt;Well that’s crap; let’s start learning!&lt;/p&gt;

&lt;h2 id=&quot;what-is-knn-k-nearest-neighbor-good-for&quot;&gt;What is KNN (K nearest neighbor) good for?&lt;/h2&gt;

&lt;p&gt;This is a good question to answer up front. Why are we doing this in the first place?&lt;/p&gt;

&lt;p&gt;KNN is a “classifier”, which is a type of algorithm that (you guessed it) classifies things.&lt;/p&gt;

&lt;p&gt;Let’s put it in more concrete terms: We want to teach the computer to answer the question, “&lt;strong&gt;What kind of fruit is this?&lt;/strong&gt;”&lt;/p&gt;

&lt;p&gt;You’re the owner of an orchard, and you’re tired of paying workers to sort your fruits on the assembly line. The job is boring, the workers hate it, and you already measure the weight and color of every fruit on the line anyway. It should be simple enough to have a machine do it.&lt;/p&gt;

&lt;p&gt;You have a set of already classified (categorized, tagged, etc)  information - and you want to automatically figure out where new data (fruits) fits into your classification automatically. i.e., Is it an Apple or a Banana?&lt;/p&gt;

&lt;p&gt;Here’s some fruit the workers logged before they got shit-canned:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     --------------------------------------------
    |  weight (g)  |   color  ||  Type of fruit  |
    |==============|==========||=================|
    |  303         |  3       ||  Banana         |
    |  370         |  1       ||  Apple          |
    |  298         |  3       ||  Banana         |
    |  277         |  3       ||  Banana         |
    |  377         |  4       ||  Apple          |
    |  299         |  3       ||  Banana         |
    |  382         |  1       ||  Apple          |
    |  374         |  4       ||  Apple          |
    |  303         |  4       ||  Banana         |
    |  309         |  3       ||  Banana         |
    |  359         |  1       ||  Apple          |
    |  366         |  1       ||  Apple          |
    |  311         |  3       ||  Banana         |
    |  302         |  3       ||  Banana         |
    |  373         |  4       ||  Apple          |
    |  305         |  3       ||  Banana         |
    |  371         |  3       ||  Apple          |
     --------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice they assigned numbers to the colors, that’s useful because we need to do math with these values (numbering non-numerical stuff is known as &lt;a href=&quot;http://en.wiktionary.org/wiki/discretization&quot;&gt;discretizing&lt;/a&gt;). The colors are in order of the color wheel, so similar colors &lt;em&gt;are&lt;/em&gt; closer together than less similar colors.&lt;/p&gt;

&lt;p&gt;Here’s the color key from the foreman’s clipboard:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;          red         1
          orange      2
          yellow      3
          green       4
          blue        5
          purple      6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So our data set has some apples which are red, green, and yellow, and a bunch of bananas which are all yellow except one that is green.&lt;/p&gt;

&lt;p&gt;It’s 9 AM.&lt;/p&gt;

&lt;p&gt;A loud bell rings.&lt;/p&gt;

&lt;p&gt;The conveyor belt starts turning, and fruit starts flowing in from outside.&lt;/p&gt;

&lt;p&gt;But the factory is empty. All our factory workers are home learning to maintain fruit classifying robots and re-reading the &lt;a href=&quot;http://www.marxists.org/archive/marx/works/1867-c1/ch32.htm&quot;&gt;primitive accumulation of wealth&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;…and the first fruit rolls onto the classification machine.&lt;/p&gt;

&lt;p&gt;What is this thing?&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    Weight:  373g
    color:   1 (red)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We better write some software to handle that fruit before it rots!&lt;/p&gt;

&lt;p&gt;How do we decide whether this unknown fruit is an apple or banana?&lt;/p&gt;

&lt;p&gt;The K-nearest-neighbor approach is to calculate the distance between our unknown fruit and each of the known fruits and assume the “k” closest fruits are probably the same type of fruit.&lt;/p&gt;

&lt;p&gt;Sort of like graphing all the fruits and drawing a circle around the “?”. Whatever is closest to it is probably the same kind of fruit.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                   Graph of Fruits
             |
             |            
         380 |   AA      AA       
    weight   |   A?      A  A
         330 |       A    B B
             |           BB BB     
         280 |            
             |__________________________
                 1   2   3   4   5   6              
                        color

        note: the question mark is the “unknown fruit”
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;math-is-delicious&quot;&gt;Math is delicious&lt;/h2&gt;

&lt;p&gt;Before we can start with the KNN algorithm, we need to do a little math review. Remember good old pythagorus? a² + b² = c² right? If you’re comfortable with this, just &lt;a href=&quot;#ok_back_to_knn&quot;&gt;skip to the next section&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you don’t remember: this is the formula for calculating the hypotenous (see: the diagonal side) of a right triangle.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;         J
        | \
        |  \    
     7  |   \   ⟵  this side == (5**2 + 7**2) **0.5
        |    \   
         -----
           5    K
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You could also say “longitude” instead of “height”, “latitude” instead of “width” and say you’re calculating the “distance“ from point “J“ to point “K”.&lt;/p&gt;

&lt;p&gt;That part is crucial.&lt;/p&gt;

&lt;p&gt;Well the real world isn’t 2D, it’d 3D, but I have great news! You can do this in 3D too. So now we can calculate distances in a 3D space the same way:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;or…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;aside: raising something to the .5 power (i.e., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;**0.5&lt;/code&gt;) is the same as taking the square root.&lt;/p&gt;

&lt;p&gt;With KNN you can actually have as many dimensions as you want, but to keep it simple, we’ll just use 2.&lt;/p&gt;

&lt;h2 id=&quot;ok-back-to-knn&quot;&gt;OK, back to KNN&lt;/h2&gt;

&lt;p&gt;So this is what a function would look like that tells us the distance from our unknown fruit to one of the known fruits in our dataset&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    The args are iterables of the values in the table. 
    for example the args should look something like this:
    
    #         weight,  color
    fruit1 = [303,     3]  # Banana from the data set
    fruit2 = [373,     1]  # the unclassified fruit
    &quot;&quot;&quot;&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# first let's get the distance of each parameter
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# the distance from point A (fruit1) to point B (fruit2)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here is the python representations of the stuff we’ve discussed so far:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# the unknown fruit from above
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unknown_fruit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;373&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This is arbitrarily chosen for this example. Generally
# you need to play with this magic number to find what works
# best for your case.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# here's the dataset as a python list…
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# weight, color, type
&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;370&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;298&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;277&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;377&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;299&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;382&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;374&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;309&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;359&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;366&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;311&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;302&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;373&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;305&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;371&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;…and with that being said, let’s sort the dataset using this function…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# using the distance() function from above, sort
# the data set by smallest distances on top
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sorted_dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unknown_fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here is the table of distances from our unknown fruit to the known fruits in the data set.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        --------------------------------------------
       |  weight (g)  |   color  ||  Type of fruit  |  distance
       |==============|==========||=================|
       |  371         |  3       ||  Apple          |   2.8
       |  370         |  1       ||  Apple          |   3.0
       |  373         |  4       ||  Apple          |   3.0
        \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/  
       
       |  374         |  4       ||  Apple          |   3.2
       |  377         |  4       ||  Apple          |   5.0
       |  366         |  1       ||  Apple          |   7.0
       |  382         |  1       ||  Apple          |   9.0
       |  359         |  1       ||  Apple          |  14.0
       |  311         |  3       ||  Banana         |  62.0
       |  309         |  3       ||  Banana         |  64.0
       |  305         |  3       ||  Banana         |  68.0
       |  303         |  3       ||  Banana         |  70.0
       |  303         |  4       ||  Banana         |  70.1
       |  302         |  3       ||  Banana         |  71.0
       |  299         |  3       ||  Banana         |  74.0
       |  298         |  3       ||  Banana         |  75.0
       |  277         |  3       ||  Banana         |  96.0
        --------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, which classification the unknown fruit belongs to is determined by taking a vote of the “k“ nearest neighbors – so if “k“ is 3, then we take the top 3 fruits by distance and select whichever is most common.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# from the python std library
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# take only the first K items
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;top_k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sorted_dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;class_counts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fruit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top_k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# class_counts now looks like this:
# {&quot;apple&quot;: 3}
&lt;/span&gt;   
&lt;span class=&quot;c1&quot;&gt;# get the class with the most votes
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classification&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;class_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# There you have it!
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classification&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this case we see that the top 3 are all “Apple“ so we conclude this unknown fruit must be an apple.&lt;/p&gt;

&lt;p&gt;You can expand this to more more than two features though. You can actually use that distance formula from earlier with as many dimensions as you want.&lt;/p&gt;

&lt;p&gt;Let’s try it with 4:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So if we’d done this using more characteristics of the fruits than just weight and color (like number of seeds in the fruit for instance), the distance calculation (we have 3 factors now) would have just been:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    
&lt;span class=&quot;c1&quot;&gt;#         weight, color, seeds
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Banana from the data set
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;297&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# unknown (but it's an apple)
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fruit2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;distance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;blockquote&gt;
  &lt;p&gt;You: &lt;strong&gt;This is repetitive&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;True. This code is designed to make it easy to understand… in real life, you should use numpy (or similar) for performance reasons anyway (ML is very computationally expensive).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You: &lt;strong&gt;What if one factor is more important than the others?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s a really good point. Maybe the number of seeds is &lt;strong&gt;much&lt;/strong&gt; more important than the color of the fruit (&lt;a href=&quot;http://www.mainstreettrees.com/apples/&quot;&gt;it is&lt;/a&gt;), but color is still an important differentiator among fruits with the same number of seeds?&lt;/p&gt;

&lt;h2 id=&quot;neutralizing-the-effects-of-different-units&quot;&gt;Neutralizing the effects of different units&lt;/h2&gt;

&lt;p&gt;Right now your weight values are much bigger than our color ones, which we’ve discretized to single digit numbers.&lt;/p&gt;

&lt;p&gt;That means weight is causing much bigger changes in distance between fruits than color is.&lt;/p&gt;

&lt;p&gt;What are we going to do about that?&lt;/p&gt;

&lt;p&gt;Well, what if we measure all our inputs on a scale of 0 - 1.0?&lt;/p&gt;

&lt;h2 id=&quot;thats-normalization-kyle&quot;&gt;That’s Normalization Kyle!&lt;/h2&gt;

&lt;p&gt;In short, we’re going to take the &lt;em&gt;biggest value in the dataset&lt;/em&gt; and the &lt;em&gt;smallest value in the dataset&lt;/em&gt; and put all the other numbers on a scale of 0.0 - 1.0 from smallest to biggest.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Biggest fruit:   382g
Smallest fruit:  277g
range = 382-277 = 105
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;normalize_weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# convert the units to a float so python's wonky
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# division doesn't break anything later on
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# first subtract 277 (the smallest weight)
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# so that the smallest fruit becomes 0.0
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;277&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# now the biggest fruit is 105 (382-277), but
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# we want the biggest fruit to become 1.0 so 
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# let's divide!
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;105&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Obviously you wouldn’t hard-code those numbers (largest/smallest weight) in real life. Again, just for clarity.&lt;/p&gt;

&lt;p&gt;You can do the same approach with the colors, number of seeds, etc.&lt;/p&gt;

&lt;p&gt;If you’re going to normalize your dataset, you have to normalize &lt;em&gt;all the columns&lt;/em&gt;. Otherwise you’re not doing what you think you are.&lt;/p&gt;

&lt;h3 id=&quot;wait-but-i-thought-we-mainly-cared-about-seeds&quot;&gt;Wait, but I thought we mainly cared about seeds?&lt;/h3&gt;

&lt;p&gt;Right. So once you’ve done this, let’s say you want number of seeds to be twice as important as weight and color to be half as important as weight.&lt;/p&gt;

&lt;p&gt;You’d just multiply the “number of seeds“ value for every fruit in your dataset by 2.0, and multiply the “color“ value of every fruit in your dataset by 0.5. Try calculating the weights now.&lt;/p&gt;

&lt;p&gt;These are magic numbers that (like the K value) need to be tested and tweaked to see what will work best for you.&lt;/p&gt;

&lt;h2 id=&quot;homework&quot;&gt;HOMEWORK:&lt;/h2&gt;

&lt;p&gt;I’m going to leave it as an exercise to the reader to apply these ideas (dataset follows):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Write a distance function that will accept 3 columns of data instead of 2&lt;/li&gt;
  &lt;li&gt;Normalize the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Color&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Weight&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;# of Seeds&lt;/code&gt; columns of the dataset&lt;/li&gt;
  &lt;li&gt;Apply weights to the columns:
    &lt;ul&gt;
      &lt;li&gt;Color is least important: give it a weight of 0.5&lt;/li&gt;
      &lt;li&gt;Weight is a good differentiator: give it a weight of 1.0&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;# of Seeds&lt;/code&gt; is most important: give it a weight of 2.0&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Classify these 3 unknown fruits (UFs) using your classifier&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;UF1: [color: green, weight: 301g, seeds: 1]&lt;/li&gt;
      &lt;li&gt;UF2: [color: yellow, weight: 346g, seeds: 4]&lt;/li&gt;
      &lt;li&gt;UF3: [color: red, weight: 290g, seeds: 2]&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;dataset:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     -------------------------------------------------------
    |  weight (g)  |  color  |  # seeds  ||  Type of fruit  |
    |==============|=========|===========||=================|
    |  303         |  3      |  1        ||  Banana         |
    |  370         |  1      |  2        ||  Apple          |
    |  298         |  3      |  1        ||  Banana         |
    |  277         |  3      |  1        ||  Banana         |
    |  377         |  4      |  2        ||  Apple          |
    |  299         |  3      |  1        ||  Banana         |
    |  382         |  1      |  2        ||  Apple          |
    |  374         |  4      |  6        ||  Apple          |
    |  303         |  4      |  1        ||  Banana         |
    |  309         |  3      |  1        ||  Banana         |
    |  359         |  1      |  2        ||  Apple          |
    |  366         |  1      |  4        ||  Apple          |
    |  311         |  3      |  1        ||  Banana         |
    |  302         |  3      |  1        ||  Banana         |
    |  373         |  4      |  4        ||  Apple          |
    |  305         |  3      |  1        ||  Banana         |
    |  371         |  3      |  6        ||  Apple          |
     -------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;as python:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# weight, color, # seeds, type
&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;370&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;298&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;277&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;377&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;299&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;382&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;374&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;303&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;309&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;359&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;366&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;311&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;302&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;373&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;305&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;banana&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;371&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After you’ve classified the 3 Unknown Fruits, consider which columns you could remove without losing any accuracy. It’s often the case that simpler classifiers are better, and the facets of your data may not be as related as you originally thought!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is my first crack at this type of tutorial, so please give me feedback, and/or corrections! (email: &lt;a href=&quot;mailto:blog@jiaaro.com&quot;&gt;blog@jiaaro.com&lt;/a&gt; )&lt;/p&gt;

</description>
                <pubDate>Mon, 25 Mar 2013 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/KNN-for-humans</link>
                <guid isPermaLink="true">http://www.jiaaro.com/KNN-for-humans</guid>
            </item>
        
            <item>
                <title>The myth of pervasive Internet &amp; why “offline mode” is the best free marketing you could ask for</title>
                <description>&lt;p&gt;I'm sitting on a train, making my 45 minute, 3 mile commute.&lt;/p&gt;

&lt;p&gt;And by train, I mean: tiny aluminum can filled to capacity with iPhones and their owners.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://thechive.com/2010/12/07/subway-sardines-why-dont-asians-value-personal-space/&quot; rel=&quot;nofollow&quot;&gt;&lt;img src=&quot;http://thechive.files.wordpress.com/2010/12/a-tokyo-subway-sardines-10.jpg?w=500&amp;amp;h=357&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The alarming speed and sheer mass of concrete above our heads isn't getting any attention from these nerds.&lt;/p&gt;

&lt;p&gt;Because they're too busy looking at iPhones.&lt;/p&gt;

&lt;p&gt;But wait a minute &amp;ndash; not their own iPhones. A lot of them are looking at somebody else's. In fact, I'd say in a given subway ride at least half of them will glance at their neighbor's display. You know you've done it. Moving, flashing lights are hard to ignore.&lt;/p&gt;

&lt;p&gt;Eavesdropping. &lt;em&gt;iVesdropping&lt;/em&gt;? Heh. I love a good pun.&lt;/p&gt;

&lt;p&gt;Let's talk about &lt;strong&gt;pervasive Internet&lt;/strong&gt;. That idea mobile developers keep spouting about how we have Internet access &quot;everywhere&quot; thanks to our iThings. What shit.&lt;/p&gt;

&lt;p&gt;I spend an 90 minutes a day using an iPhone with no Internet. That's very possibly &lt;em&gt;the majority&lt;/em&gt; of my phone usage. 5 days a week.&lt;/p&gt;

&lt;p&gt;And I'm not the only one.&lt;/p&gt;

&lt;p&gt;Most of the iVesdropping I see is people watching somebody else play a game.&lt;/p&gt;

&lt;p&gt;I think it's because games are immersive and the device owner is least likely to look up and trigger that awkward moment where you both realize just how long you've been snooping.&lt;/p&gt;

&lt;p&gt;Speculations aside, this is not going away. And I know I've searched the App Store on more than one occasion for an app I saw in that sardine can.&lt;/p&gt;

&lt;p&gt;Guess which apps I never see down there. Words with friends, song pop, facebook, twitter, buffer.&lt;/p&gt;

&lt;p&gt;All those social ones that &lt;em&gt;demand&lt;/em&gt; network access.&lt;/p&gt;

&lt;p&gt;But Mail works, so does Podcasts, and Reeder, and letterpress (sort of).&lt;/p&gt;

&lt;p&gt;And I know that not everyone lives in the city. But cities are cultural centers. Getting big in New York or San-fran can catapult an app into the charts, and the visibility of being in the charts can make or break your sales numbers.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;Dear app developers, I'm begging you. Please make your apps work offline. At the very least make sure they don't&amp;nbsp;&lt;strong&gt;&lt;em&gt;crash&lt;/em&gt;&lt;/strong&gt;&amp;nbsp;when you launch them without internet (I'm looking at you zynga).&lt;/p&gt;

&lt;p&gt;It's in your best interest.&lt;/p&gt;
</description>
                <pubDate>Wed, 12 Dec 2012 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/the-myth-of-pervasive-internet-and-why-offlin</link>
                <guid isPermaLink="true">http://www.jiaaro.com/the-myth-of-pervasive-internet-and-why-offlin</guid>
            </item>
        
            <item>
                <title>The Good Idea Lottery</title>
                <description>&lt;p&gt;Have you ever tried to sit down and come up with a good idea?&lt;/p&gt;
&lt;p&gt;It's really hard.&lt;/p&gt;
&lt;p&gt;After long, painful hours you still have a blank sheet of paper. Not a single good idea written down. Sound familiar?&lt;/p&gt;
&lt;p&gt;I think we've all been there. If you've ever been a student you know exactly what I mean.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://esploded.s3.amazonaws.com/anon_data/2012/KlUh-mftAtWs.jpg&quot; alt=&quot;Blank notepad&quot; width=&quot;222&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The craziest part is that during those excruciatingly long minutes, you probably weren't even thinking of ideas the whole time. An idea comes into your mind, you consider it, decide it's not &lt;em&gt;the one&lt;/em&gt; and then you try to think of something else.&lt;/p&gt;
&lt;p&gt;But then you get distracted.&lt;/p&gt;
&lt;p&gt;You'd be appalled how much time distractions take out of the process when you do &amp;ldquo;brainstorming&amp;rdquo; this way.&lt;/p&gt;
&lt;p&gt;I've been in this situation many, &lt;em&gt;many&lt;/em&gt; times, and I finally realized something that totally changed the way I approach creative thinking:&lt;/p&gt;
&lt;blockquote class=&quot;posterous_short_quote&quot;&gt;
&lt;p&gt;Coming up with 1 good idea is actually &lt;strong&gt;harder&lt;/strong&gt; than coming up with 10 good ideas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It sounds crazy, but I'm about to convince you it's true ;)&lt;/p&gt;
&lt;h2&gt;Being prolific when you're brainstorming is &lt;em&gt;absolutely key&lt;/em&gt; to finding good ideas.&lt;/h2&gt;
&lt;p&gt;In part, because as humans, we're not very good at focusing our thoughts when the rest of our body is idle. But also because we're notoriously bad at identifying &lt;strong&gt;which ideas are &lt;em&gt;good&lt;/em&gt;&lt;/strong&gt;, and which ones aren't.&lt;/p&gt;
&lt;p&gt;The trick is to accept failure from the start.&lt;/p&gt;
&lt;p&gt;Most of your ideas will suck, but that's fine. Just write them all down. Every. Single. Stinking. Idea.&lt;/p&gt;
&lt;p&gt;Don't stop until you have at least 15 (and hopefully 30, 50, or 100). Every idea you write down is a ticket in the Good-Idea Lottery.&lt;/p&gt;
&lt;p&gt;Obviously this exercise leaves you with a list of dozens of ideas which you now have to vet, but (and here's a third reason to do it my way):&lt;/p&gt;
&lt;blockquote class=&quot;posterous_short_quote&quot;&gt;
&lt;p&gt;Vetting ideas and coming up with ideas are different frames of mind.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When you're coming up with ideas you want to be open minded, creative, and optimistic. When you're vetting ideas you want to be analytical, realistic, and tactical. Trying to do both is hard &amp;ndash; yet another fault of our species &amp;ndash; &lt;a href=&quot;http://blog.bufferapp.com/what-multitasking-does-to-our-brains&quot; title=&quot;http://blog.bufferapp.com/what-multitasking-does-to-our-brains&quot;&gt;we suck at multi-tasking&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So how do you vet all these ideas?&lt;/p&gt;
&lt;p&gt;Well, I thought about this for a while and the answer is really: &quot;it depends&quot; as it always seems to be (nod to &lt;a href=&quot;http://www.startupsfortherestofus.com&quot; title=&quot;http://www.startupsfortherestofus.com&quot;&gt;startups for the rest of us&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;But in most cases (all?) you are well served by soliciting opinions from others.&lt;/p&gt;
&lt;p&gt;So do that.&lt;/p&gt;
&lt;p&gt;If it's artwork, show it to people with good taste.&lt;/p&gt;
&lt;p&gt;If it's a business idea, show it to some would-be customers.&lt;/p&gt;
&lt;p&gt;If it's a blog post&amp;hellip; well if it's a blog post quit loafing and just post it ;) Your loyal readers are step 1 in vetting the content. When something seems to resonate with them, &lt;a href=&quot;http://hive.rootbuzz.com/12y-the-secret-to-social-marketing-rocket-fuel&quot; title=&quot;http://hive.rootbuzz.com/12y-the-secret-to-social-marketing-rocket-fuel&quot;&gt;*that's* when you go all-out and try to promote it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I started doing this sort of thing a lot.&lt;/p&gt;
&lt;p&gt;At first I was just keeping hand written lists of people's feedback. Then it was excel spreadsheets.&lt;/p&gt;
&lt;p&gt;Business ideas, marketing plans, songs, resume designs&amp;hellip; all kinds of stuff.&lt;/p&gt;
&lt;p&gt;I was really just collecting anecdotes &amp;ndash; I'd ask 3 people here, 5 people there &amp;ndash; sometimes that's good enough. It's certainly a good place to start.&lt;/p&gt;
&lt;p&gt;As I continued my education I learned about statistical significance, and other fun things and the urge to make these decisions based on (more) data resurged.&lt;/p&gt;
&lt;p&gt;I was an economics student, and a closet hacker.&lt;/p&gt;
&lt;p&gt;There are a lot of ways to gather data, but I didn't use any of them. I did want any na&amp;iuml;ve hacker would: &lt;strong&gt;I built myself a tool that took all these unwashed ideas and ranked them&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And I called it the Whicher. (this may sound familiar if you follow me on twitter, facebook, etc).&lt;/p&gt;
&lt;p&gt;Essentially, you put in a question, and 20 images and it shows people 2 at a time until they've gone through all of them.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.thewhicher.com/&quot;&gt;&lt;img src=&quot;https://whicher.s3.amazonaws.com/img/hero-screenshot.png&quot; alt=&quot;&quot; width=&quot;480&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You're probably wondering at this point, &quot;why not just ask people to rank the ideas instead of this convoluted tournament thing?&quot;&lt;/p&gt;
&lt;p&gt;That was my first plan.&lt;/p&gt;
&lt;p&gt;Let's rewind. It's story time&amp;hellip;&lt;/p&gt;
&lt;p&gt;My band was making a CD. There were 6 of us which meant lots of arguments about how much violin should be in the chorus of song X, and whether or not it was a good idea to cover songs our friends had written.&lt;/p&gt;
&lt;p&gt;One day we're all sitting around in the &quot;Recording Studio&quot; (e.g., my parent's formal living room) trying to pick which 10 of our 30ish songs &lt;em&gt;deserved&lt;/em&gt; to be included in the album.&lt;/p&gt;
&lt;p&gt;We took ourselves very seriously. Don't laugh, this is important.&lt;/p&gt;
&lt;p&gt;So Matt (drummer) proposes that we all make a top 10 list and then we'll all compare. 10 minutes of scribbling, crossing out, eraser dust, new sheets of paper, and general kindergarden activity ensues.&lt;/p&gt;
&lt;p&gt;When Matt read my list his reaction was, &quot;really? you like Song A more than Song B?&quot;. And answer was, &quot;No.&quot; I didn't.&lt;/p&gt;
&lt;p&gt;That's the funny thing about rankings. You can get circular logic: Song A beats Song B, Song B beats Song C, but Song C beats Song A.&lt;/p&gt;
&lt;p&gt;In other words, lots of rankings aren't necessarily transitive. A brief aside: Phil Haack wrote a fascinating article &lt;a href=&quot;http://haacked.com/archive/2012/11/27/condorcet-paradox.aspx&quot; title=&quot;http://haacked.com/archive/2012/11/27/condorcet-paradox.aspx&quot;&gt;about this in regards to political elections&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Our (again, suboptimal) human brains end up performing the ranking process as a series of X vs Y choices anyway.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Do I like this song more than that one, and less then the one above it? Perfect. I'll just slip it in there.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;And it occurred to me,&lt;/p&gt;
&lt;blockquote class=&quot;posterous_short_quote&quot;&gt;
&lt;p&gt;why don't we just simplify the whole thing to just &lt;strong&gt;A&lt;/strong&gt; vs &lt;strong&gt;B&lt;/strong&gt; choices?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My hacker brain took off from there.&lt;/p&gt;
&lt;p&gt;In fact it's not just simpler, but now we can get useful data even if the person don't make a choice about every song.&lt;/p&gt;
&lt;p&gt;And besides, who are we do choose? We should ask &lt;em&gt;THE FANS&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So here we are&amp;hellip; in the present day. I didn't actually build the tool because I was too busy economics-ing or whatever.&lt;/p&gt;
&lt;p&gt;I think we voted on which songs to put on the album. yay irony!&lt;/p&gt;
&lt;p&gt;But I did &lt;em&gt;eventually&lt;/em&gt; build this thing.&lt;/p&gt;
&lt;p&gt;I'm still working on it, but you can check out &lt;a href=&quot;https://www.theWhicher.com&quot; title=&quot;https://www.theWhicher.com&quot;&gt;theWhicher.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also, there's a little more history to the story, which you can read on &lt;a href=&quot;https://www.theWhicher.com/about/&quot; title=&quot;https://www.theWhicher.com/about/&quot;&gt;the Whicher's About Page&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;But really, seriously, in conclusion: Stop doing it the hard way&lt;/h2&gt;
&lt;p&gt;Don't let your single-minded, reptilian, teenaged, brain thing hold you back.&lt;/p&gt;
&lt;p&gt;Please consider brainstorming without any fear of failure; in fact, do it for me. Plan on coming up with &lt;strong&gt;swaths of bad ideas&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It's a good idea.&lt;/p&gt;
&lt;p&gt;And you'll have plenty of time to vet them afterward ;)&lt;/p&gt;
</description>
                <pubDate>Fri, 30 Nov 2012 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/the-good-idea-lottery</link>
                <guid isPermaLink="true">http://www.jiaaro.com/the-good-idea-lottery</guid>
            </item>
        
            <item>
                <title>You need to support mobile, even if you don't support mobile</title>
                <description>&lt;p&gt;Your application emails people when important things happen, right?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If it doesn't it should. People like to know about important things (and it's the &lt;a href=&quot;http://www.kalzumeus.com/2012/05/31/can-i-get-your-email/&quot;&gt;best marketing you could ask for&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Most people check email on their phones &amp;ndash; among other places &amp;ndash; and the &lt;em&gt;best email is actionable&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&amp;hellip;so they log in to take care of whatever you emailed about.&lt;/p&gt;
&lt;p&gt;On their phone.&lt;/p&gt;
&lt;p&gt;You probably have more mobile traffic than you think. And if you don't, you probably don't use email very effectively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr: You need to support mobile, even if you don't.&lt;/strong&gt;&lt;/p&gt;
</description>
                <pubDate>Thu, 26 Jul 2012 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/you-need-to-support-mobile-even-if-you-don-t-support-mobile</link>
                <guid isPermaLink="true">http://www.jiaaro.com/you-need-to-support-mobile-even-if-you-don-t-support-mobile</guid>
            </item>
        
            <item>
                <title>Python performance the easy(ish) way</title>
                <description>&lt;p&gt;Ctypes is great. Let's start with a simple (and trite) example: Summing a range of numbers.&lt;/p&gt;
&lt;p&gt;Here it is in python:&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;def sumrange(arg):
    return sum(xrange(arg))&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Very nice! But let's say we're summing a LOT of numbers, like 0 through 10**8 (that's 100,000,000).&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; %timeit sumrange(10**2)
1000000 loops, best of 3: 1.42 us per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange(10**8)
1 loops, best of 3: 1.13 s per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange(10**10)
1 loops, best of 3: 701 s per loop&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Well that's no fun. Let's try something else:&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;def sumrange2(arg):
    x = i = 0
    while i &amp;lt; arg:
        x += i
        i += 1
    return x&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;How'd we do?&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; %timeit sumrange2(10**2)
100000 loops, best of 3: 14.9 us per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange2(10**8)
1 loops, best of 3: 16.5 s per loop&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Wow... that's even worse... (I dare not attempt this one with 10**10) so how do we speed it up? (don't suggest math tricks... this is the the new world of computing!)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;*edit*&lt;/strong&gt;: yes I know there's a constant time algoritm, n*(n+1)/2 . That isn't the purpose of this post&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;how about ctypes?&lt;/p&gt;
&lt;p&gt;sumrange.c&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;

unsigned long long sumrange(unsigned long long arg)
{
    unsigned long long i, x;
    x = 0;

    for (i = 0; i &amp;lt; arg; i++) {
        x = x + i;
    }
    return x;
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;compile it:&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;$ gcc -shared -Wl,-install_name,sumrange.so -o sumrange.so -fPIC sumrange.c -O2&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;and the python code...&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;import ctypes
sumrange_ctypes = ctypes.CDLL('/path/to/sumrange.so').sumrange
sumrange_ctypes.restype = ctypes.c_ulonglong&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I &lt;a href=&quot;http://stackoverflow.com/questions/12394616/python-int-overflows-when-calling-types-functions&quot;&gt;learned on StackOverflow that you have to set the restype&lt;/a&gt; or else python will assume it's an int (which will overflow)&lt;/p&gt;
&lt;p&gt;And the winner is...?&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**8)
1000000 loops, best of 3: 590 ns per loop&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Wow that's fast... too fast. Let's experiment&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**2)
1000000 loops, best of 3: 601 ns per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**10)
1000000 loops, best of 3: 592 ns per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**16)
1000000 loops, best of 3: 602 ns per loop&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It seems gcc has optized this into a constant time algorithm LOL. Let's try without the optimize flag (for the record I tried with -O1 and it was still contant time)&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;$  gcc -shared -Wl,-install_name,sumrange.so -o sumrange.so -fPIC sumrange.c&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;... and in python (ipython in my case)...&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**2)
1000000 loops, best of 3: 807 ns per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**8)
1 loops, best of 3: 214 ms per loop

&amp;gt;&amp;gt;&amp;gt; %timeit sumrange_ctypes(10**10)
1 loops, best of 3: 3.01 s per loop&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Roundup!&lt;/p&gt;
&lt;div class=&quot;CodeRay&quot;&gt;
  &lt;div class=&quot;code&quot;&gt;&lt;pre&gt;iterations      |   10**2       10**8       10**10
--------------------------------------------------
pure python     |   1.42 us     1.13 s      701 s
ctypes          |   807 ns      214 ms      3.01 s&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;That is a hell of a performance boost!&lt;/p&gt;
&lt;p&gt;For nodejs hackers, the node equivalent of ctypes is FFI (Foreign Function Interface): &lt;a href=&quot;https://github.com/rbranson/node-ffi&quot;&gt;https://github.com/rbranson/node-ffi&lt;/a&gt;&lt;/p&gt;
</description>
                <pubDate>Mon, 27 Feb 2012 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/python-performance-the-easyish-way</link>
                <guid isPermaLink="true">http://www.jiaaro.com/python-performance-the-easyish-way</guid>
            </item>
        
            <item>
                <title>Why do we still hate Microsoft but love Apple?</title>
                <description>&lt;p&gt;Apple has grown larger than Microsoft. This is old news. Steve Jobs (RIP) never became a philanthropist like Bill Gates. So why do the technorati hold Jobs in such high regard will still harboring resentment for Gates?&lt;/p&gt;
&lt;p&gt;I think the differentiation is in the context under which we use their products.&lt;/p&gt;
&lt;p&gt;I find myself with other options in every arena in which I use Apple's products. I &lt;strong&gt;choose&lt;/strong&gt; to use them because I want to.&lt;/p&gt;
&lt;p&gt;Let's compare this with Microsoft. I often find myself using Microsoft products because I have no other choices.&lt;/p&gt;
&lt;p&gt;I use Excel because Google docs wasn't able to open a complex spreadsheet created with Excel.&lt;/p&gt;
&lt;p&gt;I use Word because Open Office couldn't display the track changes recorded in Word.&lt;/p&gt;
&lt;p&gt;I use Windows to test my websites in Internet Explorer because IE isn't available anywhere else.&lt;/p&gt;
&lt;p&gt;The one &lt;strong&gt;notable exception&lt;/strong&gt; is Xbox; I love my Xbox. I chose it over playstation.&lt;/p&gt;
&lt;p&gt;I wasn't strong-armed into using Xbox through anti-competitive practices, it's a good product that I &lt;em&gt;wanted&lt;/em&gt; to use.&lt;/p&gt;
&lt;p&gt;I don't think profit, or good vs. evil has anything to do with it. We simply like companies when we&amp;nbsp;&lt;strong&gt;choose&lt;/strong&gt; to use their products -- over and over -- because they're better.&lt;/p&gt;
</description>
                <pubDate>Mon, 07 Nov 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/why-do-we-still-hate-microsoft-but-love-apple</link>
                <guid isPermaLink="true">http://www.jiaaro.com/why-do-we-still-hate-microsoft-but-love-apple</guid>
            </item>
        
            <item>
                <title>960gs Reference</title>
                <description>&lt;p&gt;I am sick of the &lt;a href=&quot;http://960.gs&quot;&gt;960.gs webpage&lt;/a&gt;&amp;nbsp;I have shit to get done and I don't want to be sold on 960 -- just remind me what the damn css classes are.&lt;/p&gt;
&lt;p&gt;Here is my own personal 960.gs documentation :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt;: In the list below XX is used to denote a number of columns&lt;/p&gt;
&lt;p&gt;Quick reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;container_XX&lt;/li&gt;
&lt;li&gt;grid_XX&lt;/li&gt;
&lt;li&gt;prefix_XX&lt;/li&gt;
&lt;li&gt;suffix_XX&lt;/li&gt;
&lt;li&gt;push_XX&lt;/li&gt;
&lt;li&gt;pull_XX&lt;/li&gt;
&lt;li&gt;alpha&lt;/li&gt;
&lt;li&gt;omega&lt;/li&gt;
&lt;li&gt;clear&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;container_XX&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;All elements in the page should be inside one of these -- it tells the grid system how many columns your layout should be.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;grid_XX&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Makes the element XX columns wide&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;strong&gt;prefix_XX&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Shift the element XX columns to the right (take up XX more columns on the left)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;suffix_XX&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Push the next element XX columns to the right (take up XX more columns on the right)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;push_XX&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Shift this element XX columns to the &lt;strong&gt;right&lt;/strong&gt; without affecting any other elements&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;pull_XX&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Shift this element XX columns to the &lt;strong&gt;left&lt;/strong&gt; without affecting any other elements&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;alpha / omega&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When using grid_XX inside another grid_XX element. use &lt;strong&gt;alpha and omega&lt;/strong&gt; on the &lt;strong&gt;first and last element&lt;/strong&gt; respectively to avoid doubling the gutter padding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;clear&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;clears floated elements in a way that doesn't suck&lt;/p&gt;
</description>
                <pubDate>Thu, 11 Aug 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/960gs-reference</link>
                <guid isPermaLink="true">http://www.jiaaro.com/960gs-reference</guid>
            </item>
        
            <item>
                <title>Google Plus is good, but don't switch to it</title>
                <description>&lt;p&gt;I'm going to assume that since you're reading this, you're a technophile and you're already in the Google+ beta. I'm not going to talk about why Google+ is good, or how google finally &quot;got social right&quot;, or why I love it more than life itself or any such nonsense. I'm going to talk about facebook.&lt;/p&gt;
&lt;p&gt;Please don't misunderstand the title, I think you should try google+ out. If you like it (I do) then great! keep using it to your hearts content.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;strong&gt;It's still about search&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I'm pretty sure the primary reason for google+ is the +1 button. All this +1 action is going to give Google's search team a HUGE dataset to mine; no more scraping twitter for &quot;social data&quot;. &lt;a href=&quot;http://blog.facebook.com/blog.php?post=33443992130&quot;&gt;Facebook talked about doing this years ago&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's good to understand Google's motivation before we pass judgement.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now about switching: &lt;strong&gt;don't&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Google is a very powerful company and they've (finally) created a good social network with some profound insights. One that I personally enjoy using more than facebook and twitter. Facebook is also a powerful company, let's not kid ourselves but they are *much* smaller than google.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;strong&gt;Competition works&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If everyone switches away from facebook and uses google+ instead, what we will have is facebook again, except owned by google (remember myspace). That isn't great.&lt;/p&gt;
&lt;p&gt;Remember when Firefox started getting traction and over time started getting slow and bloated? And then Google released their own web browser, and all of a sudden Firefox was &lt;a href=&quot;http://arewefastyet.com/&quot;&gt;getting HUGE speed improvements&lt;/a&gt;? Right now we have 4 browsers with significant marketshare (sorry opera) all competing to be fast. &lt;strong&gt;That &lt;em&gt;was&lt;/em&gt; great&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Well right now facebook has lost focus. They're the biggest by a lot and, frankly, they've got a bad case of slow-and-bloated syndrome (and a case of doing evil as well, but the degree to which they are doing it on purpose has been debated).&lt;/p&gt;
&lt;p&gt;I'd like to see facebook have a change of heart on their &lt;a href=&quot;http://www.readwriteweb.com/archives/facebooks_zuckerberg_says_the_age_of_privacy_is_ov.php&quot;&gt;crazy policies&lt;/a&gt;, and I hope Google+ is the catalyst. But it'd be a day when google controls our search, email, phones, photos, AND social graph.&lt;/p&gt;
&lt;p&gt;Let's keep the Social Web &lt;strong&gt;competitive&lt;/strong&gt;: let's force them not to be evil (and I don't just mean Google).&lt;/p&gt;
</description>
                <pubDate>Sun, 24 Jul 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/google-plus-is-good-but-dont-switch-to-it</link>
                <guid isPermaLink="true">http://www.jiaaro.com/google-plus-is-good-but-dont-switch-to-it</guid>
            </item>
        
            <item>
                <title>Decoding facebook's base64url signed_request</title>
                <description>&lt;p&gt;In python:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;signed_request_to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encoded_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;encoded_json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encoded_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;=&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'sig'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'json'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encoded_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
                <pubDate>Wed, 16 Mar 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/decoding-facebooks-base64url-signedrequest</link>
                <guid isPermaLink="true">http://www.jiaaro.com/decoding-facebooks-base64url-signedrequest</guid>
            </item>
        
            <item>
                <title>SSL Certificates are Miserable</title>
                <description>&lt;p&gt;So... I was tasked with setting up https for a website recently. I was setting up Nginx with an ssl certificate from thawte. &lt;/p&gt;
&lt;p&gt;Pretty normal. Pretty standard. Pretty aweful.&lt;p /&gt;Here's to helping the next guy get through the process quicker than I did.&lt;/p&gt;
&lt;h2&gt;Testing&lt;/h2&gt;

&lt;p&gt;Before you start. &lt;strong&gt;Don't use a browser or openssl&lt;/strong&gt; to test your config. It will waste your time and make you unhappy. &lt;/p&gt;

&lt;p&gt;Use this tool to test your ssl config:&lt;/p&gt; 

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.digicert.com/help/&quot;&gt;http://www.digicert.com/help/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Certificate Signing Requests (*.csr), PEM Files, Intermediary Certificates, root CACertificate, Secondary Certificate BS, and more&lt;/h2&gt;

&lt;p&gt;You should know Apache and several other web servers expect your ssl certificate to be in a separate file from the intermediary certificates Like this &lt;a href=&quot;http://www.apache-ssl.org/httpd.conf.example&quot;&gt;example http.conf&lt;/a&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# your key file (often called www.example.com.key or privatekey.pem)&lt;/span&gt;
SSLCertificateKeyFile /www/certs/ssl.fictional.co.key

&lt;span class=&quot;c&quot;&gt;# your ssl certificate (often called www.example.com.crt or certificate.pem)&lt;/span&gt;
SSLCertificateFile /www/certs/ssl.fictional.co.cert

&lt;span class=&quot;c&quot;&gt;#intermediary certificates (often a *.crt or *.pem file)&lt;/span&gt;
SSLCACertificateFile /www/certs/CA.cert&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;ok great... but some other web servers expect &lt;strong&gt;your intermediary certificates to be concatenated with your ssl certificate&lt;/strong&gt; (i.e. the one you paid for). So open up notepad and copy/paste that CA.cert into the end of your ssl.fictional.co.cert and hit save.&lt;/p&gt;

&lt;h2&gt;What about Nginx?&lt;/h2&gt;
&lt;p&gt;now your nginx config for ssl (&lt;a href=&quot;http://wiki.nginx.org/HttpSslModule&quot;&gt;documentation here&lt;/a&gt;) will look like this:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nginx&quot; data-lang=&quot;nginx&quot;&gt;&lt;span class=&quot;k&quot;&gt;http&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;443&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;ssl&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# this file contains the ssl.fictional.co.cert AND CA.cert from&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# the apache example&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;ssl_certificate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/usr/local/nginx/conf/cert.pem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# this file corresponds to the ssl.fictional.co.key from the apache example&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;ssl_certificate_key&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/usr/local/nginx/conf/cert.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Conclusion. SSL…&lt;br /&gt; is a pain in the ass.&lt;/p&gt;

</description>
                <pubDate>Tue, 15 Mar 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/ssl-certificates-are-miserable</link>
                <guid isPermaLink="true">http://www.jiaaro.com/ssl-certificates-are-miserable</guid>
            </item>
        
            <item>
                <title>Making Python Objects that act like Javascript Objects</title>
                <description>&lt;p&gt;Been writing a lot of javascript and I thought this was neat:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JsObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JsObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dict__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</description>
                <pubDate>Sat, 12 Feb 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/making-python-objects-that-act-like-javascrip</link>
                <guid isPermaLink="true">http://www.jiaaro.com/making-python-objects-that-act-like-javascrip</guid>
            </item>
        
            <item>
                <title>OS X Devs Fail Usability: Tabbing Hotkeys</title>
                <description>&lt;p&gt;This is going to be short; I just want to point out how bad a user &lt;br /&gt;experience this is on OSX. &lt;p /&gt; On windows (and linux) there is ONE default hotkey for cycling through tabs in any UI: Ctrl + Tab &lt;p /&gt; So why does OSX have so many? Here are just a few: &lt;p /&gt; Adium: &lt;br /&gt;Cmd + left/right arrows &lt;p /&gt; Firefox, Chrome: &lt;br /&gt;Cmd + Option + left/right arrows &lt;p /&gt; Safari, Skype, Terminal: &lt;br /&gt;Cmd + Shift + left/right arrows &lt;p /&gt; The worst part about this is that it confuses the text editing options...&lt;p /&gt; If I want Cmd + arrow to go to the beginning or end of the current &lt;br /&gt;line of text and be able to hold shift to select then the Apple &lt;br /&gt;endorsed default (via safari and terminal - e.g. Cmd + Shift + arrows) is already accounted for. &lt;p /&gt; The Current state of things is not good :(&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit: Things that should be reserved for consistant text editing:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Cmd + Arrow: (go to beginning/end of the current line)&lt;/p&gt;
&lt;p&gt;Cmd + Shift + Arrow: (go to beginning/end of current line while selecting)&lt;/p&gt;
&lt;p&gt;Opt + Arrow: move one word to the left or right&lt;/p&gt;
&lt;p&gt;Opt + Shift + Arrow: move one word to the left or right while selecting&lt;/p&gt;
&lt;p&gt;Shift + Arrow: move cursor one char while selecting&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As far as I can tell, you can't edit the Safari or terminal hot keys either :(&lt;/p&gt;
</description>
                <pubDate>Thu, 03 Feb 2011 00:00:00 +0000</pubDate>
                <link>http://www.jiaaro.com/os-x-devs-fail-usability-tabbing-hotkeys</link>
                <guid isPermaLink="true">http://www.jiaaro.com/os-x-devs-fail-usability-tabbing-hotkeys</guid>
            </item>
        
    </channel>
</rss>