{"title":"Ryan Seys","link":[{"@attributes":{"href":"https:\/\/ryanseys.com\/atom.xml","rel":"self"}},{"@attributes":{"href":"https:\/\/ryanseys.com\/"}}],"updated":"2026-02-18T12:46:00-08:00","id":"https:\/\/ryanseys.com","author":{"name":"Ryan Seys","email":{}},"entry":[{"title":"Learning to live, by learning to breathe","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/breathing"}},"updated":"2018-03-31T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/breathing","content":"<p><img src=\"\/img\/breathe-calvin.gif\" alt=\"\" \/><\/p>\n\n<div style=\"text-align:center;\">&bull; &bull; &bull;<\/div>\n<p><span><\/span><\/p>\n\n<p><em>\u201cYou Are Now Breathing Manually\u2026\u201d<\/em><\/p>\n\n<p>When someone tells you this, your initial reaction is to likely try to fight the urge to think about your breath, and soon you\u2019ll realize that the more effort you put in to fight it i.e. the more you try to not think about thinking about your breath, the more you\u2019re unlikely to be successful in doing so. It\u2019s only by completely letting go, giving up your sense of control of the breath, that you\u2019re able to get it to return to its natural rhythm and fade into the background of your mind.<\/p>\n\n<blockquote>\n  <p>One of the funny things about the mind is that it doesn\u2019t like being told what to do, despite it being the one telling it what to do.<\/p>\n<\/blockquote>\n\n<p>For the past 4 months (starting last December), I\u2019ve been exploring this idea and the inner processes of my own mind through daily meditation. This practice initially started as an attempt to try to calm my own mind from the sporadic thoughts that tended to cloud my daily life, but has since developed into a daily routine that provides  me so much joy and has helped build my ability to feel compassion and empathy toward others, and ultimately learn how to live more intentionally.<\/p>\n\n<p>This term \u201cmeditation\u201d gets thrown around a lot but it\u2019s really just a fancy word for \u201cfocused awareness of what\u2019s happening right now\u201d. The idea around meditation is that by focusing your mind on what\u2019s happening right now, your mind will become clearer and calmer.\u00a0<\/p>\n\n<p>If I may entertain you for a few minutes more, I\u2019m going to reflect and share with you a few things that I\u2019ve learned and observed through this practice so far.<\/p>\n\n<div><\/div>\n\n<h2 id=\"be-aware\">Be aware.<\/h2>\n\n<p>Before I started this practice, meditation to me was a foreign idea, something I thought only monks did, or certainly wasn\u2019t for a \u201cregular\u201d person like myself. I also thought meditation was extremely difficult to do, and even if I could convince myself to try to do it, I figured it would require considerable practice to really get started. I\u2019ll show you right now why all of these preconceptions were wrong.<\/p>\n\n<p><strong>Breathe.<\/strong><\/p>\n\n<p>No seriously, breathe right now. As you breathe in, <em>feel it<\/em> in your chest as your lungs fill with air. Focus on that feeling, letting everything else fade into the background. <em>Don\u2019t judge<\/em> that feeling, just be aware of it. Now breathe out, continuing to hold onto that feeling. Breathe again, continuing to hold that focus. If your mind wanders, acknowledge the passing thought, and bring your focus back to the breath. Rinse &amp; repeat.<\/p>\n\n<p>Congrats, you just <em>~meditated~<\/em><\/p>\n\n<p>Everything else you may hear about meditation these days: meditation pillows, meditation apps, mantras &amp; sound bites, are only there to try to help you create an environment that is conducive to being able to sustain that focused awareness. At the end of the day, no matter what you do to create that mental space for yourself, don\u2019t lose track of the real purpose of meditation: to simply be aware.<\/p>\n\n<p>Which leads into the next thing I\u2019ve learned\u2026<\/p>\n\n<p><\/p>\n\n<h2 id=\"be-awake\">Be awake.<\/h2>\n\n<p>Through the 4 months of logging my daily meditation experiences, one of the trends I noticed more than anything else was that the easiest way to make meditation more difficult and less effective for myself was to try to do it when I\u2019m sleepy. This isn\u2019t to say it\u2019s impossible, but it certainly makes it more challenging, like trying to go to the gym in a state of physical exhaustion.<\/p>\n\n<p>I typically do anywhere from 10\u201330 minutes of meditation per day (you can do as little or as much as you like), but even that small amount of time can seem like an eternity to your mind when you\u2019re tired.\u00a0<\/p>\n\n<p>One of the most effective ways that I\u2019ve found to combat the possibility of falling asleep and to increase my awareness is to meditate right in the morning, after a shower &amp; a cup of joe. At that point, you should be awake enough that you aren\u2019t going to fall back asleep but it\u2019s still early enough in the day that you can approach that time with a fresh, clean slate of curiosity.<\/p>\n\n<p>Which leads me into my third observation\u2026<\/p>\n\n<p><\/p>\n\n<h2 id=\"be-curious\">Be curious.<\/h2>\n\n<p>Don\u2019t take meditation too seriously. Meditation is just about being aware of what\u2019s going on around you, so have fun with it and be curious about what you\u2019ll find. Try not to think of meditation as something that is separate from your everyday life. Recognize that when you\u2019re meditating, you\u2019re living as fully as ever.<\/p>\n\n<p>When thoughts inevitably pop up during your meditation practice, be curious about what they are, observe them and acknowledge them, but then let them go.<\/p>\n\n<p>All in all, be sure to have fun, and\u2026<\/p>\n\n<p><\/p>\n\n<h2 id=\"be-deliberate\">Be deliberate.<\/h2>\n\n<p>If you\u2019re going to meditate (as you should), don\u2019t half-ass it. Be deliberate in what you want to achieve. Try your best in your meditation to bring your full energy and focus into that awareness, but recognize when your mind fails on that promise and find the capacity to admit it, forgive yourself, and try again.<\/p>\n\n<p>The best things in life are usually those worth working for. Meditation is something you need to practice, but its rewards are worth the effort. By being deliberate, you can be sure that you are focusing your energy in the most effective way.<\/p>\n\n<div style=\"text-align:center;\">&bull; &bull; &bull;<\/div>\n<p><span><\/span><\/p>\n\n<p>I hope these few reflections help provide you with a bit of insight into what meditation is, and how you can get the most out of your practice. As you may note, the above musings could be applied to not only meditation but also to life in general. This shouldn\u2019t really come as too big of a surprise given how meditation is simply living with more intentional awareness.<\/p>\n\n<p>So go out there, and enjoy each breath. Happy meditating, happy living\u00a0:)<\/p>\n"},{"title":"Hello, Verily","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/hello-verily"}},"updated":"2016-06-01T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/hello-verily","content":"<p>Exactly one year ago, I joined Google DevRel with the hope of helping improve developer\u2019s lives, making them more productive and successful while building on Google\u2019s developer platform. With an amazing team supporting me, I was able to deliver on that dream for products such as Android TV and Nest, and ultimately this success was shown through the delivery of a talk this year at Google I\/O.<\/p>\n\n<p>Today I\u2019m excited to announce I\u2019m starting my next adventure, this time outside of Google \u2014 but still within Alphabet \u2014 to help improve the lives of all those affected by disease. Today, I\u2019m joining <a href=\"https:\/\/verily.com\">Verily<\/a> to help develop tools and technologies that can detect diseases earlier, understand them better, and intervene more precisely.<\/p>\n\n<p>Thank you to everyone who has supported me in this decision. Working with such an incredible team within Google DevRel this past year has made this switch difficult to come to terms with, but I\u2019m excited to start this new chapter of my life, with the ultimate dream of discovering the truth behind nature and disease.<\/p>\n\n<p><span class=\"heart-container\"><img class=\"heart\" src=\"\/img\/heart.png\" alt=\"Heart\" \/><\/span><\/p>\n\n"},{"title":"Contribute to READMEs","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/contribute-to-readmes"}},"updated":"2015-05-17T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/contribute-to-readmes","content":"<p>Open source development is booming and many people, developers or otherwise, are eager to jump onboard! Lots of people have approached me asking how they can get involved in open source projects and how I stay afloat in the ever-changing ecosystem of open source. My answer is: \u201cby editing READMEs\u201d.<\/p>\n\n<h2 id=\"large-reach-large-importance\">Large reach. Large importance.<\/h2>\n\n<p>READMEs, especially those that exist in GitHub projects, are one of the first things that users and developers see when coming across a project. Tom Preston-Werner, the Cofounder of GitHub, even suggests <a href=\"http:\/\/tom.preston-werner.com\/2010\/08\/23\/readme-driven-development.html\">README Driven Development<\/a>. This means that the README is one of the most highly viewed documents in any repository and so its quality can make or break whether the project receives any further attention.<\/p>\n\n<p>Having a good README shows that care went into the project and that documentation is treated as a first-class citizen in the project. Your contribution will impact all those that read the README. That\u2019s huge!<\/p>\n\n<p>In addition, GitHub, one of the world\u2019s largest respositories of open source projects, makes this super easy. You\u2019re only a couple clicks away from making your first contribution to your favourite open source project.<\/p>\n\n<p><img src=\"\/img\/edit-readme.png\" alt=\"Click to edit\" \/><\/p>\n\n<h2 id=\"valuable-and-harmless\">Valuable and harmless.<\/h2>\n\n<p>Many people are intimidated by editing real code in projects because they feel that their code contributions might be heavily scrutinized, or introduce bugs into the project which will reflect negatively on them. Many highly technical developers constantly struggle with imposter syndrome, especially outside the comfort of their own projects. I suggest editing the README of a project first because it\u2019s hard to break things in a static document. Whether you\u2019re fixing a grammatical mistake, spelling error, missing documentation or adding links to important related resources, contributions to READMEs vary widely and can be as small as a single character diff.<\/p>\n\n<h2 id=\"technical-and-non-technical\">Technical and non-technical.<\/h2>\n\n<p>Both technical and non-technical people can contribute to a README equally. Although many open source projects focus heavily on code, a README comprises of both technical and non-technical parts and both are equal playing field when it comes to contributions. As mentioned previously, even grammatical issues are fair game when it comes to legitimate edits.<\/p>\n\n<h2 id=\"gauge-project-health\">Gauge project health.<\/h2>\n\n<p><img src=\"\/img\/eat-it.gif\" alt=\"Eat it\" \/><\/p>\n\n<p>One of the most important reasons that I suggest you edit READMEs is that your small edit can quickly establish a relationship with the maintainers of the project and allow you to evaluate how they proceed to handle your contribution and the overall health of the project.<\/p>\n\n<p>For example, if your contribution to their README is never addressed in any form, the project is likely carelessly maintained and you should be careful when contributing to other aspects of the project to ensure that it will receive any attention at all. In this case, I wouldn\u2019t spend a lot of time on further contributions until I\u2019ve established a closer relationship with the maintainers to ensure that my time isn\u2019t completely wasted on a project that has been silently abandoned. If this happens, at least you didn\u2019t spend countless hours carefully adding a new feature complete with tests and documentation only to be given the cold shoulder.<\/p>\n\n<p>On the other hand, if your contribution is quickly addressed by the maintainers, you can further gauge how they handled your contribution. Were they friendly? Did they give you advice on how you can further expand on your contribution? Did they accept it and thank you for the contribution? All these things can give you hints as to how the maintainers will treat you in the future if you continue to contribute to the project.<\/p>\n\n<h2 id=\"get-comfortable-with-the-project\">Get comfortable with the project.<\/h2>\n\n<p><img src=\"\/img\/comfy.gif\" alt=\"\" \/><\/p>\n\n<p>There are many ways to learn about a project but one very effective way is to read the current README and learn from what has already been wrote, then investigate the project and cross-reference what the code says versus what the README documents as truth. Here you can find gaps in the documentation that you can fill, or errors if changes were made to code but the README was neglected (a very common issue I see). Another idea is to follow links in the README, both to get familiar with the various documentation external to the repository but also to potentially find dead links. All of these are important to maintaining a healthy and happy open source project and allow you to start contributing today!<\/p>\n\n<p>Need a repo to get started? <a href=\"https:\/\/github.com\/ryanseys\/edit-my-readme\">Edit my README on GitHub<\/a>.<\/p>\n\n<p>Happy contributing!<\/p>\n"},{"title":"Twenty-fourteen","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/twenty-fourteen"}},"updated":"2014-12-29T00:00:00-08:00","id":"https:\/\/ryanseys.com\/post\/twenty-fourteen","content":"<p>Twenty-fourteen has been a fantastic year for me. The following post allows me to both reminisce on all the fun times I\u2019ve had in 2014 (and that not-so-fun time my laptop was stolen) and to also look ahead to the arrival of 2015, where I hope to have bigger, better adventures (and have less laptops stolen)! Between school, interning at Google in California, and traveling this year has been total amaze-balls. Here\u2019s my story\u2026<\/p>\n\n<p><img src=\"\/img\/google-camping.jpg\" alt=\"Camping\" \/>\n<i><small>Camping out in the boonies with my summer roommates was a favourite memory of mine. This post is written in loving memory of Michael\u2019s GoPro.<\/small><\/i><\/p>\n\n<h2 id=\"school\">School<\/h2>\n\n<p>Study study study. A large portion of 2014 for me has been school. I\u2019m in the works of finishing up my degree at Carleton University for Software Engineering and should be graduated by May 2015. It\u2019s right around the corner now!<\/p>\n\n<p>School has been a wild ride for me and it\u2019s not yet over, but chugging through these last couple years has been slow and painful, especially just knowing I\u2019m in the final stretch.<\/p>\n\n<p>Looking back on all the people I\u2019ve met in school makes me really appreciate all the time (and not to mention money) I\u2019ve spent going through post-secondary education to get my degree. These people are irreplaceable and when we all move on to our big, important grown-up jobs, I hope to continue to keep in touch with them. No photos here because school is boring <a href=\"http:\/\/www.urbandictionary.com\/define.php?term=AF\">af<\/a>.<\/p>\n\n<h2 id=\"google\">Google<\/h2>\n\n<p>Sandwiched between two school terms was my amazing adventure at Google as a summer intern. I had the absolute honour of working with the Developer Relations team at Google as a Software Engineering Intern. This unique opportunity exposed me to the weird and wonderful world of DevRel.<\/p>\n\n<p><img src=\"\/img\/self-car.jpg\" alt=\"Google self-driving car\" \/>\n<i><small>Posing with the new Google self-driving car on the day it was announced. It\u2019s so freaking cute.<\/small><\/i><\/p>\n\n<p>Typically at Google, Software Engineering Interns are either given a project to work on or have some say in the project they want to work on during their summer. At the end of the summer, you\u2019ll have to gauge the impact you had using real-world metrics and write yourself a self-review on how successful your summer internship was at Google for both yourself and for Google.<\/p>\n\n<p>I\u2019m lucky to say that I had it even better than most other interns. During my 14 weeks at Google I got to work on <strong>two<\/strong> different projects and have a large impact on both:<\/p>\n\n<ol>\n  <li>Google API NodeJS Client<\/li>\n  <li>Google I\/O Codelab Kiosks<\/li>\n<\/ol>\n\n<h3 id=\"google-api-nodejs-client\">Google API NodeJS Client<\/h3>\n\n<p>The Google API NodeJS Client library, found <a href=\"https:\/\/github.com\/google\/google-api-nodejs-client\">here on GitHub<\/a>, is Google\u2019s official library used for interacting with Google APIs in NodeJS. Originally developed to support most Google APIs out of the box, it was slow, buggy and just didn\u2019t deliver the right experience that NodeJS developers expected.<\/p>\n\n<p>During my summer, myself with lots of help of my mentor <a href=\"https:\/\/github.com\/rakyll\">@rakyll<\/a>, rewrote the majority of the library\u2019s codebase to deliver a better experience to Node developers, resulting in a skyrocketing of popularity for the module, nearly doubling its number of stars to 2600+ and decreasing issue counts by over 50%.<\/p>\n\n<p>Overall the project re-write was a huge success and I\u2019m super happy to have had the opportunity to contribute to it. If you\u2019re a node hacker and wanna get your hands messy or give feedback on the project, <a href=\"https:\/\/github.com\/google\/google-api-nodejs-client\">check it out<\/a> on GitHub.<\/p>\n\n<h3 id=\"google-io-codelab-kiosks\">Google I\/O Codelab Kiosks<\/h3>\n\n<p>With Google I\/O fast approaching and the World Cup eating up much of the Developer Relation full-timer\u2019s attention, they needed to recruit me, the intern with ever-lasting energy, to work on Google I\/O Codelab Kiosk software to be used at the 2014 Google I\/O conference in San Francisco.<\/p>\n\n<p>Again, this was an amazing opportunity being able to work with so many awesome people across many different parts of Developer Relations. The big difference between this project and the traditional intern project is that it had a REALLY HARD deadline (you can\u2019t just move Google I\/O\u2026 and we\u2019re talking weeks until lift-off, not months) that would have REALLY BAD consequences if they weren\u2019t met.<\/p>\n\n<p>Stress levels were high during this time, but caffeine levels were higher and together we all got it done and we saw it all come together (I won\u2019t say smoothly but rather in good timing) at Google I\/O that year.<\/p>\n\n<p><img src=\"\/img\/google-io.jpg\" alt=\"Google I\/O\" \/>\n<i><small>Google I\/O 2014 registration lines. Where all the developers got their free watches!<\/small><\/i><\/p>\n\n<p>Seeing hundreds of developers using the Codelab Kiosk system to learn about new Google technologies and being able to first-hand mentor these developers at Google I\/O was a great experience for me as a learner but also as a teacher and as a peer.<\/p>\n\n<h3 id=\"going-back\">Going back<\/h3>\n\n<p>Overall interning at Google was an amazing opportunity. So amazing that I just had to try and go back. Fortunately, Google also wants to have me back so I\u2019m very excited to say that I\u2019ll be joining Google full-time in June 2015 as a Developer Programs Engineer in California. I cannot wait to be finished school and on my way to the warm sun-soaked California.<\/p>\n\n<p><img src=\"\/img\/google-carnival.jpg\" alt=\"Google Carnival\" \/>\n<i><small>The Google Intern Carnival was a fun-filled afternoon filled with bouncy castles, ice-cream trucks, mechanical bulls and free alcohol. A true intern\u2019s paradise.<\/small><\/i><\/p>\n\n<h2 id=\"travel\">Travel<\/h2>\n\n<h3 id=\"yosemite\">Yosemite<\/h3>\n\n<p>Working at Google can be an exhaustingly fun place to work which means winding down with a solid weekend vacation at 10,000 ft elevation is the only natural way to rejuvenate. This memorable weekend trip was to Yosemite National Park in California, where we (my amazing Google roommates and I) drove 3-4 hours up into the mountain air and enjoyed the weekend without cell-phones, electricity or a single fuck to give.<\/p>\n\n<p><img src=\"\/img\/google-yosemite.jpg\" alt=\"Yosemite\" \/>\n<i><small>Yosemite\u2019s views are to die for. This one spotted on the side of the road was too good to pass up for a photo-op.<\/small><\/i><\/p>\n\n<p>We climbed the rocks in the late hours of the night, nearly walking off cliffs and watching the stars twinkle and shoot across the sky. We rode pack-mules around the mountains and through the bushes before arriving at a beautiful picturesque view that could never equally be captured in a photo.<\/p>\n\n<p><img src=\"\/img\/yosemite.jpg\" alt=\"Mule ride\" \/>\n<i><small>The view at the end of our pack-mule ride. I\u2019m there on the left soaking it all in.<\/small><\/i><\/p>\n\n<p>Yosemite was a great deal of fun and created a mule\u2019s pack worth of memories to cherish for years to come. Anyone considering Yosemite as their next destination should definitely go through with it. Just be sure to pack lots of warm clothes, especially for the winter months. The summer nights, as we learned, dip to nearly freezing, 0 degrees Celsius (32 in Freedom degrees), resulting in a rather chilly surprise.<\/p>\n\n<h3 id=\"europe\">Europe<\/h3>\n\n<p>Even as a Canadian, I\u2019ll take any chance I can get to escape the cold hands of mother nature\u2019s winters or the sweaty humid hands of the Ottawa summer. So naturally moving to California to intern at Google for the summer was such a blessing, though eventually I did start to miss the rain due to the ever-lasting record-breaking drought California saw this year.<\/p>\n\n<p>Before returning to Ottawa following my internship, I decided to take a solo backpacking journey around Europe to refresh before school started again.<\/p>\n\n<p>My travel plans were as follows:<\/p>\n\n<p>San Francisco, USA\n\u2192 London, UK\n\u2192 Amsterdam, Netherlands\n\u2192 Oslo, Norway\n\u2192 Rome, Italy\n\u2192 Barcelona, Spain\n\u2192 Porto, Portugal\n\u2192 London, UK\n\u2192 Toronto, Canada<\/p>\n\n<p><img src=\"\/img\/amsterdam-shoe.jpg\" alt=\"Amsterdam Shoe\" \/>\n<i><small>Posing in a giant clog in Amsterdam. I\u2019m like the little old lady that lived in the shoe.<\/small><\/i><\/p>\n\n<p><img src=\"\/img\/amsterdam-coffee.jpg\" alt=\"Amsterdam Coffee\" \/>\n<i><small>The coffee and the \u201ccoffee\u201d in Amsterdam wasn\u2019t so bad. <b>Out of shot:<\/b> A couple cool Aussies I befriended from my hostel.<\/small><\/i><\/p>\n\n<p>Unfortunately, my travel was cut short in Amsterdam after having nearly all my belongings stolen from me including my laptop, clothes and most importantly my dignity and energy. The unfortunate event happened rather simply: I placed my luggage in a locked-yet-unmonitored luggage room at my hostel, left to find coffee, and later returned to discover my luggage had mysteriously vanished from previously-said-room\u2026<\/p>\n\n<p>My resulting trip looked like this instead:<\/p>\n\n<p>San Francisco, USA\n\u2192 London, UK\n\u2192 Amsterdam, Netherlands\n<strong>\u2192 Amsterdam Police Station<\/strong>\n\u2192 Toronto, Canada<\/p>\n\n<p>Luckily I had my money and passport on me but rather than continue the journey in an exhausted state of paranoia, I decided it was healthier for myself and my wallet to cut my losses and head home early. Months later, the Amsterdam court mailed me a letter saying they found the suspect that stole my belongings and put them in jail for 4 months for the crime. JUSTICE! (Sorta, I never did get my things back\u2026)<\/p>\n\n<h2 id=\"new-years-in-nyc\">New Years in NYC<\/h2>\n\n<p>In two days, I\u2019ll be traveling to NYC for the first time to experience New Years Eve in New York with my roomies and friends from the summer. Though I don\u2019t expect NYC to disappoint, it\u2019s the people I\u2019m most excited to see again! Cheers to all your New Year\u2019s Eve celebrations and resolutions!<\/p>\n\n<h2 id=\"twenty-fifteen\">Twenty-fifteen<\/h2>\n\n<p>I\u2019ve met so many fantastic people and seen so many fantastic places that it\u2019s going to be hard to 1-up it all next year.<\/p>\n\n<p>Here\u2019s a couple lessons I\u2019ve learned this year that hopefully I can carry into 2015:<\/p>\n\n<ol>\n  <li>\n    <p>Don\u2019t leave your luggage unattended in a public space. Be extra cautious while traveling abroad and don\u2019t trust \u201cthe system\u201d to always work. Make sure you keep your money and passport on you at all times.<\/p>\n  <\/li>\n  <li>\n    <p>People are awesome. Don\u2019t take them for granted.<\/p>\n  <\/li>\n  <li>\n    <p>Don\u2019t fall off cliffs (e.g. at Yosemite). That wouldn\u2019t be very fun.<\/p>\n  <\/li>\n  <li>\n    <p>Google\u2019s a cool place to work, but the perks don\u2019t really matter <em>that<\/em> much. The people do. See #2 for more information.<\/p>\n  <\/li>\n  <li>\n    <p>Travel more and make more mistakes. It\u2019s the best way to learn for yourself.<\/p>\n  <\/li>\n  <li>\n    <p>Write more blog posts. Here\u2019s a start.<\/p>\n  <\/li>\n<\/ol>\n\n<p>Cheers to your twenty-fifteen!<\/p>\n\n<p><img src=\"\/img\/cali-rock.jpg\" alt=\"California\" \/><\/p>\n\n<p>For more silly ramblings like this, <a href=\"https:\/\/twitter.com\/ryanseys\">follow me<\/a> on Twitter.<\/p>\n\n"},{"title":"Mozilla Internship FAQ","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/mozilla-internship-faq"}},"updated":"2014-07-19T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/mozilla-internship-faq","content":"<p>Over the past year I have received numerous emails regarding my internship at Mozilla. I wrote this post to answer some of the more common questions that I was asked. This is my experience based on a technical position so it may be quite different for non-technical roles. Regardless, this FAQ should give you a good feeling for how the Mozilla internships work.<\/p>\n\n<p>Disclaimer: I can\u2019t guarantee you a similar experience, but I do guarantee that what I say here is true for what I experienced for my intership at Mozilla.<\/p>\n\n<blockquote>\n  <p>Can I intern at Mozilla?<\/p>\n<\/blockquote>\n\n<p>Absolutely! If you love the web and stand by it as a platform, you should love what Mozilla is doing for it. Freshen up on <a href=\"https:\/\/www.mozilla.org\/en-US\/about\/manifesto\/\">their mission<\/a> and think hard about whether Mozilla is right for you.<\/p>\n\n<blockquote>\n  <p>How did you manage to get an internship at Mozilla?<\/p>\n<\/blockquote>\n\n<p>Believe it or not, I just applied online! I didn\u2019t have references within the company, I just went to their <a href=\"https:\/\/mozilla.org\/careers\">careers website<\/a> and <em>applied<\/em>. In the cover letter section, I wrote a little blurb about why I think Mozilla would be a good fit for me and what I could bring to them. If you have to think really hard about this part, you may not be the best candidate.<\/p>\n\n<blockquote>\n  <p>What was the interview process like?<\/p>\n<\/blockquote>\n\n<p>All the other interns that I spoke to had varying experiences when it came to their interviews at Mozilla. Here\u2019s a few things I found that were similar:<\/p>\n\n<ol>\n  <li>You typically interview directly with a member \/ members of the team you would end up working with during the internship.<\/li>\n  <li>You <strong>will be<\/strong> interviewed for your technical ability in a wide variety of areas. This is very dependent on your team.<\/li>\n  <li>You will likely have numerous interviews. I had five (5) interviews total before an offer was given. Expect two interviews at the very least.<\/li>\n  <li>All of my interviews were remote video Skype calls. Your interviewer could also whip out a Google Doc for you to code on.<\/li>\n<\/ol>\n\n<blockquote>\n  <p>What were the technical questions like?<\/p>\n<\/blockquote>\n\n<p>The topics covered in your technical interviews will vary greatly from team to team. The format of such questions will also vary greatly. Some teams will prefer to ask you more formal problem solving questions and expect more formal coded solutions. Yes, expect to code in your interviews.<\/p>\n\n<p>Other teams prefer a more conversational style interview where you\u2019ll discuss with them previous projects, your skills in an applied context and more open ended problems that require you to think a little harder. In all cases, relax. Your interviewers want to see you succeed just as much as you do.<\/p>\n\n<blockquote>\n  <p>Does Mozilla provide housing for interns?<\/p>\n<\/blockquote>\n\n<p>They did provide housing for me. I didn\u2019t have to find housing or roommates. In fact, I had little say in where I lived for my internship. Housing situations change from year to year and greatly depend on your office location.<\/p>\n\n<p>If you already have housing or otherwise prefer to find your own place, they also offered a small stipend instead. This stipend was much less compared to the value of the housing they provided so I greatly recommend letting them provide you with housing if given the option. It was also hassle-free and super close to the office.<\/p>\n\n<blockquote>\n  <p>How does an internship visa work?<\/p>\n<\/blockquote>\n\n<p>I acquired a J-1 visa for my summer internship. It was sponsored by a company whom Mozilla arranged to work with me. This means that a company guides you through the process and collects all information and documentation neccesary for acquiring a visa for the internship. As a Canadian, getting a US J-1 visa was very straightforward, however I do not know how the J-1 visa acquisition works for other countries. See <a href=\"http:\/\/J-1visa.state.gov\/programs\/intern\/\">here<\/a> for more information about the J-1 visa process in the US.<\/p>\n\n<blockquote>\n  <p>How long did the whole process take?<\/p>\n<\/blockquote>\n\n<p>Overall my process took about 4 months from application to offer. This is greatly dependent on when they look at your application and how quickly interviews can complete. It also matters what months your internship takes place. A friend of mine applied after I received my offer in March, got his offer and started the same day as me that summer so it\u2019s all variable.<\/p>\n\n<p>As an example, the following is my timeline:<\/p>\n\n<ul>\n  <li>Nov 2012 - Apply for Mozilla online<\/li>\n  <li>Early Jan 2013 - Response from Mozilla recruiters requesting interviews<\/li>\n  <li>Jan to Feb 2013 - Interviews with Mozilla (five in total)<\/li>\n  <li>Early March 2013 - Response from Mozilla with offer<\/li>\n  <li>March to May - Visa application, flights and housing planning<\/li>\n  <li>Mid May - Start internship at Mozilla :)<\/li>\n  <li>Late Aug - End internship at Mozilla :(<\/li>\n<\/ul>\n\n<blockquote>\n  <p>What\u2019s awesome about interning at Mozilla?<\/p>\n<\/blockquote>\n\n<p>A lot! Read my post <a href=\"\/post\/summer-at-mozilla\">My Summer At Mozilla<\/a> here for more details (and pictures).<\/p>\n\n<blockquote>\n  <p>Any last tips?<\/p>\n<\/blockquote>\n\n<p>Contribute to open source! Mozilla just loves to see that stuff and it\u2019s just good karma in general. Fork a project from <a href=\"https:\/\/github.com\/mozilla\">Mozilla on GitHub<\/a> and start sending pull requests. Even if you don\u2019t land that internship you can still contribute to what Mozilla is doing for the web.<\/p>\n\n<p>Best of luck in your internship endeavours. If you have any questions I didn\u2019t cover in this FAQ, <a href=\"mailto:ryan@ryanseys.com\">email me<\/a>.<\/p>\n\n"},{"title":"Fooling with Open Data","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/fooling-with-open-data"}},"updated":"2014-02-09T00:00:00-08:00","id":"https:\/\/ryanseys.com\/post\/fooling-with-open-data","content":"<p>This evening after a long day of working on school assignments (<strong>BORING<\/strong>), I got a really big urge to start fooling with open data. So I did.<\/p>\n\n<p>I live in Ottawa Canada, and Ottawa has an <a href=\"http:\/\/data.ottawa.ca\/\">Open Data Catalog<\/a> that gives you access to various types of data. In my struggle to find something interesting to do with the data in the little time and imagination that I have, I found myself scowring other sources for other types of data to peek my interests.<\/p>\n\n<p>I made my way to Open Data Toronto, Open Data Waterloo and finally found myself at Health Canada, more specifically their food and nutrition site containing the <a href=\"http:\/\/www.hc-sc.gc.ca\/fn-an\/nutrition\/fiche-nutri-data\/cnf_file_structure-des_fichiers_fcen-eng.php\">Canadian Nutrient File<\/a>. I was just hungry\u2026 for data!<\/p>\n\n<p>The Canadian Nutrient File contains a plethora of information regarding all ranges of food types. I was specifically drawn to the <a href=\"http:\/\/www.hc-sc.gc.ca\/fn-an\/nutrition\/fiche-nutri-data\/cnf_file_structure-des_fichiers_fcen-eng.php#a10\">Refuse Amount File<\/a> containing information regarding the amount of refuse, i.e. the inedible portion for each food.<\/p>\n\n<p>I immediately downloaded their data set (<strong>11MB!<\/strong>) which turned out to contain a boatload of files I had no idea how to open.<\/p>\n\n<p><img src=\"\/img\/refuse-data.png\" alt=\"Refuse DBF\" \/><\/p>\n\n<p>A quick Google search for DBF directed me to <a href=\"https:\/\/github.com\/infused\/dbf\">a dbf library<\/a> to open said files with Ruby. Time to whip out the Terminal!<\/p>\n\n<p>First I installed the library like a boss.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"nv\">$ <\/span>gem <span class=\"nb\">install <\/span>dbf\nSuccessfully installed dbf-2.0.7\n1 gem installed<\/code><\/pre><\/figure>\n\n<p>Rather anti-climatic, but so far so good. Next lets just jump into <code class=\"language-plaintext highlighter-rouge\">irb<\/code> to fool around.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-bash\" data-lang=\"bash\"><span class=\"nv\">$ <\/span>irb\nirb<span class=\"o\">(<\/span>main<span class=\"o\">)<\/span>:001:0&gt;<\/code><\/pre><\/figure>\n\n<p>And now lets <code class=\"language-plaintext highlighter-rouge\">require 'dbf'<\/code> and read in the dbf file.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">001<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"nb\">require<\/span> <span class=\"s1\">'dbf'<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"kp\">true<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">002<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">data<\/span> <span class=\"o\">=<\/span> <span class=\"no\">DBF<\/span><span class=\"o\">::<\/span><span class=\"no\">Table<\/span><span class=\"p\">.<\/span><span class=\"nf\">new<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"REFUSE.DBF\"<\/span><span class=\"p\">)<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"c1\">#&lt;DBF::Table:0x007f8b1b02b4a0 ...etc... @memo=nil&gt;<\/span><\/code><\/pre><\/figure>\n\n<p>Cool! We read in this weird file! So <code class=\"language-plaintext highlighter-rouge\">data<\/code> is now a table with records. Let\u2019s get the first one and take a look at its attributes.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">003<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">data<\/span><span class=\"p\">.<\/span><span class=\"nf\">first<\/span><span class=\"p\">.<\/span><span class=\"nf\">attributes<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span><span class=\"s2\">\"FD_ID\"<\/span><span class=\"o\">=&gt;<\/span><span class=\"mf\">2.0<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"REFUSE_ID\"<\/span><span class=\"o\">=&gt;<\/span><span class=\"mf\">750.0<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"REFUSE_AMT\"<\/span><span class=\"o\">=&gt;<\/span><span class=\"mf\">0.0<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"CF_DT_ENT\"<\/span><span class=\"o\">=&gt;<\/span><span class=\"s2\">\"01\/05\/1997\"<\/span><span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>So each record has some refuse amount. Let\u2019s do something neat with it, say, calculate the average across all food records.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">004<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"mi\">0<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">005<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">sum<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"mi\">0<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">006<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">data<\/span><span class=\"p\">.<\/span><span class=\"nf\">each<\/span> <span class=\"k\">do<\/span> <span class=\"o\">|<\/span><span class=\"n\">record<\/span><span class=\"o\">|<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">007<\/span><span class=\"p\">:<\/span><span class=\"mi\">1<\/span><span class=\"o\">*<\/span>  <span class=\"n\">sum<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">record<\/span><span class=\"p\">.<\/span><span class=\"nf\">attributes<\/span><span class=\"p\">[<\/span><span class=\"s2\">\"REFUSE_AMT\"<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">00<\/span><span class=\"mi\">8<\/span><span class=\"p\">:<\/span><span class=\"mi\">1<\/span><span class=\"o\">&gt;<\/span>  <span class=\"n\">count<\/span> <span class=\"o\">+=<\/span> <span class=\"mi\">1<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">00<\/span><span class=\"mi\">9<\/span><span class=\"p\">:<\/span><span class=\"mi\">1<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">end<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"mi\">7138<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">010<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">sum<\/span><span class=\"o\">\/<\/span><span class=\"n\">count<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"mf\">9.901528593443539<\/span><\/code><\/pre><\/figure>\n\n<p>Wow! So on average across 7138 food items, the average refuse amount is <strong>9.9%<\/strong> That\u2019s kinda interesting.<\/p>\n\n<p>Let\u2019s see what the max refuse amount is\u2026<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">011<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">data<\/span><span class=\"p\">.<\/span><span class=\"nf\">each<\/span> <span class=\"k\">do<\/span> <span class=\"o\">|<\/span><span class=\"n\">record<\/span><span class=\"o\">|<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">012<\/span><span class=\"p\">:<\/span><span class=\"mi\">1<\/span><span class=\"o\">*<\/span>  <span class=\"k\">if<\/span> <span class=\"n\">record<\/span><span class=\"p\">.<\/span><span class=\"nf\">attributes<\/span><span class=\"p\">[<\/span><span class=\"s2\">\"REFUSE_AMT\"<\/span><span class=\"p\">]<\/span> <span class=\"o\">&gt;<\/span> <span class=\"n\">max<\/span> <span class=\"k\">then<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">013<\/span><span class=\"p\">:<\/span><span class=\"mi\">2<\/span><span class=\"o\">*<\/span>    <span class=\"n\">max<\/span> <span class=\"o\">=<\/span> <span class=\"n\">record<\/span><span class=\"p\">.<\/span><span class=\"nf\">attributes<\/span><span class=\"p\">[<\/span><span class=\"s2\">\"REFUSE_AMT\"<\/span><span class=\"p\">]<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">014<\/span><span class=\"p\">:<\/span><span class=\"mi\">2<\/span><span class=\"o\">&gt;<\/span>  <span class=\"k\">end<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">015<\/span><span class=\"p\">:<\/span><span class=\"mi\">1<\/span><span class=\"o\">&gt;<\/span> <span class=\"k\">end<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"mi\">7138<\/span>\n<span class=\"n\">irb<\/span><span class=\"p\">(<\/span><span class=\"n\">main<\/span><span class=\"p\">):<\/span><span class=\"mo\">016<\/span><span class=\"p\">:<\/span><span class=\"mi\">0<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">max<\/span>\n<span class=\"o\">=&gt;<\/span> <span class=\"mf\">86.0<\/span><\/code><\/pre><\/figure>\n\n<p>Disregarding my terrible coding, this is actually cool. The maximum refuse a food has in the database is <strong>86%!<\/strong> That\u2019s a huge inedible portion! Now in theory I could continue to look up in the other DBF files to find out what that food was, and possibly correlate it with all other high-refuse foods. For the sake of this example I just wanted to show you what is possible with a couple hours, a few cups of tea and a little imagination. And really, the possibilities are endless, all thanks to Open Data (and tea)!<\/p>\n\n<p>Go make some cool stuff with open data! :) Get started <a href=\"http:\/\/data.gc.ca\/eng\/open-data\">here.<\/a><\/p>\n\n"},{"title":"I made a thing","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/i-made-a-thing"}},"updated":"2013-12-01T00:00:00-08:00","id":"https:\/\/ryanseys.com\/post\/i-made-a-thing","content":"<p>I made <a href=\"https:\/\/github.com\/ryanseys\/node-jawbone-up\">a thing<\/a>. It only took me this weekend to do, but now there it is. It is that fact, its existence, that made it all worth it.<\/p>\n\n<p>Perhaps I rushed it? Maybe I should have taken a couple weekends, sat on the idea a bit longer? Drilled over the design a bit harder? Wrote more tests before releasing it into the wild? Maybe I should have taken <em>less<\/em> time and shipped it from day one? Designed in the open? Wrote no tests or documentation and just hacked it?<\/p>\n\n<!-- end_excerpt -->\n\n<p>Who cares what I <em>should have done<\/em>, when all we know is what I <em>did do<\/em>. I made a thing. It\u2019s not perfect, but it works.<\/p>\n\n<p>I\u2019m not <em>that<\/em> proud of what it is, for it\u2019s only a thing. I\u2019m more proud that I was able to get it <strong>done<\/strong>. I\u2019m more proud that I told myself I was gonna make it, and then I made it.<\/p>\n\n<p>When I envisioned on day one what this thing would look like on release day, I have to say it looked a hell of a lot better than this. More tests, cleaner docs, dryer code. Now don\u2019t get me wrong, it could also be a lot worse. It\u2019s not that I don\u2019t care about all those good things, but countless times I\u2019ve waited for that right moment to launch only to never launch at all. Don\u2019t do that.<\/p>\n\n<p>So there we are, I made a thing. And I wrote this post. I told myself I would do something, and I kinda actually did it. That\u2019s what success is to me.<\/p>\n"},{"title":"Show People","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/show-people"}},"updated":"2013-11-11T00:00:00-08:00","id":"https:\/\/ryanseys.com\/post\/show-people","content":"<p><em>\u201cThe truth is generally seen, rarely heard.\u201d<\/em> \u2014 Baltazar Gracian (1601-1658)<\/p>\n\n<p>Recently I\u2019ve been thinking about <a href=\"https:\/\/shopify.com\" title=\"Shopify\">Shopify<\/a>\u2019s mantra \u201c<strong>Do things, tell people<\/strong>\u201d and it makes me wonder more about what catalyzes success. <a href=\"http:\/\/carl.flax.ie\/dothingstellpeople.html\">Here<\/a> it is discussed that these two things are all it takes to be successful. But I have to ponder, is it simply <em>doing stuff<\/em> that has the largest impact on success? Or is it <em>telling people<\/em> about the things you do that is more impactful? I have come to reason that of those two, what is most often overlooked is telling people. But it still might not be enough.<\/p>\n\n<p><img src=\"\/img\/show-and-tell.png\" alt=\"ShowAndTell\" \/><\/p>\n\n<h2 id=\"make-to-show\">Make to Show<\/h2>\n\n<p>People have no problems making things, cool things for that matter, but if nobody knows about it then what good is it? I have written numerous software projects, <a href=\"https:\/\/github.com\/ryanseys\" title=\"Ryan Seys GitHub\">open sourced<\/a> them, but have never first hand <em>told<\/em> anyone about them, and their \u201csuccess\u201d (or lack there of) can be attributed to this fact. I started thinking that success is defined by how much you tell someone about something, but as I thought about it more there was a finer distinction between telling someone something and <strong>showing<\/strong> them it.<\/p>\n\n<p>Showing involves both doing stuff, i.e. making the stuff you want to show, and then interactively telling someone about it. Demos are a great way to show off your work. As an example, what do you think would be more effective: telling someone that your cheese is the best cheese in town or giving out free samples to show them that it is the best? Apple claims its products are a joy to use, and then they show the devices to their users so they can try them out and judge for themselves. Telling people about your idea is easy, but if you believe in an idea then you should turn it into a real thing and show it off.<\/p>\n\n<h2 id=\"show-to-persuade\">Show to Persuade<\/h2>\n\n<p>Showing people is also a very strong way to persuade people to your point of view. For example, rather than telling someone they should do something because it\u2019s more efficient, show them. Show them by doing, and if it actually is more efficient, they will naturally follow by example. They may not even realize it and think they decided all themselves. Law #9 from the book <a href=\"http:\/\/www.amazon.ca\/The-Laws-Power-Robert-Greene\/dp\/0140280197\" title=\"The 48 Laws of Power\">48 Laws of Power<\/a> is <strong>Win through your actions, never through argument<\/strong>. A great point is made with this law: showing people through example is much more effective than simply telling them or arguing your point of view. \u201cDemonstrate, do not explicate.\u201d<\/p>\n\n<p>Showing should be seen as an extension of \u201cDo things, tell people.\u201d You should continue to do things, tell people, but also show people. Show people why they should use your product. Show people why they should help you. Tell people why by showing them why.<\/p>\n\n<h2 id=\"persuade-to-succeed\">Persuade to Succeed<\/h2>\n\n<p><img src=\"\/img\/win-friends.png\" alt=\"WinFriends\" \/> <a href=\"http:\/\/www.amazon.ca\/How-Win-Friends-Influence-People\/dp\/0671027034\" title=\"How to Win Friends and Influence People\">How to Win Friends and Influence People<\/a>, a timeless classic and highly recommended book by Dale Carnegie talks of influencing people to gain your point of view. Rule #3 in the book can be summarized as \u201cArouse in other people an eager want.\u201d Carnegie makes a very good point in saying that the only way to get someone to do something is to make them want to do it. \u201cEvery act you have ever performed since the day you were born was performed because you wanted something.\u201d Carnegie also states \u201cSo the only way on earth to influence other people is to talk about what <em>they<\/em> want and <strong>show<\/strong> them how to get it.\u201d Yes, <em>show<\/em> them.<\/p>\n\n<p>I challenge you to show someone something today. Whether it be a new lifehack you\u2019ve recently learned, a side-project you\u2019re \u201calmost done\u201d, or even that new recipe you\u2019ve been dying to try. Just <em>show people<\/em>.<\/p>\n\n<p><a href=\"https:\/\/twitter.com\/ryanseys\" title=\"Ryan Seys Twitter\">Follow me<\/a> on Twitter :) Email me at <a href=\"mailto:ryan@ryanseys.com\" title=\"Email me\">ryan@ryanseys.com<\/a> or <a href=\"https:\/\/news.ycombinator.com\/item?id=6721553\">Discuss on HN<\/a><\/p>\n\n<p><small>Disclaimer: Please don\u2019t take my advice too far and get yourself arrested for indecent exposure.<\/small><\/p>\n\n"},{"title":"177 Days of GitHub","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/177-days-of-github"}},"updated":"2013-09-14T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/177-days-of-github","content":"<p>This is the story of how I contributed to <a href=\"https:\/\/github.com\/ryanseys\" title=\"Ryan Seys GitHub\">GitHub<\/a> for 177 consecutive days, nearly half a year. I will talk of why I did it and why you should too, or at least why you should do something similar. This is a story about accepting challenges, making habits, and knowing when to stop. I learned a lot through this, and I hope to teach you all something. Let\u2019s begin.<\/p>\n\n<p><img src=\"\/img\/ch_habit.gif\" alt=\"CH-Habits\" title=\"Calvin and Hobbes - Bill Watterson\" \/>\n<i><small>We can\u2019t all fight habits as well as Calvin.<\/small><\/i><\/p>\n\n<h2 id=\"the-30-day-github-challenge\">The 30-day GitHub challenge<\/h2>\n\n<p>It all started as a 30-day challenge. A good friend of mine <a href=\"https:\/\/shuhaowu.com\/\" title=\"Shuhao Wu\">Shuhao<\/a> messaged me on the 21st of February, challenging me to contribute to GitHub every day for 30 consecutive days and he would do the same. At that time my longest streak on GitHub had been a measly 5 days. It was a lack-luster streak that I wanted to improve but just couldn\u2019t find enough motivation. This opportunity to both challenge myself and challenge him was just what I needed to make it all happen. I accepted the challenge under a few simple conditions:<\/p>\n\n<ol>\n  <li>Edits to README don\u2019t count unless significant in nature.<\/li>\n  <li>No scripting; you must personally make the contributions.<\/li>\n  <li>No funny business editing commit times and such.<\/li>\n<\/ol>\n\n<p>I started this streak off with a <strong>bang<\/strong>, contributing nearly 30 commits to my website and other various projects on the first day. This actually happened to be the most contributions in a single day that I made throughout the entire half-year streak. I was motivated to make it to 30 days and maybe even keep going until one of us declared defeat, so this was the best way to start.<\/p>\n\n<h2 id=\"one-week\">One week<\/h2>\n\n<p>A week into the challenge, difficulty started to set in. I was nearly forgetting to commit or otherwise contribute, waiting until the last possible moment to submit my daily contribution. Shuhao ended up dropping out of the challenge at 8 days. I think he just forgot, which I don\u2019t blame him.<\/p>\n\n<p>But I kept going\u2026<\/p>\n\n<h2 id=\"two-weeks\">Two weeks<\/h2>\n\n<p><img src=\"\/img\/habit-book.png\" alt=\"HabitBook\" title=\"The Power of Habit\" \/><\/p>\n\n<p>Two to three weeks in it was easier to remember to commit, it was becoming more of a habit. Soon internal reminders to contribute were paired with the reminder to brush my teeth, something I rarely forget to do. Around the same time I picked up a book called <em><a href=\"http:\/\/www.amazon.com\/The-Power-Habit-What-Business\/dp\/1400069289\" title=\"The Power of Habit\">The Power of Habit<\/a><\/em> which educated me on habits and how to understand and change your habits for your benefit. I recommend you read this book if you have any interest in how your brain deals with habits. It\u2019s quite fascinating, one story in the book spoke of a man who couldn\u2019t remember how to navigate his own home and yet could go for daily walks around the block and not get lost, all thanks of the power of habits. But I digress. Before I knew it, the power of habit had brought me to\u2026<\/p>\n\n<h2 id=\"30-days\">30 days!<\/h2>\n\n<p>Thirty days was exciting! I had <strong>made it!<\/strong> And all I wanted to do was keep going! After 30 days, it just became a way of life. Eat, sleep, commit. It became normal and I no longer found it difficult to include in my day-to-day rituals. But like any habit, it was hard to be 100% consistent, so there were definitely some close calls on busy days. I commited from my phone. I committed after getting home extra late from hanging with friends. I even commited in a state of <a href=\"https:\/\/xkcd.com\/323\/\" title=\"Ballmer Peak\">Ballmer Peak<\/a>. This reminds me of a few tricks I learned along the way regarding GitHub contributions:<\/p>\n\n<h2 id=\"github-contribution-tricks\">GitHub contribution tricks<\/h2>\n\n<ol>\n  <li>GitHub runs on PST, which meant I could contribute anywhere from 12am \u2014 3am local time (EST) and have it count for the previous day. When I got home extra late a few nights, this trick had my back.<\/li>\n  <li>Filing an issue on any repo counts as a contribution. This saved me a few times I was short on code ideas.<\/li>\n  <li>Commits are separate from pushes. Commit now and push later and it will still count for whenever you commited.<\/li>\n  <li>Initial commits from newly created repos <strong>don\u2019t<\/strong> count. But the second commit on that repo will make both commits count. This one is weird.<\/li>\n  <li>Pull requests count for 1 contribution when you make them and another contribution if they are merged. If they don\u2019t get merged, sorry, no second contribution.<\/li>\n<\/ol>\n\n<p>Though these tricks admittedly saved my ass when it came to my GitHub streak, I was keeping within the simple conditions originally outlined above. You can see more tips from GitHub <a href=\"https:\/\/help.github.com\/articles\/why-are-my-contributions-not-showing-up-on-my-profile\" title=\"GitHub Contribution Tips\" target=\"_blank\">here<\/a>.<\/p>\n\n<h2 id=\"100-days\">100 Days<\/h2>\n\n<p>One hundred days was a big moment for me as well. At this point I was in San Francisco, interning at <a href=\"https:\/\/www.mozilla.org\/\" title=\"Mozilla\">Mozilla<\/a>. You can read all about that experience <a href=\"\/post\/summer-at-mozilla\" title=\"My Summer at Mozilla\">on my blog<\/a>. The great thing about working at Mozilla is that everything is open source, so I more or less could just <em>work<\/em> and keep my streak going. It wasn\u2019t as easy as that, but being at Mozilla really helped.<\/p>\n\n<p>Mozilla had their fair share of internal competition as well, including Shuhao who joined me in interning there this summer and was back at his streak, this time with much more <a href=\"https:\/\/github.com\/shuhaowu\" title=\"Shuhao Wu GitHub\">success<\/a>, as well a <a href=\"https:\/\/github.com\/willkg\" title=\"Will Kahn-Greene\">silent competitor<\/a> I never knew personally but whom I heard about through the Mozilla grapevine.<\/p>\n\n<h2 id=\"150-days\">150 Days<\/h2>\n\n<p>There reached a point where my motivation to keep the streak going took a nose-dive. I attribute this to a lack of ideas, a drive for a fresh challenge, and the realization of the inevitability that my streak would eventually end. All this combined with the fact was that there was just too many ways to \u201ccheat\u201d the system, like <a href=\"https:\/\/github.com\/antimatter15\/daily\" title=\"Shameful\">this guy<\/a> did, and thus the challenge started to turn into a chore.<\/p>\n\n<p>I wanted to escape. I wanted time to refresh and forget about GitHub for just a little bit. I just wanted to be free to think about new ideas and not worry about making that commit just for the sake of it. I decided to end the streak on a nice round number. I decided to continue until 200 days were reached and then I would graciously sit back and watch the streak come crumbling down.<\/p>\n\n<h2 id=\"oops\">Oops<\/h2>\n\n<p>200 days didn\u2019t come. I forgot to commit on day #178, and with this tragic realization a sudden weight was lifted off me and I felt simultaneously relieved. It was all finally over.<\/p>\n\n<p><img src=\"\/img\/streak.png\" alt=\"ContributionsTable\" title=\"GitHub streak\" \/><\/p>\n\n<h2 id=\"looking-back\">Looking back<\/h2>\n\n<p>My 177-day streak taught me a lot about habits. It taught me how good habits can turn evil when excessively executed. It taught me a lot about the power of \u201c<a href=\"http:\/\/dontbreakthechain.com\/what\" title=\"Do Not Break The Chain\">don\u2019t break the chain<\/a>\u201d, the motivational technique behind successful GitHub streaks. I still commit to GitHub on a regular basis but now I make less <em>required<\/em> and more <em>desired<\/em> contributions. I take regular days away from the computer to refresh my ideas and come back stronger than when I left. I recommend everyone try to break a habit or start a habit using this technique, but it can be really powerful so much as to be draining so watch out!<\/p>\n\n<p>If you know of anyone with a longer GitHub streak than me, please let me know! I haven\u2019t found anyone yet! ;)<\/p>\n\n<p>Happy contributing! <a href=\"https:\/\/github.com\/ryanseys\" title=\"Ryan Seys GitHub\">Follow me<\/a> on GitHub! :) <a href=\"https:\/\/news.ycombinator.com\/item?id=6389019\" title=\"Hacker News discussion\">Discuss<\/a> on HN.<\/p>\n\n"},{"title":"Atom Support","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/atom-support"}},"updated":"2013-09-07T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/atom-support","content":"<p>This blog now supports Atom feeds for your subscribing pleasure. Please <a href=\"mailto:ryan@ryanseys.com\">email me<\/a> if you have any issues!<\/p>\n\n<p><a href=\"\/atom.xml\">Atom feed<\/a><\/p>\n\n"},{"title":"My Summer at Mozilla","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/summer-at-mozilla"}},"updated":"2013-09-01T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/summer-at-mozilla","content":"<p>As of writing this, I am currently on my flight back to Canada wrapping up my internship at <a href=\"https:\/\/www.mozilla.org\/\" title=\"Mozilla\">Mozilla<\/a> for the summer. I just wanted to take this time to reflect on my experience working there and why Mozilla has been a truly life-altering experience! Overall it was <strong>AWESOME<\/strong>, but WHY, you ask? Well keep reading there cap\u2019n, and I\u2019ll tell ya!<\/p>\n\n<h2 id=\"1-the-projects-were-awesome\">1. The projects were awesome<\/h2>\n\n<p><img src=\"\/img\/me-moz-sign.jpg\" alt=\"MozillaandMe\" \/><\/p>\n\n<p>My internship specifically took place with the <a href=\"http:\/\/identity.mozilla.com\/\" title=\"Identity Team blog\">Identity team<\/a>, the good folks that bring you <a href=\"https:\/\/login.persona.org\" title=\"Persona\">Persona<\/a>. I hacked on a new initiative to bring <a href=\"http:\/\/dev.w3.org\/2011\/webrtc\/editor\/webrtc.html#identity\" title=\"WebRTC Auth\">authentication to WebRTC<\/a> in Firefox. In addition to this, I also hacked on Persona (more specifically, <a href=\"https:\/\/github.com\/mozilla\/browserid\/\" title=\"browserid on GitHub\">browserid<\/a>) to support this new authentication module, allowing any website that uses Persona to seamlessly authenticate their users\u2019 WebRTC calls.<\/p>\n\n<p>During my time at Mozilla, I also built a WebRTC demonstration web app called <a href=\"https:\/\/github.com\/mozilla\/tincan\/\" title=\"Tin Can\">Tin Can<\/a> to showcase the importance of WebRTC auth. This app was such a hit with Mozilla and looked so damn polished thanks to a couple amazing <a href=\"https:\/\/github.com\/johngruen\/\" title=\"John Gruen\">Identity<\/a> <a href=\"http:\/\/ryanfeeley.com\/\" title=\"Ryan Feeley\">designers<\/a>, it prematurely hit Hacker News and climbed to the front page due to shear awesomeness of what WebRTC + Persona means for the future of web calls.<\/p>\n\n<p>Unfortunately, Tin Can is not quite ready for public consumption so it was promptly taken down for now but like all Mozilla projects, it is open source so please contribute to this project by forking it on GitHub and send me some sexy pull requests. :)<\/p>\n\n<p>You can learn more about the details of what I did by watching <a href=\"https:\/\/air.mozilla.org\/intern-presentation-seys\/\" title=\"Persona + WebRTC = &lt;3\">this screencast<\/a> on Air Mozilla.<\/p>\n\n<h2 id=\"2-the-places-were-awesome\">2. The places were awesome<\/h2>\n\n<p>Mozilla flew me out from Ottawa, my homebase, to San Francisco, CA! Having never been to California before, what an adventure it was and has been! Now those from San Francisco warned me about the weather in the \u201csummer\u201d here, but you just can\u2019t beat the lack of humidity in SF.<\/p>\n\n<p>In Canada (Ottawa at least), contrary to popular belief, we do have hot summers and boy are they ever humid. It was a nice change to spend my summer in jeans and a hoodie. Plus, if the fog ever got me down, I\u2019d just hop on the Caltrain and head down to the Mountain View office for the day. I also went to France! But more on that later!<\/p>\n\n<p>Mozilla provided us SF interns with housing just a 6 minute <strong>walk<\/strong> from their San Francisco office. This may have been so we stayed at the office longer, but who wouldn\u2019t want to stay in the office when it provides you with free snacks and drinks, and a view that just cannot be beat.<\/p>\n\n<p><img src=\"\/img\/bay-bridge.png\" alt=\"pic\" \/><\/p>\n\n<p>Which brings me to my next point\u2026<\/p>\n\n<h2 id=\"3-the-perks-were-awesome\">3. The perks were awesome<\/h2>\n\n<p>Interns at Mozilla, myself included, are truly spoiled rotten. Competitive pay, free travel\/housing, free snacks\/drinks and catered lunches every week were really just icing on the massive cake that was my internship!<\/p>\n\n<p>Oh, and did I mention that Mozilla also sent me to <strong>Paris, France?!<\/strong> Yeah, it happened. For my final working week, myself and a handful of the Identity team met up in the Paris office and hacked on Persona, and ate\u2026 and drank\u2026 a lot!<\/p>\n\n<p>It was quite the trip and I feel very privileged to be apart of it, but it was only as good as it was because of the people. Mozillians are really a different breed of people, which leads me to #4\u2026<\/p>\n\n<h2 id=\"4-the-people-were-awesome\">4. The people were awesome<\/h2>\n\n<p><img src=\"\/img\/moz-paris.jpg\" alt=\"MozParis\" \/><\/p>\n\n<p>Working at Mozilla wasn\u2019t work, it was long conversations over espresso with some abnormally smart people. It was scribbling on whiteboards at 6pm that kept getting more detailed as the sun fell. It was morning conference calls that would span several different timezones and continents. Sounds like work right? Well, at Mozilla it certainly didn\u2019t feel like it. Now don\u2019t get me wrong, the Identity team is composed of some of the most productive people I\u2019ve ever worked with, but they also know how to party!<\/p>\n\n<p>A hard day\u2019s work does not go unnoticed or unrewarded at Mozilla. The work-life balance is something that is not an after-thought, it\u2019s your right as a Mozillian (after your patches land and pull requests are merged of course).<\/p>\n\n<h2 id=\"summary\">Summary<\/h2>\n\n<p>Interning at Mozilla has really been a life-changing experience. I\u2019ve met so many amazing people and learned so much along the way. I would highly recommend to anyone that\u2019s awesome, <a href=\"https:\/\/careers.mozilla.org\/\" title=\"Mozilla Careers\">apply<\/a> for an internship (or job) there, you won\u2019t be disappointed. During my short time with them, I was able to contribute to Mozilla in ways I never imagined.<\/p>\n\n<p>Mozilla, keep rockin\u2019 the free web and thank you for the rockin\u2019 summer! :)<\/p>\n\n<hr \/>\n\n<p>If you have any questions regarding my personal experience at Mozilla, discuss them with me <a href=\"https:\/\/news.ycombinator.com\/item?id=6317851\" title=\"Hacker News discussion\">here on HN<\/a> or email me at <a href=\"mailto:ryan@ryanseys.com\" title=\"Email me\">ryan@ryanseys.com<\/a><\/p>\n\n<p><small><b>Disclaimer: <\/b>Yeah, I worked at Mozilla but these thoughts and (rather awesome) experiences are my own and may not represent the views of Mozilla or their employees. Individual results may vary. Ask your doctor if Mozilla is right for you.<\/small><\/p>\n\n"},{"title":"Building PhotoGPS","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/building-photogps"}},"updated":"2013-07-13T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/building-photogps","content":"<p><a href=\"http:\/\/ryanseys.github.io\/photogps\/\">PhotoGPS<\/a> is a simple and fast web app you can use to instantly plot your photos on Google Maps, based on where they were taken.<\/p>\n\n<p>It does this by extracting the GPS location (latitude &amp; longitude) from the Exif metadata within the photo itself, and then using Google Maps API to display exactly where this is in the world.<!-- end_excerpt --> In modern browsers, there exists an API for reading files directly in the browser. This API is called <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FileReader\">FileReader<\/a> and it is what PhotoGPS uses to read your images directly, without first uploading them to the cloud. This keeps your data completely private from any server, while speeding up the extraction and plotting process significantly. You can plot literally 1000 photos in less than a minute.<\/p>\n\n<p><img src=\"\/img\/photogps.png\" alt=\"PhotoGPS\" \/><\/p>\n\n<h2 id=\"building-it-out\">Building it out!<\/h2>\n\n<p>The initial PhotoGPS app showed markers on the Google Maps for every GPS-embedded photo it processed, but how can you even reflect on the memories taken at that point without a preview of the image. So a more recent version of PhotoGPS included thumbnail previews of your images (as shown in the screenshot above). Getting the thumbnails without using a server side is not too complicated in modern browsers. I just read the file in as a DataURL using the FileReader API, wrap that data in an image and voila!<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-js\" data-lang=\"js\"><span class=\"kd\">function<\/span> <span class=\"nf\">drop_files<\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">files<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">files<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">dataTransfer<\/span><span class=\"p\">.<\/span><span class=\"nx\">files<\/span><span class=\"p\">;<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">reader<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">FileReader<\/span><span class=\"p\">();<\/span>\n  <span class=\"nx\">reader<\/span><span class=\"p\">.<\/span><span class=\"nf\">readAsDataURL<\/span><span class=\"p\">(<\/span><span class=\"nx\">file<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]);<\/span> <span class=\"c1\">\/\/ let's assume they drop only 1 file<\/span>\n\n  <span class=\"c1\">\/\/wait until the whole file has been read<\/span>\n  <span class=\"nx\">reader<\/span><span class=\"p\">.<\/span><span class=\"nx\">onloadend<\/span> <span class=\"o\">=<\/span> <span class=\"kd\">function<\/span><span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"c1\">\/\/ you've got image data!<\/span>\n    <span class=\"kd\">var<\/span> <span class=\"nx\">image_as_base64<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">event<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">result<\/span><span class=\"p\">;<\/span>\n    <span class=\"kd\">var<\/span> <span class=\"nx\">img<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">Image<\/span><span class=\"p\">();<\/span>\n    <span class=\"nx\">img<\/span><span class=\"p\">.<\/span><span class=\"nx\">src<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">image_as_base64<\/span><span class=\"p\">;<\/span>\n    <span class=\"c1\">\/\/ now you've got an image to do whatever you want with!<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<h2 id=\"scaling-it-up-or-down\">Scaling it up (or down)!<\/h2>\n\n<p>The above code is proof of concept, and would result in the entire full resolution file being processed and spat back out as a base64 string. When you start processing thousands of photos, each being stored as full resolution base64 strings, you\u2019re going to suck up a lot of memory pretty damn fast, so the obvious thing we can do is reduce the size of the image we store in the browser. We can use some fancy HTML5 Canvas elements to reduce the image by creating a canvas element of a particular size (let\u2019s say 100x100), calculating the proper dimensions of the image that would fit in such a box, and rendering the image in the canvas from our base64 string, then immediately asking for the rendered copy back (at 100x100 size), and throw out the original.<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ ...continue from previous code snippet<\/span>\n<span class=\"nx\">img<\/span><span class=\"p\">.<\/span><span class=\"nx\">src<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">event<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">result<\/span><span class=\"p\">;<\/span>\n<span class=\"nx\">img<\/span><span class=\"p\">.<\/span><span class=\"nx\">onload<\/span> <span class=\"o\">=<\/span> <span class=\"kd\">function<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span> <span class=\"c1\">\/\/ image loaded in img?<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">canvas<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nf\">createElement<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">canvas<\/span><span class=\"dl\">'<\/span><span class=\"p\">);<\/span>\n  <span class=\"nx\">canvas<\/span><span class=\"p\">.<\/span><span class=\"nx\">width<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">imageWidth<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/calculated new image width of thumbnail<\/span>\n  <span class=\"nx\">canvas<\/span><span class=\"p\">.<\/span><span class=\"nx\">height<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">imageHeight<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/calculated new image height of thumbnail<\/span>\n\n  <span class=\"kd\">var<\/span> <span class=\"nx\">ctx<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">canvas<\/span><span class=\"p\">.<\/span><span class=\"nf\">getContext<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">2d<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n  <span class=\"c1\">\/\/ redraw smaller<\/span>\n  <span class=\"nx\">ctx<\/span><span class=\"p\">.<\/span><span class=\"nf\">drawImage<\/span><span class=\"p\">(<\/span><span class=\"k\">this<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"nx\">imageWidth<\/span><span class=\"p\">,<\/span> <span class=\"nx\">imageHeight<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">thumbnail_data<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">canvas<\/span><span class=\"p\">.<\/span><span class=\"nf\">toDataURL<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">image\/jpeg<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n  <span class=\"c1\">\/\/ use the thumbnail_data now as your base64 string<\/span>\n<span class=\"p\">};<\/span><\/code><\/pre><\/figure>\n\n<h2 id=\"speeding-it-up\">Speeding it up!<\/h2>\n\n<p>In the initial versions of PhotoGPS outlined previously, the speed at which files were processing relied on the size of the file itself. This was because initial techniques for reading and extracting the GPS location from the files were inefficient. It involved reading in the entire file including all of the image data to extract the GPS location and image data and then proceeding to extract the data. With <a href=\"http:\/\/code.flickr.net\/2012\/06\/01\/parsing-exif-client-side-using-javascript-2\/\">a little research<\/a>, I was able to determine that the Exif data is limited to a certain section of the file (within the first 128 kilobytes of the file). This meant that we can reduce the extraction time from O(n) where n is the filesize, to O(1). Awesome!<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-js\" data-lang=\"js\"><span class=\"kd\">var<\/span> <span class=\"nx\">files<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">files<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">dataTransfer<\/span><span class=\"p\">.<\/span><span class=\"nx\">files<\/span><span class=\"p\">;<\/span>\n<span class=\"kd\">var<\/span> <span class=\"nx\">reader<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">FileReader<\/span><span class=\"p\">();<\/span>\n<span class=\"c1\">\/\/ splicing the first file up to 128kb (saves reading entire file)<\/span>\n<span class=\"kd\">var<\/span> <span class=\"nx\">filePart<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">files<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">].<\/span><span class=\"nf\">slice<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">131072<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/ 131072 bytes = 128 kilobytes<\/span>\n<span class=\"nx\">reader<\/span><span class=\"p\">.<\/span><span class=\"nf\">readAsBinaryString<\/span><span class=\"p\">(<\/span><span class=\"nx\">filePart<\/span><span class=\"p\">);<\/span> <span class=\"c1\">\/\/read in as binary string<\/span>\n\n<span class=\"nx\">reader<\/span><span class=\"p\">.<\/span><span class=\"nx\">onloadend<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">function <\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/feed the resulting binary string into the EXIF reader!<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">exif_data<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">EXIF<\/span><span class=\"p\">.<\/span><span class=\"nf\">readFromBinaryFile<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"nc\">BinaryFile<\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">target<\/span><span class=\"p\">.<\/span><span class=\"nx\">result<\/span><span class=\"p\">));<\/span>\n  <span class=\"c1\">\/\/ boom! exif data extracted!<\/span>\n<span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>EXIF.readFromBinaryFile is a function exposed by <a href=\"https:\/\/github.com\/jseidelin\/exif-js\">a library<\/a> I discovered (and <a href=\"https:\/\/github.com\/ryanseys\/photogps\/commits\/master\/js\/exif.js\">contributed to<\/a>) which allows EXIF parsing in the browser. I added thumbnail extraction to this library by reading the <a href=\"http:\/\/www.exif.org\/Exif2-2.PDF\">Exif spec<\/a> and <a href=\"http:\/\/code.flickr.net\/2012\/06\/01\/parsing-exif-client-side-using-javascript-2\/\">blog posts<\/a> on the topic of client-side Exif extraction, and with a little bit of elbow grease I was able to get thumbnail extraction working!<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-js\" data-lang=\"js\"><span class=\"c1\">\/\/ If IFD1Offset exists in the Exif tags then thumbnail data exists!<\/span>\n<span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"nx\">oTags<\/span><span class=\"p\">.<\/span><span class=\"nx\">IFD1Offset<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ this reads in the tags associated with the thumbnail<\/span>\n  <span class=\"c1\">\/\/ this includes the starting address (JPEGInterchangeFormat)<\/span>\n  <span class=\"c1\">\/\/ and length of the thumbnail data (JPEGInterchangeFormatLength)<\/span>\n  <span class=\"nx\">IFD1Tags<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">readTags<\/span><span class=\"p\">(<\/span><span class=\"nx\">oFile<\/span><span class=\"p\">,<\/span> <span class=\"nx\">iTIFFOffset<\/span><span class=\"p\">,<\/span>\n      <span class=\"nx\">oTags<\/span><span class=\"p\">.<\/span><span class=\"nx\">IFD1Offset<\/span> <span class=\"o\">+<\/span> <span class=\"nx\">iTIFFOffset<\/span><span class=\"p\">,<\/span> <span class=\"nx\">EXIF<\/span><span class=\"p\">.<\/span><span class=\"nx\">TiffTags<\/span><span class=\"p\">,<\/span> <span class=\"nx\">bBigEnd<\/span><span class=\"p\">);<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">JPEGstart<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">IFD1Tags<\/span><span class=\"p\">.<\/span><span class=\"nx\">JPEGInterchangeFormat<\/span><span class=\"p\">;<\/span>\n  <span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"nx\">JPEGstart<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n      <span class=\"c1\">\/\/ See function readThumbnail() below for details<\/span>\n      <span class=\"nx\">oTags<\/span><span class=\"p\">[<\/span><span class=\"dl\">'<\/span><span class=\"s1\">thumbnail<\/span><span class=\"dl\">'<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">readThumbnail<\/span><span class=\"p\">(<\/span><span class=\"nx\">oFile<\/span><span class=\"p\">,<\/span> <span class=\"nx\">JPEGstart<\/span><span class=\"p\">,<\/span>\n          <span class=\"nx\">IFD1Tags<\/span><span class=\"p\">.<\/span><span class=\"nx\">JPEGInterchangeFormatLength<\/span><span class=\"p\">,<\/span> <span class=\"nx\">iTIFFOffset<\/span><span class=\"p\">);<\/span>\n  <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ no luck finding thumbnail data<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"c1\">\/\/ Reads the thumbnail data from an oFile given<\/span>\n<span class=\"kd\">function<\/span> <span class=\"nf\">readThumbnail<\/span><span class=\"p\">(<\/span><span class=\"nx\">oFile<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ThumbStart<\/span><span class=\"p\">,<\/span> <span class=\"nx\">ThumbLength<\/span><span class=\"p\">,<\/span> <span class=\"nx\">TIFFOffset<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n  <span class=\"c1\">\/\/ if the end of the file occurs before end of thumbnail<\/span>\n  <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">oFile<\/span><span class=\"p\">.<\/span><span class=\"nx\">length<\/span> <span class=\"o\">&lt;<\/span> <span class=\"nx\">ThumbStart<\/span><span class=\"o\">+<\/span><span class=\"nx\">TIFFOffset<\/span><span class=\"o\">+<\/span><span class=\"nx\">ThumbLength<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">return<\/span><span class=\"p\">;<\/span> <span class=\"c1\">\/\/ no luck finding thumbnail data<\/span>\n  <span class=\"p\">}<\/span>\n  <span class=\"kd\">var<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">oFile<\/span><span class=\"p\">.<\/span><span class=\"nf\">getStringAt<\/span><span class=\"p\">(<\/span><span class=\"nx\">ThumbStart<\/span><span class=\"o\">+<\/span><span class=\"nx\">TIFFOffset<\/span><span class=\"p\">,<\/span><span class=\"nx\">ThumbLength<\/span><span class=\"p\">);<\/span>\n  <span class=\"k\">return<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">data:image\/jpeg;base64,<\/span><span class=\"dl\">'<\/span> <span class=\"o\">+<\/span> <span class=\"nf\">btoa<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n  <span class=\"c1\">\/\/ image data is returned here! :D<\/span>\n<span class=\"p\">}<\/span><\/code><\/pre><\/figure>\n\n<p>This allowed me to get previews for images without reading in the entire file, unless the Exif thumbnail was not present in which case I didn\u2019t have much choice but to read the whole file in to generate a thumbnail using HTML5 Canvas like discussed earlier.<\/p>\n\n<h2 id=\"conclusion\">Conclusion<\/h2>\n\n<p>This little project was great for a lot of reasons. I learned a lot when it comes to the FileReader API and how much you can really do completely on the client-side. It challenged my low-level skills (reading specs can be a bitch) and pushed me to implement something which I knew was possible but had not yet been documented well. PhotoGPS is a nice little app I use from time to time to plot my photos and see how much I have explored, and what is still left to be discovered!<\/p>\n\n<p>Keep on discovering!<\/p>\n\n<p><img src=\"\/img\/pin.png\" alt=\"Pin\" \/><\/p>\n\n<p><a href=\"http:\/\/ryanseys.github.io\/photogps\/\">app<\/a> \u22c5 <a href=\"https:\/\/github.com\/ryanseys\/photogps\">code<\/a> \u22c5 <a href=\"https:\/\/news.ycombinator.com\/item?id=6039888\">discuss<\/a><\/p>\n\n"},{"title":"Going Paperless","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/going-paperless"}},"updated":"2013-04-07T00:00:00-07:00","id":"https:\/\/ryanseys.com\/post\/going-paperless","content":"<p>I was inspired today by a <a href=\"http:\/\/lifehacker.com\/5993869\/five-best-document-scanners-for-going-paperless\">Lifehacker post<\/a> to go paperless. I am in the midst of decluttering my life in preparation for moving, and with a large box full of documents laying around, I thought this would make the perfect day project.<!-- end_excerpt --><\/p>\n\n<p>One large problem about going paperless is that you still need the information on the paper you currently have laying around; it\u2019s not as easy as simply throwing it all out. But with a good scanner, one may hope to turn that box of documents into a neatly organized folder of PDFs, fully indexed and searchable.<\/p>\n\n<p>That is the ideal world of course. It is much more easily said than done, and I\u2019d need to be efficient about it if I wanted to succeed in turning a whole box of documents into digital files without spending an eternity of time and effort. So I spent money instead, went to the local Staples and purchased myself a <a href=\"http:\/\/www.fujitsu.ca\/products\/scansnap\/ix500\/\">Fujitsu ScanSnap iX500<\/a>, inspired by the Lifehacker post as well as numerous YouTube videos showing it in action, to what I would hope would be as smooth a process as they display.<\/p>\n\n<p><img src=\"\/img\/ix500.png\" alt=\"iX500\" \/><\/p>\n\n<p>This scanner set me back quite a bit of money, though I hope it makes up for in efficiency. I owned a scanner previous to this purchase, though considering it\u2019s a flatbed-type, it would take me weeks upon weeks to scan the documents I already had (the trick is to scan as the documents come to exist in your life, though this is not really an option for me right now).<\/p>\n\n<p>Things I want to come of this:<\/p>\n\n<ol>\n  <li>To be able to scan 40-50 pages at a time with little-to-no effort.<\/li>\n  <li>To have the documents be analyzed with OCR software for indexing and searchability.<\/li>\n  <li>To have the documents backed-up to Dropbox (my cloud of choice).<\/li>\n<\/ol>\n\n<h2 id=\"my-setup\">My Setup<\/h2>\n\n<ul>\n  <li>Fujitsu iX500<\/li>\n  <li><a href=\"http:\/\/www.fujitsu.com\/global\/support\/computing\/peripheral\/scanners\/software\/ix500w-setup.html\">ScanSnap Manager<\/a> (included)<\/li>\n  <li><a href=\"http:\/\/finereader.abbyy.com\/\">ABBYY FineReader<\/a> for ScanSnap (included)<\/li>\n  <li>Macbook Pro<\/li>\n  <li>Lots of documents!<\/li>\n<\/ul>\n\n<p><img src=\"\/img\/going-paperless.png\" alt=\"My Setup\" \/><\/p>\n\n<h2 id=\"my-impression\">My Impression<\/h2>\n\n<p>Holy fuck this thing is awesome. In a little less time that it takes to send a friend a text message, it can be done scanning 80+ pages (front and back), put them in a PDF, and be running OCR software on the document. It\u2019s fast at what it does, it\u2019s efficient and painless to setup. I never thought I\u2019d be so excited about scanning until I met the iX500.<\/p>\n\n<p>ScanSnap Manager includes OCR software built-in which is very fast (10 seconds per document) and good at analyzing and embedding text into the document but it\u2019s not perfect, however no OCR software is perfect. I decided to hook up ABBYY FineReader OCR recognition software to see how it compared, and although it is much slower (5-10 minutes per document), it is very good at what it does, a significant improvement over the ScanSnap software. If you don\u2019t have time to analyze all the documents you scan, might as well use the built-in OCR software, it\u2019s still very good and doesn\u2019t add much time at all.<\/p>\n\n<p>I decided to skip the auto-firing OCR due to time, but it will be very easy for me to drag and drop these PDF files of scanned documents when I want them to be processed.<\/p>\n\n<p>So in a half-afternoon I managed to scan 2000+ pages (lots of which were also double-sided), put them into PDFs and have them uploaded to the cloud! I started scanning things I never even would have thought of scanning, such as my reciepts and old photos just because the scanner made it so easy.<\/p>\n\n<p>Insert pages, press \u2018Scan\u2019, done!<\/p>\n\n<p><img src=\"\/img\/scanned.png\" alt=\"Done\" \/><\/p>\n\n"},{"title":"Getting browser location with tmprtr","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/browser-location"}},"updated":"2013-02-02T00:00:00-08:00","id":"https:\/\/ryanseys.com\/post\/browser-location","content":"<p>I very recently created an app called <a href=\"\/project\/tmprtr\">tmprtr<\/a>. It is a very simple weather app that uses your location to get weather data. I created it using <code>navigator.geolocation<\/code> which in modern browsers requests the user to allow\/deny the website from getting an accurate geolocation. This is great because I get a very accurate location for the user and they get the weather! But I wanted to do better.<\/p>\n\n<p>Immediately after visiting my site for the first time, a user will be greeted with a \u201cGIVE ME YOUR LOCATION\u201d request and to me that, from a user experience, raises a big red flag. I wanted a way to get the location using the most unintrusive way and considering I don\u2019t need exact location, I decided to attempt to get location based on IP address first. This location is less accurate than the previously mentioned method, but for the purposes of weather, it\u2019s close enough. I request IP location (all under the hood) and if that fails, fallback to a geolocation request, so I always ensure the user has the best experience possible. To get the IP location I embed a javascript library from <a href=\"http:\/\/www.geoplugin.net\/javascript.gp\">http:\/\/www.geoplugin.net\/javascript.gp<\/a> into my page and request the latitude and longitude values through two requests:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-js\" data-lang=\"js\"><span class=\"nf\">geoplugin_latitude<\/span><span class=\"p\">();<\/span>\n<span class=\"nf\">geoplugin_longitude<\/span><span class=\"p\">();<\/span><\/code><\/pre><\/figure>\n\n<p>From here I request the weather data from the server, just as I would had I got the coordinates from the more obtrusive (yet more accurate) request:<\/p>\n\n<figure class=\"highlight\"><pre><code class=\"language-js\" data-lang=\"js\"><span class=\"nb\">navigator<\/span><span class=\"p\">.<\/span><span class=\"nx\">geolocation<\/span><span class=\"p\">.<\/span><span class=\"nf\">getCurrentPosition<\/span><span class=\"p\">();<\/span><\/code><\/pre><\/figure>\n\n<p>Overall, switching to a default IP-based location has not affected my app in any negative direction. The user has their weather information nearly instantly after visiting and is less disrupted in the process.<\/p>\n\n"},{"title":"Using Jekyll with Github Pages","link":{"@attributes":{"href":"https:\/\/ryanseys.com\/post\/using-jekyll"}},"updated":"2012-11-25T00:00:00-08:00","id":"https:\/\/ryanseys.com\/post\/using-jekyll","content":"<p>In the last couple days, I fired up this personal website for myself to showcase some of the projects I have been working on as well as to get even MORE experience developing for the web. I wanted something simple and static, nothing too fancy, something I could understand inside and out just in case I ever needed to make a modification. I wanted something that I could use to create content when I needed and to get things up fast! Gone are the days writing raw HTML.<\/p>\n\n<p>Hello, <a href=\"http:\/\/jekyllrb.com\/\">Jekyll<\/a>.<\/p>\n\n<!-- end_excerpt -->\n\n<p>Using <a href=\"http:\/\/pages.github.com\/\">Github Pages<\/a>, I was able to get a site up and running in no time flat. Now, mind you, I\u2019ve been making a steady sleuth of changes over the past couple days to modularize everything, but I think I\u2019ve got the structure nearly down to a T.<\/p>\n\n<p>My journey actually started out with no Jekyll at all, just Github Pages hosting a bunch of static files. I took one of the themes they had sitting around and hacked &amp; slashed it to make it what I wanted. Jekyll came into the picture when I remembered that I\u2019m a lazy developer and I wanted something else to do the dirty work for me. Considering I was using Github Pages already, well, Jekyll just fell into place.<\/p>\n\n<p>It\u2019s been a really great experience so far, I\u2019ve learnt about new technologies and wonder how I ever got by without a website! It makes me feel empowered! If you don\u2019t have yourself a personal website, I highly recommend you create one for yourself. Considering Jekyll is backed by Github, I\u2019m relying on the fact that they won\u2019t remove support for it someday. But if they do, I\u2019ve luckily got every change I\u2019ve ever made to my website backed up with git! Another great reason to go the Github route, because every publish to the site is made through a commit and push to Github.<\/p>\n\n<p>What more reason do you need! Honestly, the hardest part of my journey through creating this website was \u201cWhat icon should I use for my favicon?\u201d I couldn\u2019t be happier with the result. Jekyll is great.<\/p>\n\n"}]}