Search

beehollander

Things I didn’t learn at code school

While the Flatiron School’s Learn Verified program is amazing, a recent freelance project exposed me to some things that I had not seen before in the wild.  Here they are, and as Bob Saget used to say, “in random order”.

HAML
HAML is just like ERB in that it’s just a ruby markup language that pre-calculates all your values/variables in your template to yield an HTTP-ready HTML page.  HAML takes some getting used to, and I think it gives you a smidge less control than ERB, but DAMN if it doesn’t make the most readable templates I’ve ever seen.

Sortable
A beautiful vanilla-javascript library for creating drag-and-drop elements.  For this project, I had to figure out how to make it work with <table> elements and all associated children.  It was a bit tricky, and I would have used <div>s if I had started with a blank slate, but it worked out.

WebPack
This packs all your files into single, concatenated versions of the same type.  Rails usually does something similar, but after you spend more than 15-20 seconds adding javascript to your app/site, you’ll need something less restrictive.  Webpack bundles things up nicely.  You have to be careful when pushing to things like Heroku to make sure what gets bundled is what’s running, but other than that, I’d say it’s a win.

Foreman
Foreman is pretty much the software version of the construction site foreman.  The author has portals for over half a dozen different languages (Python, Java, Node, GO, et. al).  Foreman makes it easier to start/stop things in development more similar to production.

Pry-Remote
If you use its more popular and simpler ancestor Pry as much as I do, this is a *must-have* to enable the use of breakpoints in a production-esque development environment.

SendGrid
If you’ve ever wondered how “Thanks for signing up!” emails get sent, this one is for you.  There’s even a free plan where your first 12,000 emails are free!  There are many other tools like it, but this is just one.  You can even use it to set up ‘alert’ emails inside conditionals.  Coupled with Whenever, you can do some really useful stuff using emails.

MailCatcher
If you’re going to be sending emails, nobody wants their real inbox flooded with test emails.  MailCatcher is like Pry, but for email.  It sets up a simple SMTP server locally and a “dummy” email address that it sends email to.  You’ll be debugging emails for hours and only have to spend about a minute setting it up.

Sadly, the client had a strict NDA on the contract, so I can’t show off the code OR the finished product.  The changes implemented were a productivity tool for the managers of PurrInc, a  Chicago-based cat-sitting service website.  I am quite proud of how it turned out and would love to show it off if I were allowed.

Advertisements

Because ESC is *just* too far away

When I first met vim, it was behind locked doors.  A friend who was a vim user brought it in and loaded it onto the internet-less machines we worked on in a secure lab.  I was floored that somebody could be so devoted to their text editor of choice as to burn it to a CD just so he could use it.  I tried to use it a couple times but slid straight back down the learning curve onto Notepad++ et al.

If there was ONE thing that changed my mind about vim, it’s this:

inoremap jk <esc>

Lemme `splain:

No, there is too much.  Lemme rant.

Tutorials and Practice

The most difficult part of using vim at first, for me at least, was navigation.  I had firmly committed to muscle memory using ctrl + <up> etc. to navigate and felt totally crippled without it.  So I knew the first thing I had to do was change my first-response reflex.  I needed to NEED to use the home row in order to navigate, because as soon as I couldn’t recall the right keys instantly, I just moved my hand and used the arrow keys.  I learned to touch type via gamification, so my first thought on how to learn vim was to find a game that’s played through that interface.

After a bit of googling, my first encounter with vim-adventures went well, but I was unemployed at the time and $25 for a temporary asset seemed a bit pricey.  So I’ve never actually played any levels beyond the paywall, but I enjoyed every moment before it.  After a bit more googling and a few false starts, I found Pac-Vim.  It worked perfectly for what I needed and soon I was darting around those ghosts like a pro.  After that, I found a cheat sheet I liked, laminated it all, and it began to feel like home.

Custom-made

I really took to Doug Black’s advice: Don’t put anything in your vimrc file that you don’t understand.  It emphasizes the development version of “skiing at your level.”  But I think the only thing I would add to that is “…or use.”  For me, the biggest benefit of using vim instead of anything graphics-based is that you can log in via SSH to almost any server anywhere in the world and, in a matter of seconds, be developing just as comfortably as if you were local.  However, the more things you add, the further you get from what comes built-in with most Linux distributions.  The more you ingrain what *is* built in, the faster you can edit on brand new server instances.

I don’t use too many packages, and my .vimrc isn’t very entertaining. Pathogen makes adding a new package super easy when I find one I like, but that’s *still* not going to help you settle in.

Having a seamless path from navigation to editing and back to navigation without leaving the home row is the key to becoming truly fluent in vim.  inoremap jk <esc> is the gateway to that.  With that in your vimrc file, pressing jk in rapid succession (like one second) is the same thing as pressing Esc (normally the only way from insert mode back to normal mode).  After a year, I would say the biggest hiccup I’ve ever had is when typing out the entire alphabet, you have to be careful not to type jk too fast.  That and you start typing jk whenever you’re editing anything outside of vim.  Between that key remap and actively trying to use all the little built-in shortcuts, I would say it only takes a few weeks to get “un-uncomfortable”.  I am quite proud to say that when I saw Amir Salihefendic‘s Top 10 Vim tricks you should know, I knew all but two!

You might not think that you spend a lot of time going between document editing and navigation, but when you add pressing the Esc key into that loop, it becomes painfully long.  However, when you not only cut out that extra motion, but ANY hand motion/distance, you start to realize just how much time you can save by not moving your hands from one place to another when there’s no real NEED for that.

It was never a choice

I had heard about the vim vs emacs debate a few times during my “hardware days” (undergrad, grad school, volunteer years).  I always expected to have some “bridge troll” moment where I was asked which will be my editor.  I just started using vim and was never consciously exposed to emacs at all.  I’ve only ever used it by accident until I realized you can switch your git commit message editor to vim, (I do almost exclusively in-line commit messages now).

I had never given my newfound bias towards vim a second thought until I heard Leo Laporte from Security Now say that the first thing he does when he gets a new computer is re-map CapsLock to Ctrl.  Apparently, Ctrl was originally where CapsLock is located, but CapsLock won the battle for position despite losing the war for relevance and use.  I don’t think there really is a wrong decision in the editor wars, and I also don’t think they’re mutually exclusive.  However, it does stir up memories of trying to learn the Dvorak layout while still having to use the Qwerty layout (tried it in college, definitely more comfortable, not worth the effort IMHO).  Muscle memory confusion abounds.

Browsing changed forever

There was a moment when I switched from preferring vim to advocating for vim, and that moment was when I discovered Vimium.  I can browse the internet without leaving the home row and yes, it’s as awesome as it sounds.  My only complaint, even though there is a built-in workaround, is how it collides with other shortcut keys like Youtube and Gmail.

So even though I don’t pose as a troll, forcing you to choose between them before I let you develop with me, I would ask that you choose through experience and not bias. I would also ask you which you chose and why.

The 6 Month Bug (and why I will never abbreviate variable names)

I used to work at a prominent defense contractor in the US.  I’m glad I did it as it had always been a dream of mine, but I’m also glad I’ve had the opportunity to move on.  I learned a lot, met a TON of wonderful people, and will never abbreviate another variable as long as I live.

I worked on a contract regarding a Stealth aircraft, which shall remain nameless, and the radar receivers that were made for it.  “Why does a stealth aircraft need radar receivers?” you ask?  Well, 2 reasons.  These receivers were custom-made to be able to receive and identify the geographic location as well as the nationality of radar pulses emitted by enemy systems.  First of all, knowing where the enemy radars are, geographically,  helps you not fly right over their heads by accident (what good is radar invisibility if your shadow flies right over the enemy air base?).  Second, it gives you intel to analyze as to where the enemy is looking for you (if there’s a Russian SAM site on a mountain top that wasn’t there last month, you know something’s probably up).

With a receiver in the test lab, you’re usually looking at anywhere from 20-30 lbs of beautifully milled aircraft-grade aluminum filled with 10-20 custom-built electronics cards running $0.5-$1 million dollars worth of software.  Moving it around is pretty easy, and most of the ones I dealt with were in the lab for some sort of problem the Air Force had with them.  99.9% of these problems were electronic in nature, and so we had to be able to trick the box into thinking it was flying through the air and receiving radar pulses from enemy sites.  The test equipment and software, which were probably cutting edge when purchased, were under contract to remain unchanged after the test system was approved.  However, since they were approved in the early 90’s, one can only imagine the relics we had to deal with 20 years later.  Ancient CPUs measured in MHz, OS licenses older than me, and software about as user friendly as a hibernating bear.  Part of my job was to execute the new contract in which we were charged to upgrade everything to modern test equipment and new software with which to run it.  Then the fun began.

There were many layers of this enormous task, one layer that I had to deal with was running the old tests and the new tests on the same receiver, checking for any difference, finding the software root-cause, and correcting the error.  Things were pretty slow but steady as there were MANY small problems to be worked out, but none will stay in my memory as much as SlowPOP.  Slow Rise-Time Pulse On Pulse, aka SlowPOP, was a test to make sure that the receiver could function when two radar pulses were received overlapping each other when the rise/fall times were very slow compared to normal.  The exact details are not only boring, but classified, so suffice it to say, the results just didn’t quite look right.  The input parameters had been tweaked so that the test passed….pretty much…but it still didn’t look right, and the post-tweaking parameters were not near enough to the original parameters for my comfort.

I rebooted.  I re-calibrated.  I re-installed.  I re-ran and re-ran and re-ran.
I asked.  I inquired.  I requested.  I quizzed.  I conjectured.
We shipped other deliverables in the months that passed by.
It was funny, every time I asked about WaveGenAPI, everybody said “there’s no way that’s wrong, 80% of the other tests use it and it’s been perfect for over a year.”
Then at last, after turning every other stone, I knew that WaveGenAPI had to be checked.

When I looked into the code behind WaveGenAPI, after a few days of digging, I had my first suspect.  One line didn’t seem to be right.  It was adding a bunch of terms and one of the terms seemed incorrect.  I brought the author of WaveGenAPI, a man I highly respected with 26 years of experience, down to the lab to sit with me and look at the results together.  He stared at it in silence for nearly half an hour, only asking the odd question here and there, covering basic checks and possibilities.  Then he finally just said “good catch” and we shook hands and he walked away.

The problem: One file.  One line.  One term.  One variable.  One letter.

The senior programmer was trained in the days of limited space for variable names, so his typical practice was to use variable names for everything that were 8 characters or less.  In this case, the variable in question represented the “time of ten percent height on the falling edge” of the pulse.  The term was supposed to be “Ttpfe”, but he had mistakenly called it “Ttpre”, which was a real term for the “rising edge” counterpart.  This term would have existed which is why the typo didn’t flag an “undefined” error.  Also, the time difference in error for all tests EXCEPT SlowPOP was probably less than a picosecond.  Finding and fixing this error was the culmination of about 6 months of work and the most satisfying bug-find of my career so far. Now, SlowPOP will always be perfect instead of just close enough.

That is why I will never abbreviate my variable names for as long as I live.

TL; DR It took 6 months of work to find 1 wrong letter, a typo by an engineer with 26 more years experience than myself.

Why did you do a Code School?

If I were to say “I get asked this a lot” I would be lying.  I just know that the answer won’t really change over time, and this is a question that *I’ve* known the answer to for a while, but haven’t actually published anywhere.

I have 2 degrees from Auburn University.  A BS in Wireless Engineering (yes, I know you’ve never heard of it) and an MS in Electrical Engineering (MEMS).  This time was very valuable to me.  I don’t regret it.  I learned a lot.

I spent 2 years aboard a non-profit motor vessel, the MV Logos Hope that sells books to developing nations.  This time was just as valuable for me and taught me things that I could never have learned in school.  Things like: How to lead an international team of people who are more skilled than you; How good it feels to successfully complete a project that 400 other people are waiting on; What it feels like to be at sea for 12 days; The fact that I get seasick on the first day at sea.

I also learned that you can’t count on the economy staying the same over any given period of time.  News of the financial crisis that shook the world was at best thin while on board.  When I got home not only were no companies offering cars as hiring bonuses, but nobody was hiring at all now.

I (eventually) worked at Lockheed Martin for 4 years working on the <Stealth Aircraft>’s ESM testing and integration systems.  I learned a lot there too.  I learned that my dream of working for Lockheed Martin was just a dream being empowered to innovate.  I also learned that a VERY small number of people get to innovate at companies of 100,000+ employees.

I’ve been around computers since before I can remember.  My dad worked on computers in a home-based business, so I was raised knowing computers intimately.  I was terrified of the idea of spending my whole career in a cubicle.  So I studied hardware engineering.

But now I need remote work (thank you internet, for making this a thing!).  Professionally, I would be considered a “Junior Developer” even though I’ve been programming in some way at some level or other for over 20 years.  And my educational background is in hardware not software.  3 strikes.  After realizing the “perfect storm” of those 3 strikes, I needed some help.

I can’t expect a company to take a gamble and invest in me if *I’m* not even willing to.  So I decided to invest in myself and get a verification from an outside party that Yes Brian Can Code.

TL; DR: investing in myself for a third-party stamp of approval.

Springfield’s new IT guy

So the SCC just hired a new IT guy and he is busying himself upgrading their website.  Mostly it’s just downloading and installing upgrades and new software, but he says there are things that jQuery can do to reduce the load on their server.  By folding a few things into AJAX calls instead of full page loads, not only will it be a better experience for the user, it will save them on bandwidth costs with their ISP.

He says that in this domain, because Assets cannot be created or edited by users, they will be the best candidate for moving forward with the SCCAPI rollout.  He’s convinced that an API will help the community somehow.  Whatever.

The first snag he hit was with the interference in the Javascript environment caused the TurboLinks (automatically installed with Rails 5).  After much confusion and some googling, jquery-turbolinks was discovered and implemented.  This one comes with a small price though: our JS will end up running on every page.  The time/memory it takes will be minimal, but we have to watch where we step to make sure we don’t get into crazyland.  TL;DR: Turbolinks caches everything in the world to speed up navigation for the user, but doesn’t bother to help the javascript (re)run, but jquery-turbolinks fixes that.

Onward.

I think the hardest part of projects like this is pretending their real.  A paid job with an actual product is an entirely different world from a dreamed up domain model with the intent of nothing more than technical exercise.  Coming up with excuses to use certain programming features is a terrible way to move a product forward (or make any money for that matter).

Financially, as well as technically, speed is my main concern.  Flashiness is subjective to the client, functionality is subject to the market/competition, all that matters is finishing.  That is my goal, that is what will move things forward.  Don’t judge me.

Springfield Community Center

As a part of the review of learning Rails in Flatiron’s Learn program, we were charged with building an app with certain technical features.  In a production environment, you would never search for a model to include a new technical feature, but for training purposes, that sounds great.

I chose to give the Springfield Community Center an online tool to help Lisa, Bart, and Marge with their goal of serving their community better.  (This is also slightly inspired by my time aboard the Logos Hope, but that’s a story for another day.)

Starting from a bare-bones Rails project is as easy as typing ‘rails new MyProject’ into a terminal, but fleshing it out takes time and care.  There’s models to decide on, interactions to plan, and an overall idea of how the app will operate that must at least be thought about before the first keystroke will ever make any sense.

Users, is easy.  You’ve gotta have users.
Events are what will take place.  Meetings, parties, rehearsals, bridge tournaments, pasta bridge tournaments, whatever.
Assets are what will be utilized and reserved for an event.  Everything from Tables and Chairs to Projectors and Speakers would be assets.  Add Rooms to that, and it’s a good basic level to start with.  These will not have CRUD functionality for basic users.
EventAsset will be the model for the join.  An EventAsset is the registration of a specific asset for a specific event.

The OmniAuth bits are so incredibly annoying for small projects like this.  In production, when you are planning on thousands of people using your product, it is obviously worthwhile to code it properly.  If you request a profile of a user from a provider, they’ll give it to you if the user lets them; however, the problem comes if a user has different emails for any provider and tries to log in by those two ways.  Have a different github email from your facebook?  Well you’ll end up with two different profiles in the app.  Did you use your work email for your linkedin profile?  Well if you log in with google, you’ll have some of your app data/history on one profile, and some of it on another.  This is totally aside from the fact that Twitter doesn’t necessarily return an email at all.  There are ways around this, and these are good ways.  But these are the ways of professionals who are paid for their time, not students who are paying for the time and on a budget.

The basic flow of the app is to display events, if you want to register an event, you have to sign up and sign in.  An event is created and EventAssets are associated with it as needed.

I think the biggest hurdles I had with this one was getting the EventAsset management to work.  I know it’s not the best or even close to perfect, but it works.

I noticed as I was working that I had a lot of good ideas for good features.  But most of them fell under You Ain’t Gonna Need It reasoning, so I made a note and kept my focus on only features that would count towards to completion of the project.  That includes styling and making it look ‘pretty’.  There MUST be a balance between how much time a project consumes vs how much payoff there is.  The payoff, in this case, is the project’s submission and successful review.  I’m not making portfolio material here.  Perfect isn’t the goal, completed is.

Mall-Recipes.com

Overall, having functional code for yourself is only mildly exciting.  Having code you can share with others is good.  The best, however, is when your code becomes invisible and is no longer the product, but the avenue for the product or service.

Most people have heard of All-Recipes.com, but this will be the cheap knock-off: Mall-Recipes.com.  Most things with malls are cheap, quick, and dirty and this will be no exception.

My Fwitter project, along with all my other submissions to Flatiron’s Learn program, have been pretty rough, stylistically.  I’d like this to be a *little* bit prettier, but it’s gotta be quick.  (I wanted to keep it under 24 hours, but PostgreSQL had other ideas)  This will be greatly sped up by simply re-factoring code I already have functioning give it a new-found purpose.

I also wanted to have it live on Heroku and found ample set-up help.  Then as new features were installed, push out to it like a normal release cycle.  After the initial difficulty in deploying due to the fact that they run on PostgreSQL, not SQLite, it’s at long last up and running.

A quick note here about database usage.  There are many blog posts and tutorials out there that seem to have no problem with having development and test use one database, SQLite for example, and then have the production space run on an entirely different database software suite, PostgreSQL.  This is absolutely in no way acceptable in a truly production environment.  In ANY situation, you always want your production/development/test points to be as close to each other as absolutely possible.  All the database, framework, infrastructure, architecture, and platform documentation I read about it said that they should be as similar as possible.

Simply put, I built a recipe app.  But when you get into the nitty gritty of it, it’s actually pretty complicated.  You want to create a new recipe?  You have to be logged in.  That’s easy enough in plain english, but teaching a server how to do that isn’t.  You want to be able to list all the recipes in your database that have a certain ingredient in it?  Well, imagine the hassle it would be to do that for your own recipe box, but oh the revelations when you do it online and shows you hundreds of tofu recipes!

I have several classes: Users, Recipes, Reviews, Ingredients, and RecipeIngredients.  I have database tables to go with each one of those, the most interesting of which I thought was the RecipeIngredients table.  Each row of that table represents a single entry of a single ingredient in a single recipe and has all the information for that entry like ‘how many/much’ of the ingredient, how many ‘whats’ you’re putting in (3 cups, 5 cloves, 2 lbs, etc.), and also a ‘qualifier’ (chopped, warm, cubed, chilled, pressed, etc.).

It actually worked out really well because I could then have a simple dropdown menu so the user can easily choose from the available ingredients.  However, at scale, this would be a little impractical.  In reality, if your business/site takes off, you could potentially end up with 1,000’s of ingredients!  Selecting each new ingredient would be like a whole trip through the grocery store!  So the practicality of this implementation has it’s limits, and they’re pretty low, but still it was fun.

A user has many recipes, a recipe has many ingredients through recipe_ingredients.  An ingredient has many recipes through recipe_ingredients.  A review belongs to a user and a recipe.  A user has many reviews and a recipe belongs to a user.  You got all that?  😉

A recipe must have a name and a description; a user has to have a username, email, and password; a user must have a unique username and unique email.

Well, after several days of development, it’s finished.  Overall I’d say with this project I wish I had bitten off a little bit less.  Sure I accomplished most of what I set out to do.  My app is live on Heroku.  But at what cost?  4 days?  Probably 2 of those were from the Postgres nightmare, but 2 of those at least were from simply choosing a scope that was too large.  This wasn’t meant to push the horizons of internet architecture.   It was just meant to show that I can do what I want in Sinatra.

Facets: the making of ‘rubedility’

This project is part of my Learn.co curriculum, yes, but it is one that I’ve actually been interested in doing for a while.  I discovered the wonderful land of Codility last year when I tried out (and sadly failed) for Toptal.  I know I shouldn’t feel bad because (according to them) I’m just not in the top 3% of developers.  I can get over that.  What I can’t get over is how excited I am to be moving into this realm of remote/distributed software development.

Codility – Language Agnostic Software Skills Assessment

It really is an incredibly difficult puzzle to solve: how do you assess someone’s software skill level?  Should there be a time limit?  Should there be a quiz about some obscure functionality that the test’s authors like or utilize?  Should it be totally open-ended: “tell me everything you know about software?”  Should there be a language-specific problem that the candidate needs to know about, or that shows some level of intimacy with a given language?  I think those are all legitimate questions, and the answers will vary between companies.  Codility gives a company the chance to have a “first line of defense” against being overwhelmed with candidates.  Codility’s business model makes them a neutral third-party to the candidate’s assessment and is funded by companies that pay them to proctor tests to candidates, and is totally free for programmers to practice and learn.

They do this by offering language-agnostic lessons and tests aimed at testing a candidates abilities to take an abstract problem description and turn it into a usable program.  Their problem descriptions have been, in my experience, some of the best out there.  Very specific, and difficulty-level appropriate, as well as marked accordingly with ‘painless’, ‘respectable’, or ‘ambitious’.

Open Source

You don’t really realize how amazing it is until you start to think about it.  Only 20 years ago this idea didn’t even exist for even the most well-funded and immutable companies on the planet.  Now anyone with internet access can write programs and share them with the world.  People who have common interests can come together and make something amazing and share it with the world.  This is a huge step in helping the world be a better place, and Ruby is part of that world in a big way.

Nitty Gritty

You can read the source code to the gem if you want.  Hence it’s, “open source”.  But the TL;DR of it is this: it pulls text from specific portions of codility.com and displays them in the terminal window.

 

So I needed 3 classes: Lessons, Tasks, and Difficulties.  This way you could link them together in such a way that made sense without having to have a gazillion lines of code in one file.  This also makes it easier to extend the program later, or re-use parts of it.

Lessons Learned

So I think the most frustrated I got was the 2-hour window when some portion of my code magically didn’t get saved correctly.  I put in some changes, saved the file, and then re-ran it, but the changes were obviously not there in what was running.  So I spent *way* too much time

Draw as many diagrams as you can before you write a single line of code.  Picture as much of it in your head as you can to try and find out things that you’ll eventually wish you had started out knowing.

Keep a running list of “future plans” and if at any point what you *actually* plan on doing becomes too hard to re-factor for, take a break.  Take a long break.  Use it to decide which is more important, saving the work you’ve put in going down the current path, or saving yourself trouble by factoring for the future plans now, but have to throw away some code in the process.

The ‘interface’ part of a ‘command line interface’ is incredibly annoying.  If users will be ‘navigating’ data through your interface, you’r pretty much better off figuring out how to wedge your data into somebody else’s interface.  Plus there’s really no point in re-inventing the wheel.  There are tons of good interfaces out there, and if inventing new interfaces is your thing, rock on.  But for most ‘command line interface’ tools, the ‘interface’ part of it is pretty weighty.  Aliases, searching, help, loading, nesting, displaying; each piece of it adds new complexity to your code that really shouldn’t distract you from what you’re really trying to do.  If I had this to do over again, I would probably have all of the information scraped into files and directories instead of objects and variables.  That would solve SO many of the interface issues and open up a world of possibilities for the user.

Future Expansions

The first thing I saw happening was the snowballing of HTTP requests that had to go out.  As soon as I knew I was sending around 100 HTTP requests, I knew Asynchronous requests would bring an order of magnitude speed increase.  But that’s for later in our coursework, so I’m excited for that.

As already mentioned above, I can definitely see value in having these saved as text files.  My original decision to keep them as object variables was because I thought a student-level gem that downloads a fair amount of material, just for the sake of seeing it, is probably not the best idea.  But I think this, my future self, would encourage my past self to go for it.

Arguments.  As already mentioned, the ‘interface’ part of this is, in my mind, so much more annoying than parsing an HTML response.  That’s the interesting part, and I only spent maybe 10% of this project’s time on it.  The rest is on creating classes, instantiation, blah, blah, blah…  A much more rich interface would be one that could accept “open task 5” instead of just “open task” and then prompt the user for information that could have just as easily been passed in already.  Again, a better interface, but not the point of this project.  Requesting and parsing the HTML was, and I’ve done a smashing job at that if I may say so.

The ‘task’ object I created just stores a text value for the ‘level’ property for the ‘difficulty’.  A more truly Object Oriented solution would have stored an actual Difficulty object there.  I can do that, and I see the benefit of that if this were a business or money-making software, but not for a tiny project.

Test-Driven-Development is much better when you’ve written 2 lines of ruby test code.

Listing lessons and tasks would probably look better in columns.  But columns are hard.  And annoying.

There was a small amount of code that could have been pulled out into a separate module.  Again, pet project, pet-level complexity.

Summary

All-in-all, I’d say it’s a winner!  Check it out!

 

We live in the future, yes, but,…… imagine even MORE future!

The Internet is just one of the many things that makes now an exciting time to be alive. But between Bitcoin, Maidsafe, IPFS, Bridgefy, AirBNB, Uber, and so many other things that are just starting out their journey, the horizons of what technology *should* do are being pushed in a direction that could take us even further than the richest fantasy novel.

Blog at WordPress.com.

Up ↑