Udemy Course: All about Node.js

I am working on a personal side-project for some friends and decided to build it using Node, Express, Mongo, and Passport.

About the time I was working on the database architecture I received a coupon via email for the Udemy course “All about Node.js” taught by Sachin Bhatnagar. The full price for the course is currently $150 but it comes up on-sale from time-to-time and coupons are often available.

The course is 64 lectures with 8 hours of video and a handful of quizzes. It took me 3 weeks to work my way through all of the lectures as I was also reading a couple of books on Safari Books Online and Learn All The Node http://www.learnallthenodes.com/.

Sachin’s class is great; the lectures about using Amazon’s CloudFront and EC2 alone are worth the full price of $150. He is very articulate, easy to understand, and does a great job breaking complicated systems into easy to digest lessons.

From the course description:

“My intent is hand hold you all the way from writing your first NodeJS app to deploying production level apps on the cloud.”

What am I going to get from this course?

  • Over 64 lectures and 7.5 hours of content!
  • Build High Performance and Scalable Apps using NodeJS
  • Use NodeJS Streams to write a Web Server
  • Use the Node Package Manager (NPM) for managing dependencies
  • Use the Express 4 Framework for building NodeJS Apps
  • Use the Hogan Templating Language
  • Understand MongoDB as a NoSQL Database
  • Create & Use MongoDB Databases using services like MongoLab
  • Create Realtime Apps that use Web Sockets
  • Upload & Resize Images using NodeJS
  • Integrate Authentication using Social Media Sites like Facebook
  • Structure the NodeJS app into modules
  • Create and Deploy EC2 Cloud Server Instances on Amazon Web Services
  • Create and Use Amazon’s S3 Storage Service with NodeJS
  • Use Amazon’s Cloudfront Service
  • Using Amazon’s Elastic IP
  • Configure Security Groups, Ports & Forwarding on Amazon EC2
  • Deploy a NodeJS app on the EC2 Instance
  • Deploy a NodeJS app on Heroku
  • Deploy a NodeJS app on Digital Ocean
  • Install & Deploy NGINX as a Reverse Proxy Server for NodeJS Apps
  • Configure NGINX as a Load Balancer

What is the target audience?

  • Web Designers & Front End Developers who wish to extend their knowledge of Javascript for building high performance network applications.
  • Software Developers who want to build high performance network applications.
  • Absolute beginners with basic knowledge of HTML, CSS and Javascript, wanting to upgrade to professional Web Development and Building Web Apps.
  • PHP, ASP.net, Perl, Java & Ruby coders wanting to leap onto the Node.Js bandwagon.
  • Anyone who wishes to get hands-on training with setting up an Amazon EC2 Instance with a host of other services like Cloudfront, Elastic IP and S3
  • Anyone who wishes to get hands-on training with deploying a NodeJS app on the cloud
  • Computer Engineering students
  • Tech Entrepreneurs who want to get their hands down and dirty with Web Coding & App Development.
  • Anyone who wishes to stay on the forefront of technology!

I rate the Udemy Course: All about Node.js a 10 out of 10 and highly recommend it to anyone who wants to learn Node.js and its surrounding technologies and frameworks.

Concatenate and Optimize Your JavaScript & CSS

Just how important is it to concatenate and optimize your javascript? In reading this article about the healthcare.gov article "Analysis: IT experts question architecture of Obamacare website" it is apparently extremely important.

Among other problems it was found that a large number of JavaScript files were being requested and then parsed by the customer’s web browsers causing an overload of requests from the server and an overtaxing of the web browser.

"Of the 92 he found, 56 were JavaScript files, including plug-ins that make it easier for code to work on multiple browsers (such as Microsoft Corp’s Internet Explorer and Google Inc’s Chrome) and let users upload files to HealthCare.gov."

I bet that the majority of the other 36 files are CSS files.

At a minimum those 56 JavaScript files should have been optimized and concatenated in such a way as there would only be 1 request to the server followed by 1 response.

There are many ways to do this, I really like the idea of doing it during the build process but it could also be more dynamic and done as required by the server. Whichever way you choose it will always be better than serving a huge number of separate files.

Here is a screencast walking you through how to set up a build process for JavaScript and CSS files using Ant.

Another option is to use "minify" instead of optimizing during the build process.

No matter how you do it, if you build web sites you have no excuse not to use some method to optimize your JavaScript and CSS to improve your customer’s experience.

Delicious Library 3

Delicious Library 3 WebsiteMy wife and I read a lot of books. Now that our son has gotten a little older and needs less attention, I go through more than a book a week on average, Bobbie doesn’t go through as many books in number, but she is reading much larger non-fiction books and taking copious amounts of notes.

Many years ago I bought Delicious Library 2 (DL2) as a part of a bundle deal. Bobbie and I used it to catalog all of our fiction and collectable books. It worked well enough and with some simple PHP and YUI coding I built a simple web page we could use on our phones to check our library while out and about.

Then disaster struck, I reformatted/re-installed all of our computers and updated them to the latest version of the Mac OS. I thought I had backed everything up, but apparently Delicious Library’s database was not.

Lately Bobbie has been asking me about how to update the Library page with the new books we have purchased. I did another round of research for library software and came to the decision to buy and use Delicious Library 3 (DL3).

I bought it from the Apple App Store, which means it can run on all of our machines and it will stay up-to-date via the App Store app.

The great news is that even though I had lost the DL2 database, DL3 was able to import the CSV file I was using on our website and retrieve the information for the 450+ plus books that were in it from Amazon. That was pretty amazing and made me very happy.

Also, the iPhone app Delicious Scanner worked great for me successfully scanning about 75% of the books that had barcodes in our library. I was kind of surprised how well it worked, DL2 was not nearly as successful using the iSight camera on a laptop. I was also surprised by how many books we have that do not have any kind of bar code or even an ISBN code, a lot of Bobbie’s antique books predate ISBN.

The good news is that scanning the rest of the books went faster than I expected and DL3 did a good job of finding the books on Amazon with a little bit of manual help. DL3 is not fully automatic; I don’t think any book library app could be, there is always going to be manual work involved. Adding the meta-data that is important to us like the name of the Series that a book is a part of, the book’s number in the series, and the character name’s that appear in the book is always going to be manual because what is important to us is not going to be important to everyone.

The bad news is the DL3 is still burying its database in a proprietary format in a deeply hidden corner of your computer. There is still no way for multiple people to collaborate on a single library, you can export/import libraries but it is very klunky and if every book does not have an associated ISBN or Amazon code you are bound to have duplicate entries. And the templates for exporting an HTML version of your library are absolutely useless!

The HTML output and even the default interface of DL3 makes me very sad and frustrated. The developers/designers of the app spent all this time on graphics, 3D effects, and a multitude of wood grains instead of on the usability of the app.

This is what we need from a library app:

  1. Easy book entry
  2. Easy to find a book in the library

Delicious Library 3 is awesome at book entry, that part fits my needs almost perfectly. The only thing that would make it better is integration with data sources other than Amazon.

DL3 Bookshelf ViewWhen it comes to finding a previously entered book, the DL3 app on the desktop works ok. The default 3D Bookshelf view with the books on a shelf (duh) is absolutely worthless for this, it makes it almost impossible to scan through the books and the cover from Amazon may not match the cover of the real book on your shelf making it counter-productive.

Switching to List view improves the situation a lot. You can control what fields/columns are visible and sort the columns.

DL3 Search ResultsOh wait; right there in the top left is search box. Well that should help right? WRONG, when you enter text in that box it displays the results in a pop-up with a fixed width that truncates the book titles to the point that they are useless.

I am going to stop complaining right there. Delicious Library has a lot of usability issues that will apparently never be addressed, lets move on to why it is still a very useful app.

You can output a CSV file!

DL3 Export a CSVI have written a little PHP file that takes the CVS file that DL3 outputs and makes a very simple HTML table with the data. Then I use jQuery and a couple libraries to make the table sortable, searchable, and filterable.

The PHP is not very efficient, if we had many more books the JavaScript/jQuery would be to slow to be useful, and having it all in a database would make it easier to do some other cool stuff with the data. But for now the simple PHP and JavaScript fit our needs and give us a great interface into our book library.

My Simple Library

My Simple Library

Here is my UGLY PHP:


<?PHP
$firstRow = true;
$file_handle = fopen("export.csv""r");
while (!feof($file_handle) ) {
    $line_of_text = fgetcsv($file_handle1024);
    $author = $line_of_text[1];
    $title = $line_of_text[4];
    $series = $line_of_text[2];
    $subtitle = $line_of_text[3];
    if ($author == "") {
        $author = " ";
    }
    if ($title == "") {
        $title = " ";
    }
    if ($series == "") {
        $series = " ";
    }
    if ($subtitle == "") {
        $subtitle = " ";
    }
    if ($firstRow == false) {
        if ($line_of_text[0]) {
            print "" . $author . "" . $title . "" . $series . "" . $subtitle . " ";
        }
    } else {
        $firstRow = false;
    }
}
fclose($file_handle);
?>

I am using jQuery 2.0.2 and tablesorter with the Zebra and Filter widgets.

Here is the JavaScript, it is almost entirely cut and paste from the tablesorter web page:


$(document).ready(function()
    {
        $("#myTable").tablesorter({
          theme : 'blue',
          sortList: [[0,0], [1,0]],
          widgets: ["zebra""filter"],
          widgetOptions : {
            // If there are child rows in the table (rows with class name from "cssChildRow" option)
            // and this option is true and a match is found anywhere in the child row, then it will make that row
            // visible; default is false
            filter_childRows : false,
            // if true, a filter will be added to the top of each table column;
            // disabled by using -> headers: { 1: { filter: false } } OR add class="filter-false"
            // if you set this to false, make sure you perform a search using the second method below
            filter_columnFilters : true,
            // css class applied to the table row containing the filters & the inputs within that row
            filter_cssFilter : 'tablesorter-filter',
            // class added to filtered rows (rows that are not showing); needed by pager plugin
            filter_filteredRow   : 'filtered',
            // add custom filter elements to the filter row
            // see the filter formatter demos for more specifics
            filter_formatter : null,
            // add custom filter functions using this option
            // see the filter widget custom demo for more specifics on how to use this option
            filter_functions : null,
            // if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately
            // below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus
            filter_hideFilters : false// true, (see note in the options section above)

            // Set this option to false to make the searches case sensitive
            filter_ignoreCase : true,
            // if true, search column content while the user types (with a delay)
            filter_liveSearch : true,
            // jQuery selector string of an element used to reset the filters
            filter_reset : 'button.reset',
            // Delay in milliseconds before the filter widget starts searching; This option prevents searching for
            // every character while typing and should make searching large tables faster.
            filter_searchDelay : 300,
            // if true, server-side filtering should be performed because client-side filtering will be disabled, but
            // the ui and events will still be used.
            filter_serversideFilteringfalse,
            // Set this option to true to use the filter to find text from the start of the column
            // So typing in "a" will find "albert" but not "frank", both have a's; default is false
            filter_startsWith : false,
            // Filter using parsed content for ALL columns
            // be careful on using this on date columns as the date is parsed and stored as time in seconds
            filter_useParsedData : false,
            filter_onlyAvail : 'filter-onlyAvail'
          }
        });
    }
);

If you are looking for a way to keep track of your books, give Delicious Library 3 a try. So far it is working well for us.

Codecademy JavaScript Courses

Codecademy Web Site

Codecademy

I first learned about Codecademy last year and I immediately jumped into it and completed a few of the JavaScript courses and promptly forgot about it.

Lately I have been writing more and more JavaScript and jQuery to make interactive prototypes for work. I rate my JavaScript skills somewhere around intermediate and I am challenging myself to work my way up to expert by the end of the year. As a part of that personal challenge I have been reading a lot of JavaScript, jQuery, and Git books and websites, this is how I ended up back on the Codecademy website.

Compared to last year, Codecademy has made many improvements. The JavaScript courses have been updated, they still have plenty of ambiguous wordings that makes completing the lesson harder than it should be and many of the lessons don’t teach much more than how to cut-and-paste. But with some help from the available Forums, I finished the JavaScript courses in 4 days without too much trouble.

I really enjoyed the courses on inheritance and constructors. I am going to put that to use immediately and refactor a lot of code and use courses to make my code much easier to maintain, modify and re-use.

All that said, I did have some issues while working through the lessons. A handful of times, I thought I understood the task but just couldn’t get it to accept my answer. The forums were helpful but it was not easy to find questions/answers related to the exact lesson/task I was having trouble with. I would appreciate it if the forums were broken down by individual lessons instead of by whole class.

The in-browser coding environment is very slick, but in many of the lessons there were warnings from JSHint. Those warning were very distracting when I was starting out, after awhile I learned to ignore most of them.

Overall I enjoyed the Codecademy experience and I plan on continuing participating on the courses offered there. In between reading books and writing code, probably while on the couch in front of the TV, I will work my way through the Web Fundamentals, jQuery, JavaScript (done), Projects, Python, Ruby, PHP, and APIs lessons.

From Codecademy:

Codecademy is an education company. But not one in the way you might think. We’re committed to building the best learning experience inside and out, making Codecademy the best place for our team to learn, teach, and create the online learning experience of the future.

Education is old. The current public school system in the US dates back to the 19th century and wasn’t designed to scale the way it has. Lots of companies are working to "disrupt" education by changing the way things work in the classroom and by bringing the classroom online.

We’re not one of those companies. We are rethinking education from the bottom up. The web has rethought nearly everything – commerce, social networking, healthcare, and more. We are building the education the world needs – the first truly net native education. We take more cues from Facebook and Zynga in creating an engaging educational experience than we do from the classroom.

We do not want to open up universities. We want to open up knowledge. Everyone knows something they can teach someone else and we want to help them do it. Our community has created tens of thousands of courses and taken millions of courses. At this point, more than a billion lines of code have been submitted to Codecademy.

Education is broken. Come help us build the education the world deserves.

I rate Codecademy a 9 out of 10 and it wouldn’t take many improvements to make it a 10.

Fotorama Slide Show and phpSmug

Fotorama Web Site Home Page

Fotorama

As a part of my web site moving and redesign I wanted to include a slideshow at the top of the home page.

After researching and thinking about writing one of my own I found Fotorama which is a jQuery based slideshow framework that allows for many different types of slideshows with a ton of options. Take a look at the website and the examples, they are amazing.

So I broke the process down into a handful of steps and iterated up to the dynamic slideshow that it is now.

The first step was getting a version running on a test page with static content hard-coded into the page. There was a bit of tweaking here and there along with coming up with the idea to have a design that resembles a new window "Window" with Hide and Fullscreen buttons.

The next step was figuring out how to dynamically get the picture URLs and Captions directly from SmugMug so that anytime I update SmugMug the slidesow on my website would also be updated. For that I chose to use phpSmug which is a wrapper class for the SmugMug API written and maintained by Colin Seymour.

I ran into 2 issues with implementing phpSmug, the biggest of which was that it would randomly error out with a "CURL Error 7" which was causing my website to load very slowly and breaking the slideshow. I have addressed this issue by using the caching built into phpSmug combined with writing the parsed data necessary for the slideshow into a MySQL table. Anytime the SmugMug API is not available and the phpSmug cache has expired the data for the slideshow will be pulled from the database.

Here is the code:


<?php
$user="username";
$password="password";
$database="database_name";
$tablename="table_name";
mysql_connect(localhost,$user,$password);
@mysql_select_db($databaseor die"Unable to select database");
/* Last updated with phpSmug 3.0 */
require_once"/path/to/phpSmug.php" );
try {
  $code = "SmugMug API";
  // My API Key and App Name from SmugMug Admin Panel
  $f = new phpSmug"APIKey=api_key""AppName=app_name_and_version" );
  // Enable disk based caching with expires in 1 hour
  $f->enableCache("type=fs""cache_dir=/path/to/phpsmugcache""cache_expire=3600" );
  // Set timeout
  $f->req->setConfig(array'timeout' => 2));
  // Login Anonymously
  $f->login();
  // Get images from Portfolio
  $images = $f->images_get"AlbumID=album_id""AlbumKey=album_key""Heavy=1" );
  $images = ( $f->APIVer == "1.2.2" ) ? $images['Images'] : $images;
  $i = 0;
  foreach ( $images as $image ) {
    if ($i != 0) {
      $query .=  ",\n";
      $output .=  ",\n";
    }
    $i++;
    // Create SQL String
    $query .= "('','".$image['X2LargeURL']."','".$image['TinyURL']."','".htmlentities($image['Caption'],ENT_QUOTES)."')";
    $output .= "{img: \"".$image['X2LargeURL']."\", thumb: \"".$image['TinyURL']."\", caption: \"".htmlentities($image['Caption'])."\"}";
  }
  // Empty Out Table
  mysql_query('TRUNCATE TABLE '.$tablenameor die(mysql_error());
  // Populate Table
  mysql_query("INSERT INTO cache (`id`, `x2largeurl`, `tinyurl`, `caption`) VALUES ".$query);
} catch ( Exception $e ) {
  $code = "{$e->getMessage()} (Error Code: {$e->getCode()})";
  //Read from Database
  $query="SELECT * FROM ".$tablename;
  $result=mysql_query($query);
  $num=mysql_numrows($result);
  $i=0;
  while ($i < $num) {
    $X2LargeURL=mysql_result($result,$i,"x2largeurl");
    $TinyURL=mysql_result($result,$i,"tinyurl");
    $Caption=mysql_result($result,$i,"caption");
    if ($i != 0) {
      $output .=  ",\n";
    }
    $i++;
    // Create SQL String
    $output .= "{img: \"".$X2LargeURL."\", thumb: \"".$TinyURL."\", caption: \"".$Caption."\"}";
  }
}
mysql_close();
?>
jQuery(document).ready(function(){
  try { console.log('code: <?php echo $code ?>'); } catch(err) { }
  // Load Fotorama.js script
  jQuery.getScript("/scripts/fotorama.js"function(){
    var portfolioBuildFlag = false;
    jQuery('#main').prepend('<article class="fotoramaWrapper"><div class="portfolioHeader gradient">Dave Nelson's Portfolio <div><span id="portfolioHide">[ Hide ]</span> <span id="portfolioFullScreen">[ Fullscreen ]</span></div></div><div id="myPortfolio"></div></article>');
    jQuery('#portfolioHide').on('click',portfolioToggle);
    jQuery('#portfolioFullScreen').on('click',function() {
      if(jQuery("#myPortfolio").is(":hidden") || portfolioBuildFlag === false) {
        portfolioShow();
      }
      jQuery('#myPortfolio').trigger('fullscreenopen');
    });
    function portfolioBuild() {
      jQuery('#myPortfolio').fotorama({
        data: [
        <?php
          echo $output."\n";
        ?>
        ],
        width'100%',
        height'auto',
        aspectRatio1.5,
        minHeight500,
        fitToWindowHeightfalse,
        margin0,
        shadowsfalse,
        cropToFitfalse,
        caption'overlay',
        autoplay3000,
        thumbBorderColor'#FCB03E',
        fullscreenIcontrue
      });
      portfolioBuildFlag = true;
    }
    function portfolioCookie(state) {
      if (state === "hidden") {
        document.cookie = "portfolioHide=true";
      } else {
        document.cookie = "portfolioHide=false";
      }
    }
    function portfolioToggle() {
      if(jQuery("#myPortfolio").is(":hidden") || portfolioBuildFlag === false) {
        portfolioShow();
      } else {
        portfolioHide();
      }
    }
    function portfolioShow() {
      if (portfolioBuildFlag === false) {
        portfolioBuild();
      }
      jQuery('#myPortfolio').slideDown('fast');
      jQuery('#portfolioHide').text('[ Hide ]');
      jQuery('#myPortfolio').trigger('play')
      portfolioCookie('shown');
    }
    function portfolioHide() {
      jQuery('#myPortfolio').slideUp('fast');
      jQuery('#portfolioHide').text('[ Show ]');
      jQuery('#myPortfolio').trigger('pause')
      portfolioCookie('hidden');
    }
    function portfolioInit() {
      var portfolioHide = document.cookie.replace(/(?:(?:^|.*;\s*)portfolioHide\s*\=\s*((?:[^;](?!;))*[^;]?).*)|.*/"$1");
      if (portfolioHide != "true") {
        portfolioBuild();
      } else {
        jQuery('#portfolioHide').text('[ Show ]');
      }
    }
    portfolioInit();
  }); // Load Fotorama.js script

}); // document ready

Responsive Design in Practice

What the heck does "Repsonsive" mean when it comes to a web site?

For my own practical purposes it means that I have a single web site with one set of HTML, CSS, and JavaScript being served to all web browsers, but the appearance of the website changes based upon the width of the web browser’s window to give a great viewing experience to everyone.

Haha, that is a mouthful.

So here it is in action:

davenelson.com Desktop Web Browser Screen Shot

Desktop Web Browser


davenelson.com iPad Screen Shot

iPad


iPhone

davenelson.com iPhone Screen Shot

The great thing is I did not need to build three different websites, no "mobile" version, just "The Website." Another great thing is that I was able to start with a WordPress theme that someone else spent a lot of time an effort in building. I just tweaked it to fit my needs.

Sunspot WordPress Theme Screen Shot

Sunspot WordPress Theme Screen Shot

The theme is called Sunspot by Automattic and I really like the way my content looks when using it.

From the author:

A sharp theme with subtle grid lines and sun-splashed accents, Sunspot is a great all-purpose blogging canvas, especially for those who prefer a dark color scheme. Sunspot offers two arrangements for posts on the front page. Additional features include a custom header and a custom background, two optional widget areas, and a responsive layout that adapts gracefully to smaller screen sizes.

Responsive design is not a fit for all web sites, content and interactions that work great in a desktop web browser are not always appropriate for the really small screens of smartphones and conversely content made for smartphones does not always scale well for big screens. But for a blog or any site that is primarily text-based I think responsive design is a great way to reach a broader audience.

I Changed Web Site Hosts

web site screen shot

Dreamhost’s Web Site

After 4 years at my previous host I had become pretty unhappy with them.

I was running a WordPress blog and a PHP/MySQL based app to track an office football pool along with a handful of pictures for clients to download and prototype websites for conducting usability tests. But I was regularly having issues, mostly based around the web site being really slow.

So after reading a post in Lifehacker about the best personal web host which highlighted Dreamhost as the best option, I decided to make the jump.

The Dreamhost discount from the article was no longer valid, but I was able to find a $50 off coupon when signing up for a year or more. It made my first year cost less than $70. And after that the cost will be within $20 of what I was paying my previous host.

It took about 2 days for the DNS entries to be updated, to make my tweaks, and to get WordPress up and running with my imported content.

A big shout-out to the folks that make WordPress happen, exporting the content from my old provider then importing it into the new one worked like a charm. I had to tweak some settings and add some information in widgets and plug-ins, but overall it was amazingly easy.

I’ve spent some time over the last 2 weeks picking a Responsive theme, Sunspot by Automattic, that works great on a desktop at any width, smartphone, and tablet. It took some tweaking based on the heading and navigation, but it is clean and easy to modify.

Then I started with the basic plugins, Akismet and Jetpack by WordPress.com which are great and easy to install and setup.

Then I tried a bunch of different plugins that were all awful. For any WordPress install I highly recommend you go to a site like Pingdom Website Speed Test and check your speed with no plugins installed and then run it again after you add each plug-in. Also check it again anytime you make big changes to any plugins. Using Pingdom I was able to see that the “SmugMug for WordPress” plugin was absolutely killing the speed of my website, even when it was not displaying content on my website, so I am not using that anymore.

In the end I am using SmugMug Widget to display some of my most recent photos uploaded to my photography website. With some tweaking to the CSS I have the widget working great in the Sunspot theme and is now a part of the responsive design. Best of all the SmugMug Widget did not negatively affect the speed of my website.

Then I tried W3 Total Cache and after a day of fiddling with it decided it was not for me. If you are not running some type of minification and caching system on your WordPress website I do suggest giving it a try, but I chose to go a simpler route.

I am using WP Minify to remove all of the extra white space and combine separate files for JavaScript, CSS, and HTML. Running YSlow using minification made a difference, but not a big one.

The big performance improvement for my website comes from WordPress Super Cache which makes dynamic pages static. On my server the pages are still served by PHP, but they are so much faster!

Now my website includes the content I want, has a responsive design that looks great on desktop web browsers, iPads, and iPhones, and is faster than I could have ever hoped for.

97 Things Every Programmer Should Know

This book is a part of O'Reilly's 97 Things series where individuals contribute short entries to a wiki, which are then edited, from which 97 items are selected for a book.

I found this book on the shelf at Fry's and after paging through it a bit decided buying it and having a hard copy to let others borrow was worth the cover price as opposed to reading it online. The series is different from most books as the entire contents are available to read for free at http://programmer.97things.oreilly.com/

I feel like I got a lot out of this book, maybe the most valuable was that I need to read the book "The Pragmatic Programmer" ASAP.

Here are links to entries that I found the most interesting, they are really short so give a couple of them a look and let me know what you think:

Comment Only What the Code Cannot Say

"…comments should be treated as if they were code. Each comment should add some value for the reader, otherwise it is waste that should be removed or rewritten."

Continuous Learning

"Follow the advice of The Pragmatic Programmers and learn a new language every year."

Do Lots of Deliberate Practice

"Deliberate practice does not mean doing what you are good at; it means challenging yourself, doing what you are not good at. So it's not necessarily fun."

"Deliberate practice is about learning. About learning that changes you; learning that changes your behavior."

Don't Be Cute with Your Test Data

"…when writing any text in your code — whether comments, logging, dialogs, or test data — always ask yourself how it will look if it becomes public."

The Professional Programmer

"Professionals are responsible. They take responsibility for their own careers. They take responsibility for making sure their code works properly. They take responsibility for the quality of their workmanship. They do not abandon their principles when deadlines loom. Indeed, when the pressure mounts, professionals hold ever tighter to the disciplines they know are right."

Read Code

"…don't read another book. Read code."

Simplicity Comes from Reduction

"The code should be simple. There should be a minimal number of variables, functions, declarations, and other syntactic language necessities. Extra lines, extra variables… extra anything, really, should be purged. Removed immediately. What's there, what's left, should only be just enough to get the job done, completing the algorithm or performing the calculations. Anything and everything else is just extra unwanted noise, introduced accidentally and obscuring the flow. Hiding the important stuff."

Two Heads Are Often Better than One

"When pairing, we each bring our collective programming experiences — domain as well as technical — to the problem at hand and can bring unique insight and experience into writing software effectively and efficiently."

Ubuntu Coding for Your Friends

"I get better because you make me better through your good actions."

I hope to put what I have learned into practice immediately and look forward to reading more of the entries that did not make it into the book.

I rate this book a 8 out of 10 and believe that anyone who programs will get something out of it. Remember that the entire book and more are available for free via a Creative Commons License at http://programmer.97things.oreilly.com/

Photogrpahy Blogs

Almost every day I use Google Reader to read RSS feeds from many different web sites, 44 of them today, and I would like to share the photography feeds.

The Big Picture

The Big Picture is a blog over at boston.com where they post some of the most amazing pictures of the week. These picture regularly inspire me to get out there and do that thing that I do.

http://www.boston.com/bigpicture/

Blue Pixel Musings

Blue pixel is a site billed as “Inspiring and Educating Photographers Worldwide” and I learn something from them every post.

http://www.bluepixel.net/

Hyperphocal

Hyperphocal posts tend to be pretty basic stuff, but I like the subjects they choose and I find something interesting in every post.

http://hyperphocal.com/

News: Digital Photography Review

DPReview covers everything that is new in photography. It is a great place to learn about new and upcoming cameras.

http://www.dpreview.com/

Photo Attorney

Photo Attorney is written by Carolyn E. Wright is an attorney who works for photographers. The posts are always relevant to photographers and photography. This is a great source of information on the war against photography.

http://www.photoattorney.com/

Photo-Resoures.org

Photo-Resources is full of posts similar to this one, bringing attention to other web sites and resources with every post.

http://photo-resources.org

Photo Permit

Photo Permit is a great blog to keep you on top of what is happening in the war on photography.

http://www.photopermit.org/

Photoshop Insider

This is Scott Kelby’s blog about Photoshop and photography. It is also where you can keep track of the worldwide photo walk (http://www.photoshopuser.com/photowalk/).

http://www.scottkelby.com/

Rob Galbraith DPI

This blog is usually very short posts about anything that may be happening in the world of photography from photo slideshows to new equipment reviews and announcements.

http://www.robgalbraith.com/

Sisters

Jason Lee is a great wedding photographer who has made a project out of taking and manipulating photos of his two daughters. The results are amazing an fantastic!

http://kristinandkayla.blogspot.com/

Strobist

The Strobist has a cult-like following for the great posts about lighting and photography. There is a lot to learn as it is not just a blog but also includes tutorials about off-camera lighting.

http://strobist.blogspot.com

StudioLighting.net

Studio lighting dot net contains a lot of tutorials and the blog feed contains new camera and accessory announcements.

http://www.studiolighting.net/

TWIP

I have written about This Week In Photography as a podcast before, but it is also a great blog with tutorials, product reviews, and more.

http://twipphoto.com/

Zack Arias

Zack is an Atlanta based editorial and music photographer who also produces DVD tutorials. I like the photos that Zack shares via his blog and the local Atlanta flair appeals to me.

http://www.zarias.com/

Vincent Laforet’s Blog

Vincent is in China shooting the Olympics and is planning to blog about it all along the way. Including an awesome post about what he has packed to capture the event.

http://vincentlaforet.wordpress.com/

Sports Shooter

I do not look at Sports Shooter every day and do not subscribe to a feed from them, but I do recommend checking the site out on a regular basis for lots of great information about being a professional photographer.

http://www.sportsshooter.com

Hollywood Stock Exchange

The Hollywood Stock Exchange (HSX) is a web based stock trading game that trades in the success and failure of movies. The game is free to play and can provide some real insight into how a stock exchange works and what makes for a successful movie.

By creating an account you receive $2 million HSX dollars to buy and sell stocks, bonds, and funds with.  It is plenty of money to jump right in and create a portfolio that can take off but not so much money that you cannot lose most of it in one bad weekend.

On HSX you can trade in stocks, bonds, and funds. Stocks are holdings in specific movies, bonds are holdings in credited actors, and funds are managed groups of stocks and bonds that have been brought together to create a single investment.

The most powerful feature of HSX is the community forums, here you can learn about what movies are in development, who’s career is taking off, what the next big movie is going to be, and more about movies than anywhere else.

I really enjoy playing the Hollywood Stock Exchange game. It keeps me informed about upcoming movies and how well the HSX community thinks they will do at the box office.

My Username is Phrop, look me up and let me know what you think about the game.

Financial Peace

About four years ago I found myself deep in debt to the point that I spent many nights laying awake worrying about it. I was making enough money to pay the bills that came in the mail every month, but there wasn’t a lot of money left over for having fun. I was fed up and sick of it all.

I sat down with my computer and worked out a written budget, I included everything I spent money on every month, all of the bills, food, gas, rent, etc… Putting everything in a spreadsheet where I could see exactly where the money was going made it much easier for me to funnel more money to my largest bills. After two years I had made a very nice dent in the mountain of debt.

Then I heard this guy on the radio telling people that they needed to have a written budget and to spend every dollar on purpose. This rang true enough with me that I started to really listen to him and tweaking the way I was working my plan.

His name is Dave Ramsey and over the last couple of years his plan has helped thousands of people make a real difference in their lives, including mine. Dave’s message is now available on the radio, television, multiple best selling books, and Financial Peace University.

About a year ago I married my beautiful wife; we owed money on two cars, credit cards, and a student loan. Over the past year, following what we learned by reading “The Total Money Makeover” and “Financial Peace Revisited” along with taking the “Financial Peace University Online” course, we not only paid off all those loans, but we were also able to pay cash for our wedding, buy a new camera, pay for a broken timing belt, and many other surprises that were no big deal because we had a plan.

What we have learned from Dave Ramsey over the last two years has not only changed our lives but will have repercussions for our entire family tree for generations to come.

For more information about Dave Ramsey and FPU:

We are holding FPU at St. Michaels in Brookhaven August 19th to November 11th on Tuesday nights. Contact Neal Marwitz at franklin-mcnealofg@comcast.net for more information or to sign up.