2009-03-28

Freedom

SUPPORT 51 MILLION PEOPLE RESIGN FROM CHINESE COMMUNIST PARTY

Freedom: many human beings still can't take it for granted.

2008-06-10

Portugal Day

Or in portuguese, Dia de Camões, de Portugal e das Comunidades Portuguesas.

Being currently living outside of Portugal, this day had a special meaning for me today. No, I'm not about to cite the "usual bs" about being nostalgic and The Lusiads (Os Lusíadas) being on par with the Iliad and the Odyssey. This day had a special meaning because of someone's initiative: Mr. José Bouza Serrano, the ambassador of Portugal in Denmark.

I spent some hours at his house today, at first mostly with Danish people and then with people mostly from Portugal. It was a very good experience – the chance to talk with Portuguese people living here both for a few (0-4) and many (20+) years was priceless.

On one hand, I had an interesting time just trying to analyse how entusiastic people were about staying in Denmark for some time; On the other hand, I had a few inspiring conversations on how peoople got here, what was their living condition then and now, what plans do they have for the future and how can we make our own lives easier living almost "alone" in this pretty closed society.

That being said, I really haven't made up my mind on whether I'm going to aim at staying here in Copenhagen after the internship or not (remember the first rule of career planning?)... but I certainly have a quite broader perspective on working an living here than I had when I woke up this morning!


Speaking of career planning, while in my previous post I didn't mean to be explicit about how I came in contact with Microsoft Copenhagen, it has been pointed to me that I should perhaps refer that that. So, in my case, I was already percolating in my mind the possibility of an internship abroad and I basically seized an opportunity presented by my faculty – FEUP – and particularly the association of alumni of my programme (Master in Informatics and Computing Engineering) – AlumniEI (formerly AlumniLEIC). Some FEUP teachers and AlumniEI members are really the ones who presented the dots, I just connected them :)

2008-03-19

Internship at Microsoft Copenhagen – how did I get it and where to go from here?

As Marc Andreessen (pmarca) would say:

The first rule of career planning: Do not plan your career.

I read pmarca's posts on career planning at a crucial time in my own career: I was in my last university semester with classes, thinking about what would be the best option to start my career in the so-called software industry. To tell the truth, I wasn't really starting my career as much as re-starting it -- I had previously participated in some projects with real-life goals and real customers, projects that were a bit complex both by social and technical perspectives. I found it really amazing that I was able to review my past choices and bets, matching them with some of the advices Marc gives, just when I was finishing studies to start working full-time.

Of the pmarca career posts I linked earlier, the one that really resonated with me was the one about opportunity. Spotting, evaluating and seizing opportunities were what drove me to where I am now. Call me opportunist, but that's the way it is. (Apart from these three actions that you can "apply" to opportunities, there's only one better action: creating opportunities. But I'm not there quite so often yet.)

Throughout the previous four college years, after weighting my options -- 1) doing the best possible at exams and assignments and doing little else vs. 2) doing acceptable at exams and assignments and have time to pursue other ambitious opportunities -- I can say with some certainty (looking at my grades vs. my resume) that I chose option 2 about 80%-90% of the time. And I absolutely don't regret it. These choices have granted me extra experience, knowledge and personal interactions that I can't really measure. Sure there was also some time that was lost and opportunities that I couldn't pursue, but hey, that's life -- I also learned (a bit by the hard way) that I can't do all I'd like to and that it's important to know when to say no (and being able to do it).

Since I'm all out referencing Marc Andreessen, I might as well point to another article he posted (a bit off-topic): Luck and the entrepreneur: The four kinds of luck. Luck or chance is present in everyone's life. However, I've always been a fan of "you make your own destiny" kind of philosophies, and that's where I find the article interesting (most of the article cites a book by Dr. James Austin, a neurologist and philosopher). To try and sum it up nicely, I'll focus just two points:

  • you can either walk through life from objective A to objective B (and so forth) focusing on the objectives, or you can pay more attention to the path between each objective while moving;

  • what sometimes seems a lucky person in the right place at the right time is the result of that person's knowledge, hobbies and day-to-day behaviour -- and those can be controlled/improved.


Of course it's not always possible to do what seems more appealing to our tastes or that would have the best outcome, or seizing opportunities just for the sake of not losing them -- sometimes I really just had to do the right thing. Like not charging a client that asks for some changes to his website two months after he said that it was just perfect, or planning six months in advance to stop accepting projects because of a very important lab class at the university.

So, I guess I've painted a kind of abstract picture of how I came to Microsoft Copenhagen for a one year internship. Well, I guess the title was just an excuse to speak about career, seizing opportunities, luck and doing the right thing.

Where will I go from here? See the first rule of career planning.

2008-01-16

Will everything be free?

Or, more specifically, will every (Web 2.0 or not) service and application be free?

Many Web startups and new services concentrate on collecting a very large user base, and only after thinking about monetizing, which is inevitably ads or has a very strong ads component. That way, they never get customers, only users, because they never get money from them. This uneases me a bit, maybe because I'm not a big fan of marketing and publicity, or maybe because I can't conceive the online publicity model to scale into the de-facto monetizing solution for the Web.

That and I've started following the "There Is No Such Thing As A Free Lunch" motto long ago (I like the Portuguese variant a lot: NHAG - "Não Há Almoços Grátis"), so I don't trust "free" completely anymore.

Well, this was just an oppinion of mine that I summarized quickly as an introduction to point you, my dear reader, to this article written by Alex Iskold on ReadWriteWeb: The Danger of Free. The article also focuses on the effects of free products in the economy and market competition.

I might get back on the subject with more of my own words later. More goodies after the jump.

2008-01-09

Delay sending emails by one minute

I've told some people that I have configured my MS Outlook to delay sending of emails by one minute. They all acted quite surprised and a few were even confused. "That's right, when I press send, it's only actually sent one minute later."

I've started to use that more than a year ago. At the time, I had to deal with clients in some ongoing projects, faculty assignments, participated in a couple other side projects... I had a lot of context-switching going on, especially with email.

Sometimes when composing or replying to emails, I would press the "send" button and shortly after find myself saying out loud stuff like "damn, I forgot the attachment", "oh no, I didn't write the subject", "oops, forgot to mention subject X" or "shit, I just misspelled his/her name"... Too many times, for sure!

As much as I trained myself to re-read every email before sending, it seemed that the "send" action triggers something else that I couldn't consciously trigger myself, something that often spots some other flaw previously uncovered.

So, I roamed Outlook preferences, filters and rules until I discovered a rule that delays sending of all emails by any amount of minutes. That was what I needed :)

Initially I started with a two-minutes delay, but quickly brought it down to one minute. If you suffer from this "syndrome" I tried to describe here, maybe you'll find this little lifehack useful too!

2007-12-30

Easily sorting an ASP.NET GridView binded to an ObjectDataSource

Last summer, I was involved in building a complex, multi-tiered application in ASP.NET. It has the usual data, business logic and presentation layers, together with some additional modules. Every layer and module exposes a webservice and that's how it's all wired up. The project had all the data needs and operations very well specified and translated into stored procedures. The data layer is abstracted by business objects, that are passed from one service to another and finally to the presentation layer. Very enterprise-ish, wouldn't you say?

When the system was designed it was assumed that the presentation layer, or in other words, the ASP.NET pages, could easily paginate, order, and do other presentation transforms to the lists of business objects returned by the lower layer. The thing is, it was not so simple. More about that in a moment.

ASP.NET 2.0 has evolved in terms of data visualization and interaction, providing easy-to-use but also powerful controls like the GridView and FormView, just to name two of the most popular. There has also been some improvement in terms of integration with different sources of data other than SQL, namely XML and business objects / data objects. For the latter, the ObjectDataSource control, we can provide a type and a method to retrieve data and the wire it with a GridView to display some data. Very nice and easy, about 12 mouse clicks total. Now rinse, repeat in as many pages as you need.

Oh wait, we need sorting and pagination. Well, pagination is implemented by default, no problems there.
«Sorting, let me see... Oh, here is the AllowSorting property, let me just set this to true. It's don... Oh fsck!»

This was aproximately my mental monologue some months ago when asked to add sorting to a GridView and encountering a nasty error. A quick Google-ing leads me to a Microsoft MSDN page that explains what must be done in order to add sorting capabilities to an ObjectDataSource. Long story short, it was necessary to create an overload to every method that returns data, with two additional parameters (SortExpression and SortDirection, if I recall correctly).

We were on a pretty tight schedule to present a prototype to the client, so there was not much time to go around modifying every method to include sorting support. And there definitely wasn't enough time to traverse all the layers so that sorting was introduced at the stored procedures level, which is where it belonged in the first place!

When push comes to shove, it's time for "Reflection and XORs".
(I love this expression! It's used by some friends of mine to express unnecessary complexity of design and/or implementation.)

My quick (and a little dirty) solution to this problem – which I've already shared with some people and might be useful for others, so that's why I'm making this post – was to create a user control that "catches" the sorting events on the GridView and transforms the data coming from the ObjectDataSource so that it reaches the grid sorted as expected. The downside is that in the headings of the table there are no visual cues to what is being sorted or in what direction.

I didn't have to use XORs, but I sure used a lot of reflection, because I didn't know beforehand what type of objects and which properties I would be sorting. It was also interesting to explore the reflection world of generics, particularly creating a generic delegate in run-time!

Here is the most interesting method in the code:

protected void DataSource_Selected(object sender, ObjectDataSourceStatusEventArgs e) {
if(e.ReturnValue != null) {
if(sortExpression != null && sortExpression != string.Empty) {
MethodInfo sort = new List(e.ReturnValue.GetType().GetMethods()).Find(
delegate(MethodInfo m) { return m.ToString().ToLower().StartsWith("void sort(system.comparison"); });
if(sort != null) {
object helper = Activator.CreateInstance(
typeof(ComparisonDelegateHelper<>).MakeGenericType(sort.GetParameters()[0].ParameterType.GetGenericArguments()[0]));
MethodInfo generateComparisonDelegate = new List(helper.GetType().GetMethods()).Find(
delegate(MethodInfo m) { return m.ToString().Contains("GenerateComparisonDelegate"); });
sort.Invoke(e.ReturnValue,
new object[] {generateComparisonDelegate.Invoke(helper, new object[] {sortExpression, sortAscending})});
}
}
}
}
If it comes in handy or you're just curious, download the whole thing.

The usage of the GridViewSorter control is as simple as this:
<gv:GridViewSorter runat="server" ID="gvs" EnableViewState="true"
GridViewID="SomeGridView" DataSourceID="SomeDataSource">
</gv:GridViewSorter>

Temporary variables regarding the last sorted field and direction are kept on the viewstate, but could also be as hidden fields on the form or even in the session (the latter would have to take care of collisions with other pages or even the same page open in two browser windows).


Hope your Christmas was good. Happy New Year!