<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Noel Bautista</title>
    <description>The latest articles on DEV Community by Noel Bautista (@nbau21).</description>
    <link>https://dev.to/nbau21</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F94175%2F12d591e1-e466-4fc1-aea1-e308cef3c3f1.jpg</url>
      <title>DEV Community: Noel Bautista</title>
      <link>https://dev.to/nbau21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nbau21"/>
    <language>en</language>
    <item>
      <title>Ergodox-EZ Bundle Review</title>
      <dc:creator>Noel Bautista</dc:creator>
      <pubDate>Sun, 19 Aug 2018 21:22:39 +0000</pubDate>
      <link>https://dev.to/nbau21/ergodox-ez-bundle-review-2g5b</link>
      <guid>https://dev.to/nbau21/ergodox-ez-bundle-review-2g5b</guid>
      <description>&lt;p&gt;This review is a cross-post from my &lt;a href="https://blog.codingdoodles.com/ergodox-ez-bundle-review-2017/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;, in April 2017. My opinions haven't changed much, so here's my initial review.&lt;/p&gt;

&lt;p&gt;After a month of waiting, my Ergodox split keyboard is finally here! At $295 for the new &lt;a href="https://ergodox-ez.com/collections/keyboard-bundles/products/snow-and-shine" rel="noopener noreferrer"&gt;Ergodox Snow bundle with Gateron White switches&lt;/a&gt;, it's definitely not for the faint of heart. I decided to splurge as I spend a lot of time on my home workstation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Packaging
&lt;/h2&gt;

&lt;p&gt;The Ergodox shipped around 2-3 weeks after purchasing from ergodox-ez.com. Delivery took 2-3 days from Taiwan to Los Angeles, CA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftpj88yyjqx8tholb6zyu.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ftpj88yyjqx8tholb6zyu.JPG" alt="ergodox-ez packaging"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UPS packaging was solid, as it protected the actual boxes from scratches. There were some minor dents on the boxes though.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F43u7zbytmblvwstywoxa.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F43u7zbytmblvwstywoxa.JPG" alt="ergodox-ez bundle boxes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was disappointed at the lack of documentation that came with the Ergodox. Thankfully there's nothing to assemble, even the tents come attached!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc9cxidgh9j8fa54baplf.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc9cxidgh9j8fa54baplf.JPG" alt="ergodox-ez box"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I like that it's ready to go out of the box. I guess that justifies the lack of documentation!&lt;/p&gt;

&lt;h2&gt;
  
  
  Ergodox EZ Snow
&lt;/h2&gt;

&lt;p&gt;But first, some photos!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fizlchaisv2002o4xtee2.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fizlchaisv2002o4xtee2.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgsrf6jsu9ibtokarmh8l.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgsrf6jsu9ibtokarmh8l.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Figzf6qx113lays5808o4.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Figzf6qx113lays5808o4.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0izn0r5h269ln6bs70su.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0izn0r5h269ln6bs70su.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqoamh34zeyw1tqhoefox.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqoamh34zeyw1tqhoefox.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The body of this ridiculously expensive keyboard feels reasonably rigid. Everything from the tents, the cables, and the rubber feet do not feel flimsy at all. Weight seems to be distributed well around the body. I don't feel any shaking or the keyboard sliding as I type.&lt;/p&gt;

&lt;p&gt;The switches feel really nice. The Gateron White switches are supposedly really light, only requiring 35g of force to actuate. I chose them as Gateron Blue switches are too loud (otherwise they would have been my first choice) and I really like the feeling of light linear switches.&lt;/p&gt;

&lt;p&gt;&lt;del&gt;I'm not a fan of the tents.&lt;/del&gt; The good about them is that they let the user tilt and angle the Ergodox in a lot of ways. The bad is that they sort of grind when you rotate them after tightening. After removing the tents, I noticed some metal powder coming out of the holes. Yikes! They hold the keyboard up nicely, as long as you don't put your entire weight on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit: After giving the tents another chance, I realize that they help a lot in making your hand placement more natural. I set the tents to lift the inner side of the keyboard and lower the outer side. See photos below.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8nq9x0xlkmlxzxs1v8su.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8nq9x0xlkmlxzxs1v8su.JPG" alt="ergodox-ez tents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpdtbutpegjnv4ockda1g.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpdtbutpegjnv4ockda1g.JPG" alt="ergodox-ez tents hand placement"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The wrist rest (called Wing) is made of some rubbery feeling material. It's amazing because it's not too soft and is angled perfectly for the keyboard. It weighs heavier that it looks, but that's a good thing! The wrist rest's weight seems to help it stay in place. It feels REALLY good. That said, it is very solidly made with no cosmetic imperfections.&lt;/p&gt;

&lt;p&gt;I highly recommend getting the bundle just for the wrist rests alone.&lt;/p&gt;

&lt;p&gt;The default configs were pretty usable, but I found myself wanting more. Personally, I don't like the idea of keys sharing a modifier and a command (ex: Z and CTRL share the same key). It was pretty cool at first, as holding the key would activate the modifier (CTRL) and tapping activates the command (Z). However, it felt wrong and I like my modifiers at a familiar place away from other keys. &lt;/p&gt;

&lt;p&gt;I spent about 2 hours remapping my keys using the &lt;a href="http://configure.ergodox-ez.com/" rel="noopener noreferrer"&gt;configurator&lt;/a&gt; from the Ergodox-EZ website. It was time well spent as I feel great about my new configs.&lt;/p&gt;

&lt;p&gt;Even after customizing, I still need practice with the Ergodox :P I still type really slow and make a ton of typos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkpwfa7szun0t5fjs4iov.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkpwfa7szun0t5fjs4iov.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Feevu1v4o1psfoffqs46l.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Feevu1v4o1psfoffqs46l.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffw9qhg3t2ymvfymdmr2b.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffw9qhg3t2ymvfymdmr2b.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I like how the keycaps were marked to help the user identify how the keycaps go in. This was particularly helpful to me, as I have blank keycaps! The yellowing is from the sunset and bad photo angles.&lt;/p&gt;

&lt;p&gt;I had one or two keycaps with weird excess plastic in the bottom. It's not noticeable while typing, but it would have been nice to not have.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1ydhv1d7jmhphqi5idtg.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1ydhv1d7jmhphqi5idtg.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmfypm8zy19qhm4glcy1y.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmfypm8zy19qhm4glcy1y.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've always thought it was weird to have multiple stems for 1 switch. Not a big deal as the thumb cluster feels fantastic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgzjn37065oa5prdnsnmi.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgzjn37065oa5prdnsnmi.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The cords are decent enough. They feel solid and rigid, but nothing crazy. They are a good length and should be good for the majority of users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1bk0ahgu0m95se04umbs.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1bk0ahgu0m95se04umbs.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O-Rings for Extra Silence (Not Included in Bundle)
&lt;/h2&gt;

&lt;p&gt;The Gateron White key switches are fairly silent (as any other linear switch). However, I wanted a quieter one! So I bought some 1.5mm thick o-rings from &lt;a href="http://lpwl.bigcartel.com/" rel="noopener noreferrer"&gt;LPWL&lt;/a&gt;. All the rings I received were perfect and worked amazingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvtn57tdeezj3fisckug3.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvtn57tdeezj3fisckug3.JPG" alt="lpwl-thin-orings-silencers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a sound test of the Ergodox with (top row) and without the o-rings.&lt;/p&gt;

&lt;h2&gt;
  
  
  End
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5zb57vbusekn263s6nx4.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5zb57vbusekn263s6nx4.JPG" alt="ergodox-ez snow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://ergodox-ez.com/" rel="noopener noreferrer"&gt;Ergodox-Ez&lt;/a&gt; is awesome. It's solidly built and &lt;em&gt;gasp&lt;/em&gt; ergonomic! It definitely takes a while to get used to, but once you do, it's hard to go back. At $295, it's hard to recommend to the casual user. Power users will feel right at home especially after customizing.&lt;/p&gt;

&lt;p&gt;So if you have money.. give the Ergodox-Ez a chance, maybe even get the DIY &lt;a href="https://www.massdrop.com/buy/infinity-ergodox" rel="noopener noreferrer"&gt;Ergodox Infinity&lt;/a&gt; kit from Massdrop.&lt;/p&gt;

</description>
      <category>gadgets</category>
      <category>ergonomics</category>
    </item>
    <item>
      <title>Writing Code That Makes Your Teammates Lives Easier</title>
      <dc:creator>Noel Bautista</dc:creator>
      <pubDate>Wed, 28 Mar 2018 11:00:00 +0000</pubDate>
      <link>https://dev.to/nbau21/writing-code-that-makes-your-teammates-lives-easier-2e8</link>
      <guid>https://dev.to/nbau21/writing-code-that-makes-your-teammates-lives-easier-2e8</guid>
      <description>&lt;p&gt;Working alone =/= working in a team. There might be things in your code now that might not be as easy to understand for other developers, including your future self. This is not about spending an hour automating a boring task. These tips are simple trivial changes. Simple enough that you wouldn’t have to rewire your brain or change your workflow 👍&lt;/p&gt;

&lt;p&gt;PS: This is a cross-post from my &lt;a href="https://blog.codingdoodles.com/writing-code-that-makes-your-teammates-lives-easier/"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;tl;dr&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write good commit messages&lt;/li&gt;
&lt;li&gt;Add comments to hacky implementations&lt;/li&gt;
&lt;li&gt;Write self documenting code / variables / methods / classes instead of adding comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PS: These tips have been helpful with me getting on and off with my side projects for long periods of time. I used to spend an hour or two getting back up to speed with my side projects. Now it only takes about 15 minutes!&lt;/p&gt;

&lt;p&gt;PPS: Writing a good README with installation and usage guide helps :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Write good commit messages
&lt;/h3&gt;

&lt;p&gt;Commits are great are providing context about the project. In an ideal world, one could look into the history to understand why certain changes were made and how.&lt;/p&gt;

&lt;p&gt;don’t:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Refactor
- Fix bug
- Fix bug
- Cleanup
- Remove test [0]
- Add feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Many things wrong here. What did the programmer &lt;code&gt;refactor&lt;/code&gt;? What bug/s were fixed? What was cleaned up? What test was removed? What feature was worked on?&lt;/p&gt;

&lt;p&gt;[0] When I inspected closely what test was removed, it turned out that it meant a ‘test’ word that somehow snuck in some css file as opposed to an actual test removed.&lt;/p&gt;

&lt;p&gt;do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Refactor for loop to use .filter
- Handle edge cases
  - Don't empty cart when user logs out
  - Prevent crashes when more than 3 tabs open
- Remove redundant and unused code
- Implement feature X
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This style of writing commits shares a living diary of the project. This makes it easy for anyone to find relevant changes just by looking at the logs (ex: &lt;code&gt;git log&lt;/code&gt;). Chris Beams wrote a great piece on &lt;a href="https://chris.beams.io/posts/git-commit/"&gt;how to write commits&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add comments to hacky implementations
&lt;/h3&gt;

&lt;p&gt;What is bad about hacky code is that it is often undocumented and invites other developers to build on top of it. It becomes something that no one understands or knows about. Newer members of the team will try to avoid touching this code as much as possible and attempt to work around this code.&lt;/p&gt;

&lt;p&gt;don’t:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-class {
  ...
  flex-direction: column;
  ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our little hacky code could into something bigger and badder. It might not be obvious what it’s for and if it’s still relevant today. Working around it will eat up precious development time.&lt;/p&gt;

&lt;p&gt;do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-class {
  ...
  flex-direction: column; // hack to center overflowing text in IE 10 https://stackoverflow.com/a/42302827
  ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Months, or years down the line, your project might not even support IE 10 anymore. We can now remove this hack, and now we don’t have to worry about this hack’s other side effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write self documenting code / variables / methods / classes instead of adding comments
&lt;/h3&gt;

&lt;p&gt;Easier to read methods when accessed in a different class. Otherwise, user of API will have to read into the method/class to understand what it does. This is unnecessary and a waste of time!&lt;/p&gt;

&lt;p&gt;dont:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main() {
  play = true
  board = board()

  while (play) {
    input()
    play = win()
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void game() {
  isPlaying = true
  initBoard()

  while (isPlaying) {
    getUserInput()
    playing = !hasWon()
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can easily tell that the &lt;code&gt;game()&lt;/code&gt; method initiates the game, prepares the game board, gets user input, and ends the game if the user has won.&lt;/p&gt;

&lt;p&gt;The same applies to variable names.&lt;/p&gt;

&lt;p&gt;dont:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Updates the UI
void updateUI() { ..

// the data store
var store = ..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These comments add nothing to my understanding of what this variable is for. &lt;code&gt;updateUI()&lt;/code&gt; -should- update the UI, etc.&lt;/p&gt;

&lt;p&gt;do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void updateUI() {
}

var store = Store()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Read this post for a more thorough reading on &lt;a href="https://a-nickels-worth.blogspot.com/2016/04/a-guide-to-naming-variables.html"&gt;naming variables&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>software</category>
      <category>codereviews</category>
    </item>
    <item>
      <title>Modular and Dynamic UI for Android Phones and Tablets</title>
      <dc:creator>Noel Bautista</dc:creator>
      <pubDate>Sun, 12 Mar 2017 00:00:00 +0000</pubDate>
      <link>https://dev.to/nbau21/modular-and-dynamic-ui-for-android-phones-and-tablets-56de</link>
      <guid>https://dev.to/nbau21/modular-and-dynamic-ui-for-android-phones-and-tablets-56de</guid>
      <description>&lt;p&gt;This guide was originally posted last year at my &lt;a href="https://blog.codingdoodles.com/modular-and-dynamic-ui-for-android-phones-and-tablets/"&gt;blog&lt;/a&gt;. A year and a half later, the content still is very applicable.&lt;/p&gt;

&lt;p&gt;A short Android developer’s guide on how to make responsive UI that makes both phone and tablet users happy. This is the companion blog post for my &lt;a href="https://docs.google.com/presentation/d/1pm3wfW-Md8adLeSEZ0sz6ek--FKWPOkZN-ihSxJWpMY/pub?start=false&amp;amp;loop=false&amp;amp;delayms=3000&amp;amp;slide=id.p"&gt;10 minute presentation of the same title&lt;/a&gt;. There are code samples in the Example section of this post.&lt;/p&gt;

&lt;p&gt;You can see the actual presentation here!&lt;/p&gt;

&lt;p&gt;I want to highlight two things in this post: &lt;strong&gt;Modularity&lt;/strong&gt; and &lt;strong&gt;Responsiveness&lt;/strong&gt;. I think apps that keep both phone and tablet users in mind should have modular views/code and look good regardless of screen size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modular
&lt;/h2&gt;

&lt;p&gt;Some views should be thought of individual modules: they should be able to stand on their own, or complement other views. Example: You’re building a screen that is somewhat similar in functionality for both phone and tablet, but the tablet version has an extra view.&lt;/p&gt;

&lt;p&gt;You can do two things 1) create an activity that works for phone, another for tablet, or better 2) create fragments for these two views, use the same ‘modules’ for tablet version.&lt;/p&gt;

&lt;p&gt;This way, you can avoid copy-pasting the same code for your views.&lt;/p&gt;

&lt;h2&gt;
  
  
  Responsive
&lt;/h2&gt;

&lt;p&gt;A responsive app means the app can present itself well regardless of orientation or screen size. As a programmer, you don’t want to create different activities/fragments/views for different screen sizes. Instead, you want to write the same code and have Android do all the work for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Makes Sense to Use Modular/Dynamic UI
&lt;/h2&gt;

&lt;p&gt;Let’s look at the similarities and differences between phones and tablets.&lt;/p&gt;

&lt;p&gt;People typically use phones in portrait mode. Portrait is somewhat limited in screen real estate, but it works well for lists.&lt;/p&gt;

&lt;p&gt;Tablets gain a lot more screen space when used in landscape mode. A tablet in landscape showing the same layout as if it were in portrait mode looks awkward. There’s too much underutilized space! We could use that space to show more relevant information.&lt;/p&gt;

&lt;p&gt;Phone users use one hand while navigating using their thumb, with the “sweet spots” located near the lower right corner of the screen. Tablet users vary. Sometimes they use two hands, one hand to hold the tablet, the other (forefinger) to navigate. Maybe they use one hand with the tablet laid flat on the table or docked at an angle. This tells us that locations of buttons, etc. on the phone may not work as well as on a tablet.&lt;/p&gt;

&lt;p&gt;Phones and tablets share the same interaction paradigm. Users can swipe, tap, long press, etc. This is awesome, because this enables us to create a familiar experience for both users. We don’t have to “teach” them how to use a tablet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr - Users can perform the same actions, but you can show more data with a tablet in landscape mode. You might need to reposition stuff to help the user navigate the app better.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So.. now we’re motivated to write a responsive app that works well on both phone and tablet! How do we do this on Android?&lt;/p&gt;

&lt;p&gt;Android resources can be specified using &lt;a href="https://developer.android.com/guide/practices/screens_support.html#qualifiers"&gt;qualifiers&lt;/a&gt;. Android loads the corresponding &lt;code&gt;.xml&lt;/code&gt; resource based on declared qualifiers. Qualifiers are simple to get into, but could get quite complicated depending on usage.&lt;/p&gt;

&lt;p&gt;To simplify this post, let’s stick to using the &lt;code&gt;smallest width&lt;/code&gt; qualifier (specifically, 600dp). This ensures that we will use a different layout whenever Android detects that there is at least 600dp available for either length or width of the screen.&lt;/p&gt;

&lt;p&gt;Wait, why not check if the device is used horizontally (landscape mode)?&lt;/p&gt;

&lt;p&gt;We care about showing the user more data / repositioning views when there is enough screen the app could use. Using &lt;code&gt;land&lt;/code&gt; (landscape) as a qualifier only checks if the device is used horizontally. What if the device is actually 4:3, and landscape mode doesn’t have as much screen space as we thought?&lt;/p&gt;

&lt;p&gt;Consider the gif below. This is a tablet in landscape mode. If we used &lt;code&gt;land&lt;/code&gt; as the qualifier for the “bigger” layout, the app would have been only displayed in the “bigger” layout. Instead, we let Android use the “smaller” layout if necessary by using the &lt;code&gt;w600dp-land&lt;/code&gt; qualifier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p50a0OqJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cn7h6b7kzw96ibtbx488.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p50a0OqJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cn7h6b7kzw96ibtbx488.gif" alt="Multi-Window Demo"&gt;&lt;/a&gt;&lt;em&gt;&lt;code&gt;w600dp-land&lt;/code&gt; lets Android choose the bigger layout when there is at least 600dp width and if the device is in landscape. The bigger layout is commonly referred to as the &lt;code&gt;Master-Detail Pattern&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let’s look at this example from one of the open source projects I follow, &lt;a href="https://github.com/standardnotes/android"&gt;Standard Notes&lt;/a&gt;. It has a generic user interface, making it easy for us to pick it apart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XvjG0PPd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4xzchls0hd7rv7lclr8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XvjG0PPd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4xzchls0hd7rv7lclr8e.png" alt="portrait"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s a regular RecyclerView with a Floating Action Button (FAB). Let’s call this screen the &lt;code&gt;NotesListFragment&lt;/code&gt;. Upon clicking the FAB, it takes the user to the &lt;code&gt;CreateNotesFragment&lt;/code&gt; screen. Let’s refer to the “meat” of the window (white area w/ text below the toolbar) as &lt;code&gt;R.id.main_content&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SFF5BcWw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7nqj6ch36zmxvy74586x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SFF5BcWw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7nqj6ch36zmxvy74586x.png" alt="portrait1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see there’s nothing crazy here. I am simply using &lt;code&gt;FragmentTransaction&lt;/code&gt; to &lt;code&gt;add&lt;/code&gt; whatever is on &lt;code&gt;R.id.main_content&lt;/code&gt; with our new &lt;code&gt;CreateNotesFragment&lt;/code&gt;. I also used &lt;code&gt;addToBackStack()&lt;/code&gt; so that when the user hits the back button, the user is brought back to the &lt;code&gt;NotesListFragment&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;supportFragmentManager
   .beginTransaction()
   .add(R.id.note_list_container, noteFragment, TAG_NOTE_FRAGMENT)
   .addToBackStack(null)
   .commit()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s call the Activity handling these Fragments as &lt;code&gt;MainActivity&lt;/code&gt;, and it’s corresponding layout &lt;code&gt;activity_main.xml&lt;/code&gt;. &lt;code&gt;activity_main.xml&lt;/code&gt; contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Drawer layout + toolbar stuff..&amp;gt;
    &amp;lt;include layout="@layout/main_container" /&amp;gt;
&amp;lt;/closing tags&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And under &lt;code&gt;layout/main_container.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;FrameLayout
    android:id="@+id/note_list_container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_width="match_parent"
    android:layout_height="match_parent" /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, so good!&lt;/p&gt;

&lt;p&gt;What about tablet/large landscape layouts? We can use the &lt;code&gt;Master-Detail&lt;/code&gt; pattern for this!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DChAY-eh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1vpwk8tkrmphxvys3dcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DChAY-eh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1vpwk8tkrmphxvys3dcn.png" alt="w600dp-land"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created a new layout under the &lt;code&gt;w600dp-land&lt;/code&gt; folder. Recall earlier that Android will load this layout when the &lt;code&gt;w600dp-land&lt;/code&gt; criteria is met. All this new layout contains is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:showDividers="middle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"&amp;gt;

    &amp;lt;FrameLayout
        android:id="@+id/note_list_container"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" /&amp;gt;

    &amp;lt;FrameLayout
        android:id="@+id/note_container"
        android:layout_marginTop="?android:attr/actionBarSize"
        android:layout_weight="3"
        android:layout_width="0dp"
        android:layout_height="match_parent" /&amp;gt;

&amp;lt;/LinearLayout&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, nothing too crazy here. I am adding the &lt;code&gt;NotesListFragment&lt;/code&gt; to &lt;code&gt;R.id.note_list_container&lt;/code&gt;, and replacing &lt;code&gt;CreateNotesFragment&lt;/code&gt; to &lt;code&gt;R.id.note_container&lt;/code&gt;. (This is a simplified example. In the app I am doing a few checks for &lt;code&gt;savedInstanceState&lt;/code&gt;, etc)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;supportFragmentManager
    .beginTransaction()
    .add(R.id.note_list_container, noteListFragment, TAG_NOTE_LIST_FRAGMENT)
    .add(R.id.note_container, noteFragment, TAG_NOTE_FRAGMENT)
    .commit()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Phew! That was a lot. However, there’s more :D&lt;/p&gt;

&lt;p&gt;In the screenshots, the &lt;code&gt;FAB&lt;/code&gt; in landscape disappears and turns into a &lt;code&gt;MenuItem&lt;/code&gt;, with the text “New Note”. Thankfully, qualifiers work on &lt;code&gt;menu&lt;/code&gt; layouts as well! In this example, the &lt;code&gt;NotesListFragment&lt;/code&gt; layout handles the &lt;code&gt;FAB&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s refer to the &lt;code&gt;NotesListFragment&lt;/code&gt; regular menu layout as &lt;code&gt;menu_list.xml&lt;/code&gt;. This “menu” layout is left empty for our purposes.&lt;/p&gt;

&lt;p&gt;but in &lt;code&gt;menu-w600dp-land&lt;/code&gt;..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"&amp;gt;

    &amp;lt;item
        android:id="@+id/new_note"
        android:title="@string/new_note"
        android:orderInCategory="1"
        app:showAsAction="ifRoom" /&amp;gt;
&amp;lt;/menu&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re adding a new menu item with the id &lt;code&gt;new_note&lt;/code&gt; whenever the qualifier &lt;code&gt;w600dp-land&lt;/code&gt; is met.&lt;/p&gt;

&lt;p&gt;How will &lt;code&gt;NotesListFragment&lt;/code&gt; know when &lt;code&gt;New Note&lt;/code&gt; is clicked? There’s quite a bit of boilerplate, but it’s relatively short. We want to tell &lt;code&gt;MainActivity&lt;/code&gt; that &lt;code&gt;NotesListFragment&lt;/code&gt; has its own menu items, and we want to display it. &lt;code&gt;NotesListFragment&lt;/code&gt; will also handle click events for &lt;code&gt;New Notes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Excuse my kotlin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;override fun onCreateView(-stuff-): View? {
    val view = inflater.inflate(R.layout.frag_note_list, container, false)
    setHasOptionsMenu(true) // tell `MainActivity` to display this fragment's menu  
    return view
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.note_list, menu) // inflate this menu layout
    super.onCreateOptionsMenu(menu, inflater)
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    when (item?.itemId) {
         R.id.new_note -&amp;gt; startNewNote(selectedTagId) // handle click events for "New Notes'
    }
    return super.onOptionsItemSelected(item)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it for this example!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/google-developers/building-a-responsive-ui-in-android-7dc7e4efcbb3#.egs8l4uji"&gt;Building a Responsive UI on Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cognitiveclouds.com/insights/mobile-vs-tablet-user-interface-ui-design-key-differences-explained"&gt;Mobile vs Tablet UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toAndroid%20Programming:%20The%20Big%20Nerd%20Ranch%20Guide"&gt;Android Programming: The Big Nerd Ranch Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>android</category>
    </item>
  </channel>
</rss>
