General Assembly WDI, Week 4

Rubber ducks, Das Sound Machine, and spaceship operators.

Day 15

Monday was project presentation day: we each got five minutes to present our Tic-Tac-Toe games, and two minutes to field questions. I found myself strangely nervous—I was proud of what I had accomplished, but the thought of having to stand up and talk about it, justifying my decisions and explaining my approach, was terrifying.

The order of our presentations was randomized, and I drew one of the last slots, which gave me some time over lunch to open up a couple of different tabs and zoom in on a few things I wanted to talk about in my code—specifically, how I automatically logged users in when they signed up (this Stack Overflow question on passing additional data to AJAX callbacks, which I mentioned in my last weekly write-up, was helpful) and how I checked whether a game had been won or tied. I was proud of the first, and not so proud of the second—I still don’t think a Tic-Tac-Toe game should take 60 lines of code to figure out if it’s over, and near the top of my to-do list is streamlining this.

Taking the time to tee up a browser tab for each of my talking points helped the presentation go smoothly, and at the end, the instructors gave us each a rubber duck, then sent us home early to get some rest. All in all: a good day.

Day 16

Our assignment on Monday night was to walk through a couple of intro to Ruby tutorials and, if we had time, to read Why’s (Poignant) Guide to Ruby. It….

I….

It’s hard to describe.

You should probably read it for yourself.

And then, if it sparks your curiosity as much as it did mine, read Annie Lowrey’s 2009 piece for Slate, “Where’s _why?.”

I read the first half on Monday night and most of the second half on my phone while I was on the train on Tuesday morning, which didn’t in any way do this book justice. I think I need to go back and reread two or three more times at least, preferably on a large screen so I can properly appreciate the sidebars and illustrations.

Jumping into Ruby on Tuesday morning after working with JavaScript for the past year and PHP for several years before that felt like the Barden Bellas felt when they first saw Das Sound Machine.

A few initial notes/impressions (please don’t use these to teach yourself anything about Ruby—this is all Day One knowledge that may or may not be accurate/correct):

  • You don’t need parentheses to call a method without parameters in Ruby. You also don’t need them, even if you’re passing arguments, unless you want to use the results of that call immediately and chain on additional methods.
  • Ruby uses symbols, which, depending on where you read about them, are “lightweight strings,” “a string and a number,” or “the name of the variable, not the value of that variable.” My best shot at describing them: symbols represent a unique spot in memory. They have the same value everywhere in your program. They’re often used in class definitions.
  • Ruby doesn’t have an increment (++) operator. Use += 1 instead.
  • Floats and fixed numbers (integers) are distinct types in Ruby. 7 / 2 will return 3 in Ruby, not 3.5. If you want 3.5, you have to attach .to_f to either the 7 or the 3 before dividing.
  • .to_i truncates, it doesn’t round.
  • Ruby hashes do not allow you to access their keys through a dot notation; you must use square braces.
  • Ruby lets you access values from the end of an array: array[-1] will be the last element in the array.
  • a.equal?(b) will return true if and only if a is the same object in memory as a. Use .eql? to test if the values of a and b are the same.
  • Along the same lines, == is used to test whether values are equal. === is not used to test equality at all, but rather to test for inclusion (is a value in a particular range?). See this Stack Overflow question for details.
  • puts vs p vs print:
    • puts calls .to_s on an object, appends a new line, and prints it.
    • print calls .to_s on an object and prints it without appending a new line.
    • p calls .inspect on an object, appends a new line, and prints it. This can be helpful for debugging because it doesn’t automatically convert everything to a string.
  • Remember my excitement about fat arrow functions in JavaScript? Ruby uses the same symbol (=>) in hash definitions, only it’s called a “hash rocket.”

Day 17

  • More on symbols: Always use symbols as keys when writing hashes. Symbols perform better because Ruby compares them using their object IDs, instead of comparing strings letter by letter.
  • You can search for symbols using Symbolhound. No more frustrating Googling for the Paamayim Nekudotayim!
  • Ruby uses blocks instead of callbacks.
  • In JavaScript, all arguments are optional. JS will try to run the function even if you don’t provide the correct number of arguments. In Ruby, all named arguments are required. In other words: Ruby checks arity (the number of arguments or operands that the function takes); JS does not.
  • The exclamation point after an enumerable method in Ruby means that the method alters the original array.
  • All operators in Ruby are methods. 2 + 2 is the same thing as 2.+(2).

Day 18

We started talking more seriously about enumerables today.

  • Ruby has three basic types of ordered lists: hashes, arrays, and ranges.
  • All of these lists are enumerable, meaning they can take advantage of Ruby’s enumerable methods.
  • In Ruby, hashes have order (in most programming languages, they don’t).
  • In order to use these methods, a class must include the Enumerable module (include Enumerable) and define an each method.
  • Other things—files, for example—are also enumerable. Anything you can iterate over is an enumerable.

We also talked about classes.

  • Ruby is a “classical” language; this means that Ruby uses classes to define and instantiate new objects. JavaScript is a “prototypal” (not prototypical) language; it uses prototypes.
  • Ruby classes have an initialize method that acts like a JS Constructor function. The instance variables set within this method are private by default; “getter” and “setter” methods defined in the class provide access to these variables outside the class definition.
  • Ruby convention is for “getter” and “setter” methods to be named, respectively, propertyName and propertyName=. We can also use attr_reader :varname (getter), attr_writer :varname (setter), and attr_accessor :varname (getter & setter) to create simple versions of these methods.

Day 19

A high-level view of Ruby (made by Artem S.):

Ruby Core Object Model by Artem S.

And a handdrawn version by Jerome Dalbert:

Ruby Core Object Model by Jerome Dalbert

We talked a bit more about enumerables today, and introduced comparables: like enumerables in Ruby, comparables are anything that can be compared, that uses the comparable methods defined in the Comparable module, and that defines a <=> method (aka the “spaceship operator,” apparently so named because it reminded PERL expert Randal L. Schwartz of the spaceship in a Star Trek game).

We also talked briefly about how defining <=> on a comparable class allows you to use the .sort method, which made me wonder what Ruby’s built-in sorting method is. Fun fact: .sort_by in Ruby uses a Schwartzian transform, a sorting algorithm named after the aforementioned Randal L. Schwartz.

A few other notes:

  • Ruby has implicit returns: the last line is always what’s returned.
  • Ruby also has an implicit receiver: you don’t have to use self when you’re calling a getter method on an instance from within a class (though you do have to use it when calling a setter method).
  • super will call the same method defined in the parent or superclass and give you the result.
  • .new is a Class method that calls the Instance method .initialize. .new allocates memory for a new object, creates that object, calls .initialize, and returns the object.
  • self will point to one of three runtime contexts: global context, object context, or class context.
  • In Ruby documentation, # indicates an instance method, while . indicates a class method.
  • def methodname inside a class is how you define an instance method. def self.methodname inside a class is how you define a class method

To sum up

Everyone I know who uses Ruby tells me it’s orders of magnitude better than PHP. I’ve people clap their hands in glee when I told them I’d be learning Ruby as part of GA. I’m hoping to feel some of that excitement soon, but for now:

General Assembly WDI, Week 3: Project Week

Project week! *jumps for joy* *whimpers* *bravely soldiers on*

Squeaking this one in under the wire—the last two weeks have been a whirlwind (I expect I’ll be saying this for a while)!

Last Monday was a holiday. Tuesday was a normal class day. Wednesday through Friday were allocated for work on our first project: a single page Tic-Tac-Toe game built in JavaScript and jQuery, using a Rails API for user authentication and game data storage.

To sum up:

Let’s start at the very beginning, with Tuesday’s class on CSS and SASS:

Day 11

SASS (which GA teaches) and LESS are probably the two best-known CSS preprocessors, but many others exist. We didn’t talk much about the pros and cons of different options, but based on some quick Googling:

  • SASS is written in Ruby; LESS is written in JavaScript.
  • SASS seems to have more available tools to help developers: frameworks like Compass, mixin libraries like Bourbon. LESS has libraries, too, but they’re not quite as powerful and less cohesive.
  • SASS offers selector inheritance via @extend, which is pretty sweet.
  • SASS has better logic than LESS, which is fairly limited.

Fun fact about colors in SASS: the native lighten and darken functions aren’t stellar—they move pretty quickly into complete white/black, rather than tinting or shading things gradually. To fix this, you can use mix to adjust your colors with a bit more control. You can also write custom tint and shade functions that mix colors with white and black to lighten or darken more gradually.

A CSS style best practice I didn’t know before: you should sort your rule declarations by property name in alphabetical order.

Days 12-14: Project Work

The assignment was fairly simple: build a single page JavaScript-based Tic-Tac-Toe game that:

  • renders a game board
  • alternates turns between X and O
  • shows in the browser who’s won at the end of the game, or identifies the game as a tie
  • allows the user to play multiple consecutive games
  • uses AJAX to interact with a provided Rails API to
    • handle authentication
    • store and retrieve game data

My instinct when we got the assignment was to start downloading and playing as many mobile games as possible. I knew I wanted my game to be responsive—who really wants to sit with a laptop and play game after game of Tic-Tac-Toe? It seems like something to do on the train, or while you’re waiting in line for your (much-needed) coffee. Looking at mobile games to identify examples of clean design and intuitive user interaction felt like a good place to start. (The final UI is heavily inspired by the Dots.co family of games, which are among my favorite mobile games for their design, which feels colorful without being overwrought, and their fluidity.)

In hindsight: I wish I’d spent more time thinking about my data models, key functionality, and game logic first. I wrote a handful of user stories and spent a lot of time playing tic-tac-toe and diagramming win conditions, and I didn’t start *coding* the design until I had was able to authenticate users, play games, and log them to the server, but even as I worked on those things, I kept having to stop and reorganize my code to accommodate new features. Taking an hour or two to try to diagram the flow of logic and the exact points at which I needed to interact with the server would have brought more helpful structure to my approach and, I think, kept my code more elegant.

That said: I’m pretty proud of what I built in the span three five days (counting a few hours each on Saturday and Sunday):

Tic-Tac-Toe: large screen log in

Tic-Tac-Toe: mobile game play

Tic-Tac-Toe: mobile game end

Give it a whirl here (and please do let me know if you find any bugs!), or check out the code on GitHub.

Things I learned: I wrote a bit about my adventures in game board design earlier. As I built the functionality, I got some great practice with AJAX (including learning how to pass additional data to AJAX callbacks), and as I styled, I learned how to make a sticky footer. I also learned that it’s shockingly, embarrassingly easy to keep reverting to “x and y” instead of “x and o.” Warning to future tic-tac-toe game developers: this will cause you at least an hour of distress.

Current status: I’m midway through fixing a few small bugs, and I’m still waiting to hear feedback from my instructors at GA—I’m planning to ask them about ways to refactor/restructure and make my logic and flow a bit more elegant.

And my last takeaway: I CAN’T WAIT to learn how to do test-driven development. The single most frustrating part of building this app was having to test each feature manually every time I changed something. I tried to keep careful track of what I needed to test each time, but I *know* I missed things—as evidenced by the remaining bugs in my game—and the process was prone to error (see: manual). I’m not sure if GA teaches TDD explicitly or not, but tests are built into some of the repos they use in training, and I’ve started to track down the frameworks they use (Rspec for Ruby; Mocha and Chai for JavaScript). (In writing this paragraph, I learned about TDD vs BDD. So many things to explore….)

On to week 4 (which is coming to a close today, so expect another recap soon!)!

Ill-Advised Adventures with SVG

In which I am resourceful, if not efficient.

Tl;dr: Don’t do this.

Last week was our first official project week at General Assembly WDI. The challenge: build a tic-tac-toe game in JavaScript that uses AJAX to interact with a Rails API.

I got my basic logic up and running on Wednesday, and on Thursday, I decided to tackle UI. I grabbed a color scheme from an ad for Two Dots, picked out a font, added some nice border radii on a couple of elements, and used a couple of dot-like Font Awesome icons as my game pieces. Overall, I was feeling pretty good about my overall aesthetic:

Tic Tac Toe homepage

And then I took a look at my game board:

unstyled game board

Yeah.

gif-disappointed

It wasn’t time to panic—I could fix this! All I needed to do was to give the board a background, round its edges board, remove the outside border, thicken up those grid lines a bit, and—the final touch—round the edges of the grid lines to better match the overall feel of the game.

I thought about doing this in CSS, but Googling didn’t turn up a way to put round endcaps on border lines in CSS. Rather than wasting time (HA. HA HA HA. This is the part where there’s a freeze frame, and you remember that I said this for the rest of the story for it will prove to be ironic.), I decided to open up Photoshop and make a background image that I could drop into the game board div and be done with it.

Teensy problem: I don’t currently have access Photoshop, a fact I remembered late Thursday night.

I was faced with two options: research open source / low cost graphics programs, acquire one, learn how to use it. Or: further investigate this stroke-linecap attribute that showed up when I was Googling before.

Given that I identify deeply with this joke about Atom, and that it applies to almost every application on my six-year-old laptop, I decided to avoid installing something new. Time to code an SVG element!

I started with this:

See the Pen SVG Game Board v1 by Rebekah Heacock Jones (@rhj) on CodePen.light

Ooooooh, shiny! I was feeling excellent about this until I realized that it was getting later, and I wasn’t sure how to adjust the size of the rectangle and the positions of the lines dynamically at different screen sizes. (I didn’t yet know about ViewBox.)

Solution: pull all the SVG code into a separate file. Apply inline styling. Use the SVG as a background image on your game board div. Go to add/commit, and realize that the provided template for your project includes SVG files in its .gitignore, which you’re too afraid to overwrite because you don’t know why that choice was made in the first place. Export to PNG using SVGtoPNG.com. Since you’re now using PNG, which doesn’t scale well, make a bigger version of the SVG to use on larger screen sizes, and export that.

Stop awkwardly in the middle when you accidentally do this:

Finally end up using image files like you always intended, only you’ve taken the VERY LONG WAY there.

What’s the point of this blog post? It’s part cautionary tale—be careful not to get so attached to an aesthetic that you end up spending hours on a single, unimportant element of a project (unless, of course, that’s actually your job). There are better ways to do this: use SVG correctly and write the code that makes it scale. Ask your instructor (or your boss) why they don’t want SVG files in your git repo, and see if you can work out a better solution together.

I’m also writing this because it’s a good reminder to myself that I can be resourceful. I had a goal, and I achieved it with the tools at my disposal. And now it’s part of a functional public Tic Tac Toe app that anyone—even you?—can use! All in all: a good day.

Some fun side notes: while writing this, I ended up using git checkout [commit hash] to (temporarily) go back to an earlier version of my code, pre-svg, so I could grab screenshots. The Atlassian tutorial on Reset, Checkout, and Revert has an excellent explanation of how to do this.

General Assembly WDI, Week 2

More JavaScript, our first encounter with Rails, and three days of AJAX.

Friday wrapped up my second week of General Assembly Boston’s Web Development Immersive program: as of this weekend, I’m one-sixth done, which is at this point mostly terrifying. How can there be only ten weeks to go?!?

I feel like I’m learning cool things (making AJAX requests that use methods other than GET, for example), but in a very, very controlled and somewhat black box-y environment. GA’s basic approach to a day of class is: pull down these git repos, run Node and/or Bundler commands, and then open up a specific file and do a specific thing. I understand why they don’t want to throw us off the deep end and go too far into things like “runtime environments” and “what is a gem” while we’re still asking questions like “what does ‘PATCH’ mean?,” but at this point I would struggle to implement what I’m learning outside of the structure of GA’s pre-packaged tooling.

To be fair, this is probably because at this point, most of us are only maybe half a step above this:

So. On to the cool stuff:

Day 6

More about fat arrow functions, which (along with template literals) remain one of my new favorite things about JavaScript:

  • The value of this doesn’t change (and can’t be changed) within a fat arrow function. this is fixed at the value it was when the function was called. (This is also known has “having only a lexical this, not a dynamic this).
  • Fat arrow functions can’t be used as Constructors: they don’t have a prototype, and they don’t have a Construct method.
  • Fat arrow functions don’t have an arguments variable.

A bunch of methods for array manipulation: .every().filter(), .forEach(), .map(), .reduce(), and .some().

Assignment using the || (OR) operator: result will be set to the first truthy value. If there are no truthy values, result will be set to the last value. Examples:

     let result = 'result' || 0;
     > 'result'
     let result = undefined || 0;
     > 0
     let result = 7 || 3;
     > 7

Apparently it’s now déclassé to set CSS styles on IDs.

A couple of cool tricks for Sublime/Atom:

  • ⌘ + ? will add an empty comment (using the correct syntax for whichever language you’re using)
  • ⌘ + multiple clicks will set multiple cursors within a document

Day 7

Building multi-row, multi-column CSS layouts from scratch: a serious weakness of mine. Ouch. Also, wireframes that don’t conform to a grid: BOOO.

There are THREE values for box-sizing: content-box (default), border-box (reasonable), and padding-box (only supported in FF.). More in CSS Tricks: Box-Sizing.

An explanation of those horrid unwanted spaces between inline-block elements.

Day 8

First time using Rails! Though only very, very lightly: we cloned the existing Rails code for a simple API and got it running locally so we could make curl and AJAX requests against it.

Some conventions for writing JavaScript:

  • “Predicate” functions return true or false. Begin names of predicate functions with “is” (isEven, isOdd, etc.).
  • Use “on” as a prefix for handlers (onGetAllBooks, onSignUp, etc.).

You can use debugger; as a standalone line in Node to set a breakpoint.

Day 9

Philip Roberts’ “What the heck is the event loop anyway?” is an excellent introduction to the JS event loop. My notes:

  • one thread === one call stack === one thing at a time (single threaded)
  • call stack: data structure. records place in the program. step into a function: add something to call stack. complete a function: pop it off call stack.
  • slow things “block” the stack b/c JS can only do one thing at at time.
  • particularly bad in JS b/c of browsers: you click on a button and get stuck, and the browser can’t return that button back to its un-depressed state. everything hangs. this is because the browser can only render when the call stack is empty.
  • callbacks get pushed to a queue when they’re ready to run, NOT to the call stack.
  • the event loop monitors the queue & the call stack. when the call stack is empty, it moves one thing from the queue to the call stack so it can run.
    • this is why callbacks passed to setTimeout with a timeout of 0 ms will run *after* lines of code that follow setTimeout. the event loop has to wait to give that callback to the call stack until the call stack is empty, even though the timeout is 0.
    • setTimeout is not a guaranteed time to execution. it’s a *minimum* time to execution, since we have to wait for call stack to clear before callback can run.

Day 10

We spent the last three days of this week on HTTP methods (GET/POST/PATCH/DELETE) and AJAX. We started by using curl requests to interact with a basic books API, then built AJAX requests to replicate that process in the browser (click on a button, send the request, handle success and failure). Day 10 focused on authentication: signing up/logging in/logging out, and doing things (changing information, viewing protected information) that require an auth token.

Coming up

Next week is our first “project week.” The challenge is to build a single-page tic-tac-toe game in JavaScript that relies on an existing Rails API to help with authentication and data storage. I’m looking forward to putting what we’ve learned over the last two weeks together into something usable, rather than a series of code snippets that aren’t connected. I feel like I have a good pile of building blocks now, and I’m excited to start using them to *build.*

General Assembly WDI, Week 1

Template literals, fat arrow functions, callbacks, closures, and overwhelming joy.

Today is the first day of my second week in General Assembly Boston’s Web Development Immersive program, a twelve-week, full-time course focused on JavaScript and Rails. The course is intended to take people from no knowledge of programming to a full-time position as a developer, so some of the past week has been review, but I’ve loved every single second of it. Instead of my standard-ish This Week I Learned posts for the next three months, I’m hoping to do quick weekly recaps of how the program’s going.

Day 1

We spend most of Day 1 on the command line interface and on git. A couple of cool things:

  • cd - takes you to your previous working directory. SO HANDY.
  • use git checkout -b newbranchname to create a new branch and check out that branch simultaneously
  • I fixed my first-ever merge conflict!
  • GA emphasizes frequent commits and long commit messages. This wasn’t part of the course, but I recently learned about Angular.js-style commits, which seem like a great way to organize and communicate.

Day 2

Day 2 was our first day working with JavaScript. A couple of new pieces of information/new conventions:

Day 3

  • Seems obvious in hindsight, but you can isolate the unique elements in an array like this:
    let words = ['lots', 'of', 'words', 'of', 'words'];
    let uniqueWords = {};
    for (let i = 0, max = words.length; i < max; i++) {
      uniqueWords[words[i]] = true;
    } 
    

    This will give you an object where the keys are the unique elements in the array, and the values are true (as a convention; you can choose anything you want for the values). This is much simpler than my original approach, which involved…comparing all of the elements of the array to all of the elements? I don’t know. It was complicated and involved, and I don’t recommend it. Do this instead. If you want the final format to be an array, you can use Object.keys() to extract the keys (the unique words) and store them in a new array.

Day 4

  • Object properties are “attributes” when they point to values/primitives. Use constructor functions to attach attributes to an object.
  • Object properties are “methods” when they point to functions. Use prototypes to attach methods to an object. (Why? Functions that are attached using a constructor will be copied and attached over and over again to each new instance of an object. This is a huge waste of memory.)
  • Properties that begin with underscores are private (by convention): not intended for direct access or assignment.
  • “accumulator pattern” (all of the online resources I can find about this talk about it in Python, but it applies in other languages): initialize result, iterate, return result
  • We started using node to run and test scripts.
  • A callback is a function that is passed as a parameter to and executed inside of another function.

Day 5

    • When filtering and transforming an array (arrresultsresults[i] within an if statement can result in “holes” in the array when the original arr[i] doesn’t pass the filter. It’s better to use results.push to skip values that don’t pass, resulting in a cleaner results array.
    • Template literals (WHAAAAAAAAT so cool).

To sum up the week: