Friday, January 9, 2015

A Gift to Myself: My 2015 Gaming PC

Recently, I've been itching to play some of the newer PC games coming out (or recently released), but my laptop was lacking the power to do so. I've always been into PC games, but I drift in and out. This year, I decided I would get back into playing again. So, I built myself a "Black Friday-Christmas-New Years" gift: a gaming PC!

The Build

Here are the parts in all their glory!

And the build details:

Type Item Price
CPU Intel Core i5-4440 3.1GHz Quad-Core Processor $169.99 @ Newegg
Motherboard ASRock H97M PRO4 Micro ATX LGA1150 Motherboard $74.99 @ Newegg
Memory G.Skill Ripjaws Series 8GB (2 x 4GB) DDR3-1600 Memory $54.99 @ Newegg
Storage A-Data Premier Pro SP600 128GB 2.5" Solid State Drive $49.99 @ Newegg
Video Card Gigabyte GeForce GTX 970 4GB Video Card $339.90 @ Amazon
Case Fractal Design Core 1300 MicroATX Mini Tower Case $49.99 @ Newegg
Power Supply Corsair CX 600W 80+ Bronze Certified Semi-Modular ATX Power Supply $53.99 @ Amazon
Total
Total includes shipping, taxes, and discounts $797.65


Fractal Core 1300

I opted for micro-ATX because I wanted a smaller footprint, but enough airflow to keep my components cool. Mini-ITX seemed too cramped and ATX was too large. I don't see myself overclocking and liquid-cooling any time soon, but with this case, I'll have the option if I decide to later. However, I've pretty much ruled out SLI/Crossfire, as micro-ATX motherboards don't support it. The Fractal Core 1300 has solid construction with very good-quality material. It comes with two 120mm case fans that run almost completely silent.

I decided to remove the mount that holds additional SSDs and HDDs in the lower-front part of the case. There are places to mount the SSD on the upper-front mount or back behind the motherboard. So, there was no need for it to stay.

I found these two Reddit articles especially helpful for choosing a case:

ASRock H97M PRO4

The ASRock PRO4 was the cheapest H97 motherboard available at the time. I went with the H97 chipset because I have no immediate plans to overclock. Not to mention, the blue heatsinks look awesome!

Getting ready to seat the CPU!

I found these Puget Systems articles helpful in choosing the right Intel chipset:

Intel Core i5-4440

I spent a lot of time deciding which CPU to buy. My use-cases were pretty standard: gaming, multitasking, web-browsing, and music-streaming. In the end, I ended up going with the "true" four-core Intel i5-4440.

The i7 just seems too overkill for gaming, it's much better suited for video-encoding or extreme photo-manipulation. If I were on a tighter budget, I'd probably go with an i3. It's only dual-core, but Hyper-Threading allows it to run more threads. So, games that require four cores (Far Cry 4), would run on an i3. If I were only worried about handling games at mid to low settings on an extremely low budget, I'd probably opt for the Pentium G3258 and overclock it. An overclock G3258 can perform pretty admirably with newer games!

The i5 was the best choice for my needs, and my wallet isn't burning!

I found these tools helpful for selecting a decent CPU:

GSkill Ripjaws 8GB DDR3

I try not to overthink memory. It's memory. I used Ripjaws in my last build, so I used them again.



Seating the Motherboard

The ASRock H97M fits nicely in the Fractal Core 1300. However, there is one thing to note: the case does not have support for the right side of the micro-ATX board. The right side sort of "hangs" off the supports in the middle of the board. Pushing too hard on that side of the board will bend it back!


Corsair CX600M Power Supply

For the i5 and GTX 970, the 600W Corsair CS600M is more than enough to power the entire rig. I generally look for semi-modular, 80-Plus-rated power supplies with a single 12V rail. Corsair has had a great reputation for stable power supplies in the past. Hopefully, this one holds up!

In my last build, I used a modular power supply. Once you go modular, it's really hard to go with anything else!

Great tool for determining power supply needs for your system configuration:

ADATA Premier Pro 128 GB SSD

I have an 1TB external hard drive holding all of my media, so I really only needed disk-space for Windows 8.1 and my games. So, I opted for one 128 GB SSD. This ADATA one was the cheapest at the time, which made the decision easy.

I mounted it behind the motherboard and power supply, down below. It was quite snug, and it was pretty tricky getting the SATA cables back there, but I managed to cram everything into place!


Gigabyte GeForce GTX 970

I spent a good amount of time deciding which graphics card to buy. In my previous build, I went with an AMD/ATI 5850 to save some cash, and still got decent performance. However, it ran fairly hot, very loud, and took a lot of power. This time around, I spent more money and splurged on this Gigabyte GTX 970. At this time, it runs every game I throw at it on "ultra" settings. It runs smooth, cool, and doesn't suck much power.



Another minor reason for going with Nvidia was Linux driver support. I do some software development on the side and spend time in Ubuntu frequently.

I found these tools helpful for selecting a decent graphics card:

Cable Management

Took a bit of time to figure out how I wanted to route my cables. The key to a cool (and cool-looking) PC is how the cables are managed.


I decided to finally settle on something simple. I was in a hurry to turn the thing on for the first time!


The Finished Product

Once everything was hooked up, I plugged it in and turned it on. It started up without a hitch!

I really like blue, so I pulled some old blue-LED fans from my old build and threw them in. It's a little corny, but I don't mind it.


The PC looks really sleek sitting on my desk. It runs exceptionally quiet, even under load!


The Story: A PC Builder from the Start

I've always been interested in building/modding PCs. From a very young age, I was exposed to the ins and outs of computers. My dad studied and worked in IT during the early 90s, arguably the boom of the PC age. We were one of the very few households in the neighborhood with a PC sitting in the living room at this time. My dad built computers for my family from surplus parts at work and trips to Computer Sonic, one of the few local computer stores I can remember at the time.

As a kid, I fell in love with PC games. I remember playing (or watching my dad play) Oregon Trail, Doom, Warcraft, SimCity 2000, etc. I enjoyed other, less popular games like Jazz Jackrabbit, Gizmos and Gadgets, and Tyrian. As time went on, and I got older, I continued to play games like Age of Empires, Myth, and Starcraft. Inevitably, my love for PC games led to my love for custom-built gaming PCs.

Fast-forward to my freshman year in college. Following in my dad's footsteps, I landed a job working in IT at my university while studying computer science. I had the opportunity to build entire computer labs from component to workstation. It was here where I learned the importance of each and every PC component and how they work together.

Fast-forward to my junior year (3rd year) in college. I managed to save up money over a couple of years, along with some help from the holidays, and build my very first gaming rig. It was definitely an "extreme budget" build, with an OC'd Intel E5200 paired with a low-end GeForce GPU (don't remember which one). It worked decently for my word-processing, programming, and CounterStrike needs!

Fast-forward to graduation a couple of years later. After taking a summer off, I landed my first "true" job as an entry-level web developer. At this point, I was making fairly decent money, and also playing more demanding games with the free time. So, I decided to build a decent gaming PC with an Intel i7-860 CPU and paired with an AMD Radeon HD 5850. I managed to play all kinds of games with this baby: CounterStrike Source, L4D, Simcity 4, ANNO Series, etc. Sadly, I began to lose interest in PC games at this point. I ended up selling the PC to some high schoolers.

Once you've forayed into the wonderful world of PC gaming and rig-building, it's impossible to let go. I know I'll continue to build PCs (for myself and others) and explore new PC games as they come. Can't wait to see what the future holds!

Monday, April 14, 2014

DRYer Ruby Class Definitions w/ Struct

Many web developers subscribe to a principle know as the DRY principle. It translates to Don't Repeat Yourself. I try my best to adhere to the DRY principle, but sometimes I repeat snippets of code here and there, especially if the footprint is small. Well, today, a coworker showed me a clever way to DRY up some of my "small footprint" repeated code. It's probably some age-old Ruby technique, but I just discovered it today, and I'm really excited about it! So, I'll share it.

A Myriad of Class Definitions

Let's say we need to implement a Pizza application for a friend. After much white-boarding, we finally decide on a code architecture and a series of fancy design patterns we're gonna use to make our Pizza site come to life! Inevitably, we are going to have several class definitions in our codebase:
class Pizza
  attr_accessor :cheese, :sauce, :toppings

  def initialize(cheese, sauce, toppings)
    @cheese = cheese
    @sauce = sauce
    @toppings = toppings
  end
  
  # ... more implementation
end
class Soda
  attr_accessor :type, :is_diet

  def initialize(type, is_diet)
    @type = type
    @is_diet = is_diet 
  end

  # ... yes, more implementation
end
class Topping
  attr_accessor :name, :cost

  def initialize(name, cost)
    @name = name
    @cost = cost
  end

  # ... you get it
end

The Boilerplate

It's pretty obvious there are repeated elements of code in each of our classes. It's small, but repetitive nonetheless! Any DRY refactors we can do to reduce the code-smell would be an improvement.

When I'm writing class definitions, I frequently find myself writing two elements:
  • getters/setters for public attributes
  • a constructor with parameterss for initial attribute values

The DRY way to get getters and setters is to use attr_accessor.
attr_accessor :cheese, :sauce, :toppings
To set initial attribute values upon construction we use an initialize method with parameters. This is basic Ruby function. Within the initialize method, we explicitly define which attribute gets which parameter.
def initialize(cheese, sauce, toppings)
  @cheese = cheese
  @sauce = sauce
  @toppings = toppings
end

Reduce the Repetition with Struct

We can get rid of BOTH of these snippets of code by inheriting from a Struct instance! Well, kind of. A Struct generates an instance of Class. The new Class instance will have predefined attributes, along with accessor methods for them. By inheriting from the generated class, we essentially get all of the goodies we want in a single line of code!

Our Pizza class from above now becomes:
class Pizza < Struct.new(:cheese, :sauce, :toppings)  
  # no more initialize, just our implementation!
end
Subsequently, our entire codebase (however tiny) becomes:
class Pizza < Struct.new(:cheese, :sauce, :toppings)  
end
class Soda < Struct.new(:type, :is_diet)
end
class Topping < Struct.new(:name, :cost)
end

Mind. Blown. Anyway, I hope this helps someone as much as it has helped me. Comments or questions? Let me know!

Friday, January 17, 2014

Cleaner Rails JSON API Controller Specs with OpenStruct


As many of us know, Ruby on Rails makes it really easy to write RESTful APIs. Paired with a rich client-side framework, we can create applications with slick user interfaces. A common approach for this is to write JSON APIs on the server for consumption by a Javascript front-end framework. To test my APIs, I like to use RSpec and build specs for the actions on each of the controllers. The goal of the tests is to make sure each JSON response returns the correct information in the proper structure.

TL;DR Example code on Github

How about an example? Let's say we have a model named Article:
class Article < ActiveRecord::Base
  attr_accessible :title, :body
end
Following standard TDD practices, we begin by writing a test. Here's a first crack at a controller spec describing the create action on our ArticlesController:
describe ArticlesController do
  describe '#create' do
    let(:title)  { 'New Title' }
    let(:body)   { 'New Body' }
    let(:attrs)  {{ title: title, body: body }} # our new Article
    let(:params) {{ format: :json, article: attrs }}

    before { post :create, params } # make the request

    it 'creates a new Article' do
      Articles.all.count.should == 1
    end

    it 'returns the title' do
      response.body.should include(title)
    end

    it 'returns the body' do
      response.body.should include(body)
    end
  end
end
The first assertion makes sure an Article was actually created. The next two assertions check the response. A successful creation should return the new Article's attributes in a JSON object. With the spec written, we can implement our controller:
class ArticlesController < ApplicationController
  respond_to :json
  
  def create
    @article = Article.new(params[:article])

    if @article.save
      render json: @article # { title: 'New Title', body: 'New Body' }
    end
  end
end
When we run our test, it passes. However, our test is incorrect! What if, for some odd reason, the title and body were actually swapped in the response (title has body, body has title)? The test would still pass! While our spec ensures the correct values are in the response, it doesn't ensure the proper structure. Let's try again:
describe ArticlesController do
  describe '#create' do
    let(:title)  { 'New Title' }
    let(:body)   { 'New Body' }
    let(:attrs)  {{ title: title, body: body }}
    let(:params) {{ format: :json, article: attrs }}

    before { post :create, params }

    # removed Article count for brevity

    subject { JSON.parse(response.body) }

    it 'returns the title' do
      subject['title'].should == title
    end

    it 'returns the body' do
      subject['body'].should == body
    end
  end
end
In this version, we make our test more descriptive by declaring our response object as the subject. We also parse our response into a Hash by using JSON.parse() in the standard Ruby JSON library. Now, our assertions make sure we get the correct attributes from the proper keys in the response object. We also get the added bonus of ensuring a valid JSON response by parsing it in our subject.

Our test is now correct, but it can still be improved. When I'm testing JSON responses, I like to use OpenStruct to clean up my assertions. In simple terms, an OpenStruct takes a Hash and returns an object with methods named according to each key in the Hash. So, we can make the keys in our JSON response behave like methods on an object! Using OpenStruct, here is a prettier version of our test:
describe ArticlesController do
  describe '#create' do
    let(:title)  { 'New Title' }
    let(:body)   { 'New Body' }
    let(:attrs)  {{ title: title, body: body }}
    let(:params) {{ format: :json, article: attrs }}

    before { post :create, params }

    subject { OpenStruct.new(JSON.parse(response.body)) }

    its(:title) { should == title }

    its(:body) { should == body }
  end
end
Compared to our first draft, this spec is more concise, correct, and straightforward.

How do you like to use OpenStructs? Any thoughts, tips, and tricks are appreciated. Let me know in the comments!