Here in the States, we typically think of gazpacho as a cold, tomato-based soup, usually a bit zingy thanks to the addition of garlic, onion and vinegar. Sometimes it's chunky, sometimes it's smooth, but it's pretty much always tomato-y.
In fact, traditional Spanish gazpacho is a creamy, lush soup made with soaked, stale bread, copious amounts of olive oil (hence the creamy lushness) and flavored with vegetables. Which isn't to say that our interpretation of the soup is wrong or bad; it's just that: an interpretation.
In his Simple to Spectacular cookbook, Jean-Georges Vongerichten spends several pages showing us how varied the interpretations of gazpacho have become. Tomato-melon gazpacho (a twist on the traditional inclusion of cucumber, which is, after all, a member of the melon family), a simple tomato-cucumber-red pepper incarnation, and the most unusual of the bunch: cucumber-coconut gazpacho.
Given my love of cucumbers, I supposed I shouldn't have been shocked by how delicious this soup was, but I admit it took me by surprise. I'd forgotten how rich and complex cooked cucumbers can be, and how delicious they are with fresh herbs, especially mint. And now that they're in glorious season, I'll be making this all the time. I might swap the mint out for some basil next time, and see how I go. Yum.
Cucumber and Coconut Gazpacho
Adapted from Simple to Spectacular by Jean-Georges Vongerichten and Mark Bittman
1 sweet or mild white onion, chopped
2 cloves garlic, chopped
2 large cucumbers (or four Kirbies), peeled, seeded and cut into 1-inch chunks
1 tbs. olive oil
1 1/2 cups chicken (or vegetable) stock
1 cup unsweetened coconut milk
3/4 cup mint leaves, whole
Tabasco, to taste
1 tbs. fish sauce
2 tbs. lime juice
Chopped mint (or cilantro, if you prefer) for garnishing the soup
Salt and freshly ground black pepper, to taste
In a large, straight-sided skillet, heat the olive oil over medium-high heat. Once the oil is hot, add the onion and garlic and saute until the onion is slightly softened and the garlic is fragrant. Add the cucumber and sprinkle with a teaspoon or so of salt and a bit of black pepper.
Saute the vegetables for five minutes, then add the stock and cook for five minutes more, until the cucumber starts to turn tender. Add the coconut milk and cook for three more minutes, then add the mint, Tabasco, limes juice and fish sauce.
Remove the soup from the heat and allow to cool slightly. Using an immersion blender, puree the soup until it is very smooth. (Alternately, you can transfer the soup to a blender to puree it; do this in batches, if need be.)
Chill the soup. (If you want to serve it shortly after making it, place the pureed soup in a medium bowl and nestle it in an ice bath - spike the water with a general handful of kosher salt to speed up the process. Stir the soup frequently to aid in cooling it.) Serve garnished with mint or cilantro.
Serves four to six, depending on how hungry you all are.
Sandusky, Ohio doesn't have a plethora of amazing restaurants (though there are some notable spots, no doubt) or a hopping nightlife, but you know what it does have? Seriously good produce. Louisa and I visited a number of different markets over the course of the week I spent there, and all yielded some good goodies.
At Louisa's perennial favorite, Kramer's Farm Market in Norwalk, we found delicious asparagus, which we promptly seasoned with olive oil, salt and pepper and grilled for dinner.
At the Sandusky farmers' market, held downtown on Fridays and Saturdays, we found sweet cherries, snappy green beans and gorgeous beefsteak tomatoes. We used the latter two in our salade Niçoise.Last, but not least, the North Union Farmers' Market in Crocker Park. We arrived a little late (prime time seems to be between nine and ten in the morning), but still managed to find some plum, juicy sugar snaps, along with some green onions for grilling.
I suppose I shouldn't be surprised; the Midwest is, after all, the bread basket of the States. The irony is, of course, that so much of what's produced there is consequently shipped off to the rest of us, or used in processed foods. These three markets, though, are doing their part to share the local bounty with, well, the locals - and that's a damn good thing.
Good morning, all! It's on its way to being another steamy day here in New York. I made my weekly pilgrimage to the Greenmarket this morning (Snap peas and cucumbers and beets - oh, my!), and am meeting up with my brother and our friend Ken for a lobster roll run this afternoon. In the meantime, though, it's time for some Treasury action!
First up this week, a quick trip to Paris for some serious cookware shopping. David Lebovitz, ex-pat and pastry cookbook author extraordinaire, posted a guide to shopping for supplies in that most culinarily obsessed of cities. He mentions, of course, the legendary E. Dehillerin, as well as the marches aux puces and some intriguing cookbook shops. Sigh. Yet another reason to get myself back to France sooner rather than later.
Next, a ridiculously delicious-looking brunch at Portland, Oregon's Simpatica. My friend Lorna posted this on her Cookbook Chronicles blog just yesterday, and it looks so. Freaking. Delicious. Smoked steak, grilled shrimp, fried eggs, potatoes and broccoli? Um, wow. Never mind the chicken and waffles. Or chicken fried bison. Drool.
Finally, a fabulous piece of art from Jane Mount, who documents people's ideal bookshelves as a form of portraiture. As a lifelong bookworm, I thoroughly approve. And, in fact, I bought a print of this piece, Ideal Bookshelf 6, GW, just yesterday. It's a portrait of George Weld, chef and owner of Egg, a restaurant in Brooklyn. And I can't wait for it to arrive so I can hang it on my ready and eager wall. Yay!
It was pretty darn warm - dare I say, hot - while I was in Ohio last week. The last thing we wanted to do was turn on the oven or use the stove too frequently. The solution, of course, was a composed salad. But not just any composed salad - oh, no. We decided to make an old favorite: Julia Child's salade Niçoise from Mastering the Art of French Cooking.
Chances are that at one point or another you've all had a version of the Niçoise salad, most likely at a restaurant, and possibly updated with, say, seared tuna. Chances also are that the version you had wasn't half as good as Julia's classic recipe. It's just a salad, sure, but she knows exactly how to make the very best of each and every ingredient.Green beans are blanched to bring out their sweetness while retaining their snap; farm-fresh eggs are hard-boiled, showing off their impossibly golden yolks; potatoes are boiled and soaked in wine, chicken stock, and vinaigrette while still warm; perfectly ripe tomatoes and simply sliced and sprinkled with salt and pepper. The whole kit and kaboodle is topped with an impossibly generous shower of chopped herbs. (We used a combination of chives, parsley, mint, tarragon and basil.)
The result is a meal for four that surpasses all of your typical salad expectations. It's a meal worthy of summer in the south of France, one that should absolutely be accompanied by a crisp rose (Give De Loach's superlative 2007 O.F.S. a go, why don't you?) and followed by a dessert of strawberries, eaten whole, warm from the sun.
I started my day today with reading my colleague's beautiful post what mindfood are we eating and it really made me think.
This is such a wonderful thought... what do we feed our mind with ? How many of us make conscious efforts to nurture our mind ? Hmm ... need to prepare healthy diet plan for our minds as well :-)
Sharing some good food of thoughts that I got from googling :-
1. Success is not the key to happiness. But happiness is the key to success.
2. You can tell whether a man is intelligent by his answers. But you can tell a man is wise by his questions.
3. Morning means one more inning given by the god to play.
4. Success is not a matter of being the best and winning the race, it is a matter of handling the worst and finishing the race. Be positive.
5. A honey bee visits 2 million flowers to collect 500 mg of honey. So our workload is nothing as compared to them. Be cheerful and keep working.
6. It is not that some people have will power and some do not. It is that some people are ready to change and others are not. Believe in yourself and change for betterment.
7. The world suffers a lot, not because of the violence of bad people, but because of the silence of good people.
There have been a lot of great summaries of what was discussed at last week's Enterprise 2.0 show in Boston. But for me, the most interesting topic was one that was not discussed: Culture. That's a big change. Right up...
I have worked with a couple of good companies. The managerial behavioral pattern that I have observed across these companies remains more or less the same. Yes... there are certainly few exceptions. I have many friends across different organizations, but to be frank, I have rarely seen people talking good about their managers. Why is this so ? Are the managers lacking the skills to effectively handle the people under them ? Or some other reason ? There is no straightforward answer to these questions, but can we improve this better ? I am not at manager level yet, but certainly I can suggest few tips which would improve this situation.
Tips for Managers :-
1. Consider people under you as people rather than only billable resources.
2. Do not let people under you to lose trust in you. It is very difficult to build back the trust again.
3. Give more importance to career progression of the people under you than billing.
4. Have faith in your people.
5. You do not have any right to play with or spoil the career of the people under you. Freshers are the best example of this. They are rarely asked about their career aspiration, rather they are asked to do things what the current situation demands.
6. Do not take people under you for granted.
7. Interact with your people regularly about their aspirations and make loyal efforts to fulfill those.
8. A little smile on your face makes a huge difference in the professional and personal lives of the people under you. The most important thing here is that it's absolutely free of cost.
9. Try to be a role model of the people under you.
10. Billing/Revenue is important. But people are more important as they sustain business with the client by their good work.
11. Micromanagement kills.
12. Try to be a thought leader than just to be a manager.
13. Do not lose your core values while dealing with the client.
Read a nice article in DNA today, and it got me thinking.
We make so much fuss about the food we eat, to ensure the right healthy food, fruits and salads, and our tastes and so on. It's essential to keep ourselves healthy, isnt it?
Do we take out time to see that we are feeding our mind with? What do we talk to people around us? What do we hear, and what do we read? What do we think when we are alone, and so on. Do we really put in efforts to ensure that things that we are putting in our mind are healthy :)
Talking /reading the positive things, and listening to those too, can really help us. And pushing off all those negative energies that might come to us from people around us, would definitely prove useful !
Good mindfood for me for today at least :)
I'm interested in analyzing and plotting Cricket data to discover interesting facts and relationships...
I'm looking for "raw" Cricket scorecard data for One-day internationals and Test matches only. Google didn't find anything useful this morning. So, I'm looking for advice and I'm happy to pay for it too. Any suggestions?
One of the Drupal based applications we manage received user feedback that performance was not meeting their expectations. Even though my background is primarily Rails and Java, I was excited to take up this challenge. Before I could really get down to business I needed a couple of tools for the job. This post is about creating those performance tools inspired by the following tips from The Pragmatic Programmer.
Tip 20 Keep Knowledge in Plain Text
There is a great module that a lot of Drupal developers use http://drupal.org/project/devel The module is great for development in that it shows the developer how many queries fire, how long they took, and if they are repeated queries. Drupal seems to be very chatty with the database and keeping this under control can really help with performance.
For this particular problem I was coming in after the development was complete and hoping to fine tune or refactor the existing code base. I wanted a logfile that could show me the queries fired per page, what the most expensive queries were, the functions that called those queries, and the ability to reproduce them in other environments (development, QA, and Production). Patrick Shaughnessy (http://patshaughnessy.net/) gave me some quick pointers on the Drupal framework allowing me to build an easy logfile strategy.
Step 1: Build a Switch for logging
I wanted to leave the logging code in place, but provide a mechanism to quickly turn the logging on and off. I did not want to store this in the variable table as I suspected most of the performance issues were database related. I resolved to create a simple global in global_settings.php
# Turn on performance tuning in the logfile
global $performance_logging;
$performance_logging = 0;
Step 2: Create a debug function
I put mine in index.php, but there is probably a better location for common methods:
function debug($s) {
global $performance_logging;
if ($performance_logging) {
$file = fopen("/tmp/performance.log", "a");
fwrite($file, $s . "\n");
fclose($file);
}
}
Step 3: Place instrumentation in the code to log performance
First lets log how long it takes to build the entire page. This can be done quickly by placing the following code in the index.php before the bootstrap include.
$then = microtime(true); # Mark the beginning of the page
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
Then again at the bottom of the page, with a call to our debug function to record the time.
$elapsed_time = microtime(true) - $then;
if ($performance_logging) {
debug(sprintf("%f ENDPAGE %s",$elapsed_time,$_GET['q']));
}
When this is shown in the logfile it will appear like this:
0.358291 ENDPAGE node/3
The time in seconds, a tag to say the page has ended, and the parameter that was used to build the page.
Step 4: Record the database performance metrics
In the database.mysql.inc file all database transactions will flow through this method. We can log how long these database calls took with a couple of pieces of code in the _db_query method around the call to mysql_query.
Add the following code to the _db_query function:
if ($performance_logging) { $then = microtime(true); }
$result = mysql_query($query, $active_db);
if ($performance_logging) {
$elapsed_time = microtime(true) - $then;
$bt = debug_backtrace();
debug(sprintf("%f -- %s -- %s",$elapsed_time, $bt[2]['function'], $query));
}
}
This will log the time in seconds, a tag to indicate the function called, and the query that was executed to the database.
Step 5: The Results
Now when a page is rendered we will get a log file like below:
0.000069 -- community_is_private -- select group_nid from og_ancestry where nid = 13430
0.000076 -- community_is_private -- select selective from og where nid = 13429
0.000599 -- taxonomy_get_vocabularies -- SELECT v.*, n.type FROM vocabulary v LEFT JOIN vocabulary_node_types n ON v.vid = n.vid ORDER BY v.weight, v.name
... A Lot more lines ...
0.000144 -- get_homepage -- SELECT * FROM og_home WHERE gid = 3
0.000448 -- statistics_exit -- UPDATE node_counter SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = 1275527799 WHERE nid = 3
0.000246 -- statistics_exit -- INSERT INTO accesslog (title, path, url, hostname, uid, sid, timer, timestamp) values('Spaces', 'node/3', '', '127.0.0.1', 14149, '983da4b0314d4dfca4c919acfcbbd33b', 346, 1275527799)
0.358291 ENDPAGE node/3
Column Breakdown:
Tip 21 Use the Power of Command Shells
This simple logfile is incredibly powerful for instrumenting the application to perform performance tuning with just a handful of Unix commands
How do I look at just the queries on one page?
cp /dev/null /tmp/performance.log
What are the most expensive queries on a page?
sort -rn /tmp/performance.log | head -5
How many queries were executed to build the page?
wc /tmp/performance.log
Tip 28 Learn a Text Manipulation Language
Now that there is a powerful flow of information, here are a couple more tools to figure out what is going on from a performance perspective:
Summary of application performance, right from the server!
- Use perl as a text parsing language from the command line and you can ascertain a lot of information. Perl is almost always installed on the server and is a powerful text manipulation tool. Here is one such use case:
perl -F"--" -lane 'if (/ENDPAGE/) {print "$F[1] $t";$t=0;next;} $t+=$F[0]' mckwiki_debug.txt
This will return something like this:
0.227044 ENDPAGE node/86 0.020057
2.461857 ENDPAGE node/3 2.128639
0.354404 ENDPAGE node/3 0.1329
0.295097 ENDPAGE og 0.03797
Breaking down the command:
Perl and Ruby both provide the capability to execute scripts directly from the command line. This can be quite powerful when trying to quickly analyze a problem. Of course if a repeatable solution is found, then the inline script should be converted into a file based script for reusing later. This is how this script above works.
perl # The script interpreter
-F"--" # this option indicates that for every line of text seen, split the line into an array delimited by "--"
-lane
# -e = Execute the next string passed as a script, for example perl -e 'print "hello world"'
# -n = Automatically loop through each line of a file (last argument)
# -a = Automatically parse each line of text into an array (using the -F argument above as a delim)
# -l = Automatically put a "\n" at the end of each line of output
I find that I am always using this four options, so I just remember -lane (nice easy phrase)
Create SQL performance scripts from the logfile:
Another handy tool is a list of all the SQL statements in an executable file to help identify performance in other environments:
I normally truncate the log file first before generating this script. This way I know the page I view has just the SQL statements for that page when I execute them on another server.
perl -F"--" -lane 'print $F[2] if $F[2]' mckwiki_debug.txt > performance_debug.sql
This will create a file with all the SQL statements for that page.
In the next article we will explore how these tools can be used to fine tune a Drupal application for performance.
We've been building up a REST API at work for a couple of months now, have an iPhone client, an Android client, and a browser-based client built on it, and are well on our way to using it for a number of other purposes. As far as client and API development are concerned, things are going pretty smoothly. So, when I read Michael Bleigh's article on how he thinks that building a pure REST API is too hard, and probably not worth the time, I was pretty surprised. I started wondering if maybe I'd misunderstood something, despite spending quite some time poring over Roy Fielding's dissertation and scads of other articles by a variety of authors. After some reflection, I've decided that I'm not missing anything, and it's a lot easier than people think to build a pure REST API, once you understand what one is, and have determined that REST is an appropriate architecture for your system.
There's a lot of information out there about REST, so naturally there's also a lot of inaccurate, incomplete, confusing, and misleading information out there. The key to learning about REST, as with everything else, is finding good sources of information. In my research, there were a handful of people who were instrumental in my understanding of the topic: Roy Fielding, Jim Webber, Ian Robinson, Mark Baker, Sam Ruby, Leonard Richardson, and Subbu Allamaraju. Specifically, the following are great sources of information on REST:
REST is a fairly broad topic to understand completely. Only after reading through the above sources, and then some, did I begin to fully grasp what it is, and why it's so important. Due to the contextualized nature of this article, I strongly suggest that you at least skim through the links above before continuing on here.
The most sparsely-documented aspect of REST in Roy Fielding's dissertation is the "hypermedia as the engine of application state" (HATEOAS) constraint; it's also the aspect of REST that has the fewest practical examples. It's no surprise, then, that HATEOAS is the part of REST most-often neglected or misinterpreted by API developers. There is one rather popular and ubiquitous hypertext-driven application out there to learn from, however: The World Wide Web.
The world-wide web is a great example of utilizing hypermedia; it's also a source of much confusion around the role of hypermedia in APIs. In his article, Michael Bleigh uses the same example that Fielding uses in a comment on his rant of how web browsers and spiders don't distinguish between an online-banking resource and a wiki resource, and only need to be aware of the "links and forms", and "what semantics/actions" are implied by traversing those links". Fielding uses the example as a way to illustrate how clients of REST services need only know about the standard media types used in a service response in order to make use of the service. The problem with this analogy is that browsers and spiders are extremely general consumers of hypermedia.
A web site can be thought of as a REST API, except the media types and link relations that are used are not structured enough to allow most applications to determine the meaning of individual links and forms. Instead, a web site typically relies on a human user to determine the semantics of the site from the natural language text, sounds, and visuals presented to them via HTML, Javascript, Flash, JPEGs, or any other standard data formats at the web site author's disposal. That's fine if you're building a system designed to be used by human beings, but if you're designing one to be consumed by other software, then your system and the systems that use it are going to have to agree on something up-front in order to play nicely.
It's an exciting, web-driven world we're building, and clients usually need to do quite a bit more than allow their users to browse or crawl the systems we build. The Twitter API, for example, has services that allow clients to update their status, or retweet one that already exists. Twitter's API is not RESTful, so the documentation for retweeting a status instructs developers to call the service by sending an HTTP POST or PUT request to http://api.twitter.com/1/statuses/retweet/[id].[format].
If the Twitter API were RESTful, clients would need to understand what it means to follow a link to retweet a status. The semantics of such a service are deeper than what Fielding talks about in his comment about browsers and crawlers. At the same time, I think that this deep level of understanding is a more common requirement for clients of web APIs. It's this need for clients to have deep semantic understanding of an API that has Michael Bleigh questioning whether it's even worth the effort to make an API like Twitter's hypertext-driven.
HATEOAS is not as difficult to adhere to as people think. If you've ever built an interactive website that includes links and forms in HTML pages it generates and returns to its users, then congratulations: You've conformed to HATEOAS! For an API to conform to HATEOAS, it must provide all valid operations, what they mean, and how to invoke them, in representations that it sends to clients. In order to provide this knowledge in-band, it must utilize standard media types and link relations. If the API can't use standard types and relations, then custom types must be defined. Regardless of what types and relations are used, the point is that clients should be bound to services they consume at a higher, more generalized level than a specific communication channel, URI pattern, and set of invocation rules. The only difference between building a web site and web API that conforms to HATEOAS is that the majority of media types and link relations that you'll need for a web site are already defined, whereas you'll most-likely need to define some of your own for an API.
Michael Bleigh states in his article that REST requires "too much work from the [service] provider in defining and supporting custom media types with complex modeled relationships", but defining media types and link relations for a REST API simply takes the place of other forms of documentation that would otherwise have to be produced. Subbu Allamaraju has a pretty good article on documenting RESTful applications. Among other things, he highlights how you no longer need to specify details on constructing requests to specific services within a REST API. The hypermedia constraint of REST requires that all possible requests be constructable at runtime, and provided by the API itself; clients must know how to interpret the hypermedia controls, but then are only responsible for interpreting the semantics of specific links and structural elements of the data format. This allows for greater flexibility on the service side to make changes, and greater resilience on the client side to those changes.
Michael states that it's too much work to define "complex modeled relationships", but defining link relations in a REST API's media type definitions is not any more complex than leaving those relationships undefined and requiring clients to figure them out on their own by poking around the documentation. The difference is just that the effort of figuring those relationships out and working with them in a consistent way gets shifted from the (single) service developer to the (multitude of) client developers. If links are provided, but relationship types are not defined or specified, clients must base their behavior on specific links, thus making it harder to change those links. As was stated earlier, having well-defined relationships also encourages consistency and sound design from the service developers, and improves the ease with which clients make sense of and build solutions against an API.
There are many short- and long-term benefits of HATEOAS. Many of the benefits that Roy Fielding talks about, such as supporting unanticipated use-cases, the ability of generalized clients to crawl a service, and reducing or eliminating coupling between a service and its clients, tend only to be fully realized after a service has been available to the public for a while. Craig McClanahan -- author of the Sun Cloud API -- suggested some short-term benefits of adhering to the HATEOAS constraint of REST. One of the benefits mentioned by McClanahan is the improved ability of a service to make changes without breaking clients. Subbu Allamaraju describes, in his previously-mentioned article, the simplification that REST lends to the documentation of services that are written within its constraints.
Another short-term benefit of HATEOAS is that it simplifies testing. I've worked on a number of projects where there was a QA team comprised of non-technical people, and my current project is no exception. The QA team performs primarily manual testing of our applications, and leave the automated testing to the developers. They do, however, have a few people on their team capable of writing automated tests. So, I wrote a simple client against our REST API with knowledge of only the hypermedia semantics, which translates the hypermedia controls of our API into HTML links and forms that can then be driven by testing tools like Selenium. This had the added benefit of allowing me to kick the tires, as it were, of the API early on and make sure that we were getting things right by writing a simple client against it. Since the client is bound only to the hypermedia semantics of the API, it's incredibly resilient to change. Also, having the QA team rely on an HTML client ensures that all aspects of the API are hypertext-driven; if they weren't, they couldn't be tested and would be kicked back to development.
It's also possible that defining media types and link relations used by an API in a standardized, generalized fashion, as required by REST, encourages the developers of an application to think about the consistency and structural clarity of their services; I definitely feel like this is the case when I work on or with REST APIs. The reasons for this higher-level of thought about the API may be due to the fact that, once the hypermedia controls have been defined, the technical details are pretty much out of the way and developers are left with determining the structure of the system their building; it's classic separation of concerns, which has yielded great results from conscientious developers for decades. In addition to encouraging better API design, defining the hypermedia controls and link relations in a consistent, standardized fashion also improves the client developers' ability to make assumptions about the API, thus improving their productivity.
A solution built on top of a true REST API can be bound to the relations and semantics in a media type, whereas a solution built on top of a partially-RESTful API, as they are typically built, is bound to each individual service in the API and the (often-times undocumented and implied) relationships between those services. Michael Bleigh suggests in his article that it's "too much work for clients and library authors to perform complex aggregation and re-formulation of data" when they're built on a true REST API. With the advantages of REST that have been mentioned so far, it should be the architecture of choice for client or library developers that are concerned with building systems that are resilient to or tolerant of common changes in and challenges of a web-based system. Developers that would like the flexibility to bind to the semantic subset of an API that is appropriate to their client or library (general hypermedia, or deep semantic understanding) would also probably prefer a REST API.
Of course, there are also the often-mentioned reasons for using REST: Scalability and maintainability. You can't work on a web application these days without having to build an API to drive iPhone, Android, mobile web, or some other client. Twitter's API has quite a few clients already (318 as of 6/21/2010). With so many clients likely to be built against a modern web API, it's important that one be written in a way that is as scalable and maintainable as possible, for the sake of both the clients and the system providing the services. The advantage of exposing services over the web is that, with REST, it's already designed to be massively scalable and maintainable, and the better a web API is at playing by the rules of the web, the more it can take advantage of those properties.
My friends Louisa and Nick have two of the cutest dogs on the planet. Oscar and Hunter have vastly different personalities (Oscar is a manipulative little cuddle-stealer, while Hunter is a quiet, loyal charmer), but they are equally cute. Each in his own way, of course.
I invite you to share the cuteness with me!
First up, the will-do-anything-to-have-his-own-way rascal, Oscar!And this is Hunter, who is sweet, smart and an all-around good guy. He also has seriously impressive eyebrows.
So freakin' cute, right?

Do you know how much more painful this would be on your scalp than a cheapie 1500 buck helmet ? And its not even a scary-helmet picture. The ones which are all smashed up.
Get a Helmet. Today !
A helmet is the most important accessory to pick up with a new bike, along with a good lock and a nice tail light. The other accessories can all wait.
A good list of accessories to pick up with a new bike on the all awesome biking notebook
The monsoon has started in Mumbai - Maharashtra with full force and one of my friends forwarded some great nature pictures especially from Konkan region to me. I can not resist myself to share some of those beautiful photos with you all.
Marleshwar waterfall near Sangameshwar in Ratnagiri district:
Jog waterfall:
A typical home in Konkan:
River bank:
Happy monsoon ! :-)
It's real time to go for a trek / nature trail !
It's pretty freaking hot out today, no? Seems like the perfect day for a composed salad. All you need:
- Chopped romaine lettuce
- Chopped Kirby cucumber
- Corn (either cut off of a raw cob, or defrosted from the freezer)
- Cold chicken
- A potato or two, boiled and sliced
- A radish or two, thinly sliced
- Snap peas
Arrange it all artfully atop a bed of the lettuce, top with some vinaigrette, and there you have it: the perfect warm weather meal. Expands or contracts to serve one or many.
Go ahead; give in to the laziness. You won't regret it.
This is a post from Peter Bragman on Harvard Business review site's guest blog. It made me thinking, see if it does the same to you...
http://blogs.hbr.org/bregman/2010/06/why-i-returned-my-ipad.html
In my last post, I discussed that even unglamorous, low profile 'dirty jobs' can be rewarding. According to a new book profiled in CIO Magazine, "The Why of Work", even 'happiness' is optional. It all comes down to finding a sense of purpose, i.e., knowing why you do what you do.
In this long period of tough economic times, many company perks that supposedly made people "happy" are no longer available. Budgets are lean. As news headlines constantly remind us, basic job security can't be assumed. An atmosphere of persistent stress and worry takes its toll, and "The Why of Work" warns that employees can experience an internalized "psychological recession" that endures even after business begins to recover. The authors are encouraging us to shake it off and get back to living with abundance.
I'm reminded of a book that had a big impact on me in college, Victor Frankl's "Man's Search for Meaning". As both a psychiatrist and a prisoner in a WWII Nazi concentration camp, Frankl observed that prisoners who felt a deep sense of meaning had a better chance of survival. Some extraordinary people responded to their hard times by becoming even more generous and concerned for others, even though they had every reason to be self protective. Obviously, this is an extreme case (and hopefully your work doesn't feel like a prison camp!!). But it shows that while we may not choose our circumstances, we are free to choose our response. It also shows that purpose can't be dictated or taken away by an authority. Its uniquely individual and belongs 100% to you.
Helping employees find meaning in work is good for business, though. Connecting work goals to a larger personal purpose builds resilience, and allows people to stay creative and engaged in times where change and uncertainty is constant. The catch for managers is that you cannot tell people what their purpose is, and finding purpose can take hard work, exploration and introspection. Its not as straightforward as providing financial incentives, casual Friday, free snacks, or other perks.
At my workplace, two colleagues are tasked with the daunting challenge of 'inspiring' our department. They are wisely avoiding a prescriptive approach, and instead opening some great opportunities for people to explore and share what is meaningful to them. (The Why of Work offers tools like checklists and questionnaires that can be helpful for some people, as well).
I wouldn't say I'm always in touch with my purpose, but I'm getting better at it. A big 'aha' moment was when I started volunteering my professional IT skills towards global health projects and supporting science/technology education. Volunteering is a passion, and it often makes me happy. But it also takes money and precious personal time away from my family. What drives me to make the sacrifice is the realization that I can have an impact on issues that matter. My purpose is aligned personally and professionally. Volunteering builds my capacity as a private sector professional, and professional growth at work means I have more to contribute to social impact work. I'm better able to provide for my family, while actively living and demonstrating my values in action for my children.
Everyone will find their own source of inspiration, but I appreciate that I work in an environment that supports diverse interests. We recently had a 'Take your Daughters and Sons to Work Day". I wonder (somewhat tongue in cheek, of course) what a "Take Yourself to Work Day" would look like. Who would we meet?
Date: 20th June 2010 (coming Sunday)
Time: 0730 hrs IST SHARP
Category: Road race
Distance: 62 km ( there is an option to race only 31km if you like )
Location: Rajankunte
To try and get more folks into the racing mode, whenever possible, we will try and keep an option to do a smaller leg of the race. If you are unsure about doing the full race distance you can still give this a shot.
Come by. Soak in the awesome atmosphere. Get to meet some fantastic people (bikers are always nice). And give something new a shot !
What are you waiting for, go ahead and REGISTER NOW
Helmet and Gloves are mandatory. No excuses.
We have positioned 4 sharp shooters at various places on the track to shoot you with their hi fi DSLRs. So, please put your best foot forward :)
These races are very community oriented. If you would like to contribute back – we are in dire need of posters, wallpapers, photos, writeups about these races and volunteers.
We think its a great idea to get your family and friends to the races, this way we have more ppl to cheer for you and also many photographers at the venue.
I was in a very interesting discussion on Invention vs Innovation and this is what the difference looks like
So essentially Invention turns the money invested into Ideas, whereas Innovation turns these ideas into more money (amplified ), which is the returns
Good morning, all! It's a bit early for me to be posting, I know. I'm writing this from the American Airlines terminal at LaGuardia, where I'm waiting to board the teeny regional jet that will whisk me away on my annual pilgrimage to Sandusky, Ohio!
No, I'm not going to pay homage to the roller coasters at Cedar Point; I'm going to visit my friends Louisa and Nick! Many of you are already familiar with our culinary pursuits, be they the pork belly-off, homemade banh mi, or dinner at Per Se (just to name a few). This week promises more of the same, though we are aiming to be healthier than is normal for us during these visits.
Don't worry; I'll see if I can't get them to sneak in a cocktail or two. After all, I'm on vacation!
Happy weekend, everyone! I'll be spending my weekend dog-sitting for my friends' dog, Dexter, out in the wilds of Brooklyn. Before I head off into the outer boroughs, though, it's time for a little Treasury action.
First up this week, a seriously awesome series of photos from photographer Bryan Solarski. Little World is composed of iconic scenes from around the world, all captured by the magical, miniaturizing effect of tilt shift photography. The unreality of the images makes you stop and reconsider the familiar. I especially love the ones involving water, including Venice's Grand Canal, Coney Island, and the Amalfi coast. Wouldn't mind being any of those places right now, come to think of it.
Next up, another set of photos, this time courtesy of the blogger Frau Haselmeyer. She recently took a trip to Switzerland and became enchanted with the country's gorgeous consumer packaging. As someone long enamored of Europe's superior design sense (at least when it comes to the little things), I heartily encourage her obsession.
Last but not least, a seriously beautiful, sumptuous wedding at the Parker Palm Springs, via Martha Stewart. I cannot get enough of the invitations, the bride's ruffly dress, or the table settings. Oh, the table settings. Are those not insanely beautiful? Makes me want to recreate them for a dinner party sometime soon.
The Ruby interpreter calls method_missing on a Ruby object whenever it receives a message (method call) that it cannot handle. One of the best examples of using method_missing that I’ve come across is in the SearchLogic plugin, which allows you to dynamically create named scopes. Today I’m going to take some time to explain how method_missing works, show how it’s used by SearchLogic, and finally show how you can use method_missing yourself to customize SearchLogic’s behavior.
Simple sorting with SearchLogic
Suppose I have an ActiveRecord model called “book” with a “title” attribute:
$ rails books
$ cd books
$ script/generate model book title:string
$ rake db:migrate
$ script/console
>> ["one", "two", "three"].each { |title| Book.create :title => title }The best way in Rails to display the books sorted by title would be to use a named scope like this in my model:
class Book < ActiveRecord::Base named_scope :sorted_by_title, { :order => 'title' } end
If I use a trick my colleague Niranjan Sarade showed me, we can see the SQL produced by ActiveRecord for the named scope in the console, like this:
$ script/console
>> ActiveRecord::Base.logger = Logger.new(STDOUT)
>> Book.sorted_by_title.collect { |book| book.title }
Book Load (1.6ms) SELECT * FROM "books" ORDER BY title
=> ["one", "three", "two"]This is a good example of why I’m a Rails developer: with just a single line of code in my model I can sort the values in a database column! But it gets even easier if I install SearchLogic:
$ script/plugin install git://github.com/binarylogic/searchlogic.git
Now I get a whole series of named scopes created for me automatically! For example, I can now just call the “ascend_by_title” and “descend_by_title” named scopes as if I had written them myself:
$ script/console
>> Book.ascend_by_title.collect { |book| book.title }
Book Load (1.3ms) SELECT * FROM "books" ORDER BY books.title ASC
=> ["one", "three", "two"]
>> Book.descend_by_title.collect { |book| book.title }
Book Load (2.0ms) SELECT * FROM "books" ORDER BY books.title DESC
=> ["two", "three", "one"]Brilliant! Using SearchLogic I can filter/sort on any attribute of any model in my application without writing a single line of code. I can even sort and filter on attributes of associated models, e.g. if I had “Book has_many :authors,” I could sort books by their author’s names, or sort the authors for each book, etc., all without writing any SQL or even Ruby code.
Sorting with NULL values last
Recently at my day job I came across a business requirement to sort a list of values, always displaying the NULL or empty values at the end of the list. In our example, this would mean that there might be some books with missing titles:
$ script/console
>> 2.times { Book.create :title => nil }
Here’s the behavior I get from the ascend_by_title and descend_by_title named scopes with NULL values:
>> Book.ascend_by_title.collect { |book| book.title }
Book Load (2.5ms) SELECT * FROM "books" ORDER BY books.title ASC
=> [nil, nil, "one", "three", "two"]
>> Book.descend_by_title.collect { |book| book.title }
Book Load (2.7ms) SELECT * FROM "books" ORDER BY books.title DESC
=> ["two", "three", "one", nil, nil]In other words, the NULL values are considered to be less than the other values by the database server, and are sorted accordingly. To get the behavior I want, I need to use a slightly more complex sorting pattern in a named scope, like this:
class Book < ActiveRecord::Base named_scope :sorted_by_title_nulls_last, { :order => 'title IS NULL, title' } named_scope :sorted_by_title_nulls_last_desc, { :order => 'title IS NULL, title DESC' } end
Trying it out in the console:
$ script/console
>> Book.sorted_by_title_nulls_last.collect { |book| book.title }
Book Load (2.6ms) SELECT * FROM "books" ORDER BY title IS NULL, title
=> ["one", "three", "two", nil, nil]
>> Book.sorted_by_title_nulls_last_desc.collect { |book| book.title }
Book Load (2.5ms) SELECT * FROM "books" ORDER BY title IS NULL, title DESC
=> ["two", "three", "one", nil, nil]These named scopes first sort on “title IS NULL” and then on the actual title value, causing the NULL values to appear at the end. This code is fairly clean and would work fine – the problem I had at my day job, however, was that I needed this sorting behavior for about six different columns in various database tables. To make this work, I would need to repeat these two named scopes in each model for each attribute that I wanted to sort on. If only SearchLogic had supported this sorting behavior, I wouldn’t need to copy and paste all of the named scopes.
Using method_missing
Specifically, here’s the method that I wished SearchLogic had implemented for me:
>> Book.ascend_by_title_nulls_last undefined method `ascend_by_title_nulls_last' for #<Class:0x2234978>
As you can see it doesn’t. But I mentioned above that SearchLogic works by using method_missing; let’s see if I can use method_missing myself and implement the NULLs last behavior… in other words, let’s see if I can use metaprogramming to implement the “nulls last” named scopes on all of my model classes all at once!
I’ll start by using the simplest possible implementation of method_missing:
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) puts "This method is missing: #{name}" end end end
Here “class << self” indicates that method_missing will be a class method on my Book class; Ruby calls method_missing on the class that is missing the method. The code here simply writes out a message when an unknown method is called:
>> Book.ascend_by_title_nulls_last This method is missing: ascend_by_title_nulls_last => nil
Now I’m ready to think about how to implement the nulls last sorting. But not so fast: it turns out that I have just broken my model class! Aside from SearchLogic, ActiveRecord itself also uses method_missing extensively. The simplest examples of this are the “find_by_...” methods. For example, calling find_by_title should return the book record with the given title:
>> Book.find_by_title 'one' This method is missing: find_by_title
But now instead of Book “one” I just get the debug message from method_missing. The correct solution here is to pass along the method_missing call to the super class, like this:
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) if name == :ascend_by_title_nulls_last puts "This method is missing: #{name}" else super end end end end
Let’s try find_by_title again in the console:
>> Book.find_by_title 'one'
Book Load (0.5ms)
SELECT * FROM "books" WHERE ("books"."title" = 'one') LIMIT 1
=> #<Book id: 1, title: "one", created_at: "2010-06-11 18:39:26", etc...
>> Book.ascend_by_title_nulls_last
This method is missing: ascend_by_title_nulls_last
=> nilSigh of relief – it works again! Looking at the if statement above, you can see that I check if the missing method is called “ascend_by_title_nulls_last,” in which case I write the debug message; if any other missing method is called I pass the call along to the super class. In this case, the super class is actually the SearchLogic module; it uses method_missing with super in exactly the same way that I do here. If the missing method is not recognized by SearchLogic, super is called again and finally ActiveRecord receives the method_missing call, which eventually evaluates find_by_title.
How does SearchLogic work?
SearchLogic uses method_missing as follows, the first time a missing method is called on an ActiveRecord model:
If the same missing method is called again, it will no longer be missing since the corresponding named scope will now exist. ActiveRecord caches a list of scopes that are created by calls to named_scope for each model class.
Ok – let’s try this idea on my Book model:
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) if name == :ascend_by_title_nulls_last named_scope :ascend_by_title_nulls_last, { :order => 'title IS NULL, title' } ascend_by_title_nulls_last else super end end end end
In the console again:
>> Book.ascend_by_title_nulls_last.collect { |book| book.title }
Book Load (1.9ms) SELECT * FROM "books" ORDER BY title IS NULL, title
=> ["one", "three", "two", nil, nil]
It works! The code above implements SearchLogic’s algorithm: if someone tries to use a named scope called “ascend_by_title_nulls_last” then actually create the scope at that moment with the proper sorting behavior.
Adding custom sorting to SearchLogic
Now I’m ready to generalize this for any model and attribute. First, I’ll look for any missing method name that matches a certain regex pattern (“ascend_by_XYZ_nulls_last”):
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) if name.to_s =~ /^ascend_by_(\w+)_nulls_last$/ named_scope :ascend_by_title_nulls_last, { :order => 'title IS NULL, title' } ascend_by_title_nulls_last else super end end end end
The line highlighted above first converts the method name from a symbol to a string, and then matches it against the “nulls_last” syntax I’m looking for. Next, I’m still hard coding “title” in the named_scope call; let’s replace that with the proper value, and also use the name passed into method_missing instead of the hard coded symbol for the scope name:
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) if name.to_s =~ /^ascend_by_(\w+)_nulls_last$/ named_scope name, { :order => "#{$1} IS NULL, #{$1}" } ascend_by_title_nulls_last else super end end end end
“$1” returns the string that matched the first expression contained in parentheses in the regex pattern above, “(\w+)” in this case. This will be the name of the attribute between ascend_by… and …nulls_last, taken from the missing method’s name. Now the proper named scope is created using this attribute name in the SQL fragment. So for example, if I call “Book.ascend_by_author_name_nulls_last” a named scope called “ascend_by_author_name_nulls_last” will be created, using :order => “author_name IS NULL, author_name.”
One last hard coded value to remove: the call to “ascend_by_title_nulls_last” still refers to title directly. To fix this, I just need to use “send(name)” – this calls the method whose name is in the “name” string, which is the named scope we just created. Here’s how that looks:
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) if name.to_s =~ /^ascend_by_(\w+)_nulls_last$/ named_scope name, { :order => "#{$1} IS NULL, #{$1}" } send(name) else super end end end end
Now I can add in the case for the descending sort as well:
class Book < ActiveRecord::Base class << self def method_missing(name, *args, &block) if name.to_s =~ /^ascend_by_(\w+)_nulls_last$/ named_scope name, { :order => "#{$1} IS NULL, #{$1}" } send(name) elsif name.to_s =~ /^descend_by_(\w+)_nulls_last$/ named_scope name, { :order => "#{$1} IS NULL, #{$1} DESC" } send(name) else super end end end end
The last thing I’ll do today is generalize this for any model in my application by moving the method_missing code into a module that I’ll call “SearchLogicExtensions,” and then extending ActiveRecord::Base with that:
module SearchLogicExtensions def method_missing(name, *args, &block) if name.to_s =~ /^ascend_by_(\w+)_nulls_last$/ named_scope name, { :order => "#{$1} IS NULL, #{$1}" } send(name) elsif name.to_s =~ /^descend_by_(\w+)_nulls_last$/ named_scope name, { :order => "#{$1} IS NULL, #{$1} DESC" } send(name) else super end end end ActiveRecord::Base.extend(SearchLogicExtensions)
Note that I need to use ActiveRecord::Base.extend and not ActiveRecord::Base.include here, since my method_missing code calls “super” if the missing method does not match the pattern. “Extend” means that the methods of ActiveRecord::Base, including method_missing, will be overridden by the methods of the SearchLogicExtensions module, but will still be present and available via a call to “super.” Another important detail here is that I removed the “class << self” syntax. Since this is a module and not a class like Book was, I just define method_missing directly. My method_missing will be added as a class method to Book and all of my other models by the last line, when we extend ActiveRecord::Base. In my application I put this code into a file called “config/initializers/search_logic_extensions.rb,” which caused it to be loaded during the Rails initialization process. I could have also packaged the code up as a separate plugin.
That’s it for today; next time I’ll continue this discussion of metaprogramming with SearchLogic by showing how to sort with NULL values in an associated database table, using a LEFT OUTER JOIN query.
On Saturday night, Cristin and I picked Ellie up from the library and headed down to the water for a cocktail. We ended up at Belle Haven, the yacht club Ellie's parents belong to. It's not the most exciting destination for an evening out, but we were after the breeze and the view, not the raucous partying.
And what a view! Greenwich is right on Long Island Sound, and that faint stripe of green you see in the distance is Long Island itself. On a clear day, it's a crisp view, and you can even see - just barely - the Manhattan skyline.
And what's that on the cocktail napkin? That's right: the club's coordinates. How very nautical, no?
Just to make sure my message was clear at Railsconf...recursion is actually pretty cool & powerful...recursion in the database isn't cool :)
Now more recursive hasselhoff for your viewing pleasure:
Google announced the completion of new web indexing system "Caffeine" this week.
This is what Google says about it:
Old index system had several layers, some of which were refreshed at a faster rate than others; the main layer would update every couple of weeks. To refresh a layer of the old index, the entire web would need to be analyzed, which meant there was a significant delay between when a page was found and when it is available as a search result.
With Caffeine, web is analyzed in small portions and search index's are updated on a continuous basis, globally. As new pages or new information is found, it is added to the indexes, which helps in finding fresher information than ever before. Apart from this, every second Caffeine processes hundreds of thousands of pages in parallel.
Cycling and Running are something close to our hearts at BumsOnTheSaddle. Definitely happy to partner with RFL (our running counterparts) to help make the Duathlon in Bangalore happen.
Like they mentioned on their site – “The Duathlon serves an important purpose. It will get the running and cycling communities together.“
And we are all for it.
Oh yeah, Abhinandan would also be conducting a warmup and recovery session. Please do keep an eye out for him at the venue. You could ask some of the organizers about this. The warmup session would be 10 sets of Suryanamaskar followed by Oxygenics – a system of pranic breathing coupled with rhythmic stretching. The recovery session will also involve Oxygenics. A small contribution from BOTS to make sure everyone is totally ready for the action.
We heard about a couple of hard core Ironman athletes converging on Bangalore to take part in this event and whoop some ass. Should be loads of fun !
I am attending a training on Ruby and from what I have learnt so far, my take about the language
Here are my slides and code samples from my RailsConf 2010 talk. Hope you all enjoyed it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
require 'rubygems' require 'json' require 'rest_client' def create_person(name) JSON.parse RestClient.post( "http://localhost:8988/neo4jr-social/nodes", :name => name ) end def make_mutual_friends(node1, node2) RestClient.post "http://localhost:8988/neo4jr-social/nodes/#{node1['node_id']}/relationships", :to => node2['node_id'], :type => 'friends' RestClient.post "http://localhost:8988/neo4jr-social/nodes/#{node2['node_id']}/relationships", :to => node1['node_id'], :type => 'friends' end luke = create_person('Luke Skywalker') han_solo = create_person('Han Solo') chewy = create_person('Chewbacca') lando = create_person('Lando') akbar = create_person('General Akbar') make_mutual_friends(luke, han_solo) make_mutual_friends(han_solo, chewy) make_mutual_friends(han_solo, lando) make_mutual_friends(lando, akbar) suggestions = JSON.parse RestClient.get("http://localhost:8988/neo4jr-social/nodes/#{luke['node_id']}/recommendations?type=friends") friend_suggestions = suggestions.map{|n| n['name']}.join(', ') puts "Luke Skywalker should become friends with #{friend_suggestions}" #RESULT: # Luke Skywalker should become friends with Chewbacca, Lando |

Last weekend, I went out to Connecticut to keep my friend Ellie company. She was home alone at her parents' house, studying for her medical boards. We grew up in the same town, but my mother moved away when I was a senior in college, which makes homecomings (despite their requiring little more than a fifty-minute train ride from Grand Central) hard to come by.
My friend Cristin came out on Saturday afternoon, but before she arrived, I dropped Ellie off at the library and headed down to the water and to my old stomping grounds. I grew up near the beach; only a block from the water, as a matter of fact. My friend Caroline and I used to ride our bikes all over the place, sneaking onto secret little beaches and into tiny little coves. So, I parked the car and took a little walk.
And promptly discovered that trespassing, while cute in the 1980s and at 8 years old, is just plain creepy at 30 in 2010. Yeah. I only made it to two or three little spots before deciding it was time to admit that I am now too old to sneak onto people's property and stopping the madness in exchange for an iced coffee.
Of course, I had to make one last stop, at our home itself, a beautiful old (built in 1898) shingle-style house. A good number of the houses in the neighborhood were built in the late 19th century as summer homes for New Yorkers, our house among them. It was a decidedly summery place, even in the coldest, snowiest of winters.
Sigh. I do miss it.
Hello, kids! It's that time: time for a little facelift here at Queenie. My incredibly talented friend Miya has created a fabulous new header for me, based on the bistro menus of Paris. Those menus change pretty frequently, and are usually written on chalkboards or in white marker on glass partitions. Our menu is pretty simple, and won't be changing any time soon: Let's eat, let's travel, let's party!
On my last day in San Francisco, Faith and I took a drive out to Flora Grubb Gardens, a florist-cum-design shop deep in the Mission District. Loyal New York Times Weddings & Celebrations readers might recognize the name; Flora hosted her brother's wedding reception at the store, and the union was featured in the Vows column.
It's a pretty nifty place; Faith termed it the Anthropologie of flowers, and that's about right. The store sells plants, pots, stationery, cut flowers, garden furniture, Ritual coffee, brownies and assorted decorative objects.
Among its coolest items, though, are the walls of tightly-packed succulents. You can buy a small version, as small as 11 inches by 14 inches, but why would you do that when you could cover a whole wall of your apartment in such an amazing, gravity-defying mix of texture and color? It's living art, and I love it.
Flora Grubb
1634 Jerrold Avenue
San Francisco, California
415.626.7256
Are you a biker in Bangalore ? June is definitely a good month for you, with a ton of events
These two events were held on the 5th of June. The race was good, with quite a big turn out. We got a chance to check out the Indian team in action. Pretty awesome to see local bikers riding hard in the pelotons.
Thats one event every weekend for the rest of the month.
Apart from these there are a lot of rides happening (check out on the ride calendar) and loads of biking conversations on the Bangalore Community groups
Join in on the fun !
When we were in Napa a few weeks ago, my mother and I - of course - made a pilgrimage to Taylor's (now re-christened Gott's - read about that particular saga over here) in St. Helena. No trip to Napa would be complete without one of their superlative burgers.
This time, instead of fries, we decided to split an order of onion rings. Now, I don't eat onion rings very often, mostly because I find them to be nearly universally disappointing. They're feckless little things. They feign competence, arriving all hot and golden and crispy, but they shed their delicious batter on any kind of contact with my mouth, leaving me with pointless, flavorless batter and limp, sad onion. There's nothing fun about that.
But Gott's onion rings aren't like that. These have a delicious beer batter that - get this - actually sticks to the onion! No matter how many bites you take, the two remain one! And what a delicious one they are. Well-seasoned with salt, perfectly cooked and crispy. These are onion rings as God and Mother Nature intended, my friends.Oh, and - the burger is, of course, still stellar.
Gott's Roadside
933 Main Street
St. Helena, California
707.963.3486
Following my earlier post, I pushed hash_key_as_attribute gem to rubygems.org
Install
====
gem install hash_key_as_attribute
OR
Download the gem file from http://github.com/NiranjanSarade/hash_key_as_attribute/
gem install hash_key_as_attribute-0.0.1.gem
A while ago, I had read the book "In Search of Excellence" by Thomas J Peters and Robert H Waterman. One particular quote from this book had left an indelible impression on my understanding of Leadership. Sharing the same below..
"An effective leader must be the master of two ends of the spectrum: ideas at the highest level of abstraction and actions at the most mundane levels of details"
As professionals move up in the corporate ladder, I observe they becoming less and less Hands-On. Decisions made without proper understanding of ground realities or without enough attention to details almost always prove to be wrong. Hence it's imperative for professionals to keep themselves abreast of the latest happenings in their core business area.
For those who are interested, the book describes following 8 attributes of innovative organizations
Just finished reading "Good to Great" by Jim Collins.
I quite enjoyed reflecting/debating (with self) on the ideas put forth by the author. In the process, got moved by the following perspectives/Quotes
The book helped me putting leadership and management in right perspective. Recommended for all.
Happy weekend, my doves! I'm spending this weekend out in the country - well, OK, the 'burbs. My friend Ellie invited me out to spend the weekend at her parents' house in our Connecticut hometown, and I'm enjoying the excellent company, gorgeous greenery and...pool! But before I put my sunhat on and run back to the lounger, it's time for this week's Treasury!
First up, a look at Jim Datz's amazing, destined-for-iconic-status Brooklyn and Manhattan posters. Inspired by vintage signage from the 1940s and '50s, Datz has created two posters showing the (approximate) arrangement of neighborhoods in my two favorite boroughs. My friend Miya has already purchased the Brooklyn poster to hang in her new Prospect Heights digs; I think I just might need one of each.
I may have already found my dream kitchen, but that doesn't mean I can't still admire the others from afar. I'm a little bit obsessed with this kitchen's combination of green paint, wood and white subway tile. And the cookware collection ain't bad, either. One last note: is that a papier-mache donkey's head on the island? As in, Bottom's costume? Because, if so? Props. (Via the always-excellent The Goodie Life.)
Last but not least, a very dangerous destination for all things paper-related. Prints, stationery - you name it, Felt & Wire sells the best of it. This silkscreen Mokka print would look great in that green kitchen, no? Synchronicity, folks. Synchronicity.
In ruby, we have OpenStruct which allows the creation of data objects with arbitrary attributes. With ruby's metaprogramming capability, we can also allow hash values to be set and retrieved as if they were its attributes. If the key does not correspond to any hash entry, it should return “The key does not correspond to any hash entry” message. The hook that we are going to use is Kernel's method_missing.
Here we are opening the class Hash :-
And this is the sample output :-
h = Hash.new("The key does not correspond to any hash entry")
h.one = 1
puts h.one #=> 1
h.two= [1,2,3,4]
puts h.two.inspect #=> [1,2,3,4]
puts h.three #=> "The key does not correspond to any hash entry"
puts h.inspect #=> {:one=>1, :two=>[1, 2, 3, 4]}
h2 = {}
h2.four = 4
h.three = h2
puts h.three.inspect #=> {:four=>4}
puts h.three.four #=> 4
I want to share my experience in generating the data for social network analysis using R and analyzing it using Gephi...
WHICH DATA STRUCTURE TO USE FOR LARGE GRAPHS?
I quickly realized that using edge lists and adjacency matrix gets difficult as the graph size increases. So I needed an alternative graph format that was efficient (for storage) and flexible to capture details like edge weight. I chose Gephi's gexf file format as it can handle large graphs, and it supports dynamic and hierarchical structure. Checkout gexf comparison with other formats for details.
HOW TO HANDLE LARGE DATA SETS IN R?
As I tried to process millions of rows of email log to derive the edgelist, I realized a couple of things...
1) R cannot handle data larger than my computer's RAM. So I had to look for a way to use R for large data sets. R packages like RMySQL and SQLDF came in handy for this. SQLDF uses SQLlite, an in-memory database. If your data cannot fit into RAM then you can instruct SQLLITE to use persistent store for handling large data sets.
Note: There are many other ways to handle large data in R effectively, e.g. R multicore package for parallel processing, R on MapReduce/Hadoop, etc. Check out the presentation on high performance computing in R for other techniques like ff and bigmemory. Please shout if there are other ways that you used...
2) Some operations are better suited for database/RDBMS: I offloaded RDBMS-suited tasks to SQLlite, the default database used by SQLDF.
3) Learn memory management in R:
- By default R allocates ~1.5GB memory for its use. I allocated more memory for R to handle larger objects using the command "memory.limit(size=3000)"
- Remove unwanted objects from the R session e.g.
rm(raw_emails, emails, to_nodes,from_nodes,all_nodes, unique_nodes)
gc() # call garbage collection explicitly
LOADING THE GRAPH IN GEPHI
Gephi wasn't able to handle very large graph files (e.g. for files > 500MB size, Gephi was either too slow or stopped responding). So I had to do a couple of things...
1) Increase the amount of memory Gephi allocates for the JVM at startup: By default Gephi allocates 512MB memory for JVM. This wasn't enough to load the large graph file, so I increased the max. memory Gephi allocated for JVM to 1.4GB.
Edit C:\Program Files\Gephi-0.7\etc\gephidesktop.conf file and changing the line
default_options="--branding gephidesktop -J-Xms64m -J-Xmx512m" to
default_options="--branding gephidesktop -J-Xms64m -J-Xmx1400m"
2) Decrease the file size by reducing the text in the graph file e.g. use shorter node_ids, edge_ids etc.
Also, Gephi complained about incorrect file format (it expects UTF-8 encoded XML files). I fixed this simply by opening the graph file generated by R in Textpad and saving it in UTF-8 format before feeding it to Gephi.
LESSONS LEARNED
1) R is more than a statistical tool. I was able to manipulate and clean large data sets (500+ million rows) easily. I will continue learning it. Its fun and rewarding.
2) There are other sophisticated tools for visual social network analysis like Network Workbench
I will explore it for heavy analysis, but Gephi is very easy to use and continues to be my favorite.
3) Use a machine with a lot of RAM, as both Gephi and R are memory hungry
MY CODE FOR GENERATING THE GRAPH
By the way, here's the R code I used for preparing the graph from email logs for social network analysis using R and Gephi. I'm sure there are better ways to accomplish this. Please shout if you notice any.
I want to share my experience in generating the data for social network analysis using R and analyzing it using Gephi...
WHICH DATA STRUCTURE TO USE FOR LARGE GRAPHS?
I quickly realized that using edge lists and adjacency matrix gets difficult as the graph size increases. So I needed an alternative graph format that was efficient (for storage) and flexible to capture details like edge weight. I chose Gephi's gexf file format as it can handle large graphs, and it supports dynamic and hierarchical structure. Checkout gexf comparison with other formats for details.
HOW TO HANDLE LARGE DATA SETS IN R?
As I tried to process millions of rows of email log to derive the edgelist, I realized a couple of things...
1) R cannot handle data larger than my computer's RAM. So I had to look for a way to use R for large data sets. R packages like RMySQL and SQLDF came in handy for this. SQLDF uses SQLlite, an in-memory database. If your data cannot fit into RAM then you can instruct SQLLITE to use persistent store for handling large data sets.
Note: There are many other ways to handle large data in R effectively, e.g. R multicore package for parallel processing, R on MapReduce/Hadoop, etc. Check out the presentation on high performance computing in R for other techniques like ff and bigmemory. Please shout if there are other ways that you used...
2) Some operations are better suited for database/RDBMS: I offloaded RDBMS-suited tasks to SQLlite, the default database used by SQLDF.
3) Learn memory management in R:
- By default R allocates ~1.5GB memory for its use. I allocated more memory for R to handle larger objects using the command "memory.limit(size=3000)"
- Remove unwanted objects from the R session e.g.
rm(raw_emails, emails, to_nodes,from_nodes,all_nodes, unique_nodes)
gc() # call garbage collection explicitly
LOADING THE GRAPH IN GEPHI
Gephi wasn't able to handle very large graph files (e.g. for files > 500MB size, Gephi was either too slow or stopped responding). So I had to do a couple of things...
1) Increase the amount of memory Gephi allocates for the JVM at startup: By default Gephi allocates 512MB memory for JVM. This wasn't enough to load the large graph file, so I increased the max. memory Gephi allocated for JVM to 1.4GB.
Edit C:\Program Files\Gephi-0.7\etc\gephidesktop.conf file and changing the line
default_options="--branding gephidesktop -J-Xms64m -J-Xmx512m" to
default_options="--branding gephidesktop -J-Xms64m -J-Xmx1400m"
2) Decrease the file size by reducing the text in the graph file e.g. use shorter node_ids, edge_ids etc.
Also, Gephi complained about incorrect file format (it expects UTF-8 encoded XML files). I fixed this simply by opening the graph file generated by R in Textpad and saving it in UTF-8 format before feeding it to Gephi.
LESSONS LEARNED
1) R is more than a statistical tool. I was able to manipulate and clean large data sets (500+ million rows) easily. I will continue learning it. Its fun and rewarding.
2) There are other sophisticated tools for visual social network analysis like Network Workbench
I will explore it for heavy analysis, but Gephi is very easy to use and continues to be my favorite.
3) Use a machine with a lot of RAM, as both Gephi and R are memory hungry
MY CODE FOR GENERATING THE GRAPH
By the way, here's the R code I used for preparing the graph from email logs for social network analysis using R and Gephi. I'm sure there are better ways to accomplish this. Please shout if you notice any.
In ruby, instance variables have prefix '@' and class variables have prefix '@@'.
We have instance_variable_get and instance_variable_set methods from Object class and class_variable_get and class_variable_set methods from Module class in Ruby. Here is the typical usage of these methods from the ruby docs :-
----
class Fred
@@foo = 99
end
def Fred.foo
class_variable_get(:@@foo) #=> 99
end
----
class Fred
def initialize(p1, p2)
@a, @b = p1, p2
end
end
fred = Fred.new('cat', 99)
fred.instance_variable_get(:@a) #=> "cat"
fred.instance_variable_get("@b") #=> 99
----
class Fred
def initialize(p1, p2)
@a, @b = p1, p2
end
end
fred = Fred.new('cat', 99)
fred.instance_variable_set(:@a, 'dog') #=> "dog"
fred.instance_variable_set(:@c, 'cat') #=> "cat"
fred.inspect #=> #Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\"
----
However, why do we need to specify the @ and @@ when the method names are smart enough to distinguish between whether the variable is an instance or a class variable. Why does a call to instance_variable_set require the "@" symbol in the first argument? Any idea ? Or has it been done with some purpose ?
When I was little, strawberries were one of my favorite foods. And, frankly, they still are. I greet the arrival of strawberries to the market with something akin to glee; something, admittedly, rather childish. I get giggly and squirmy and, let's face it, a bit competitive. I want those berries, and have them I will, Greenmarket crowds be damned.
This weekend's berry haul was particularly tasty - tart and sweet in that way that only berries really are, and absolutely beautiful to boot. I ate a full pint dipped in crème fraiche and topped with dark brown sugar one night, cooked another quart into a batch of strawberry-rhubarb compote, and decided to make some crostatas with what was left.Crostatas are free-form cousins to pies and tarts, and they're ridiculously easy to make. Hate transferring your rolled-out pie crust to your pie plate or tart pan? Don't have a pie plate or tart pan? Crostatas are for you, my friend. A little food processor action, a bit of rolling, a spot of folding, and you have a finished dessert. The best part? They're beautiful and show off the jewel-like fruit in a way normally reserved for lattice-top pies, and they impress people in a rustic, Tuscan sort of way.
Go ahead. Show off.
Strawberry-Rhubarb Crostata
For the pastry:
1 1/4 cups flour
1/4 cup polenta
2 tsp. turbinado sugar
1/4 tsp. salt
1 stick butter, very cold or frozen, cut into 1/2-inch bits
3 tbs. ice water
For the filling:
5 stalks rhubarb, trimmed and cut into 1-inch pieces
1 pint (1/2 quart) ripe strawberries, hulled and cut in half lengthwise
1/3 cup dark brown sugar
1/2 tsp. vanilla
1/4 tsp. salt
1 tbs. butter, cut into small bits
1 egg, beaten
Softly whipped cream or crème fraiche, for serving
Place the flour, polenta, sugar salt and butter in the bowl of a food processor fitted with the blade attachment. Pulse together until the mixture is mealy and most of the butter is about the size of small peas. With the processor running, stream the water in one teaspoon at a time until the mixture begins to come together in one or two big clumps. You may not need all the water, depending on the humidity in your ingredients and the air. (Alternately, you can make the pastry in a medium bowl, using a pastry blender. A food processor is super-fast, but a pastry blender works well, too. Make sure to chill the bowl ahead of time.)
Turn the dough out onto a lightly floured surface and mold into a large disc. Wrap in plastic wrap and place in the refrigerator. Let the dough rest for at least an hour; it can sit in the fridge for up to 36 hours before you use it.
When you're ready to make the filling and bake the crostata, take the dough out of the fridge and let it sit; this will help take the chill off a bit. In the meantime, pre-heat the oven to 400°F. Combine the strawberries, rhubarb, sugar, vanilla and salt in a medium bowl. Stir to coat the fruit in the sugar, and continue to stir until it begins to dissolve. Set aside while you roll out the pastry.
You can use the pastry to make one large tart or several (three or four) little ones. No matter what size you're after, the method is the same. Lightly flour a piece of parchment paper and place the dough in its center. Flour your pin and use it to whack the disk of pastry once or twice, then start rolling it out from the middle outward, spinning it if you need to, until you have a roughly circular shape about 1/4 inch thick. Transfer the crust (on the parchment paper) to a cookie sheet.
Spoon the filling into the middle of the tart, leaving about two inches of crust as a border. Starting anywhere you'd like, fold the pastry up over the filling. Continue to fold in triangles as you go around the tart (Refer to the photo above; it's easy to do once you take a look at a finished version, I think.) until all the edges are folded over the filling, leaving a nice circle of pretty fruit exposed. Using a pastry brush, paint the crust with the beaten egg; this will give it a nice sheen. Dot the exposed filling with the butter.
Place the tart in the oven and bake for 25-35 minutes, depending on your oven, rotating the tart halfway through baking. Bake until golden-brown and bubbly; the crust may leak some juices, but should hold up pretty well in any case, despite the liquid. Once the tart is done, remove it from the oven and transfer it, on its parchment paper, to a cooling rack. Cool at least slightly before slicing. Serve topped with crème fraiche or whipped cream.
Serves 6.
Rumo ao Hexa!!!!
Good long weekend... Ready to get back into R and data mining...
After a personal appointment this morning, I'm now reading an early draft of Data Mining with R: Learning with Case Studies (Chapman & Hall/CRC Data Mining and Knowledge Discovery Series) (Hardcover) ... checkout the book's website
Good long weekend... Ready to get back into R and data mining...
After a personal appointment this morning, I'm now reading an early draft of Data Mining with R: Learning with Case Studies (Chapman & Hall/CRC Data Mining and Knowledge Discovery Series) (Hardcover) ... checkout the book's website
I was attending a workshop over the weekend on 4 roles of leadership and one of things we were discussing was the difference between an industrial age worker and knowledge age worker. Very interesting specially because i was relating it to another video I saw the other day on why bonuses don't work. The 3 basic difference between Industrial and Knowledge age worker area.
On comparing this with the other video i talked about, it is the fact that a job which needs to do a set of mechanical job corresponds to a industrial age mind set and the other is more on creative aspect/aspect of unleashing potential.
No visit to Momofuku Ssäm Bar would be complete without a dessert pit stop at the adjoining Momofuku Milk Bar. Milk Bar's staff, headed by pastry chef Christina Tosi, is famous for combining the salty and sweet into unique and often nostalgic desserts.
Cereal milk is bottled for drinking and made into soft-serve ice cream; cinnamon buns become pies; cakes are ringed in confetti. It's not hard to understand why the place is a massive hit, especially with 20- and 30-somethings raised on the giddiness-inducing sugary cereals of the 70s and 80s.After our latest bo ssäm adventure, we decided to head over to Milk Bar for a sweets fix. I went for ice cream, choosing the cinnamon soft serve with cornflake crunch topping. It was delicious, and the texture was wonderful - silky smooth and creamy. That said, I thought the ice cream was a bit too salty (and I'm someone who likes salt with her sweets). If salt has become the dominant flavor, it's no longer doing its job as an enhancer, and that was the case here. That said, Miriam's cereal milk soft serve with the same topping? Awesomeness.
I've still found nothing to beat the cornflake-chocolate chip cookie or the cinnamon bun pie, though. YUM. (Also, out-of-towners take note: some Momofuku Milk Bar goodies are available for shipment!)
Momofuku Milk Bar
207 2nd Avenue (Corner of 13th Street)
212.254.3500