Dev Bootcamp. Ten weeks of intense programming. Goal: Professional Beginner
Don't wanna be here? Send us removal request.
Link
Last December, right before Christmas, I found out that I got into Dev Bootcamp in San Francisco!
What an awesome way to start my holiday break.
While I was thrilled to be accepted, I was less thrilled that my cohort wasn’t going to start until May 13th.
To pass the time, I’ve been working...
5 notes
·
View notes
Link
Week Eight. Day four.
This morning the group of us collectively pitched about ten ideas. The initial number was reduced to five through voting. And then finally we all picked our top three and were divided into three groups of four.
At this point, everyone is mostly tight-lipped about the…
9 notes
·
View notes
Text
Whoops, I fucked up
Today we wanted to delete all our merged branches in our remote repo on Github. Clicking a delete and confirm button 105 times is not only arduous, it is straight up fucking boring. So what does a noob developer do? He whips up some javascript to do it...
https://gist.github.com/sandbochs/5209973
I ran this in the console to check out what the urls were and noticed that my selector wasn't filtering merged/unmerged branches. Whew close call! So I investigated further and ran the following.
https://gist.github.com/sandbochs/5210014
Unmerged branch count matches, check!
Merged branch count matches, check!
Cool, now I can just press up a few times, uncomment my ajax request and chill while this script does work for me.

Fuck, I pressed up too many times and just ran the code that selects the unmerged branch. Fuckup #1. Whatever, I saved most of the branches by killing my network connection and people have their branches locally. Just let the team know.
Ok, this time I'll run the right script... 'Branch Master Deleted' WHAT?! Big Fuckup #2. Our base branch is develop so Master gets counted as a merged branch. Shit shit shit, I should have noticed that when I was logging urls.
TL:DR
I deleted a lot of unmerged remote branches
Thank goodness for an awesome team
Thank goodness for backups and local copies.
Being extra careful isn't good enough when you might destructively fuck with your remote; be double extra careful and pair with another engineer.
Or just don't play with fire.
If you dare:
https://gist.github.com/sandbochs/5210068
Also, just do it with GIT (note, no conditionals to avoid blowing up master): http://hustoknow.blogspot.com/2011/07/pruning-github-merged.html
5 notes
·
View notes
Link
To follow up on a previous post, here is what we learned:
Linked lists are made up of a series of “pair” objects, each of which holds a value and a pointer to the next pair. (At the end of a linked list, the pointer points to nil.)
Here is an example of a linked list consisting of two...
5 notes
·
View notes
Link
So today I’m making a blog aka Tumblr to help track my progress in learning to code and hopefully/eventually become a web developer. I’ve begun learning maybe a little under 2 weeks ago and started with a bit Java-scripting on Codecademy. I barely made it out of the Intro to Java track and I...
1 note
·
View note
Photo

Demo day at DBC today. Filters.io is live. (at Dev Bootcamp)
8 notes
·
View notes
Photo
Made my first pull request to an open-source project, CamanJS
We'll see if it goes through~
2 notes
·
View notes
Text
gotta CACHE'em all!
Sometimes your data doesn't change that frequently so instead of rendering/serving that data when a client makes a request to a webserver, just tell it to use what it already has. I've been hacking away at writing live search/autocomplete from scratch. My first implementation would hit the server every time a key was inputted into the search field. For example, if someone entered "Banana", the server would get a post for "B", "Ba", "Ban", up to "Banana" and return an array of matching fruit each time. I'm sure you can imagine if a site has a solid user base, making six round trips to the server in addition to six queries to the database is not optimal. Well if my list of fruit isn't that big, why not just give the client the list and have it all happen client side? This is where page caching comes in handy.
This guide is great: http://www.mnot.net/cache_docs/, but if you aren't up to read that let me give a quick summary.
So what is a web cache? Caches sit somewhere between the server and client and saves copies of the responses to the client. When the client asks for the same data, instead of hitting the server, the cache will use the copy and send that to the client to use instead of having the server generate it again. Caches are handy for:
Reducing latency - Since the cache is closer to the client than the server, the site seems more responsive.
Reducing network traffic - Since data is being reused, bandwidth can be saved by both the server and client. Especially helpful for larger datasets.
So there are multiple kinds of caches but lets talk about Browser caches. Most modern browsers allow developers to store data on the client's hardrive. The browser cache will grab a page from the server and save it. If another request is made, it will check to see if the page it already has is fresh before it tries to ask the server for the page again.
The way a browser checks with the server is through HTTP headers. Whenever a browser makes a HTTP request to a server, the server sends back an HTTP Header which is not rendered by the browser. The header contains some cool information we can use to keep track of how 'fresh' our data is. Rails ships with some magical caching so we can start taking a look at the HTTP header right away. To do this open up a terminal and type and examine the output:
>> curl -I http://localhost:3000 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 X-UA-Compatible: IE=Edge ETag: "53d2b88b7648b6a7020cffb937dd4354" Cache-Control: max-age=0, private, must-revalidate
First lets look at the ETag value. An ETag is a unique identifier that is generated by the server based on the representation of the data it is serving. If you run the curl command again, you will notice that ETag value is different.
>> curl -I http://localhost:3000 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 X-UA-Compatible: IE=Edge ETag: "f8098de645bb2635d2d7804b51b9d899" Cache-Control: max-age=0, private, must-revalidate
This is because the server is generating a new page for each request. Well, if my list of fruits hasn't changed then I want the browser to use the data it already has to render the page. Somehow we have to generate the ETag based on the state of my list of fruit. Rails has a very handy method called fresh_when that can be used in controllers. Check this line of code out in my FruitsController:
def index @fruits = Fruit.all fresh_when :etag => Fruit.maximum(:updated_at) end
What this will do is generate an ETag for the index action in my FruitsController based on the last time a fruit was updated/created. So if I haven't changed or added any fruit the data should be the same and the etag shouldn't change. Let's curl again!
>> curl -I http://localhost:3000 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 X-UA-Compatible: IE=Edge ETag: "809568a0768e4fd6cd61fb15583299d5" Cache-Control: max-age=0, private, must-revalidate
>> curl -I http://localhost:3000 HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 X-UA-Compatible: IE=Edge ETag: "809568a0768e4fd6cd61fb15583299d5" Cache-Control: max-age=0, private, must-revalidate
Something to note is that when your browser makes the request, it adds something to the HTTP header, a validator called 'If-None-Match'. This is actually really interesting to check out so let's curl one more time but this time add the 'If-None-Match' header with the ETag.
curl -I http://localhost:3000 --header 'If-None-Match: "809568a0768e4fd6cd61fb15583299d5"' HTTP/1.1 304 Not Modified ETag: "809568a0768e4fd6cd61fb15583299d5" Cache-Control: max-age=0, private, must-revalidate
Can you spot the subtle difference in the header this time?
If you noticed that the header says "HTTP/1.1 304 Not Modfied" instead of "HTTP/1.1 200 OK" give yourself a pat on the back. If you also take a look at your rails server log it might look something like this:
#before Started GET "/" for 127.0.0.1 at 2012-11-17 22:44:08 -0800 Processing by FruitsController#index as */* Item Load (7.2ms) SELECT "fruits".* FROM "fruits" Rendered fruits/index.html.erb within layouts/application (10.7ms) Completed 200 OK in 86ms (Views: 19.5ms | ActiveRecord: 7.2ms)
#after Started GET "/" for 127.0.0.1 at 2012-11-17 23:22:27 -0800 Processing by FruitsController#index as */* Item Load (7.9ms) SELECT "fruits".* FROM "fruits" (0.5ms) SELECT MAX("fruits"."updated_at") AS max_id FROM "fruits" Completed 304 Not Modified in 68ms (ActiveRecord: 8.4ms)
Notice how before using the fresh_when method, when a client made a request, the database was queried to grab all the fruits. In the second time, the etag was generated by only querying the db for the last updated fruit. The server doesn't grab all the fruits again and just responds with 304 Not Modified (It actually doesn't execute any of the code in the index action except for the fresh_when method). Your database will be thanking you for giving it a break. Wow that was a long post and I haven't even touched, page/fragment caching, using memcache as a replacement for your Rails cache or using the Rails cache to CACHE db queries. I'm cached out.
IN THE NEXT EPISODE: MEMCACHE
IN THE NEXT NEXT EPISODE: more on HTTP headers, Cache-Control, page/fragment caching in Rails
7 notes
·
View notes
Text
Hash magic, overriding eql? and hash methods.
Welcome to Hash Tables 101!
In this post, I'm going to give an overview on why hash tables are considered constant lookup without diving too deep into the technical stuff happening under the hood. Then we'll take a look at some cool stuff you can do once you understand how hash tables work.
A hash table is pretty much a collection of keys paired with values (often described as a key:value pair). The two biggest differences between arrays and hashes are:
Sorted arrays are O(log n) lookup time : Hashes are constant lookup time
Arrays map an index to a value : Hashes map a key to a value
If the value you are looking for is in the last index of the array, you would have to iterate through the entire array before you would be able to find it. To find out why hash tables are constant lookup time let's take a look at how a hash works.
Let's say you grow apples and you want anyone that looks the local directory to know find your apple farm. So you give the apple and the name of your farm to Bob, the person who is running the directory. He has a special conversion table to convert your apple into a two digit number and in this case your apple converts to 20. Bob picks up your apple and nametag, walks over to bucket #20 and places the apple inside, then walks over to box #20 and drops your nametag in there.
Let's also say that you figured out a way to clone apples and all the apples you sell are exactly identical. Someone has one of your apples and wants to find out where it came from so they walk over to Bob and gives him the apple. Bob uses his conversion table and converts the apple to 20. He picks up the apple and walks over to bucket #20, and grabs whatever is in the bucket (happens to be an apple). Then he looks at both apples and says 'Yup! These are the exact same apple' so he goes over to box #20, grabs the nametag and gives it to your customer.
This is not so different from how hash tables work. The directory is essentially a hash and the conversion table Bob uses is called a hash function. A hash function is some sort of algorithm that converts a variable length data set to a shorter fixed length data set. When you want to store a key, a hash function is called to convert your key into an integer, the hash table then puts your key into a bucket that corresponds with only that integer, and the value you in another box that corresponds with the bucket.
When you want to retrieve the value associated with the object you have, the hash function is called on your object again. It returns 20, so the hash table grabs the object inside bucket #20 and compares it with the object that you have and compares to see if they are equal. If they are equal it goes over to box #20 and gives you the value inside.
In Ruby the Object class has a method called hash defined and since everything is an Object, everything has a hash method as well. Usually, the hash method returns a fixed length integer based on an object's id. Some objects, like Strings, override the hash method. Let's write some code!
https://gist.github.com/4044309
3 notes
·
View notes
Text
It's official, I'm a jeweler.
Well not really...
This week I cut my first two gems, pushed them to RubyGems.org, and got people (or perhaps bots) to download my code! It is pretty awesome to wake up in the morning and see that someone actually had some interest in the work you just created. Also, it is very fulfilling to create something that could be useful for other people. Let me list some of the things I learned from creating two gems and if you feel so inclined you can read about the two gems after.
If you are being frustrated by a problem, chances are someone else is and could benefit from what you learn or your solution.
If you don't have tests for your gem, chances are no one will use it.
That being said, Travis CI is dope.
Write clear and concise documentation on how to use your gem. No usage notes, no bueno.
Use descriptive names for your methods and variables, people will be looking at your code.
Comment your code if what it does isn't crystal clear.
Once again, people will be looking at your code so don't leave debugging puts commented out, or generally have any puts anywhere...
My RubyGems.org profile
local_message: https://github.com/sandbochs/local_message
This gem spawned from the frustration of trying to pit our Connect Four AI vs other AI's over Twitter. During this group project, all the groups were simultaneously hammering the Twitter API here at the office and it was very frustrating to try and test our code. We could have used the FakerWeb and VCR gems for our tests but those only take you so far. Also, due to the strict time constraint we couldn't TDD as much as we wanted to. It wasn't a fun weekend. I set out to create a way for us to send our C4 boards to each other over the local network.
First I read up a little on sockets and was able to send messages from one host to another. This would do the trick, but I thought that people should be able to send their boards to someone based on their username; it would be much easier to do that vs teaching people how to get their local machine's ip address and specify a port to listen on. To do that, I wrote a router that maps usernames to an ip address and listening port. The client class initializes with a randomly generated port between 2000-30000 and has a method called register. When this method is called, it sends a command to the router and the router then populates the routing table with this information. It was extremely cool to see that the router can actually route multiple messages simultaneously and properly forward them.
I still need to add exception handling, better tests, broadcasting, console logging (gosh the feature list could go on and on).
game_board: https://github.com/MrPowers/GameBoard
First of all, I co-authored this gem with Mr. Matthew Powers. This gem partially spawned from the Connect Four project but was also influenced by Tic Tac Toe and Battleship. In those projects we had to represent a game board as some type of data structure. There are many ways to do this with different benefits and drawbacks but intuitively most people probably look at those boards as a grid/nested array.
It has methods that help with analyzing the board in many different ways. You can retrieve any row or column, all the rows or columns, any two diagonals from one coordinate, or all the diagonals. We found that the diagonals take the most work to retrieve, especially just the two from one coordinate and this was the driving force for creating this gem.
3 notes
·
View notes
Text
A quick one month update!
It has been two weeks since I last blogged. The days at Dev Bootcamp are getting longer and it is hard to find time to push out a blog post every week. I do want to let everyone at home know that I am alive and just extremely focused at the office 7 days a week (Staying on top of the challenges, working on my side project, and helping others who are struggling through challenges I've finished). I have finished my Tic Tac Toe 'AI' and I can proudly say that it is unbeatable =). I want to thank my mentors Phil and Jeremy for guiding me through that little project.
It took me about a week to learn and implement the negamax algorithm on the simple two player game 'One to Ten' . At first the AI could only play up to One to Thirty because it would calculate all the possible moves each turn. To solve that problem I memoized each move value into a hash and that allowed me to cut the 'thinking' time to the first move. Still not fast enough, so I implemented pruning and only calculated each node value once. As soon as that was working, I could play One to One Thousand Nine Hundred Eleven before the stack was too deep.
The most amazing thing was that once I realized how to implement the negamax algorithm to a simple game, applying it to Tic Tac Toe only took me a few hours. Next up, Connect Four and a blog post detailing how I learned and implemented negamax!
I'm excited to find out about our first group project tomorrow!
1 note
·
View note
Text
Nap Naps
I love naps
I find that if I don't take a nap in the afternoon, I code slower, I'm less in tune with my pairing partner, I take longer to comprehend things, I skip lines when reading; my mind basically melts into a viscous goop and likes to respond a year later.
When I have taken a nap though, I feel even better than having a cup of coffee in the morning. I'm probably not a morning person but seriously, naps do amazing things. I've concluded that wherever I end up, I need to be able to take a 15-20 min nap in the afternoon.
Someone hook me up with one of these nap pods: http://bit.ly/QLsbMv
1 note
·
View note
Text
Burning the midnight oil
I just got back to the apt, and had to get this in before I sleep. Today Jeremy, my mentor, and I were the last ones to leave the office. It was a bit eerie walking home past 2am but so worth it.
We went over minimax and wrote the code in a few hours and it was fucking awesome. That is all for now. Big thanks to Jeremy for staying with me past 2am and to Phil Aquilina for sending me on this challenge.
Will have to go over all of it again tomorrow to see how well I assimilated it. Up next, negamax (whatever that is) and implementing it to Tic Tac Toe
0 notes
Text
Succeeding to fail
Last Monday Shereef asked us all to set and reach an aim (no matter what it took) by this morning. I estimated how much I could get done in a week and set a decent goal for myself, finish up to unit 2 level 1 (about 12 challenges). Having a goal to reach really got me motivated and I punched through the challenges pretty quickly; by Friday morning I had reached my aim. After lunch I spoke briefly with Lachy about reaching my aim and he basically told me that I failed. As I thought about it longer, the more I realized that he was completely right.
During the first week, we didn't set aims so even though DBC is setup to be an intense bootcamp, I didn't have as much of a sense of urgency as the second week. Actually, while doing the nested arrays challenge I ended up falling down the rabbit hole and spent two days working on developing a computer player for tic tac toe. It was a great learning experience but I found myself a little behind by the end of the week.
Coming back to 'failing'... It wasn't that I failed at reaching my aim, I failed to set an aim high enough that would really put my at the edge of my learning and panic zone. If I didn't talk to Lachy after completing my aim so quickly, I probably would have felt pretty smug about myself. Whew, thank goodness I avoided that trap. That feeling or mindset is probably one of the worst things to have while learning. It is a poison that causes you to become content and kills momentum.
Even though other boots might disagree, personal aims are a positive influence and it is important to keep one week to week. Takeaways? If you complete an aim way ahead of schedule, just keep yourself in check and set a harder one next time and build up confidence. Just make sure you do everything to reach it.
0 notes
Text
Living up to expectations
Week 2 of DBC is about to be over and I want to reflect on my expectations, how they were or were not met and what I’ve learned. I visited the summer cohort to find out if DBC was worth my money and to come up with some of my own expectations. The list I came up with before arriving in SF is pretty long but some of the key points in no particular order were:
· Having 2 mentors
· Being surrounded by amazing people with the same goal
· Networking
· An awesome distraction-free space to pretty much live in for 10 weeks
· A new pair programming partner everyday
· A great learning platform
· Guidance on best practices
· Lectures on programming topics
I have two awesome mentors that I mentioned in a previous post. My fellow boots are all amazing people with unique life stories and every single one is extremely hard working. (It’s crazy to see how many people are here past 10pm and on the weekends) The office is a great collaborative environment and pretty much distraction-free unless you’re in the kitchen.
There are a few things that are happening differently or completely unexpected and I’m learning how to work those to my advantage so I can get the most out of my experience. We are definitely not switching pairs everyday and I was looking forward to seeing many different approaches to problem solving. In the past two weeks I have had 4 different partners and each one had their own approach to solving the challenge we faced. Actually I have found switching partners every few days allows us to settle in and get to the point where we can be comfortable arguing with each other on why something should be named a certain way or whether creating another method vs. just putting the code in an existing function would be better. Our learning platform, Socrates, has been pretty buggy and there are plenty of complaints from other boots that it is holding them back. I’d have to agree that not being able to see the full curriculum or roadmap is a bit worrisome. Right now I’m not sure how much time I can spend on a challenge without borrowing it from other challenges. These challenges are basically guiding us through Ruby (and whatever we’ll be learning in the next 8 weeks) but I expected to have more insight on industry best practices and workflows. Really though, the insight is available from the staff here at DBC and I have to just actively ask for it.
For the most part, DBC has lived up to my expectations and not only have I learned so much about programming but I'm gaining more insight about myself. More about that in a future blog post.
2 notes
·
View notes
Text
An elegant and simple random line selection algorithm
If you could read in a file only once and had to select one random line from it and put it to the screen, how would you implement that?
I wouldn't be able to tell you if hadn't been for one of my mentors, Jeremy Fleischman. A short side note: I met Jeremy and my other Mentor, Phil Aquilina, two days ago during the Mentor Introduction Night here at Dev Bootcamp. Both are amazing people and I am excited to have the chance to code with both of them.
Back to the question: If you could only read a file once, could you pick a random line from that file and print it? Imagine the file is so huge, you couldn't store all of it memory. How could you FAIRLY (give each line a fair chance) pick a random line?
I wouldn't be able to give you this answer without a little guidance from Jeremy, so thank you Jeremy. Check out this code snippet:
https://gist.github.com/3870423
Let's use some math to prove that this is truly random for \(\large n\) lines.
Consider the case when there is only one line to read...
count = 1 if Random.rand(count) == 0 #==> true motd = file_reader.readline #==> "first line"
The first line will always be chosen into the array so the chances to save the first line is 100%
Now a two line file...
count = 2 if Random.rand(count) == 0 #==> 0=true 1=false motd = file_reader.readline #==>
If random returns 0 then save the second line. There is a \(\large\frac{1}{2}\) or \(\large\frac{1}{n}\) chance to keep the previously saved line.
Now for a three line file...
count = 3 if Random.rand(count) == 0 #==> 0=true 1=false 2=false motd = file_reader.readline #==>
If random returns 1, then save the third line. There is a \(\large\frac{2}{3}\) chance to keep the previously saved line. In a four line file there is a \(\large\frac{3}{4}\) to keep the previous line, \(\large\frac{4}{5}\) in a five line file and so on...
If we know that the probability to choose \(\large n\) is \(\large\frac{1}{n}\) and the probability to choose the next line is \(\large\frac{1}{n+1}\). If all lines should be chosen fairly then \(\large\frac{1}{n}\) \(\cdot P() = \large\frac{1}{n+1}\), \(P() = \large\frac{n}{n+1}\)
Let's test it. For 2 lines, there is a (\(\large\frac{1}{n}\)) or \(\large\frac{1}{2}\) chance to keep the first line. If we add one more line the chance to pick that would be (\(\large\frac{1}{n+1}\)) or\(\large\frac{1}{3}\) and the chance to keep the previous line would be (\(\large\frac{n}{n+1}\)) or \(\large\frac{2}{3}\).
3 line file: \(\large\frac{1}{n}\) \(\large\cdot\frac{n}{n+1} = \frac{1}{n+1}\) => \(\large\frac{1}{2}\cdot\frac{2}{3} = \frac{1}{3}\)
6 line file: \(\large\frac{1}{n}\)\(\large\cdot\frac{n}{n+1} = \frac{1}{n+1}\) => \(\large\frac{1}{2}\cdot\frac{2}{3}\cdot\frac{3}{4}\cdot\frac{4}{5}\cdot\frac{5}{6} = \frac{1}{6}\)
YES! You can read a file only once and choose a random line fairly without knowing the number of lines or storing the entire file. I can't wait to go over cool algorithms with Jeremy on mentor days!
1 note
·
View note
Link
*** Read this first:
To get code to show up properly in your blog post, write your posts in Markdown and use Tumblr’s built-in Markdown editor (you can switch to it in your settings).
Writing code blocks is not as simple as wrapping things in <code> and <pre> tags.
If you have no idea what...
7 notes
·
View notes