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