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