Matt Mueller https://mattmueller.me/blog Wed, 26 Oct 2011 04:02:38 +0000 https://wordpress.org/?v=2.9.1 en hourly 1 Underscore Extension: Observer Pattern https://mattmueller.me/blog/underscore-extension-observer-pattern?utm_source=rss&utm_medium=rss&utm_campaign=underscore-extension-observer-pattern https://mattmueller.me/blog/underscore-extension-observer-pattern#comments Wed, 12 Jan 2011 11:56:10 +0000 Matt Mueller https://mattmueller.me/blog/?p=616

Introduction

I thought this would be a handy snippet for anyone who wants to enable event handling on any arbitrary object. I decided to augment Underscore.js because these methods should to be on every Javascripter’s “Utility Belt”. I decided to use Node-like methods – on, once, emit, & removeEvent.

Code

_.mixin({
on : function(obj, event, callback) {
// Define a global Observer
if(this.isString(obj)) {
callback = event;
event = obj;
obj = this;
}
if(this.isUndefined(obj._events)) obj._events = {};
if (!(event in obj._events)) obj._events[event] = [];
obj._events[event].push(callback);
return this;
},
once : function(obj, event, callback) {
if(this.isString(obj)) {
callback = event;
event = obj;
obj = this;
}
var removeEvent = function() { _.removeEvent(obj, event); };
callback = _.compose(removeEvent, callback);
this.on(obj, event, callback);
},
emit : function(obj, event, args){
if(this.isString(obj)) {
callback = event;
event = obj;
obj = this;
}
if(this.isUndefined(obj._events)) return;
if (event in obj._events) {
var events = obj._events[event].concat();
for (var i = 0, ii = events.length; i < ii; i++)
events[i].apply(obj, args === undefined ? [] : args);
}
return this;
},
removeEvent : function(obj, event) {
if(this.isString(obj)) { event = obj; obj = this; }
if(this.isUndefined(obj._events)) return;
console.log("remove");
delete obj._events[event];
}
});

Usage

Example 1: Listen for events on an arbitrary object

Car = {
color : 'blue',
seats : 4
};
_(Car).on('ready', function(sound) {
alert(sound + "!");
})
_(Car).emit('ready', ['honk']);

Example 2: Define global events

_.on('ready', function(sound) {
alert(sound + "!");
})
_.emit('ready', ['phew']);
_.removeEvent('ready');
_.emit('ready', ['come again?']); // Will not fire!

Example 3: Listening for an event “once”

_.once('ready', function(sound) {
alert(sound + "!");
})
_.emit('ready', ['phew']);
_.emit('ready', ['come again?']); // Will not fire!

Conclusion

And that’s my quick little snippet for you this morning. Let me know if you have any questions!

]]>
https://mattmueller.me/blog/underscore-extension-observer-pattern/feed 1
Quick Tip: Node.js + Socket.io + Authentication https://mattmueller.me/blog/quick-tip-node-js-socket-io-authentication?utm_source=rss&utm_medium=rss&utm_campaign=quick-tip-node-js-socket-io-authentication https://mattmueller.me/blog/quick-tip-node-js-socket-io-authentication#comments Sun, 02 Jan 2011 09:04:56 +0000 Matt Mueller https://mattmueller.me/blog/node-js-socket-io-authentication

Introduction

This is an incredibly quick tip that might save you a ton of time. I hope this tip receives you well.

Problem

Socket.IO does not have access to session information, therefore the server has no way of linking a message it receives to a specific user.

Solution

If you are running into this situation the solution is to use cookies. When you authenticate your user in your main application, create a cookie with the information you’d like socket to know. The user ID is a good start. Then send the cookie to the client. In express you can do this with res.cookie(key, value); . Then you can pull in this information with javascript on the client-side using document.cookie. Now the client has a userID that he can pass within a socket.io message to the server for the remainder of the session. I sincerely believe this is the only way. I’m pretty sure I’ve tried every iteration possible, leading to all sorts of race conditions. I dare you to come up with another solution . As always, feedback is appreciated!

]]>
https://mattmueller.me/blog/quick-tip-node-js-socket-io-authentication/feed 4
Proof of Concept: Event-Driven AJAX Chaining https://mattmueller.me/blog/proof-of-concept-event-driven-ajax-chaining?utm_source=rss&utm_medium=rss&utm_campaign=proof-of-concept-event-driven-ajax-chaining https://mattmueller.me/blog/proof-of-concept-event-driven-ajax-chaining#comments Sun, 26 Dec 2010 19:02:24 +0000 Matt Mueller https://mattmueller.me/blog/?p=569

Introduction

I had one of those “aha” moments last night as I was falling asleep. I hacked up this example during my lunch break as a “proof of concept”. I was wondering, Can you have an AJAX call in a chain without halting execution, throwing errors or losing the response?

Idea

The main idea is really easy- if your AJAX call is ready you execute right away, otherwise you listen (or bind) for the AJAX call to finish. Then when the AJAX call finishes you notify (or trigger) all listeners of the event. It basically let’s you write code as you always have been before all this event-driven stuff, but the event-driven triggers and bindings are baked into the code keeping your code extremely elegant.

Example of Event-Driven AJAX Chaining

Now maybe jQuery uses this technique in their $.load and $.get but I typically use their lower level $.ajax function so this would be what I typically write:

$.ajax({
   url: 'signup.php',
   data: {form: formData},
   success: function(response) {
      showLogin();
   }
});

Instead of that mess, we can write:

AJAX("signup.php", {form: formData}).success(showLogin);

AJAX Class Implementation

var AJAX = function(url, args) {
// Lets you do AJAX(...) or new AJAX(...)
if (!(this instanceof arguments.callee)) {
   return new arguments.callee(url, args);
};
if(!url) {
   return this;
}
this.url = url;
this.args = args;
this.init();
return this;
};
// Methods
AJAX.prototype = {
   init : function() {
      this.isReady = false;
      this.response = null;
      var _AJAX = this;
      $.ajax({
         url: _AJAX.url,
         type: 'GET',
         dataType: 'html',
         data: this.args,
         // Trigger isReady for listeners to respond
         success: function(response) {
            _AJAX.isReady = true;
            _AJAX.response = response;
            $(_AJAX).trigger('isReady', [response]);
         }
      });
      return this;
   },
   success : function(context, callback) {
      if(!context && !callback) return this;
      if(!callback) {
      callback = context;
      context = window;
      }
      // If we already ready, call the callback
      if(this.isReady) {
      if(typeof callback === "string") {
         context[callback](this.response);
      } else if(typeof callback === "function") {
         callback.call(null, this.response);
      }
      // Otherwise listen for success to be ready and call
      } else {
         $(this).bind('isReady', function(e, response) {
            $(this).unbind('isReady');
            return this.success(context, callback);
         });
      }
      return this;
   }
};

Extension

Now this is clearly the beginning. This code really needs to be refactored – we have to reimplement the event-driven logic in each method we write- I’m certain we wouldn’t have to do this each time with some sort of AJAX.extend(‘isReady’, function() {…}) with a callback function. Those this example isn’t all that impressive because we are using success, we could have any arbitrary event such as AJAX(‘createForm.php’).show(showForm).

Conclusion

Now I haven’t done any research and maybe this technique is obvious, but I think this is a good way to abstract AJAX programming from the typical web developer and keep AJAX calls clean without worrying about when we’re going to get a response from the server. I’d be curious to hear your thoughts!

]]>
https://mattmueller.me/blog/proof-of-concept-event-driven-ajax-chaining/feed 0
A Tragic Tale of Web Development Today https://mattmueller.me/blog/a-tragic-tale-of-web-development-today?utm_source=rss&utm_medium=rss&utm_campaign=a-tragic-tale-of-web-development-today https://mattmueller.me/blog/a-tragic-tale-of-web-development-today#comments Sun, 03 Oct 2010 10:02:43 +0000 Matt Mueller https://mattmueller.me/blog/?p=552

Introduction

Remember the last large web application you saw? It sure was beautiful. This web application worked in every browser, had nice fluid transitions, didn’t even break the back button. This app was amazing, but you knew that it was missing a few killer features that would really make it stand out. You decided you’d volunteer your time to make this web application even better. I bet you thought that beautiful execution was the result of beautiful code. Oh how naive you were..

Alphabet Soup

The moment you opened up that first file you were shocked to see code that could only be described as alphabet soup. There was so much going on that your brain clicked off for a moment. As your brain overloaded and your eyes glazed over, you revisited a simpler time when clients loved flash websites, frames were the bees knees, and no one had heard of AJAX. Your mind wandered to IE5 for mac and you immediately snapped out of your daze. You committed yourself to the project so you took a sip of coffee and dove in.

Web 2.0

You peruse over the script files. There are 17 different external script with names like ‘makeMySiteWeb2.0.js’ and ‘cornify.js’. You think about the trend of the day – Web 2.0. You think about how developers are head over heals for javascript. They think progressive enhancement is overrated and don’t understand the semantic value of HTML. You start paging though the stylesheets only to find them riddled with browser hacks and !important rules, making them utterly incomprehensible.

AFK

Exhausted and overwhelmed, you take a break, make a nice dinner, and think about how your dinner looks a lot like the code you were trying to understand. Heck, you know you’re no master chef, and your not proud of it, but you are a proud developer. You start to get angry, you consider this code to be an insult to the business. This anger quickly resides as you bite into your charred chicken parmesan and realize that this spaghetti code was not the developer’s fault. A disheartening calm consumes you. You start to see his perspective. You see that this developer was doomed from the start. You begin to visualize his scenario:

His Story

This developer wanted a high-quality web application. He started getting really excited about it; had a hard time sleeping – missed all his classes that week. He pounded out 80% of the web application after two all-nighters. He felt this high from his accomplishment. “This is my mona lisa”, he thought. His code is clear and elegant and his application is beautiful and responsive.

Browser Problems

The next day he goes to test his code in IE 7. He opens up the web application. He starts playing around with the UI and his application breaks down. “Why isn’t my canvas working in IE?”, “My videos aren’t working at all!” This developer has heard all about HTML 5 and wanted to take advantage of it in his brand new application. As he researches the problem, he sinks into his chair when he realizes that none of these features are available in IE 7 and most of them aren’t even available in IE 8. He starts googling workarounds and discovers a few fixes, so he adds them to the page. A few hacks later, his application is good to go in IE7. That must be everything he thinks.

Quirksmode

He goes to test his application in IE6. His jaw drops – his page is in complete disarray. His floats are all over the place, his transparent PNG’s look like garbage. He learns that transparent PNGs do not work in IE6, he reads about IE6’s float bug and broken box model. He adds some more hacks – a filter hack to fix his PNGs and some obscure CSS code to fix his floats, and a jibberish doctype to get the box model to cooperate. At this point he is drained – he hates that he knows all about quirkmode and that his code is a sloppy mess. Browser incompatibilities ruined his pure code. This young, ambitious developer who got into development because he loved building and sharing beautiful things, got thrown to the waste side by a throng of inconsistencies and poor standardization. He refuses to test his mobile device.

No longer fun

This developer loses interest in his web application and begins aimlessly throwing code at these inconsistence to get a fragile, working copy. He doesn’t care about future development because he can’t see himself ever wanting to deal with this mess again. His once slim and elegant code now suffers from so much bloat that future development is unlikely.

Current Alternatives

He passes his code onto the first developer that will take it on. You snap out of your daydream to realize that this developer is you. You come to the conclusion that web development has just become too complex. You realize that is has become literally impossible for a single developer or even a small team of developers to create anything great that works on all platforms, while keeping their code clean, fast, and maintainable. You look into the attempts made by the bigger companies. You think of Google’s GWT, a web application compiler that takes the web development out of web applications. With GWT, one writes Java, which then gets rendered into the appropriate HTML, Javascript, and CSS. You remember giving GWT an honest shot one night but quickly discarded the framework because the learning curve was just too steep. You discover the promising Cappuccino Web Framework, something that excites you about the future of the web. You check out 280slides and are blown away. You watch a screencast on Atlas and freak out. You think, “this is how web applications should be.” You see that these applications are built on Objective-J, a web version of Objective-C.  You know that Apple uses Objective-C for their products and remember that you tried learning it twice but failed because its just too different and too tough to learn for your average web programmer. You turn to open source javascript alternatives – you see that the current answer to any web question is to throw more jQuery at it. You wonder if jQuery developers are trying to eliminate CSS and HTML completely. You head down this path for a while adding scripts. None of your webpage shows up until all the javascript is parsed and rendered. You turn off javascript and see your website crumble. You read about the history of HTML, CSS, and javascript and why it was separated in the first place.

Talent Wasted

At this point you’ve given up. You think about choosing another profession. Your mother wanted you to be a doctor – maybe that’ll be a less frustrating career choice. You start taking biology classes in hopes that you’ll force your interests to change. You feel like a salmon fighting its way upstream against the current because you have absolutely no passion for what you’re studying. Your mind drifts off – you think about how the world will never see your incredible talent.

To Be Continued…

]]>
https://mattmueller.me/blog/a-tragic-tale-of-web-development-today/feed 3
PHPUnit Testing in the Browser https://mattmueller.me/blog/phpunit-test-report-unit-testing-in-the-browser?utm_source=rss&utm_medium=rss&utm_campaign=phpunit-test-report-unit-testing-in-the-browser https://mattmueller.me/blog/phpunit-test-report-unit-testing-in-the-browser#comments Mon, 28 Jun 2010 09:40:52 +0000 Matt Mueller https://mattmueller.me/blog/?p=514

PHPUnit Test Report

Introduction

Over the last couple weeks, I’ve been learning PHPUnit. PHPUnit is a unit testing framework for PHP, based on the JUnit framework for JAVA. It was created by Sebastian Bergmann. I’ll be the first to say that it is a wonderful library and it greatly simplifies Unit Testing in PHP. That being said, PHPUnit is not pretty. You mainly interact with it through the terminal. Now, I like pretty things. The web is pretty. Web development is pretty (with Textmate at least). Why can’t unit testing be pretty? A few days ago, I set out to resolve this issue.

PHPUnit Test Report

PHPUnit Test Report is designed to make unit testing fun. It discovers all files in your test folder that have the suffix “TestCase.php”. From there it loads and runs any classes within those files that have the suffix “TestCase”. Following standard PHPUnit procedures, it will run all methods that has the prefix “test”. For the case above, it is loading the class “TagTestCase” (from file TagTestCase.php). It will then proceed to run through all its methods that have “test” in front of them – so it runs testStylesheet, testScript, testRemoveScript, etc.


The result colors represent the following:
  • Red – Failed (or error)
  • Green – Pass
  • Yellow – Skipped
  • Grey – Incomplete

Let’s learn about some of PHPUnit Test Report’s features.

Sandbox that PHP

PHPUnit Test Report sandboxes your PHP. If you have an error in your code, the report will give you information about the error.

Talk to me PHPUnit

One of the most frustrating aspects of Unit Testing with PHPUnit was that I was unable to print variables within the tests to help me debug my application. PHPUnit Test Report handles this nicely:

Link PHPUnit Test Report to your Tests

I made it really easy to start using PHPUnit Test Report immediately. You can either go to PHPUnit Test Report’s index in the browser and add the path to your tests:

https://localhost/PHPUnit-Test-Report/?path=PATH_TO_TEST_FILES

Or you can add an index in your tests directory (tests/index.php) and include PHPUnit Test Report’s index:

include '../../PHPUnit-Test-Report/index.php';

Start using PHPUnit Test Report today

Excited yet? I’m releasing PHPUnit Test Report today. PHPUnit 3.4.13 comes with the report. It should be self-contained, but let me know if you have any issues. As far as the continual development of this project, I started learning PHPUnit about a week ago, so I have a lot to learn about it. As I learn more and continue to test my applications, I’ll add more stuff. I’ll try to help as best I can with issues you run into but, I can’t guarantee that I’ll be able to help. Feel free to get under the hood and hack something up. It’s pretty basic code.

Download PHPUnit Test Report

Click the link below to go to PHPUnit Test Report’s project page on GitHub.

PHPUnit Test Report Project Page

Your Turn.

The project is now hosted on GitHub. I’d love to see any contributions on your part – someone with some real PHPUnit experience could really do some damage with this application! Happy testing!

]]>
https://mattmueller.me/blog/phpunit-test-report-unit-testing-in-the-browser/feed 20
A Fijian Adventure https://mattmueller.me/blog/a-fijian-adventure?utm_source=rss&utm_medium=rss&utm_campaign=a-fijian-adventure https://mattmueller.me/blog/a-fijian-adventure#comments Tue, 23 Feb 2010 05:00:14 +0000 Matt Mueller https://mattmueller.me/blog/?p=473

Middle Seat Adventure

      Last week I visited Fiji on my way over to study abroad in Australia. Booked as an “extended layover”, I had five days and few plans. I landed in Nadi, Fiji at 5:15am, woke my leg up, and straightened out the kink in my neck from the two-hour daze called “middle-seat airplane sleep”. My journey started two days earlier, where I finished shoveling two feet of February snow.  “This is it!”, I thought as I stepped out of the plane to the Pacific Paradise. Going to Fiji has been this mysterious fantasy of mine since I was a child after first hearing about it from my dad whose friends sailed around the world, spending a summer in Fiji.

Bula!

      “Bula!” a Fijian woman exclaimed as she greeted me and my new friend, Phil. Bula is how Fijians say “hello”. Bula was a word we would soon be all too familiar with. We walked into the damp airport tired, but excited. After getting ushered through customs, then baggage claim, then more customs, we were set to leave the airport and take a bus to the marina. We booked our first two nights at Bounty Island and took a ferry to get there. The ferry hopped from big island, to tiny island, from fat island to thin island. We heard “Bounty Island” over the loudspeaker, and gazed at this tiny island that had an inner layer of lush green “bush”, an outer layer of light yellow sand, and was surrounded by baby blue water.

Bounty Island

      As we pulled up to Bounty Island, we were greeted with guitar music from the locals as they welcomed us to the island. We set foot on the soft but burning sand. Bounty is where we would live for the next two days. We unpacked in a 32 bunk-bedded dorm that reminded me of the old boarding schools you see in the movies. We met our Irish roommates, unpacked, and set out for the beach. For the next couple hours, I laid out to transform my Wisconsin February skin to Wisconsin July skin. Afterwards, I decided to cool off with some snorkeling. I picked up my free snorkeling gear and set out for the reef. The beauty of the reef was stunning. There were blue fish, yellow fish, red fish, purple fish, black fish, white fish, rainbow fish. I was dropped into the audience of an underwater symphony. **cough**hack**cough** — the symphony was interrupted by heaving as salt water penetrated my snorkel. I reemerged to empty out my snorkel, then dove back in. I watch angelfish feeding on the coral, clownfish peaking out from the sea anemone, and schools of bluefish swaying with the tide. “Ow ow ow!” foot cramp from my flippers being too tight. My first snorkeling experience in Fiji will forever be associated with utter elegance and extreme discomfort.

      In the evening we dined with a Scottish couple who met while living in New Zealand. We talked about traveling, slang, Valentines Day, and ripping off Chucky Cheese.

      After dinner we listened to the natives sing and socialized. I tried Cava, a Fijian specialty drink made from some root that makes you sleepy and your tongue numb. There, I met two British girls who spent a month in Thailand, a week in Indonesia, and a few months in Australia. We talked about American entertainment, imitated the American girl accent, and compared the taste of a shot versus the taste of Cava (They liked shots better than Cava, I thought the Cava taste better than shots). We said goodnight around 2:30, and I gazed at the stars on the beach before bed.

      The following day Phil and I met Patricio, a native who works at the resort, who had a tattoo of a volleyball on his back and laughed like a hyena. He told us stories of his “sexcapades” with guests. He also tried to convince us that cheating is not really cheating until you have a ring on.

      Bounty is the place to transform your skin from a winter white to a burnt leathery red. Bounty is the place to snorkel with a shark. Bounty is the place to learn that a leaflet is the British word for pamphlet.

Manta Ray

      From Bounty Island, Phil and I took a three-hour boat ride up the Yasawa Islands to Manta Ray Resort, where we would spend the next two days. Manta Ray Resort was brushed along this large, mountainous island. Manta Ray was bustling with activity. People were lying in the sun, reading in hammocks, making bracelets, scuba diving and snorkeling. Since I was shedding my first layer of skin, I decided to spend the day in the shade, reading Fooled by Randomness in a hammock.

      Later that night, we dined with five Brits. On my right, I sat next to a balding bartender who works at a hostel in New Zealand and his stunning blonde girlfriend. He kept us laughing all night with animal impressions, fake stories, and jokes about how he ended up with his girlfriend. On my left, I sat next to a traveling poker journalist who went to Vegas once a year for “work”. He was a human encyclopedia – he knew more about American football than I did. I sat across from two lovely Indian women. They were twenty-seven. They have been best friends from high school. They recently quit their jobs to travel. I was absolutely delighted to hear Indian women speaking with a British accent. The dinner was the highlight of Fiji- the conversation was interesting and easy. We talked about politics, traveling, movies, the Queen, curry, and bulldogs. We spent the evening together and headed to bed around midnight.

      The next day I snorkeled, played volleyball, hiked to the highest point on the island, met a German florist, and talked with “the oldest people on the island” – a Canadian investment banker who fled Vancouver to avoid the winter games and a Marine Biology professor from Florida who was on sabbatical.

      Manta Ray is the place to dance with a gay guy to tribal music. Manta Ray is the place to fall asleep in a hammock. Manta Ray is the place where strangers become friends.

Smuggler’s Cove

      After five hours of traveling we arrived at Smuggler’s Cove back on the mainland in Nadi, where we would spend one more evening in Fiji before catching a 9am plane to Sydney. We ate pizza, watched a fire and dance show, and slept in a dorm room where the beds were a little too close together.

Fiji

Fiji is the place where the U.S. dollar will get you farther than you ever imagined. Fiji is the place to find unmatched beauty. Fiji is the place to escape to..

]]>
https://mattmueller.me/blog/a-fijian-adventure/feed 1
Installing Thrift on Snow Leopard https://mattmueller.me/blog/installing-thrift-on-snow-leopard?utm_source=rss&utm_medium=rss&utm_campaign=installing-thrift-on-snow-leopard https://mattmueller.me/blog/installing-thrift-on-snow-leopard#comments Fri, 15 Jan 2010 00:46:19 +0000 Matt Mueller https://mattmueller.me/blog/?p=211

Introduction

Yesterday I spent the day with Thrift. Thrift is a framework developed at Facebook for “gluing” together programming languages. The Thrift framework enables efficient and scalable communication between C++, Java, Python, PHP, XSD, Ruby, C#, Perl, Objective C, Erlang, Smalltalk, OCaml, and Haskell. Thrift allows you to chose the right programming language for the job at hand. With Thrift you won’t have to chose between development speed and performance – you can have your cake and eat it too. If you are an employer, you can relax language restraints and focus on finding the smartest people. Thrift is still very much in its infancy, and documentation on getting it to work is sparse. I hope to shed some light on Thrift and make it just a little bit easier to get up and running. This post will focus on installing Thrift. I will write a follow-up post on how to use Thrift to communicate between PHP and C++.

Why Thrift?

If Thrift is still very new and lacks documentation – why bother learning it? Especially when there are more mature alternatives like Google’s Protocol Buffer and SOAP. The answer depends on your requirements. I write web-based financial applications. I use PHP as my server-side scripting language, and C++ for the heavy-lifting. As of this writing, Protocol Buffer does not support PHP, and the SOAP protocol has too much overhead for the high-speed finance world. Furthermore, I think Thrift has more potential than both alternatives and will gain in popularity as more people learn it. Also apparently Thrift was developed by Google engineers working at Facebook who missed using Protocol Buffer, so they re-built it and expanded its feature set. You can find more information on the differences between Thrift and Protocol Buffer at: https://stuartsierra.com/2008/07/10/thrift-vs-protocol-buffers.

Installation

I will be first to say that installing Thrift was a pain. I spent about four hours getting everything to work. However, most of this time was spent finding up-to-date information. I hope to get you up in running in less than an hour. This tutorial is aimed for Snow Leopard users, but I’m sure it would apply to Leopard developers as well. I am assuming you have Xcode installed. I will also say that I am not a Unix expert – this build worked for me – I am not entirely sure about the current state of my computer (ie. what dependencies I installed in the past), but I will try to make this tutorial as generic as possible. First we’ll need to install a few dependencies before we can start installing Thrift. Update: Do not try and install these dependencies or thrift using macports. There are some inconsistencies with the macport builds. (Thanks Jonathan!)

Installing Boost

Boost is a set of C++ libraries that Thrift depends on. You can download it at: https://www.boost.org/users/download/. I downloaded Version 1.41.0. Once it’s downloaded, you’ll need to unzip it. For this I just use The Unarchiver, but using the gzip terminal command works too.
Now we’ll use the information provided with the install to build Boost, you can find that information by navigating to the unzipped boost directory and going to: index.html > “Getting Started Guide” > “Getting Started on Unix variants (e.g. Linux, Mac OS)” > “5.1 Easy Build and Install” The steps described in the documentation are as follows:

sudo ./bootstrap.sh
sudo ./bjam install

The install will take a while! This is a good time to take a break from your computer – grab a coffee, do some push-ups. Once Thrift is all set up you’ll have plenty of time to soak up the LCD rays… back with a sweat? Great! Well, that should do it. You should find evidence of boost in: /usr/local/include/ and /usr/local/lib/.

Installing libevent

The next dependency we’ll need is libevent. Libevent is an over-the-network event notification API. Now that’s a mouthful.. I’m pretty sure Thrift uses it to do client / server communication between the programming languages. The good news is you won’t have any time to exercise – this is a quick build. Download libevent from: https://monkey.org/~provos/libevent/. I downloaded libevent-1.4.13-stable.tar.gz. Navigate to where you downloaded it, unzip it, cd into the unzipped directory, the run the following commands:

./configure
make
sudo make install

I’m not entirely sure where the build ends up, but Thrift will yell at you if something went wrong so let’s move on.

Installing Thrift

Alright! We’re so close. Let’s install thrift. You can download thrift from https://incubator.apache.org/thrift/download/. I downloaded thrift-incubating-0.2.0.tar.gz. After it finishes downloading, unzip it, navigate into the directory and run the following commands:

./bootstrap.sh
./configure --with-boost=/usr/local/include/
make
sudo make install

And you’re done! You will find the thrift build in /usr/local/bin You should be able to run thrift from the terminal.

Conclusion

Now that wasn’t too bad! If you have any problems with building anything do not hesitate to ask – I will do my best to answer your questions. Stay tuned for the next article on how to establish communication between PHP and C++ using Thrift!

]]>
https://mattmueller.me/blog/installing-thrift-on-snow-leopard/feed 9
An Introduction to jQuery: Projects https://mattmueller.me/blog/an-introduction-to-jquery-projects?utm_source=rss&utm_medium=rss&utm_campaign=an-introduction-to-jquery-projects https://mattmueller.me/blog/an-introduction-to-jquery-projects#comments Fri, 11 Dec 2009 08:11:02 +0000 Matt Mueller https://mattmueller.me/blog/?p=181

I designed and now teach this class for Software Training for Students on campus. Here’s a virtual version of the class!

What is jQuery?

Straight from jQuery.com: jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.

Why use a Javascript Library?

  • Libraries make writing Javascript much easier.
  • Everybody uses a library now- It’s part of the evolution of web technology
  • Cross-browser compatibility
  • Modularity - does not break existing javascript

Alright then.. well why jQuery?

  • Easy to extend
  • Thriving developer community
  • Small (Core + UI = 254kb – without gzip)
  • Absolutely elegant

Topics

Today I will focus on learning jQuery by example. We will cover:

  • Selectors
  • Chaining
  • Events
  • Creating a slideshow with plugins
  • Drag and Drop Shopping Cart
  • AJAX

To follow along – Go to the demo page:

Selectors

Selectors lie at the core of every jQuery call. They are used to grab elements on the page. We need to grab an element before we tell it what to do. Selectors are very simple to use in jQuery. If you know how to select an element in CSS (#header {…}), then you know how to select something in jQuery. Here’s how the syntax looks:$('selector')Much more to come!

]]>
https://mattmueller.me/blog/an-introduction-to-jquery-projects/feed 0
Lessons Learned from Threadless https://mattmueller.me/blog/the-threadless-business-model?utm_source=rss&utm_medium=rss&utm_campaign=the-threadless-business-model https://mattmueller.me/blog/the-threadless-business-model#comments Sun, 06 Dec 2009 23:12:21 +0000 Matt Mueller https://mattmueller.me/blog/?p=72

I wrote this paper for my Operation Technology Management class. Enjoy!

Introduction

Threadless is a community-based online retail store. Found at Threadless.com, they are headquartered in Chicago, Illinois. Threadless is best known for their creative t-shirts and unique business model, but they also sell posters and other various merchandise. Threadless manufactures beautiful and unique prints without hiring in-house designers or contracting a design firm. They closely match supply with demand and keep inventory levels near zero. How does a company accomplish this? They leverage the power of their online community. Here is how it works: thousands of artists submit their designs to the website. The online community will then vote each week on the submitted designs, rating them on a scale from one to ten and then selecting whether or not they would buy this design as either a t-shirt or a poster print. The most popular design will be selected to be manufactured. The winning designer will be awarded $2000 and more importantly endless recognition in the community. Threadless will then use the information it acquires during the voting process, such as how many people will buy the print to determine how many t-shirts and posters to manufacture. Threadless uses “crowdsourcing”, or open decisions-making and task-allocation, to control their inventory, make inventory ordering decisions, and minimize inventory costs.

Inventory Control

Threadless employs an unconventional method to determine when to order and how much to order. Traditionally, these decisions are left to business managers who conduct market research to estimate these values. Threadless finalizes the winning design at the end of each week. This is when they will invite the winner to their headquarters to celebrate the design and prepare it for manufacturing. The fixed time frame of once a week works very well for Threadless as it fosters transparency and keeps the community involved. There is no confusion about when the voting ends because it is the same each week. Many members of the community will often visit Threadless to find out what the winning design is each week and congratulate the winner. Threadless is also untraditionally reasonable about how many prints they order. They simply ask the community – “Well how many should we make?” This seems to make perfect sense but is often an unrealistic question for many traditional businesses. This model works for Threadless because they have a thriving community and a voting system that measures public opinion about each design. The Threadless business model leverages the community to make better decisions about the order date and quantity.

Cost of Inventory

Threadless uses their community to minimize inventory costs and optimize the inventory trade-offs between fixed-order costs, holding cost, shortage costs, and purchase costs:
  • Fixed Order Costs: Since storing data is so cheap, the managerial and clerical costs associated with filling orders is minimal. They use their servers to track orders, calculate design winners and store demanded quantities. They do incur costs in maintaining the databases and website. Such costs include having technicians and programmers on staff as well as electrical costs from powering the servers.
  • Holding Costs: Threadless has a warehouse to store manufactured merchandise. Their warehouse is located on the outskirts of Chicago, where the building costs are smaller. This cost is minimized further because they maintain a relatively small warehouse since they are able to keep their inventory levels close to zero because they let the community decide on how much merchandise to make.
  • Purchase Costs:Threadless uses the internet to achieve next-to-zero material transportation costs. They also use generic printers to manufacture their t-shirts and posters so the cost of changing products is minimal. They do need to purchase ink for the printers. Also Threadless incurs a cost to “reward”, or rather purchase distribution rights from the winning designer. Furthermore, there is a cost associated with preparing the design for manufacturing. They also fly the winner to their headquarters, which is a significant cost of manufacturing the prints. Due to the relatively small costs associated with purchasing and manufacturing the print, Threadless is able to manufacture many small lots of product.
  • Shortage Costs: Threadless tries hard to match supply with demand in order to manufacture the perfect amount of merchandise, but they often under-estimate how many people want the shirt. They will lose out on some sales when they sell-out of a product. However, if enough people demand the sold-out product they will re-print the product. If the shirt is re-printed, Threadless will award the artist an additional $500, because his or her design is so popular. Re-printing a design is less costly for Threadless than printing a new design because they do not have to fly in the designer, prepare the design for manufacturing, or repurchase the rights to distribute the design.

Concluding Remarks

I believe the Threadless inventory policy is a model for companies interested in lowering inventory costs. They use the internet to achieve efficiencies that were not previously available to traditional companies, and use their community to make decisions that business managers would previously have to estimate. Nonetheless, Threadless does not have the perfect inventory policy. One improvement they could make would be to better account for shortages. They certainly know how much to produce for the people that voted. But for the casual shoppers, they will not be included in the quantity produced. Also as they could improve their manufacturing process so that the design you vote on is exactly what you will get on a t-shirt. Often times there are limitations involved that cause the design to not perfectly match the end result. As they improve the transformation, they could offer an option that would automatically purchase the winning design for you if you checked the box saying you will purchase this print. The Threadless business model is unique and profitable. They use their community to accurately control their inventory, make inventory decisions and minimize costs. As more companies flock to the internet and as we discover that advertising revenue can no longer sustain an internet company, I believe many energetic upstarts will follow the Threadless way.

]]>
https://mattmueller.me/blog/the-threadless-business-model/feed 0
Searching Images by Color https://mattmueller.me/blog/creating-piximilar-image-search-by-color?utm_source=rss&utm_medium=rss&utm_campaign=creating-piximilar-image-search-by-color https://mattmueller.me/blog/creating-piximilar-image-search-by-color#comments Mon, 30 Nov 2009 02:34:24 +0000 Matt Mueller https://mattmueller.me/blog/?p=46

The following is the final project for my Computational Photography class.

piximilar

Abstract

Piximilar: Image by Color is a project based on the work of Idée Labs, where you search for images by color rather than by text. Piximilar offers a unique experience that allows web designers to define the color scheme on the drawing board and write the cascading style sheet (CSS) before picking out the images. Piximilar leverages Flickr’s vast free photo archive picking out only the images that Flickr deems “interesting”. Piximilar analyzes these pictures using an in-house algorithm that maps each pixel to color palette options, allowing pictures to be retrieved based on their color contents. The processing is abstracted away from the user and built behind a beautiful user interface, which is user-friendly, scalable, and fast.

Introduction

One of the most important aspects of designing a website is finding the right images. Piximilar offers an innovative approach to finding these perfect images, allowing one to search through thousands of interesting images by clicking on a desired color. Piximilar can even combine up to four colors, providing designers with a new opportunity of finding interesting images that will match their website’s theme. Piximilar also adheres to businesses that rely on color combinations for branding purposes. Furthermore, unlike Google Image Search, Piximilar will only search through images with non-restrictive licenses – that is free to use, free to modify, free to profit from. As we will see, Piximilar is a very handy tool that every web developer and graphic designer should be equipped with.

Motivation

My main motivation for taking on this problem came after I saw the work of Idée Labs and how they addressed this problem. I found their tool extremely useful and innovative. This cool web application coupled with my aspirations to be a profession web developer were the main motivating factors for me to build my own web application that finds images by color.

Problem

The underlying problem that I will address in this paper is how to do you find images that are similar, not according to the text around them, but by the colors these images contain. I will go through the three main steps needed to solve this problem- how to find images to index and analyze, how to derive meaning and find similarities from images without a textual context, and how to wrap these results in an interface that makes it useful for everyone.

Related Work

This project is based off the work of Idée Labs. Idée Labs created the Multicolr Search Lab, which extracts the colors from over 10 million of the “most interesting” free photos on Flickr and allows you to search through the images by color. The picture below shows the interface they designed to leverage their visual similarity technology:
ideeAs you can see, you click on colors in the swatch palette to select the colors. In this case, I clicked on a green, yellow, red, and purple. The results represent interesting images that have the largest sampling of our selected colors from their ten million image database. Another company that has implemented searching images by color is Google. This feature is very new– in fact, they updated their Image Search to include this feature while I was working on this project. Google implements a search by color differently from Idée Labs. They offer the feature more as an additional filter for a textual search. So typically you would search for a word, say “bird” and then select a color, say “red”, to find only birds that are red. The picture below represents the results of this query:
google_imageGoogle operates on a much larger scale, analyzing billions of images indexed from the web. A “Find Image by Color” option is better as a filter for a text search in this case because their database is so vast that it would be nearly impossible to find interesting images given a set of colors.

Theory

The theories and assumptions I made going into the project were invaluable in producing the final product. I assumed that there would be a way of mining Flickr for free images that were also interesting to look at. This was a big assumption, but after looking at the Multicolr Search tool, I knew it had to be possible. The theory was that I would design a palette of colors or options for the user to choose from. Now these options were just a small subset of the possible RGB colors, but provided a good sampling of the entire set. Next I needed to go through each pixel of each image and map it to one of the colors in the color palette. I assumed that PHP, the scripting language I was using, would be capable of extracting RGB values from images and would be powerful enough to do this mapping. Next I needed a place to store these mappings, so that they could be leveraged in a web application. I assumed that MySQL would be a capable of storing over 20 million entries. I also assumed that MySQL would be able to perform calculations on these entries quickly in order to keep the interface interactive for the user. The theory was that since MySQL uses powerful set theory algorithms, it would be able to sort and multiply a vast number of rows very quickly, which was crucial for my project to function correctly. Furthermore if MySQL was capable of doing the heavy lifting, I assumed that the PHP script that is responsible for sending updates to the web application would run swiftly. My final theory was that if I obtained over 100,000 images, my application would have enough pictures to choose from that selecting images by color would work effectively.

Method

This section will be divided into the three crucial steps required for this project: Getting the images from Flickr, analyzes the images, and displaying the results. The first step involved mining Flickr for images. Luckily, Flickr provides a way of doing this, by directing your code to interact with their API*. Flickr’s API provides a method called flickr.interestingness.getList, which returns a list of interesting photos for the most recent day or a user-specified date. This method has some options including the date, how many items per page, and which page number. I designed my script to grab the XML generated from the API using URL:
https://api.flickr.com/services/rest/?method=flickr.interestingness.getList&api_key=API_KEY&date=DATE&per_page=500&page=1The API_KEY is the key every Flickr developer has to apply for, and DATE is the date I specified. One of the limitations of the Flickr API is that you can only retrieve a maximum of 500 images per page for a specified date. I needed more than just 500 images— I needed thousands of images. The work-around was to write a script that would go through each date and grab the XML the API generated. So I wrote a script that went through January 1st 2004 to March 1st 2009 and grabbed the XML from 500 of the interesting photos on each of those dates. Since this approach can lead to a lot of unexpected results- I tested my script extensively to ensure that it could handle anomalies such as days that do not have 500 interesting images as well as when the script tries to access the XML from a day that does not exist (ie. February 30th). Getting the XML for each day is only the first step in acquiring the images. The XML allows you to generate a URL that directly links to the image. So for each day, after I generated the XML, the script would generate this URL and then save the image to the desktop. The XML generated looked like this:<photos page=”1″ pages=”5″ perpage=”100″ total=”500″> <photo owner=”9137439@N08″ secret=”ea5fa34246″ server=”3550″ farm=”4″ title=”Poolside Reflections” ispublic=”1″ isfriend=”0″ isfamily=”0″ />. I then used an XML parser to obtain each photo’s farm number, server number, id, and secret code. I plugged in the values into this URL:https://farmfarm.static.flickr.com/server/id_secret_s.jpg
To obtain:
https://farm4.static.flickr.com/3550/3493249123_ea5fa34246_s.jpg
. This URL provides a direct link to the image, so that it can be downloaded. Note the _s, right at the end of the URL. This tells Flickr to give back the small version of the photo, namely a 75 by 75 pixel image. This was crucial in saving space and speeding up the image analysis. Using this method, I downloaded 177,181 images to my computer, taking up a total of 1.3 Gb. The process took two full days to finish. Once the images were saved into a folder, I was ready to analyze these images. The next step involves mapping each pixel of each image to a color in the color palette. I tried a few equal interval methods, to space out the colors evenly (ie. RGB(0,0,0), RGB(10,0,0), RGB(0,10,0), etc.), but the colors were very dull and uninteresting. I decided to map the colors to the palette used at Idée Labs. To do this, I first needed the RGB values of each of the colors in the palettes. I started to put each of these colors in a PHP array by hand using Photoshop’s Color Picker on the image, but this quickly became tedious over all 120 color options. Since the color palette was arranged in a grid format, I wrote a script that incrementally moved through an image of the palette, and found the RGB values of each color, and put them in an array automatically. Now that I had the RGB values in an array, I was ready to write a function that would map the pixels in my images to colors in the color palette. The resulting equation was:This was computed for each element in the RGB palette array, and the minimum was deemed the appropriate mapping. All in all, I simply found the minimum distance from the given pixel and a RGB pixel in the color palette. To find the RGB values of a given pixel, I used a PHP add-on feature called GD Library 2.0. This allowed me to use the built-in function imageColorAt(x, y), which returned an associative array of RGB values at a given x, y location in the image. Now that we know how to map the pixels of one image to the pixels of the palette, we need a place to save this information. I made a database that had 122 columns, one for a unique ID, one for the name or the way of referencing the image, and the other 120 columns were for each of the colors in the color palette. I wrote a PHP script to generate the necessary SQL to create these columns.  Once I had the database set up, I was ready to save the information from the mappings. As we went through each pixel of each image, the pixel would be mapped to a pixel in the color palette. At this point the column that corresponds to that color in the SQL database would be incremented. So images with a large amount of a certain color would all be mapped to the same color in the color palette, resulting in a large value in that color column in the SQL database. This is how you determine which images are rich with certain colors. The picture below illustrates the process:piximilar implementationThe above example suggests that 3 pixels have so far been mapped to RGB value 124, 44, 89. We will continue this process until all 5,625 (75 x 75) pixels of each of the 177,181 images have been analyzed and saved to the database. This pre-processing algorithm took about three full days to run, but was essential to keep our web application fast and scalable. The final step was to build an interface that would query the database and display the results of the color selections. Much of this is standard to all web sites- I build an HTML skeleton, styled it with some CSS and made some images with Photoshop. I also used jQuery, a lightweight Javascript framework to make AJAX calls easier and add effects. Designing the interface was fairly straightforward. The crucial step was to build the backend to query the database. When a user clicks on an item in the color palette, AJAX sends the RGB information of that color to a PHP script for processing. The PHP script then generates a query that finds the images with the largest number of pixels with that color. An example query looks like this:SELECT * FROM `images` ORDER BY `images`.`124_44_89` DESC LIMIT 0 , 32 This query sorts the selected color column in descending order then returns the top 32 images with RGB color: 124, 44, 89. This allows for you to pick a single color, but what if you want to find images that contain two colors, or three colors? To find images with a combination of colors, I used the equation:Result_Column = First_Color_Column * Second_Color_ColumnBy multiplying two rows together, you promote images that have a combination of colors.  If you would like to combine more colors together, you simply continue multiplying columns together. Once you have the result column, you do exactly what was done before – return top 32 images in the sorted result column. The following is an example query that shows this process: SELECT 65_126_218, 199_34_5, name, (65_126_218*199_34_5) AS sum FROM images ORDER BY sum DESC LIMIT 0 , 32 (65_126_218*199_34_5) is the result column of multiplying the two color columns together.  Once the PHP retrieves the rows in the database, it generates HTML that will format each of the photos, points the image tags to the appropriate image directory, and sends the HTML to a Javascript file that will update the browser asynchronously. These are the main steps to solve this problem. The next section contains the results of my implementation.ResultsThe results clearly demonstrate selecting images by color. As you add more colors you get more specific, honing in on images that are perfect for your current website.

Concluding Remarks

The results turned out great, but there is still room for improvements. Perhaps the biggest improvement would be to automatically link each image to its location on Flickr. The best way of solving this problem is to save the owner information from the XML feed to the database, allowing you to generate images that link to the following:https://www.flickr.com/photos/owner/id Where both the id and the owner information are retrieved from the database. Another improvement would be to acquire more images. The Multicolr Search Lab has over 10 million images making their results much more impressive. The final improvement could target performance. The web application takes about two seconds to load the images after the user clicks on a color. If I were to organize the data in a clever way, perhaps by using a tree or graph, I might be able to squeeze some extra performance out of my application.  Despite these areas that need improvement, I took a complicated problem and broke it down into steps that were each solvable to create an innovative web application that allows users to search through images by color rather than by text.

References

  • Multicolr Search Lab: Flickr Set. Idée Labs. 2008. https://labs.ideeinc.com/multicolr/
  • Google Image Search. Google. 2009. https://images.google.com/
  • Flickr Interesting Photos. Yahoo. 2009. https://www.flickr.com/explore/interesting/
  • PHP Manual. PHP. 2009. https://www.php.net/
  • jQuery Documentation. jQuery. 2009. https://docs.jquery.com/Main_Page/

The Powerpoint

Update: I talked with my CS professor for the class and he helped me get Piximilar online – check it out: Demo

]]>
https://mattmueller.me/blog/creating-piximilar-image-search-by-color/feed 5