Tuesday, April 1, 2014

Week 9, Day 2: Language 80-20 is Up and Running

Major Activities of the Day: We started in earnest on Language 80/20 today!  After figuring out how to seed the data last night, it was time to give our application a face.  We built up the views a bit, to show words from each language and paginate, and choose on the front page which language and how many words to view.  Each word now displays its translations as a tooltip.

We had some trouble getting translations to display when we launched to Heroku, and spent quite a while working with Heroku logs trying to show the information we needed, and making tons of commits in order to be able to push up to Heroku and debug.  We finally realized that the translations weren't showing up because we were using the unofficial API-ish Google Translate gem (which is more of a scraper), and Google has presumably learned not to respond to GET requests from herokuapp.com.  So we realized we would have to gather the data on our own, seed the database, and work from there.  That will be a project for the next couple of days.

We had a middle-of-the-day Skype conversation with Tom Dale, one of the creators of EmberJS.  He came down pretty hard on Rails for being slower than JavaScript (in terms of both execution and size of Ajax requests), which I was aware of, but I guess this was a good reminder to me that many employers will want me to program in other languages because of the problems with Ruby and Rails.  As an aside, he happens to be a pretty inspiring example of how quickly someone can become a great programmer.  Six years ago, he was a non-CS college grad working in the Apple store, and got himself hired for a programming job in the company.  Fast forward to today, and he's partnered with Yehuda Katz to create EmberJS, a JavaScript framework that's rapidly growing in popularity.  Pretty cool stuff.

At the end of the day, we made a brief video showcasing what we'd done over the course of the day.  We're supposed to do this every day over the course of the project.

Skills developed: Working with Twitter Bootstrap, debugging with Heroku logs

P.S. Version 0.0 is already up - check out our app at language-80-20.herokuapp.com!

Week 9 Day 1: Ready for Deploy, Captain!

Major Activities of the Day: Today we spent the morning rallying the troops and figuring out what project we're going to work on.  I'm going to be working with Chris Kohlbrenner and Jisu Kim on an app that helps users learn the most commonly used words in a language, based on the Pareto principle, also known as the 80/20 rule.  Essentially, most of our conversation consists almost entirely of the most-used words, so common words give you far more bang for your buck than less-used words.

We had a lecture today by Spike Grobstein, who showed us how to set up a Linux server using DigitalOcean's cloud service.  It was super confusing.  We all got our own little server to try with, and of course, despite working for several hours, I just couldn't get things to work properly.  (In all fairness, it may have been a problem with my app, since I tried to deploy Eateract to the server.)  Luckily for me, there are platforms like Heroku that let you avoid these problems, but eventually I'll have to learn how to do this SysAdmin stuff, I suppose.

We ended the day by conferring with our teammates about the coming few days' project.  We're starting in earnest tomorrow morning, and I'm eager to greet the challenge!

Skills developed: Server setup/administration, project planning

Saturday, March 29, 2014

Week 8 Day 5: The Calm After the Storm

Major Activities of the Day: Today we had a lot of free time.  (It's sort of a running theme for Fridays.)  Since my major presentation was yesterday, I was too wired up to really use the time productively.  I ended up chatting with a few other students, getting to know people better, talking about the meetup and our projects, trying to get some advice about what went well and what didn't.

Of course, I couldn't just abandon my project 100%.  So I went back and tried to figure out what went wrong with Facebook login.  It turns out (and I discovered this in about 2 minutes, fixed it in maybe 3 more) that Facebook requires you to tell them that your app is live and available for people to access.  In practice, this means that at developer.facebook.com, on the page for your app, you flip a switch to indicate that the app is live.  That's all.  I also now understand why I could log in - because I'm the developer - but no one else could.

At the end of the day, Avi spoke for a while about Project Mode, which we'll be having for the next few weeks.  It sounds pretty cool - build a new web app every week, in a group of 2-3 students.  We're also supposed to deploy every day - i.e., we need to have something deploy-ready on day one, and then build up from there.  It'll be a very different atmosphere than we've had until now, but that's not a bad thing - in fact, it sounds like a reasonable approximation of the atmosphere we'll have in real work environments, with strict deadlines and lots of teamword.  Looking forward!

Skills developed: Not much today, to be honest.  But I'm super excited for next week!

Friday, March 28, 2014

Week 8 Day 4: Eateract!

Major Activities of the Day: Alright, I'll be honest.  We got some labs to do today, but I ignored them, because... tonight I presented at the meetup!  My project is called Eateract.

At the center of the application is a super-fancy JavaScript/Ajax-based form that grabs user options from the server.  The user puts together a meal - invites friends, chooses a topic of conversation and some links to send out, searches for recipes (using the Yummly API) and assembles a menu, adds a custom message, picks a date and time, and submits.  The application then sends emails to the requested users, letting them know they've been invited to a meal, and giving them a link to the meal page.  On the first page load, they can accept or reject the invite, after which subsequent loads will just lead them to the page.  They can volunteer to make particular recipes, and the application shows each user who's signed up for what.  Of course, there are active links to all the recipes, as well as the links the host has selected for everyone to view in advance.

By the way, here are the pieces I added today:

  • Full display for an individual meal
  • ActionMailer to send emails to guests
  • HTML email (designed for Gmail - sadly, it broke horribly when I tried it in Yahoo! mail)
  • Authentication tokens for guests so only guests, not random people, can see the meal (the tokens are included in the links being sent out in the emails)
  • Add custom message to email
  • RSVP system

So yeah, you can do a lot with Rails in one day, even as a newbie.  You can check out the code at https://github.com/amcaplan/eateract; I'll post an update to this post once I put up the app on Heroku.

One slight problem happened during the presentation.  I have Facebook login for hosts, and during my presentation, I tried to do a live demo with a new user volunteer from the crowd.  Unfortunately, the login failed for her, even though it always worked for me.  Should have done a user test first with someone besides myself... anyway, I just logged myself in, and then let her act as me.  After that, pretty much everything was fine.

Truth is, what stuck with me wasn't a feeling of how good my product was.  I'm very proud of what I was able to put together, but to me, what was more important was just forcing myself to get in front of a crowd, present enthusiastically, and not get fazed by bugs (because I was sure that bugs would crop up, and hey, one did!).  I tried to imagine myself giving a TED talk, and used that sort of method - walk around the stage, interact with the crowd, tell people to call stuff out - I think the audience responded well, even if I went a bit overtime.

Bottom line - why did I do this project?  Because I see how we as a society are becoming more addicted to social media, and losing our ability to connect face-to-face.  I see phones getting pulled out at meals, if not entire laptops, and I worry that our connections with others are becoming superficial.  So I decided to put together a project that would flip the agenda - use technology to generate, rather than break up, meaningful social experiences.  I also imagine that this would provide a toolset for parents to talk about values with their children.  It's not a matter of parents transmitting values as much as showing their children that values are important and worth thinking about.

P.S. Here's a couple of screenshots:
Homepage before login
The beginning of the form...
Choosing a topic
It's responsive!  (This is the small-screen view)
Choosing recipes
Whoa!!! It's a super-cool modal!
After a meal is created
A dashing dashboard
Skills developed: Technical presentations in front of a crowd

Wednesday, March 26, 2014

Week 8 Day 3: Persistence is Key (or: Persistence in Object Keys... and Values!)

Major Activities of the Day: Today started with a couple of jQuery labs.  I ignored them, because I'm going crazy worrying about my project, and I feel like I'm learning more by doing an actual project than by doing predesigned labs that isolate me from many of the problems.  It's good to have that isolation and really focus on one problem initially, but once I'm more comfortable, it just feels like going backward.

We had lecture today about the power of remote: true in Rails.  It's basically a shortcut to setting up an Ajax form.  More info is available in the Rails guide about Ajax.  (Warning: the information there is written in CoffeeScript rather than plain JavaScript.)

We moved on to some more labs, which I continued to ignore for the above rationale.  Aaaaand there was homework.  Ignored.  Doing a project, is hard, ok, people?

Here's what's interesting, though: I had to figure out how to make the page persist data while the user was making selections, despite the fact that the page was displaying other things.  Here's what I mean: The page displays a bunch of links related to a particular issue, and the user can check off particular links.  The user might decide to check out a different topic, but then come back to this one.  I want the user to not need to re-check what was checked before.  So I used an array in the background that is updated when any checkbox is checked or unchecked, and when the user switches topics, it looks in the checked links array for which, if any, link have been checked before.

Here's a more complex example: I'm displaying recipes collected from Yummly's API based on a user's search.  These recipes are selectable via checkbox, and the selected recipes are displayed in a menu at the top of the page.  Here's where it gets challenging:

1) I want to let the user do multiple searches, and have the recipe data persist from search to search.
2) I want the user to be able to go back to a previous search, and have everything checked off as appropriate.
3) I want to store 2 pieces of information about each recipe: its name and its Yummly ID (which I can use to build a link in the form http://www.yummly.com/recipe/[recipeID]).
4) I want the user to be able to remove menu items by either clicking "remove" on the menu next to the item, or unchecking a box in the search.
5) When the form is submitted, exactly one copy of the selected recipes should be sent to the server.

Here's how I did it: There is a plain old JavaScript object in the background, which uses recipe IDs as keys and recipe names as values.  Every time there is a checkbox checked or unchecked, or the user clicks on "remove" next to an item on the menu, the object is updated.  Additionally, there is a hidden text area which is updated with the toString()ed contents of the object.  When the form is submitted, the contents of the text field are interpreted by the controller by converting the string to a hash using the ActiveSupport::JSON::decode method, and the hash can then be used to input information into the database.

I'm not sure this is the best pattern, but it works.

Then, to get the information back into the form if the user is editing again, I initialize the object with its contents (or an empty object if the recipes weren't filled in last time, or this is the user's first interaction with this form), and the text area is filled with the object's contents, right off the bat.  So the previous user data ends up in the form right away.  I used a similar method for the user-selected links.

Skills developed: More jQuery and Ajax, persisting data in two directions: form -> database, and database -> form

Tuesday, March 25, 2014

Week 8 Day 2: Going Deeper Into Ajax

Major Activities of the Day: We had a lecture about Ajax, followed by a slew of labs to apply our knowledge.  The first was some simple work with selectors - far less complicated than what I've been doing thus far - so I finished it quickly.  Next was taking a comment form for a news website and making it have validations.  In the middle of working on it, I just got very stressed out about my project and returned to working on it.  (I also did some work with it in the morning as well.)

Today's major task was figuring out how to get my application to properly interface with Yummly, which offers an API to gather information on recipes based on search terms.  I get 500 free API calls per day, so I have to make sure my app isn't making unnecessary calls, but otherwise it should be fine.  I also added some dynamic elements to the form to add fields on the fly and build a menu of recipes based on which recipes the user checks off.  The checkboxes and descriptions are generated through an Ajax call, where the client queries the server, and the server calls the API, gets a list of recipes, and sends them to the client.  I also figured out how to listen for an enter press as an alternative to clicking a button.

Skills developed: Working with APIs and Ajax

Monday, March 24, 2014

Week 8 Day 1: jQuery Is Now In My Vocabulary

Major Activities of the Day: Today we started JavaScript!  To make things simpler, Avi had us all go through the CodeSchool JavaScript Roadtrip videos.  In the afternoon, we had a lecture about jQuery and Ajax.

That's what (almost) everyone else did.  I had the good fortune of having done the CodeSchool course before, and I spent the weekend studying jQuery and Ajax with the CodeSchool courses.  So I spent most of the day working on my project, actually implementing jQuery stuff.  So there are lots of event listeners, a getJSON call to retrieve data stored on the server based on a user selection, etc.  It was a pain to deal with a new language and framework when I'm still struggling somewhat with Rails, but the effects were incredibly pretty, and at the end of the day, I'm proud of what I managed so far.

Skills developed: jQuery, Ajax

Saturday, March 22, 2014

Week 7 Day 5: Free Period!

Major Activities of the Day: Today we had lots of chill time, so I focused on moving ahead with my project.  And by that, I mean that I spent 2 hours putting together a logo.  It was kind of tough to find free software, and it's a raster image rather than what it should be - a vector image (faster to load and scales without going grainy) - but it's something, and the logo just isn't the main point here.  (Which is why I spent 2 hours on it.  Um...)  I added some frontend stuff, including tabbed content, which Foundation gives you right out of the box.  (Oh, to be clear, I'm using Zurb Foundation - I decided not to go the standard Twitter Bootstrap route, because I imagine I'll eventually learn Bootstrap, and Foundation looks pretty cool, so I may as well get to know it.  We'll see how it goes!)

As an aside, I learned a bit today about being open to changing directions.  I originally started out imagining a multi-page form with lots of controller actions to handle each step of the process.  Then I realized I could just have a tabbed form - hey, that's much nicer!  It's better from lots of perspectives - easier for the user (if they don't know about X, they can move on to Y and come back easily), and easier for me, the programmer (because I can just write one big controller action).  That's where tabs came in.  I didn't want to have lots of stuff appearing at one time on the page - things need to be organized, simple, attractive, and not overwhelming - so I kept it clean by showing only one piece of the form at once, using tabs.  Of course, I've only done the first part of the form, which is the easy part, just inputting names and email addresses.  The next parts will involve dynamically updated content, so basically I'm spending this weekend studying jQuery and Ajax, and hoping I can accomplish what I want to accomplish.

In the afternoon, we went over the Arel exercise from earlier this week, and then I had more time for project work.

Today was my first Feeling Friday.  (I'm an Orthodox Jew, so until this week when the days are longer, I had to leave early on Fridays to get home in time for the Sabbath.)  Essentially, everyone gathers in a big circle and we share our feelings about the week.  It was kind of neat to hear how everyone else feels, and hear that I'm not the only one who's gotten a bit stressed out about how much work we're doing!

Skills developed: Using a CSS/JS design framework (Zurb Foundation), flexibility in design

Thursday, March 20, 2014

Week 7 Day 4: Regexps and OmniAuth

Major Activities of the Day: We began with a Ruby exercise writing a program that does math in words, e.g., four times seven plus three.  This was basically a way to get some more experience with regular expressions in Ruby.  Apparently, Ruby has a Regexp syntax where you write /(?<hello>world)/.match("the world") and it will give you a MatchData object; if you assigned it to a variable m_data and write m_data[:hello], it will give you "world".  This is useful if you want to find multiple matches in a string, and access each one by an independent variable.  Additionally, under some very particular conditions, when I use the =~ operator, it will assign a local variable with the name between the <>s and the value of the match associated with it.  So in this case, if I did this in IRB: /(?<hello>world)/ =~ "the world" and then entered hello, it will respond with "world".

We kept working on Arel stuff for a while.  It was tough, but I managed to get basically everything done with one SQL query per task (it may have been 100%, but I can't remember, and possibly one of them was impossible to do without 2 queries).

We had lecture today where Avi showed us a pattern for creating users with different permissions (in the case of his blog, users need permission to create/edit a post, create/edit a comment, etc.).  We also went over OmniAuth, which I already have some experience with from adding Facebook login to my project.  It's a standardized system of user authentication using big websites like Facebook, Google, Twitter, etc.  And it's a great way to keep your users from dealing with the hassle of making a new login just for your site, while saving you from shouldering the burden of dealing with encrypting passwords (and potentially making a mistake).

I got a lot of work done on my upcoming project today.  I'm debating whether to blog about it beforehand, but I'll probably keep it secret... :)

Skills developed: Ruby Regexps, Arel, User Authentication and OmniAuth

Wednesday, March 19, 2014

Week 7 Day 3: Aspiring Rubyists Experience Learning

Major Activities of the Day: We began today with an exercise Avi calls the "Rails Bug Hunt," where you take over a codebase with a bunch of pending tests, write the tests, watch them fail due to bugs in the code, and then fix the code so the tests pass.  I enjoyed it a lot, and it was a good way to show us how important it is to thoroughly test your code.

In blog post time today, I presented a new post, about how to properly hide secret data when you're using version control on an application you're developing.  You can read it here.

We had a lecture about AREL today.  AREL (described on its Github page as "A Relational Algebra" or, alternatively, "Arel Really Exasperates Logicians") is a gem that comes with Rails that allows you to generate SQL queries on ActiveRecord objects more easily than if you had to write the SQL yourself.  We learned a lot about maximizing efficiency by using the right methods to query the database, in order to minimize the number of SQL queries (even if individual queries will take longer), because extra queries add lots of lag time to an app's performance.

Our evening assignment was to work on some queries involving boats, captains, and boat classifications.  The choice of topic was because Arel, our TA, is very into sailing (he used to be a sailing coach).  Doing the SQL to make it all happen was pretty complicated, and I didn't finish it all, but then again, it seems like no one else did either - it's hard stuff!

Skills developed: Writing RSpec tests on someone else's code, AREL

Tuesday, March 18, 2014

Week 7 Day 2: More Auctioning

Major Activities of the Day: We began the day with a couple of Project Euler problems.  I had done them already (I went through the first 12 or so before Flatiron), so I just refactored my code, then kept working on the auction app from yesterday.  This (the auction app) was meant to be continued this morning anyway, so it worked well.

Late in the day, we reviewed the auction app.

Skills developed: Creating apps with user authentication and nested associations

Monday, March 17, 2014

Week 7 Day 1: We're not in Kansas any more... we're at kansas.gov!

Major Activities of the Day: We began today with some challenging programming problems that focused on working with strings.  We went over the Sinatra & ORM challenge from the weekend, and I learned some useful tips for querying databases.  Essentially, databases are the major bottleneck for applications (since they're handing massive amounts of data), and writing efficient methods for gathering information while firing fewer SQL queries can make a major difference in application performance.  It's also important not to load objects unnecessarily, since object load time is a significant performance bottleneck.

Today's Rails lecture covered authentication with Bcrypt.  It's really important, but as Avi pointed out, once you understand it, you don't want to create it, because there's so much room to make mistakes.  Because of this, it's generally best to use Ruby gems to take care of authentication for you, so you don't miss something by accident.  The current industry standard is a gem called Devise, which is apparently crazy complicated and takes a long time to figure out, but is still better than building it yourself.

He also showed us how to add Bootstrap and set up the app he's been working on over the past few lectures (a simple blogging platform) to have a decent frontend.

In the late afternoon, we had an assignment to create a very basic Ebay clone.  There were 98 RSpec specifications, so lots to do, and it was homework as well.

It really hit me today how we've begun to move into the world of the web.  We're moving quickly, and understanding how the ideas of basic programming translate into an online arena.

Skills learned: Noticing potential performance bottlenecks, Rails CRUD apps

Saturday, March 15, 2014

Week 6 Day 5: Recoup and Reflect

Major Activities of the Day: Today we came in to find... a blank schedule.  Yeah, we had a bunch of hours to catch up on work and study whatever we wanted.  I decided to read some Rails guides - the one about routing was really helpful, though I won't understand it 100% until we actually cover it.  I also put together a chart of the schemas for my upcoming presentation project (I may or may not do it, now that I've seen the chart of 11 tables in my database!).

As the day progressed, we were given two assessments: an assignment to put together a simple blog with user comments, and an assignment to review our web app development skills in Sinatra.

Skills developed: General Rails stuff

P.S. Sorry I haven't posted QOTDs in a while.  I kind of fell out of the habit.  It's pretty tough just finding time to keep up with regular posting!

Thursday, March 13, 2014

Week 6 Day 4: A Recipe for Success

Major Activities of the Day: We started out with a review of yesterday's exercises in making forms.  To be honest, I kind of zoned out, because I had done it already.  I need to start paying more attention, even when I have the excuse that "I know how to do it already!" because there is often a better way I'm not aware of.  This is especially true in Rails where the most obvious way isn't always the best.

We then spent a few hours working (individually/in groups) on a lab where we created a website that associates Recipes and Ingredients through a join table.  The point was to figure out how to create forms that will associate items using a nested params hash including hashes and arrays.  The major technical difficulty was creating checkboxes, since checkboxes are just super-hard to deal with in form creation.  But ultimately everything was figured out, and the form for my app now lets you create a new recipe with any existing ingredients (in any particular quantity) and/or add a new ingredient.  You can also view recipes by included ingredients.

After working on this for a few hours, we got together and had a lecture where Avi ran through the lab.  There were a number of occasions where he went back and forth about using high-level Rails methods rather than dropping down a level and coding HTML or using simpler Rails methods, but ultimately students convinced him to go with the high-level Rails method for creating checkboxes for the ingredients, and it worked pretty well!

Today was also a NYC on Rails meetup.  All the projects were pretty cool.  The grand finale was Wontae Yang's project using JRuby and NYC government-provided data to visualize the movement of subway trains and buses throughout the day.  It was really amazing to watch how, as night turns to morning, the city comes alive with buses and trains, and their tracks form the shape of the city (you can see a space for Central Park!).  Check out a Vine video of it here.

Skills developed: Rails forms (but we're getting really good at it!) for objects with complex relationships

Wednesday, March 12, 2014

Week 6 Day 3: Yes, and...

Major Activities of the Day: Recently, Flatiron has been tracking our progress with an app they created to check whether each project has been submitted, and is passing its RSpec tests.  So today we were told to begin by working on a bunch of old labs and cleaning them up to make sure they're registering as passed.  (They're already automatically tested by Travis, but the Flatiron progress app collects the data and lets us see what's happening as well.)

We moved on to a lecture where Avi went through last night's homework and showed us how it's done.  We did a lot more with forms today.

In the middle of lecture, we broke for a really cool 2-hour improv workshop by Drew Tarvin, where we used improv-y exercises to learn about social skills in the workplace.  The thing that stuck with me most was one exercise where we had to go back and forth with a partner talking about an idea for a school activity.  In the first round, each sentence had to start with "Yes, but..." whereas in the second round, each sentence had to start with "Yes, and..."  It was interesting how the latter generated really cool ideas, while the former just sort of went in circles.  The point was that "Yes, but..." is a good way to graciously reject an idea, but "Yes, and..." is usually better if you want to accept that it's a good idea but push it in a somewhat different directions.

To round out the day, we did two exercises putting together Rails forms.  It was good practice, and I like how it really compartmentalized a particular part of the Rails stack so we could focus on it without being overwhelmed by all the tools and intricacies of Rails.

Skills developed: Forms in Rails, soft skills in the workplace

Tuesday, March 11, 2014

Week 6 Day 2: Stack Too Deep


Major Activities of the Day: Today we started by creating a virtual Tower of Hanoi solver.  (It's too complicated for me to explain here, but you can click the link to see Wikipedia's description.)  I wasn't really sure how to begin, and then Daniel Kronovet explained to me the algorithm (which is on Wikipedia): essentially, if I have a large stack on Peg A, move all but one over to Peg B, move the bottom one to Peg C, and then move everything from B to C.  This can further be broken down one level up, where you're moving all but the bottom two to Peg C, moving the second-to-bottom to Peg B, and then move the rest from Peg C to Peg B.  You keep breaking this down further and further until there's only one peg.  So here's my recursive solution (from, to, and via are Pegs A, C, and B, respectively):


def move_disk(num_disks, from, to, via)

  return [] if num_disks == 0

  move_disk(num_disks - 1, from, via, to)

  to.unshift(from.shift)
  move_disk(num_disks - 1, via, to, from)
  to
end

I handle the edge case first - if there are no disks to move, return an empty array.  (It shouldn't need to return any value at all, just returning should be enough, but this handles a case where the original method call sent in an empty "from" array.  Afterwards, the method does exactly what we said: move any disks above it to the "via" array, then move the bottom disk to the "to" array, and finally move the remaining disks to the "to" array above the bottom disk.  Finally, the method returns "to" so the original method call will ultimately receive the "to" stack.

I really like this computer science-y stuff.  It's just a matter of understanding the logic, whereas frameworks that depend on just knowing a lot of stuff are much more of a challenge for me.  That's probably why I've focused more on programming than on web stuff in these blog posts.

After our ToH experience, we moved on to a lecture about forms in Rails... well, actually we were supposed to, but didn't, because there were some really interesting student blog posts, and Avi decided to go deep into the topics they covered.  So instead, we did that until lunch, and then had some time to work on things, study, catch up on homework, etc., until 2.  At 2:00, we heard a lecture from Dinshaw Gobhai about DevOps and the idea of breaking down the wall between Dev and Ops, so everyone is a little bit of both.

After the lecture, we had a brief break, and then, finally, the long-awaited Rails forms lecture!  Essentially, there are three ways to make a form in Rails:
1) Write all the HTML yourself, with maybe a little bit of ERB inserted to add CSRF tokens and an action or method.
2) Use form_tag helpers, which generate forms bit by bit, writing the HTML for you and still keeping things a bit DRYer (e.g., no need to write both an ID and a name), and dynamically inserting some information for you instead of having to stick ERB in the middle of a name attribute.
3) Use form_for helpers, which basically write the whole form for you, as long as you pass in an object you are writing the form for.  (If updating, it will be an object that already exists; if creating, it will be a new object with blank attributes.)  You still have to write a line for every attribute you are prompting the user to add, but it's pretty concise, when compared with option 1, and even option 2.

There are lots of ways to write forms, because sometimes you want something more standard, but other times you want a more customized form.  When you want to customize, you can often do it by adding lots of customization in the form of hashes at the level you're on, but it can be easier (to write, and to read your code later) if you just drop down a level, doing more work, but in a way that naturally gives you more options.

Homework was putting together a todo list in Rails.  Honestly, I worked at it for quite a while, but it was too difficult for me, so I'm waiting until I learn more to give it another try.

Skills developed: Recursion, Rails forms

Monday, March 10, 2014

Week 6 Day 1: In Sinatraland, facing the Bridge to Railsabithia

Major Activities of the Day: We started with a straightforward TODO where we create a class that takes in a number and breaks it down into binary ones and zeros, and generates a list from a constant array based on which values were ones.  Well, I said it's straightforward, but the implementations ranged a lot.  Here was my solution - I couldn't figure out anything simpler, so I'm relatively certain it can't be done in any cleaner way:


In this case, 1 represented eggs, 2 represented peanuts, etc., all the way through 128 for cats.  I used the handy [n] method (which I discovered accidentally while doing the lab, trying to use the similarly-syntaxed method for Strings), which works on Fixnum integers (but not on Bignum integers!) and returns the 1 or 0 which is n digits from the end. So for the number 11, which is 1011 in binary, you would get:
11[0] #=> 1
11[1] #=> 1
11[2] #=> 0
11[3] #=> 1


After that activity, we moved on to a lab where we put together a Sinatra web app with lots of relationships between models - ponds with frogs with tadpoles.  Then we moved on to our first lecture about Rails.  Avi demonstrated the power of Rails generators by doing a bunch of stuff manually, then doing it all over again in a command or two.  Finally, since we haven't yet covered enough Rails to do useful things yet, we instead returned to Sinatra to put together a web app to store songs, artists, and genres, where each song has one artist and multiple genres, and artists and genres can access each other through songs.  (Technically we could have used a join table between artists and genres, but I felt that would mean a lot of database maintenance when instead it makes more sense to create a has_many through relationship between artists and genres, through songs.

Skills Developed: Working with binary numbers, assembling complex relationships in Sinatra apps, and a slight glimmer of Rails

Saturday, March 8, 2014

Week 5 Day 5: Feeling CRuMmy

Major Activities of the Day: We started off with an assignment to do Project Euler problems 3 and 4.  I had some fun maximizing efficiency and discovered Ruby's Array#repeated_combination method.  Cool stuff.

We then spent most of the day creating a CRM (Customer Relationship Management) system using data about ourselves from the Flatiron Students website.  It was a big project, but it got us very comfortable with forms in Sinatra.

Homework was to move forward as much as possible on the massive amounts of homework we've been racking up!

Skills developed: Create/Update forms in Sinatra, the CRM concept

P.S.  Why the title?  1. CRM  2. I got a massive stomachache midday from eating chocolate-covered pretzels, but fortunately it went away after about an hour.

Thursday, March 6, 2014

Week 5 Day 4: Seek and Ye Shall Find

Major Activities of the Day: We started today with a task to put together a binary search tree.  Since I've done this stuff before, the major leap of logic (that a depth-first search using a recursive method is necessary) was pretty trivial, and I spent most of my effort making the methods really pretty.  I used a Struct to make things a bit cleaner, since there weren't so many methods in total, though many would say the class is still too big to rely on a Struct.  You can judge for yourself:


I thought a Struct was warranted to avoid having to use self.send; this way, I could do self[side] using the built-in Struct [] method.

We spent a lot of time going over forms and associations in Sinatra, and working on some assignments dealing with complex associations.  In short, we put together a web app with virtual houses that give out candy to trick-or-treaters, i.e. users who have input a name and age.  Each user has a bucket that holds all the candy, and you can view all houses, or a particular house, view your bucket, and eat your candy - which may get you sick if you eat too much!

In the evening, we had a meetup; my favorite project was by Arielle Sullivan and Chris Guthrie, who put together a web app that finds the worst (in terms of health department violations) restaurants in any zip code in New York City.  Apparently, the Subway a lot of people go to during lunch is pretty awful.  Oops.

Skills developed: Binary search trees, forms and complex associations in Sinatra

Wednesday, March 5, 2014

Week 5 Day 3: Lost in the Maze

Major Activities Activity of the Day:  We started the day with an assignment to write a MazeSolver class that takes in a string representing a maze and implements a breadth-first search (BFS) to find the best solution.  This was rather frustrating for me at first, since I'm used to depth-first searches (DFS), and I find the BFS algorithm to be simply unintuitive.  However, after a lot of work, I figured out how to make it happen, and it was awesome!  But why use it?  Simple - BFS is always guaranteed to find a path of the shortest possible length between two points!  That's why navigation technologies use it; DFS might take you down the block through several continents, but BFS will get you there ASAP, because it's finding the shortest possible route.

So it turned out that, though we were supposed to finish at 11, almost everyone was still working on it through lunch.  We kept at it for a bit, and then Avi took those who wanted to watch him implement a solution and ran through it.  Others kept plugging away.

At the end of all this, it was 4PM, and the day was nearly over.

OK, OK, I know you want to hear about how I did.  I finished at noon, and then spent the next few hours refactoring and making things prettier, OK?  Sorry, didn't want to brag, but you forced me to.

Actually, I had a lot of fun with it - instead of defining arrays with 3 elements (x-coordinate, y-coordinate, reference to another point), I created a Node class based on a Struct with elements x, y, and reference.

Huh? you ask.  What's a Struct?  Well, I'm glad you asked.  We did blogs in the late afternoon, and today I presented.  You can see my post at http://amcaplan.wordpress.com/2014/03/05/struct-rubys-quickie-class/.  Structs are awesome little class factories that create simple data storage classes and give you lots of extra methods to go with.

In lecture, we discussed the creation of a nested params hash in Sinatra to create objects from forms in a more organized way.  A properly constructed params hash makes construction of objects really simple.  Let's say I have a Person object with name, height, and weight attributes.  I could do this:

person = Person.new
person.name = params[:name]
person.height = params[:height]
person.weight = params[:weight]
person.save


But I can also do it more simply if I have everything nested inside params[:person]:

person = Person.create(params[:person])

Isn't that much nicer?

We were already overloaded with homework from yesterday, but we got some more today anyway, for whenever we finish that.  I just did as much as I could from yesterday's homework.

Skills developed: Breadth-first search, use of nested params for forms in Sinatra

Tuesday, March 4, 2014

Week 5 Day 2: Lineup

Major Activities of the Day: We began the day with an exercise putting together queues and stacks.  While these aren't so useful in Ruby (see this post about why Ruby's Array class is reasonably memory-efficient for queues and stacks), they will come up in other languages and are just generally useful for a programmer to know.  We then moved on to a long lab where we used Sinatra to create a web app where you input a pigeon with a number of attributes, store it to a database, and display it.  We made a Pigeon model, a controller with routes, and a few ERB views.

For homework, we had 2 exercises: one to make a simple Sinatra app using sessions, and another to make a very complex Sinatra app with sessions, lots of models, two controllers, and a whole assortment of views.  This was much harder.  Honestly, though, I realized we weren't going to be expected to finish them by tomorrow, so I chose to just look over them briefly but not do them yet, and instead I focused on my blog post which is due tomorrow.

Skills developed: Working with queues and stacks, more Sinatra with adding sessions

Monday, March 3, 2014

Week 5 Day 1: Say "Ahoy" to Forms!

Major Activities of the Day: Today began with an assignment to build a Linked List.  Since I haven't done one of those since high school, it was a good refresher.  We then moved on to a lecture about how to work with forms in Sinatra.  This involves two parts.  One is understanding HTML form tags, to construct a form with various types of input, each including proper name and id properties.  The other part is understanding how the input is passed into and accessible in Sinatra through the params hash.  For example, let's say I have a form for pirates:



It would look like this:

Pirates:














How would I access the data sent?  I add to my app a route /pirates that will handle a POST request, access the params hash and create some new pirates, and then return a new page:

post '/pirates' do
  @new_pirates = params[:pirates].map { |pirate_num, attributes|
    Pirate.create(attributes) if attributes[:name] != ""
  }.compact

  erb :"success.html"
end


Simply put, this takes params[:pirates], which is a hash containing numbers (:0, :1, :2, etc.) as keys and pirate attribute hashes as values, and then creates new Pirate objects (which must be defined elsewhere) for any set of defined attributes, and finally renders a page which displays the newly input information (which is stored in @new_pirates), which can also be accessed later (if items are saved to a database).

We spent the afternoon working on two labs where we created Sinatra apps with forms and displayed the output, optionally writing tests and persisting to a database.  I had enough time to write tests for the first lab (I actually developed it entirely with tests first), and persist both to a database.

Skills developed: Linked lists, Sinatra with forms, RSpec testing in Sinatra

Saturday, March 1, 2014

Week 4 Day 5: Take a Breather

Major Activities of the Day: We started out today with an assignment to write a method that would take an array of names, mix them up, and spit out groups of a given size, with no names repeated in a group or in adjacent groups.  My solution went through a few iterations, but with a little input from Eugene Millerman (who had a pretty sweet solution already), I got it down to a single line.  Ready or not, here it comes:

def create_groups(students, group_size, num_groups)
  students.shuffle.cycle.each_slice(group_size).first(num_groups)
end


Yep, that's the whole thing, and it's a mouthful!  Here's how it works: First, the array of students is shuffled.  Then it gets called with the `cycle` method, which returns an Enumerator that will go through the end of the list, then loop back to the beginning, ad infinitum.  Then `each_slice(group_size)` returns a modified Enumerator which yields arrays of the size `group_size` one at a time.  Finally, `first(num_groups)` tells that Enumerator to yield an array containing the first `num_groups` arrays that it would yield.

After our usual brief blog post session, we had some free time to catch up on any work we had missed.  Since I was up to date, I worked on Code School's JavaScript Roadtrip series (which I've been working through recently), and finished the final course!  I then started working on a Fruitbot (for more info on the Fruitbot contest, see www.fruitbots.org) that I had been writing in Ruby, but now I want to do it in JavaScript.  So I spent some time on that.

After a late lunch, we headed back in for lecture, where we covered Sinatra testing with RSpec and Capybara in much greater detail.  This is seriously useful stuff, people.  I like Capybara a lot already.

Skills developed: JavaScript (for me), Sinatra testing

Thursday, February 27, 2014

Week 4 Day 4: RPS and MVC, find out what it means to me, and all I'm askin', is for a little RSpec!

Major activities of the day: Morning lecture about MVC, routes, and other basics of putting together a web app, afternoon lab to put together a rock-paper-scissors (RPS) game in Sinatra, review of that lab, and homework to get some more practice with routes, as well as testing Sinatra with RSpec using rack/test.

Skills developed: Understanding MVC and RESTful architecture, somewhat more developed Sinatra apps, and working with RSpec in the context of Sinatra apps.

Wednesday, February 26, 2014

Week 4 Day 3: Singing the Sweet Songs of Sinatra

Major activities of the day: We started off today with a quick assignment to make sure we understand how a status code is returned by a server.  The morning lecture covered ActiveRecord associations, dealing with all the ways ActiveRecord methods can be used to generate, save, and access objects.  We followed this up with a lab where we had to run migrations and create models for artists, songs, and genres, where each song had an artist and a genre, and the artists and genres were associated with each other through the songs.

In the afternoon, we were introduced to Sinatra, and put together a simple message-posting app.  The lecture clarified how Sinatra builds on the standard Rack framework to let you create simple websites quickly and easily.

Fun note: I found an even better way today of doing my person object.  It already exists in Ruby!  It's called an OpenStruct, and it's really cool.  Here's the code:


require 'ostruct'
person = OpenStruct.new


And you're done!  The documentation is online at http://www.ruby-doc.org/stdlib/libdoc/ostruct/rdoc/OpenStruct.html

Skills developed: ActiveRecord associations, Sinatra

Tuesday, February 25, 2014

Week 4 Day 2: I Am But Thy Humble Server

Major activities of the day: We started out today with a lab debugging a program with some intentionally inserted bugs (lack of require statements, a missing bracket, an improperly parsed hash, etc.)  It was a great way to get a taste of taking over a code base, having to analyze it and understand what's doing what, then zero in on the problems and debug.

We broke for blog posts (as usual), and then went immediately to work on a lab to learn how to use Rack, a simple server for constructing web apps.  It drills through a stack of middleware, then works its way back up, finally producing content which is sent back to the user.  We practiced adding middleware and creating a stack that returns a specific result, which is dependent on accessing the env (environment) argument which is passed in when each piece of middleware is called.

After lunch, we had another lecture discussing how the internet works.  The highlight was a demo with actors (i.e. student volunteers) pretending to be a client, a DNS, and a set of servers with different information.

Finally, we worked through another lab about Rack middleware, generating middleware and using it through the Config.ru file.

Skills developed: Debugging other people's code, Rack

QOTD: "Anyone who has lost track of time when using a computer knows the propensity to dream, the urge to make dreams come true and the tendency to miss lunch." - Tim Berners-Lee

Monday, February 24, 2014

Week 4 Day 1: Active Listening and ActiveRecord

Major Activities of the Day: Lecture. We were introduced to Rake in the morning, did a lab putting together some Rake tasks, and then at 10AM moved into the classroom for lecture. We got out at 5PM.

Well, to be fair, it wasn't without any breaks. We stopped for lunch, got a 45-minute sanity break around 2:45, and had a 7-minute break towards the end. But it was a marathon of sitting in a room with the lights off and a projector. I got really sleepy.

So what happened during lecture, exactly? First, we went over the lab from the weekend. Not surprisingly, as it was a difficult lab, it took a really long time. Hours and hours. But it was a good opportunity to watch TDD in action; this lab had some vague instructions and no tests, so he had to write the tests, make them pass, and then refactor. We watched methods broken down into simpler methods and code DRYed up.

When that was finally finished, we moved on to Rake and ActiveRecord. We got a glimpse of the awesome power of ActiveRecord, and I'm excited to use it in the future, saving myself all the frustration of the last few days' work with databases.

Finally, we got an assignment to play around with ActiveRecord. I discovered that if you take a YAML file and load it into Ruby, it generates objects, but the objects have never passed through the initialize method. So in order to get objects that have been initialized properly, you have to do this: `Class_name.create(object.as_json)`, which will initialize and save a new instance with the object's properties.

Remember my fancy method_missing from W3D4? Well, I discovered a better way to write it!  Here it is, with slightly different functionality (I'll explain, don't worry!):

def method_missing(method_name, *args)
  attribute = "@#{method_name.to_s}"
  if attribute.end_with?("=")
    instance_variable_set(attribute[0..-2], args[0])
  else
    instance_variable_get(attribute)
  end
end

And that's it!  This method creates an instance variable setter and getter for anything you want!  And unlike before, it doesn't use "eval", which is a supremely dangerous method (because it can let users have direct access to your system - bad idea!).  Here's me playing around with it in IRB:


2.0.0-p353 :001 > class Person
2.0.0-p353 :002?>   def method_missing(method_name, *args)
2.0.0-p353 :003?>       attribute = "@#{method_name.to_s}"
2.0.0-p353 :004?>       if attribute.end_with?("=")
2.0.0-p353 :005?>           instance_variable_set(attribute[0..-2], args[0])
2.0.0-p353 :006?>         else
2.0.0-p353 :007 >             instance_variable_get(attribute)
2.0.0-p353 :008?>         end
2.0.0-p353 :009?>     end
2.0.0-p353 :010?>   end
 => nil 
2.0.0-p353 :011 > person = Person.new
 => #<Person:0x000001011587e8> 
2.0.0-p353 :012 > person.height = '5\'11"'
 => "5'11\"" 
2.0.0-p353 :013 > puts person.height
5'11"
 => nil 
2.0.0-p353 :014 > person.happy? = true
SyntaxError: (irb):14: syntax error, unexpected '='
person.happy? = true
               ^
from /Users/flatironschool/.rvm/rubies/ruby-2.0.0-p353/bin/irb:12:in `<main>'
2.0.0-p353 :015 > person.happy = true
 => true 
2.0.0-p353 :016 > person.happy
 => true 
2.0.0-p353 :017 > person.favorite_author = "Ernest Hemingway"
 => "Ernest Hemingway" 
2.0.0-p353 :018 > person.favorite_author
 => "Ernest Hemingway" 
2.0.0-p353 :019 > person.favorite_book
 => nil 

So apparently our person can hold any variable we want.  Which is great, because people are multifaceted, and no person's variables will be quite like another's.  But you usually don't want to do this.

Also, note that `person.happy? = true` raised an error.  This is because Ruby doesn't allow happiness.

No, I'm just kidding!  Matz says that Ruby is all about making people happy.  The problem is that variable names can only include alphanumeric characters and underscores.  That means no punctuation.  Only method names can have that.  If I wanted to let you extract boolean values by querying with a question mark, here's an even fancier method_missing:


def method_missing(method_name, *args)
  attribute = "@#{method_name.to_s}"

  if attribute.end_with?("=")

    instance_variable_set(attribute[0..-2], args[0])
  elsif attribute.end_with?("?")
    !!instance_variable_get(attribute[0..-2])
  else
    instance_variable_get(attribute)
  end
end

And back to IRB:


2.0.0-p353 :001 > class Person

2.0.0-p353 :002?>   def method_missing(method_name, *args)
2.0.0-p353 :003?>       attribute = "@#{method_name.to_s}"
2.0.0-p353 :004?>       if attribute.end_with?("=")
2.0.0-p353 :005?>           instance_variable_set(attribute[0..-2], args[0])
2.0.0-p353 :006?>       elsif attribute.end_with?("?")
2.0.0-p353 :007?>           !!instance_variable_get(attribute[0..-2])
2.0.0-p353 :008?>       else
2.0.0-p353 :009 >            instance_variable_get(attribute)
2.0.0-p353 :010?>       end
2.0.0-p353 :011?>   end
2.0.0-p353 :012?> end
 => nil 
2.0.0-p353 :013 > person = Person.new
 => #<Person:0x0000010128e0e0> 
2.0.0-p353 :014 > person.happy = true
 => true 
2.0.0-p353 :015 > person.happy?
 => true 
2.0.0-p353 :016 > person.cool = false
 => false 
2.0.0-p353 :017 > person.cool?
 => false 
2.0.0-p353 :018 > person.employment = nil
 => nil 
2.0.0-p353 :019 > person.employment?
 => false 
2.0.0-p353 :020 > person.employment = "computer programmer"
 => "computer programmer" 
2.0.0-p353 :021 > person.employment
 => "computer programmer" 
2.0.0-p353 :022 > person.employment?
 => true 

Notice how I used the double-bang (`!!`) to force a truth value out of the variable, even if it's not a boolean.

It's amazing how a little IRB can add lots of length to an otherwise medium-sized blog post! :)

Skills developed: Rake, ActiveRecord, importing YAML files

Saturday, February 22, 2014

Week 3 Day 5: The Calm After the Storm

Major Activities of the Day: Today was actually pretty relaxed.  We've been flying forward, so we began with a few hours for people to catch up on assignments that had perhaps presented until-now insurmountable difficulties.  In the afternoon, we worked on a project to apply our knowledge: take a folder full of files named in the form "Artist - Song Name [genre]" and turn them into a directory of web pages.  I copied lots of code from previous projects and did everything through databases.  Cool beans.

Skills developed: Practice with databases, modules and class inheritance, ERB.

Sorry about the lack of QOTDs recently.  I'll try to be better about it next week!

Thursday, February 20, 2014

Week 3 Day 4: B.C.E. (Bundle, Cover, and Embed)

Major activities of the day: We started out today with an assignment to create a "Person" class that takes a hash of attributes and can then spit them out when requested.  Most people listed all the allowed attributes and `attr_accessor`ed them.  Here was my way to do it:

class Person

  def initialize(attributes)
    attributes.each do |attribute, value|
      eval("@#{attribute} = value")
    end
  end

  def method_missing(method, *args)
    eval("@#{method}")
  end

end


This takes the initial hash and sets an instance variable named for the attribute to equal the value that is passed in.  method_missing then returns whatever is held by the object for the attribute requested.  If it was initialized with a "height" attribute of 6.0, the initialize method will assign a value of 6.0 to @height, and `person.height` will return @height, which is 6.0.  My way isn't necessarily better, it just depends on the situation.  If there is a specific set of attributes which are allowed, it's probably best to use attr_accessor.  My way would be best for an object that you actually want to have a non-predefined set of values (which I imagine is sort of rare).  But I did it because it was a chance to flex my metaprogramming muscles.  eval is another of the metaprogramming methods, and a really dangerous one.  (Avi recommends never using it; I guess I'll learn why at some point.)  It takes a string as an argument, and evaluates whatever's inside of it as though it was written as regular code on that line.  This is really scary because if the string contains as-yet-unknown content, there are lots of things that might happen.  Sticking eval into method_missing, like I did, is just asking for trouble.  In this case, however, I thought it makes sense, because I'm trying to create an object that just takes in and spits out attributes with any names.

But I digress. After 10AM, we learned about Bundler and the standard ways of structuring the directories and files for a project (setting up an environment file, putting your models in lib, executables in bin, etc.).  We also covered the use of Simplecov, a neat tool to check how completely your tests cover your code.  It seems to actually track what code is executed as the tests are run.  That's awesome.  We also got some more practice writing modules, and played with Sequel, which is a Ruby gem that handles database stuff.

The last thing we covered was ERB, or Embedded Ruby, which is a way to embed Ruby code inside of HTML templates to be able to generate static pages through your Ruby program.  I've been looking forward to this for a while.  At this point, we should have the ability to, through Ruby programs, take information and get it into a database, and use that information to generate a whole slew of static pages.  That's really powerful already.  It's really amazing when diverse skills - HTML, CSS, SQL/databases, and Ruby - start coming together, interacting with each other, to form a picture of how these skills can be used to generate content for users.

Tonight was our first NYC on Rails meetup of the semester.  We heard 4 students talk about different projects, including a webscraping Pokedex, a Battleship game, a Tic-Tac-Toe game, and a Random [restaurant] Order Generator.  It's amazing how people have used their newfound skills to be creative and learn even more!

Skills developed: Metaprogramming, Bundler, Simplecov and code coverage, ERB, Pokemon knowledge

QOTD: Well, actually, I can't remember any exact words, but there were some awesome Pokemon jokes at the meetup.  It was fun to relive that part of my childhood.  :)

Wednesday, February 19, 2014

Week 3 Day 3: Mixin 'n' Match

Major Activities of the Day: Lecture and lab to introduce modules, and more work with ORMs (the latter being the "Match" in the title, because they match up all sorts of data).  Modules are Ruby's way to gain the functionality of multiple inheritance without some of the problems that come along with it.  A class can inherit from only one superclass, but it can mix in as many modules as you want, to add shared functionality.  Although we didn't discuss it yet, my favorite examples are Enumerable and Comparable, which add lots of functionality to an object as long as you define a few extra methods.  We really focused on writing our own modules, though.  The homework was our most difficult challenge yet; we had to put together a students/courses/departments/registrations model using databases, and I decided to be super-cool and write a metaprogrammed module that would take care of all the database-y stuff.  This includes a method_missing method to handle queries like Department.find_by_name or Student.find_all_by_course.  It was really hard, but it made the rest of the assignment way easier to do.

One second, though - what's metaprogramming, and what is method_missing?

Metaprogramming is writing code that writes code.  In other words, you tell the interpreter to compose methods or do other code-writing-y things on the fly.  The celebrated 'attr_accessor' method does just that; it takes one or more Symbols as an argument, and writes a method for each Symbol to assign and query an instance variable with the name defined by the Symbol.  So `attr_accessor :name` is the same as:

def name
  @name
end

def name=(name)
  @name = name
end


Pretty neat, huh?

method_missing is, in my opinion, one of the coolest - yet most dangerous - features of Ruby.  It is a method defined on every object that specifies the handling of methods whose name it doesn't recognize.  The default handling is to raise a NoMethodError.  But you can do this:

def method_missing(method_name, *args)
  7
end


and then every unknown method will instead return "7" instead of raising an error.  Why would you want to do this?  I don't know.  But maybe you would do this:

def method_missing(method_name, *args)
  if method_name.to_s.start_with?("find_by_")
    attribute = method_name.to_s[8..-1]
    @players.find{ |player| player.send(attribute) == args[0] }
  else
    super
  end
end


so you could do baseball_card_collection.find_by_homeruns(319) and, despite the method not being defined anywhere in your code, it will find the player with 319 homeruns.  By the way, player.send(attribute) in this example is also an example of metaprogramming; it sends the method that shares the name of whatever attribute is passed in.  This creates a lot of possibilities!  Supposedly, however, objects with method_missing can present really annoying behavior and be notoriously difficult to debug, so it's often ill-advised to write a method_missing method.

P.S. Today I presented a technical blog post from my other blog; you can see it at http://amcaplan.wordpress.com/2014/02/19/lessons-from-a-failed-successful-gem/ (it's all about reflections on the experience of writing a gem, what I learned, what I could have done better, etc.).

Skills developed: Module writing, more ORMs, metaprogramming

Tuesday, February 18, 2014

Week 3 Day 2: ORM (not just a sea monster!)

(If you don't get this post's title, see here.)

Major Activities of the Day: Writing a Secret Handshake class that parses a binary number (but not a string containing letters) and spits out instructions for a Secret Handshake, reviewing yesterday's assignments quickly, and then moving on to the Next Step: ORM.  ORM (Object Relational Mapping) is the interconversion between two data types that are understandable to different programs.  Essentially, we created a Student class that interfaces with a SQLite database to take input in Ruby and output SQL into the database, then draw information from the database and return a usable Student object to Ruby.  This is all very complicated, and luckily we will usually have ActiveRecord to take care of this for us.  At the end, we even touched on a bit of metaprogramming!  Apparently, there is more metaprogramming to come this week.

Skills Developed: ORM (seriously, it's fantastically difficult to do)

QOTD: "When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous." - Martin Fowler (expressing an idea that is absolutely emphasized at Flatiron)

Monday, February 17, 2014

Week 3 Day 1: Ruby Redux

Major activities of the day: Presidents' Day!!!  Spent the day at home, but had lots of assignments.  We basically redid most of the simpler assignments from before, but this time did everything in the context of a class.  I think the point was to make sure we really understand everything we've learned so far.  We also did a new playlister with a command line interface.  I really enjoyed the assignment because it demonstrated the power of classes.  This time, we were able to search by artist, genre, or song name, and if everything was programmed right, it all ran smoothly.  Cool stuff.

Skills developed: Ruby review

Saturday, February 15, 2014

Week 2 Day 5: Data - Making and Scraping

Major activities of the day: Morning assignment to put together a School model, lecture about use of databases in Ruby (very exciting to put together databases and Ruby - interactions between tools are super cool, and this allows you to let objects persists across runs of the program!), and a group assignment to scrape our student profiles from the website using the Nokogiri gem.  Nokogiri is fantastic; I'm just starting to learn its power, and I already love it.  Among other things, it lets you take a website and select bits of it using CSS selectors.  So for example, I can look at all the parts that are links within a particular type of element (div, figcaption, whatever) or have a certain class or ID.

Weekend homework was putting together a model of Artist, Genre, and Song where each class relates to the other two.  'Twas fun.

Skills developed: Combining SQLite3 with Ruby, web scraping with Nokogiri

QOTD: "Yes, I'm afraid chartreuse is one of my favorite colors... No, I'm not going to change it just because it's not your favorite..." - Larry Wall, creator of PERL, on his website's background color, see http://wall.org/~larry/

Thursday, February 13, 2014

Week 2 Day 4: SQL in the Snow

Today was a crazy snowstorm, and, sadly, school was cancelled.  We were given an online SQL tutorial and some SQL work to do at home (though of course, I'm told that some students went in anyway despite the weather).  Since all the assignments follow RSPEC-defined specifications, we got our first look at how Ruby and databases can interact through the SQLite3 and SQLRunner gems.

Skills developed: SQLite3 CRUD operations, being productive at home

Wednesday, February 12, 2014

Week 2 Day 3: A Shining Moment

Major activities of the day: Assignment working with classes, homework review, lecture about the subtleties of classes and instances and variable scope.  Honestly, though, I'm mostly focused on (and super excited about) my first Ruby Gem!  It's now available by typing "gem install check_everything" on the command line.  The documentation and source code is at https://github.com/amcaplan/check_everything.  Check it out!  It's an easy way to launch a set of favorite websites from your command line.  It takes a bit of initial configuration, but if you commonly check a particular set of websites, this will make your life just a bit easier.

Skills developed: Working with classes/objects and variable scope, and - in my case - making Ruby Gems!

Tuesday, February 11, 2014

Week 2 Day 2: I Object!

Major activities of the day: Introduction to O-values through a prime numbers exercise, more homework review, and the long-awaited intro to Object-Oriented Programming!  (Henceforth, it shall be known as OOP.)  One of today's exercises was reimplementing a jukebox we previously created, this time as a Jukebox object.  We also played around a lot with Regexps.  Lots of confusing things.  I'm not entirely clear on how they're evaluated; it's a lengthy topic, and I'm discovering it by tinkering.  Also, I am a huge fan of www.rubular.com.  The instructors have pointed us to it a few times, though I already knew about it before Flatiron.  It's a fantastic way to play with Regexps and discover how to properly construct them to evaluate the way you want.

Today was also the first day of blog reviews.  Every day, 4 students will briefly (in <5 minutes) present technical blog posts they have written.  Everyone does at least 5 over the course of the semester.  Mine is in about a week from now - I'll post a link, don't worry!

Skills developed: Working with objects and Regexps

QOTD: "The best way to predict the future is to invent it." - Alan Kay

Monday, February 10, 2014

Week 2 Day 1: Hashing Out Enumerable Methods

Major activities of the day: Homework review.  We seem to be moving a bit slowly because we're dealing with very fundamental programming tasks.  So we're focusing a lot on how to deal with hashes and arrays and manipulate them in ways that give us the information we need.

On the bright side, we had some time to go over the homework with other students and compare our algorithms, and we exchanged ideas that we had picked up while doing the homework.

One interesting thing I learned from another student was the .tap method, which can be used on all Ruby Objects.  Here's an example of how to use it:

def return_an_array_of_perfect_squares_up_to_25
  [].tap do |squares|
    i = 1
    while i**2 <= 25 
      squares << i**2
      i += 1
    end
  end
end

HUH???  What's the return value?  It turns out that .tap creates a placeholder, feeds that into a block, and returns the placeholder.  So it's the same as this:

def return_an_array_of_perfect_squares_up_to_25
  squares = []
  i = 1
  while i**2 <= 25 
    squares << i**2
    i += 1
  end
  squares
end

Possibly a bit more confusing, which is why I'm hesitant to use it in my own code, but it is a bit more concise, which is nice.  And it gives an excuse to indent!

NOTE: Example provided for illustration purposes only.  If I were programming this for real, this is how I would do it:

def return_an_array_of_perfect_squares_up_to_25
  (1..Math.sqrt(25)).map{|num| num**2}
end

And of course, that's the power of map/collect and select!    \(^○^)/


Skills developed: Extracting data from Arrays/Hashes, iterating over Arrays/Hashes


QOTD: "When you don’t create things, you become defined by your tastes rather than ability. Your tastes only narrow and exclude people. So create." - why the lucky stiff, author of why's (poignant) guide to ruby

Sunday, February 9, 2014

Week 1 Day 5: Fridays[0]

Major activities of the day: Fixing up HW and labs from yesterday, and lots of lecturing about enumerable classes (mostly Array and Hash) and the map/collect and select methods.  These were extremely useful in our labs, where we had to restructure hashes, extract data from complex multi-level hashes, and use hash data to modify Strings.  At this point, I think I'm addicted to map and select, and I've even figured out how the pretzel operator works:

an_array.map(&:to_s)

is the same as

an_array.map{ |element| element.to_s }

I'm also severely disappointed that the pretzel operator can't be used with parameters.  Oh, well.

There was also Feeling Friday, but I had to leave early, and hence missed it.  It's supposed to be lots of fun, though!

Skills developed: Iteration for enumerable classes

QOTD: "I hope that Ruby jumps out of my computer and punches me in the eye!" - Avi (before trying to pop elements off an array while mapping it)

Thursday, February 6, 2014

Week 1 Day 4: Rockin' out with Ruby

Major activities of the day: Ruby, Ruby, and more Ruby!!!  A bit about splat arguments, but mostly working with control flow (i.e. if/elsif/else and various forms of loops), plus Strings and Arrays, as well as gaining a deeper understanding of scope and how methods (and their return values) are passed around.  Today was also Flatiron's famous knot-tying workshop, led by our very own Arel English!  Homework was to make a jukebox program that responds to a variety of input commands and plays music.  Mine currently launches songs by loading a YouTube link to the song, through the "system" function.  Kinda hacky, but it works!  :)

Cool new thing I learned today: there's a convention to have a separate file which executes your program so you can run specs on your methods without having the program actually execute.  In other words, the program should be executable via a "run" method, which is called not in the program file itself, but in another program, like so:

program.rb

def run(args)
  #do some stuff
end

#helper methods


bin/program

require '../program.rb'
run(args)


This way, I can require program.rb in my specification file without the program actually running before the specs are checked.  This is especially useful for programs that usually take user input.

Skills developed: Control flow, Strings, and Arrays in Ruby

QOTD: "This is one way that knot-tying is like programming.  You're thinking about future you."  (because you'll eventually have to untie the knot, or read your code) -Avi

Wednesday, February 5, 2014

Week 1 Day 3: Welcome to the Ruby City! We're not in Kansas anymore...

Get it?  Like the Emerald City in The Wizard of Oz?   Whatever...

Major activities of the day: Git merging a large project, Ruby fundamentals (and learning why Matz is awesome and how Ruby is a secret formula for happiness through programming), programming methods to fit RSpec specifications.  Yes, you read that right - we're already learning to read RSpec code, run tests, and do TDD to fulfill the specs!  We won't be actually writing any RSpec for a while - we need to get a solid grip on Ruby first - but we're starting out with immersion in TDD best practices (including actually reading error messages - they are our friends!).

Skills developed: Git merge and rebase, Ruby coding, TDD with RSpec

QOTD + bonus extra life QOTD! (to make up for yesterday):
"The goal of Ruby is to make programmers happy." - Matz
"It's the exact same reason you make a todo list. Also testing is not for present you, it's for future you." Joe M Burgess

Tuesday, February 4, 2014

Week 1 Day 2: Bash Your HEAD 'Til You Git the Idea

Sorry for all the bad puns in the title... it may become a running theme...

Major activities of the day: Explored how Git deals with branching, merging, and rebasing.  (We were introduced to GitX(L) today - fantastic tool for visualizing repos!)  Installed a bunch of software and got our systems ready to code without being distracted by missing software or messed-up settings.  Installing software from the command line can be scary, but when you're in a supportive group and have instructors who are always ready to help, it's much easier to get past the fear and, well, just do it!  We also got the chance to tinker around with our Bash profiles.  Here's what my prompt looks like (showing my current path, working branch, and a robot smiley to keep me motivated):

~/Development/code/amcaplan.github.io  (source)
[°‿°] > 

Skills developed: Git, command line, software installation, system customization
QOTD: Sorry, wait 'til tomorrow for a great quote!  I wasn't paying enough attention today - too focused on the work!

Tomorrow we start Ruby.  Best of all, RSPEC also starts tomorrow - TDD (or will it be BDD?) from Day 3!

Monday, February 3, 2014

Week 1 Day 1: Push and Pull

Major activity of the day: Customizing a static HTML page to give ourselves a profile, working in groups of 4 to create the pages, put together a joint CSS modification, and push to Github with a pull request to be added to the project for the whole class.

Skills developed: Lots and lots of basic Git commands (Git was essentially the point of the exercise): push, pull, fetch, merge, branch.  Step 1 is to get super-comfy with Git and Github, to be able to collaborate effectively on projects in our group and with larger groups.

QOTD: "You will probably mark your life as before today and after today." - Avi

About

This blog serves as a journal of my adventures at the Flatiron School in NYC!

When I was first looking into bootcamps, I found journal-type blogs to be extremely helpful in getting a sense of each program.  I have therefore decided to give back to the community by writing my own journal.  I will try to do one post per day, including:

Activities
Skills Developed
QOTD (Quote of the Day)

An important note: good bootcamps will adjust their sights and improve their programs with every class, so if you apply to Flatiron, don't expect the exact same experience.  Hopefully it will be even better!