The shield of YAGNI

Diposting oleh good reading on Sabtu, 31 Maret 2007

YAGNI (you ain't gonna need it) is a good principal, but like anything, too much of a good thing isn't very good at all.

Yagni is a tool to keep us on track, to help us make decisions and guide us in our development. Like any other practice, it does not stand on its own without logic and reason. Sometimes its thrown around like my parents used the phrase, "because I said so." And while that works well for a crying three year old who wants to stay up late, any catch all phrase is dangerous.

When I am writing code, I add abstractions I don't need. You can argue this goes against yagni, because you don't need it (and you ain't gonna).

These abstractions are not there to support behavior that may exist in the future. They are added because, when things change (and they always do), it has ALWAYS been a lot more painful when they did not exist.

There is a very distinct difference between this and adding extra functionality or abstractions to enable change you think will happen.

This is an important difference.

Next time you are having a discussion and yagni is brought up, think about which one is driving what you supposedly don't need.
More aboutThe shield of YAGNI

Homemade Sushi

Diposting oleh good reading on Rabu, 28 Maret 2007

Since there are only 3 of us at home this week, decided to make sushi for dinner last night. Despite the fact that I have made these sushi for the 5th time this year, I still couldn't manage to roll the maki neatly :(

I find it very tricky to be able to spread the sushi rice evenly on the sheet of nori (Japanese seaweed). Even if I could get a decent rolled "log" of maki, I always "deformed" them when trying to slice it into pieces. Instead of neat round shapes, they ended up in irregular forms. I wonder how many times I must try before I could get a nice and neat on my maki?!

For the filling, I used crab meat sticks (my kids favorite), cucumber, salmon spread (ayam brand) and some pork floss. The combination of these ingredients was just right, although they were not the ones used in authentic California rolls.

With these basic ingredients, I made 4 types of sushi...Chumaki, Hosomaki, Gunkan-maki and Uramaki.

Maki Zushi
Maki Zushi or rolled sushi is made with a sheet of seaweed spread with vinegar flavored Japanese rice and then rolled up with different fillings. Hosomaki are small sushi rolls about 1 inch in diameter. I simply rolled up crab meat sticks with some mayonnaise to form these thin rolls. The medium ones are called Chumaki, around 1 1/2 inches wide. I have not ventured into making Futomaki which are large rolls, more than 2 inches wide.


Gunkan-Maki (Battleship Sushi)
These are special type of the nigiri zushi(finger sushi). Battleship sushi is make by wrapping a strip of seaweed around a small oval-shaped rice ball, and topped with soft fillings such as fish roe. The collar of nori that's wrapped around the rice ball make the sushi looks like a tiny vessel...hence the name battleship sushi. I made mine with pork floss and salmon spread toppings.

My younger boy enjoyed making the rice balls. Somehow, small kids simply like to play with anything that they could shape with their hands, like playdough and making sandcastles.


Uramaki Zushi (Reverse Maki)
These reverse maki or inside-out rolls are wrapped with the rice on the outside and the nori within. This is supposed to be easier to make than Chumaki as the sushi rice on the outside helps stick everything together when you roll it up. On the contrary, I found it more difficult as the filling couldn't stick on to the nori, as such they were not firmly bounded together. I coated the outer layer of rice with toasted black seasame. The seasame really enhanced the taste of the maki, and they were the most delicious of the lot!

More aboutHomemade Sushi

Xbox is Down!

Diposting oleh good reading on Selasa, 27 Maret 2007

And the oblivion expansion, Shivering Isles, comes out today.

What timing... not like I'd be playing anyway, being that I'm at work and have to paint my living room when I get home :(
More aboutXbox is Down!

Bonus Session

Diposting oleh good reading

Oksana and my session about pair programming is now featured on the bonus session page for devteach, check it out!
More aboutBonus Session

Dried Fig Muffins

Diposting oleh good reading on Senin, 26 Maret 2007


Dried figs are very healthy snacks. A cup of figs will give as much calcium as a cup of milk. Besides being rich in calcium, they are also high in dietary fiber and contain other minerals such as iron, potassium, omega-3 and omega-6 essential fatty acids. I used to eat quite a fair bit of dried figs when I was pregnant, they are really a good alternative source of calcium since I didn't really like milk.

I didn't know that dried figs could be added to muffins until I came across this recipe from a cookbook, Muffins by Williams-Sonoma. It didn't take me too long to get a pack of dried figs to try it out.


Unlike most muffin recipes where dried fruits are simply added to the batter, this recipe recommended that the dried figs be soaked in a mixture of orange zest, apple juice and melted butter for an hour. This softened the dried figs and turned them into a rich mahogany colour. When the muffins were still baking in the oven, my kitchen was filled with this sweet and enticing "perfume" of dried figs. The pleasant aroma lingered till the muffins were completely cooled. The muffins were a little on the sweet side (although I did cut down on the sugar a little), mainly due to the figs. My little one though I have added in a candy in the muffins ! The texture was a little dense, but overall the taste was really delicious. Definitely a wholesome and healthy bake, good for breakfast or as tea-time snacks.

Ingredients:
(makes 11 muffins)

375g dried figs
90g unsalted butter
250ml apple juice
grated zest of 1 orange
315g plain flour
2 1/2 teaspoons baking powder
1/2 teaspoon salt
125g granulated sugar
60g dark brown sugar
2 large eggs, lightly beaten
1 1/2 teaspoon vanilla extract/essence

Method:
  1. Remove the stem and cut dried figs into quarters.
  2. Heat apple juice and butter in a saucepan over low heat until the butter is melted.
  3. Remove from heat and add in the figs and orange zest. Leave to cool until the figs are softened, about 1 hour.
  4. Preheat oven to 190 degC. Grease muffin cups with butter or line with muffin liners.
  5. In a mixing bowl, stir together the flour, granulated sugar, brown sugars, salt and baking powder.
  6. Make a well in the centre and add the cooled fig mixture, eggs and vanilla. Stir until just combined. Do not overmix, the batter will be slightly lumpy.
  7. Spoon batter into muffin cups, filling to the rim of the cup.
  8. Bake for 20 ~ 25 mins, until golden, and toothpick inserted into the centre comes out clean. Transfer muffin pan to cooling rack and let cool for 5 mins. Unmold the muffins and let cool completely.
More aboutDried Fig Muffins

I am no electrician...

Diposting oleh good reading on Jumat, 23 Maret 2007

Considering the amount of time I spent as an undergraduate designing analog circuitry, I thought I'd be a decent electrician.

This couldn't be more wrong.

1. My dexterity skill is low, maybe a 9. I'm a klutz, have poor motor skills, my hand writing is illegible, the list goes on. This does not work well for wire manipulation. Actually this does not work well for manual labor in general.

2. Theoretical knowledge of electricity doesn't help much; it may even hinder you (it hinders me). In general, I like to explain everything, my husband calls this phenomena, Wendy's wack a** theories. I think coming up with connections and reasoning (more like randoming) is a lot of fun. With electricity, my theories are convoluted, usually involve Ohm's law, and are ALWAYS wrong.

3. I lack patience and after failing at wiring a circuit I start hacking away at it, just trying to make anything work... Constantly running back and forth to and from the circuit breaker. Like hacking code, this just wastes time and leads to poor quality. Not the best sacrifice when it comes to electricity in your home.

Recently, I've spent a great many hours changing a light fixture, outlets and switches around the house recently and I've come away with this knowledge:

1. A voltage tester is a worthwhile investment. I don't own one, but I really, really should. Its like coding without a debugger and with no TDD, a debugger would be quite useful.

2. Before you replace existing circuitry, study the current setup carefully before taking it apart. Otherwise, you will be confused by the 8 wires available when you only need 2.

3. Like working with other peoples code, working with others peoples circuits is scary, and things built a long time ago were built, well, oddly. Keep this in mind.

4. Refactor existing circuitry one switch, outlet, etc at a time. Its annoying, because you need to return to the circuit breaker a lot (unless you live on the edge), but at least you are always in a working state and you know when you broke your circuit.

5. If you are replacing an outlet with two pairs of wires, it is either powered by separate circuits or powering something else. You can check the hot side of the circuit to see if the bridge connecting the top and bottom is there -- if it is, then the bottom wires are being powered by this outlet, and you don't need to remove the bridge on the new outlet. If its not, remove the bridge on the new outlet. If you get this wrong, things will break.

6. Having a pair working with you is priceless. They can call 911 for you. And I was told this afternoon that your dog doesn't count (unless it knew how to call for help).

7. No matter how annoyed and frustrated you are, its never a good idea to do one more quick "test" without turning off power at the circuit breaker.

If I approached circuitry like I approached software, I would be a much better electrician! I suspect applying agile and xp methodologies work very well for all home improvements. I hope I remember this tomorrow morning!
More aboutI am no electrician...

Chewy Oatmeal Raisins Cookies

Diposting oleh good reading on Kamis, 22 Maret 2007

Almost two months back, my friend gave me a pack of rolled oats. I have not used it as I have yet to come across any suitable recipes. Lately, I have set some basic requirements when it comes to baking recipes...the amount of sugar and fat to be used should not be too overwhelming so that I could still indulge on the bakes without expanding my waistline further ;)

I finally found this cookie recipe that uses roll oats, with only 1 egg and vegetable oil instead of butter. It's taken from a cookbook, Homemade Cookies by Jacqueline Bellefontaine. The method for making these oatmeal raisins cookies is almost similar to the muffin method, where the wet ingredients(milk, egg & oil) are added to the dry ingredients (flour, rolled oats, sugar, raisins) to form a soft dough. The cookies were lightly browned by around 10mins in the oven, and I gave it a couple more mins to reach golden brown.


This is the very first time I have tasted any cookies that are made of roll oats. I was slightly taken aback by the texture of the cookies. They differ from the familiar crunchy texture I always associate with cookies. Instead, they are rather chewy, probably due to the rolled oats...and the middle is soft and moist, a result of the use of liquid oil, I think. I don't know whether this is the right texture and I seriously think that they are like half-baked cookies!

I personally have yet to acquire the taste of such kind of cookies, but surprisingly, my better half finds it very delicious! Well, like what he commented, "These certainly tasted not like cookies and not like muffins either", but he likes it that way...


Ingredients:
(makes about 36 cookies)

150g plain flour
150g rolled oats
1/2 teaspoon baking soda
150g light brown sugar
50g raisins
1 egg
125ml vegetable oil (I used sunflower oil)
4 tablespoon milk

Method:

  1. Preheat oven to 200 deg C. Lightly grease a baking sheet (I lined the baking sheet with parchment paper for ease in cleaning).
  2. Mix together flour, oats, baking soda, sugar and raisins in a bowl. (I 'plump up' the raisins a little by soaking them in water for a couple of mins.)
  3. In another bowl, whisk together the egg, oil and milk.
  4. Make a well in the centre of the dry ingredients and pour in the egg mixture. Mix together to form a soft dough.
  5. Place spoonfuls of dough well apart onto the baking sheet, and flatten slightly with the tines of a fork.
  6. Bake for about 10 mins. Transfer cookies to a wire rack to cool completely. Store in an air-tight container.

More aboutChewy Oatmeal Raisins Cookies

DevTeach here we come!

Diposting oleh good reading on Rabu, 21 Maret 2007

If you missed Oksana and me at Code Camp (or just can't get enough), we'll be hosting a session on pair programming at DevTeach in May!

Scott Bellware put together an excellent Agile track, and its going to be a great event.

If its not on your schedule, you're not thinking about missing a conference that features speakers as exciting as Oksana and me, are you?
More aboutDevTeach here we come!

I'm an abstract thinker

Diposting oleh good reading on Selasa, 20 Maret 2007

You know those idiot savants who see numbers as colors and can do complex multiplication? I'm kinda like that... I don't think of code or abstractions, I just know them immediately for every problem I encounter... kinda like seeing numbers in color, though I'm far from a programming idiot savant.

I see connections and patterns in everything, and I spent a lot of my early development days building frameworks. This was fun. At one of my previous jobs, I built so many frameworks, they created an unrelated (successful) product leveraging the frameworks from the original (also successful) product. There was a third, but I wouldn't call that as successful; its scope and complexity were too large and initial requirements were unrealistic (though I do think a poor developer is working on it and cursing me at this moment, sorry Eli).

I digress...

At Oxygen, we don't build frameworks, we use other peoples. In the beginning of my career I used many c++ libraries and frameworks that made my life more difficult than if I wrote the code myself and I stayed away from using other people's code -- it never did exactly what I wanted, it was buggy, and I had to take time to learn how to use it.

However, Kris and Luke are really good at finding the right frameworks and learning how to use them. This makes using other people's code a lot more approachable and I've grown to love some, like Castle.

Here are just a few reasons to use other people's frameworks:
1. The code evolves for you
2. Luke and Kris will figure out how to use it*
3. Respect from peers who use the framework (oh, you use castle, you must be extra cool and smart! -- I don't know if this happens in real life, but you never know)
4. Common language between developers
5. Global reduction of rebuilding of the wheel (wouldn't it be great if we shared all our code?)
6. You don't have to rewrite it when you change jobs

Here are some reasons to write your own:
1. It works exactly how you want to and you can change whatever you want (yeah, you can do this with open source, but I'm lazy and don't want to work in other peoples stuff :P)
2. You don't need to learn how to use it
3. Its fun
4. Pride of writing something cool (this can be misinterpreted as stubbornness or vanity so I would leave this one on the down low)
5. You could contribute it to open source and be super nice and cool :)
6. It doesn't exist

*You don't necessarily need someone named Luke and/or Kris on your team, just someone who's patient and interested in learning how to use other people's work :)
More aboutI'm an abstract thinker

Whats in a name?

Diposting oleh good reading

English is ambiguous. It is easy to misinterpret well formed sentences not to mention variable or class names.

As developers, we put the definition of a class in its name. Its a good practice. It enhances readability. Its a difficult skill to master, but important.

While a good tool for readability, it is not a substitute for documentation or a complete way of understanding a class' responsibilities or interactions (tests work great here). Even if a class is named well, it can still be misinterpreted and we enter a dangerous path when we rely on names alone.

English can't be taken too literally and what means something to someone means something completely different to someone else. I'm not sure English will ever be enough context to understand a class... With resharper, I'm a big fan of ctrl-b (go to definition), ctrl-alt-b (go to inheritor) and ctrl-alt-f7 (find usages), this is a quite a useful and quick way to explore code and can take even less time than analyzing a name!

The other day I read some bizarre, but entertaining and artistic naming conventions and I found readable and more enjoyable... interesting idea; I wonder if it would ever catch on :)
More aboutWhats in a name?

Depressing blog?

Diposting oleh good reading on Senin, 19 Maret 2007

One of my fellow developers told me this blog has been depressing... making them feel that we aren't quite the snazzy agile team.

I understand why they feel that way.

In the spirit of agile, I write openly about our shortcomings. In many companies people are reprimanded or even fired for pointing out issues internally, forget about posting them publicly.

I would not show weakness in our agile group if I were not confident in our teams spirit, devotion, intelligence and adaptability. We all love and appreciate the agile practices and I feel very lucky to work with such a talented group.

Agile is a great tool, but its difficult. It takes effort. Its frustrating. Like anything worth doing, you have to work at it. And like anything you love, sometimes you write about why its so great and sometimes you need to write about why its so difficult.
More aboutDepressing blog?

Banana Blueberry Bread

Diposting oleh good reading on Minggu, 18 Maret 2007

The one week school holidays is over. It was a good break for all of us. The boys are back to school and I had some quite moments this morning.

I had some left over blueberries and bananas, and decided to bake something with them. After looking through the various recipes I have gathered, a banana quick bread recipe from the Australian Women's Weekly cookbook series, Great Casual Food, caught my eye. I liked the fact that it uses 1 egg and only 20g of butter!

I added in blueberries, reduced the sugar amount, used low-fat milk and turned it to a Banana Blueberry Bread. I don't know whether this could be considered low-fat, but I would certainly feel less guilty if I eat more than 2 slices at a go.


The taste of quickbread is almost similar to muffins...this loaf turned out to be very soft and fluffy, especially when it was fresh out of the oven. The sweetness of the bananas blends very well with the slightly tangy blueberries. This recipe is certainly going to be the "base" for all my future banana quickbreads...besides being low fat, it's so easy to make! I am sure it can live up to other variations such as banana-strawberries; banana-orange, banana-raisins, and of course banana-chocolate chips.

Ingredients:
(makes one loaf)

185g self-raising flour
20g butter
80g sugar
1 egg, lightly beaten
60ml low fat milk
1/2 cup mashed banana (about 2)
1/2 cup fresh blueberries

Method:
  1. Preheat oven to 180 degC. Grease 14cm x 20cm loaf pan; line base with parchment paper.
  2. Working over a bowl, toss the blueberries with about 1 ~ 2 teaspoon of flour in a sieve, and set aside. Coating the blueberries with flour helps to keep them from sinking to the bottom of the muffins as they bake.
  3. Sift flour into a mixing bowl, rub in the butter with fingertips.
  4. Stir in sugar, egg, milk and mashed bananas. Do not over mix, the batter should be lumpy. Gently stir in blueberries and spoon mixture into loaf pan.
  5. Bake for 30 mins or until skewer inserted into the centre comes out clean.
  6. Remove from oven, let cool for a few mins. Unmold and leave to cool completely.
More aboutBanana Blueberry Bread

Chocolate Swirl Bread

Diposting oleh good reading on Kamis, 15 Maret 2007


Ventured into making this challenging Chocolate Swirl Bread this morning.

When I first saw this recipe, posted by Ida of Baking Fiend, I thot I should only give it a try after I am more comfortable with bread-making. With the little success I had earlier with my wolf berries bread, I though I should be able to manage, although this is only my 4th attempt in bread-making. Little did I know, it turned out to be a really challenging task!


After more than 30 mins of continuous kneading, the stubborn dough still remained very sticky! Since I had already gone so far, I refused to give up. I continued to wrestle with the dough for another 10 more mins and it became less sticky and slightly smoother. By then, I was too tired, and had to surrender to the dough...I left it to proof, hoping for the very best.


Fortunately, the 1st proofing turned out fine.


I took out the chocolate filling which I made last night and tried to follow the instructions to wrap the dough with it. It appeared easy before the actual hiccup surfaced. While trying to roll the dough to the required size, the chocolate paste came oozing out. I tried to "patch" out with dough from the other sides, but it didn't really help. I quickly folded the dough as instructed and left it in the fridge for an hour...hoping it would help to freeze up the chocolate paste a little. The final step was real messy...I had the dough all covered with chocolate paste, after trying to twist and plait it...and the dough really looked horrendous!!!


Since I was already at the final step, I give it a shot and sent the dough into the oven after the final proofing. As I was attending to my younger son, I didn't have a chance to remove the bread from the oven on time. The top was almost burnt :'(

Naturally, with so many hiccups along the way, I wasn't able to achieve the numerous beautiful swirl as compared to those made by Ida. Luckily, other than the slightly burnt crust, the texture and taste of the bread was surprisingly good...soft, light, airy, and almost feathery! Half of the loaf was gone by tea time and my elder boy gave me a rating of 4.5 out of 5 stars :))


It was only after making the bread that I managed to get to the original recipe in Japanese. The photos posted on the Japanese website will certainly help to give a better idea how to roll and shape the dough correctly in order to get the nice swirls. There is also a tip that says to cover the top with foil when the bread starts to brown to prevent it from getting burnt.
More aboutChocolate Swirl Bread

where do the bugs go?

Diposting oleh good reading on Rabu, 14 Maret 2007

Our 45/55 resource split (or lack of resources) has become apparent on our new product development. We spend 45% of our time on new product work (a very exciting WPF application, Ript) and the other 55% on internal enterprise work (to keep the tv station up and running). This split yields about 4 development days on Ript during each two week sprint .

We're all excited about Ript and want to share it with our friends and family. This gives us extra drive to complete the list of stories left for release!

This drive coupled with the lack of time has become evident in a recent spike in bugs and refactoring cards. The goal of the current sprint is stabilize the application, because we ended our last sprint with an unreleasable application. So, our burndown for the sprint included every known bug in application.

Our burndown looks something like this:
Sprint goal: Stabilize application -- fix 18 open issues
Bugs fixed so far: 26
Bugs left: 16 (I told you that last release was unreleasable!)

Because our goal is stabilize the application, we're treating the bugs as stories and adding stories to the sprint as bugs are found.

How did we get here? We are all profession, strong developers who are very committed to quality...

What went wrong?

Well... we've been "finishing" stories when they aren't really "done."

This isn't happening because we are lazy or over worked or don't understand the requirements, but because we are so desperate to move forward in the project.

When you have a 2 week iteration, even if you don't spend all 2 weeks on the project, you want to finish 2 weeks of work. Especially after a few weeks of enterprise work that take up more than 55%...

Enough explaining why we have bugs...

What was this post about anyway? Oh yeah... making bugs stories...

I had an ah ha moment the other day when I was thinking about where bugs belong in the sprint backlog. As a developer and a user of an application, I don't want any bugs. Our customer proxy may want features before bugs are fixed, but we may want to fix bugs before adding new features, because the bug could be a smell of a bad design or some needed refactoring... basically prioritizing bugs difficult!

Have you seen this bug rating system before (or something similar)?
Priority 1: Application crashes, no work around, data corrupted/lost
Priority 2: Application crashes, work around OR bug, data corrupted/lost, no work around
Priority 3: bug, no data corrupted/lost, no work around
Priority 4: bug, data corrupted/lost, work around
Priority 5: UI interaction, nuisance, no loss of data or work

This makes prioritizing bugs easy, but there are a lot of times a priority 5 issue, which is usually considered releasable, could be the downfall of an application. Meanwhile there could be a random crashing issue that occurs on one machine that gets fixed first because it is priority 1... not to mention, its so random it takes days to track down (there goes an entire sprint!)

Not only do these make little sense for prioritizing your sprint, they also offer no help when it comes to quantifying the impact of bugs on the teams velocity...

Introducing my new system of bugs:

Rules:
1. All bugs are stories
2. Like other stories, they are prioritized by the client and estimated by the team
3. If a bug appears as a direct result of a story completed in the sprint, it is added to the sprint and impacts velocity
4. Every sprint there is a small timebox to fixing/investigating bugs that the client hasn't included in the sprint (this doesn't affect velocity and the sprint should be planned accordingly)
5. Although the client prioritizes the backlog, the developers should feel confident about their codebase and may request bugs get fixed ahead of higher priority stories

What do you think?

The main idea is that bugs, like anything else, need to be user facing and should impact your velocity and sprint planning.

Like some other things, bugs happen :)
More aboutwhere do the bugs go?

xkcd

Diposting oleh good reading on Selasa, 13 Maret 2007

Robert recently posted about a web comic he found and I love it!
Some of my favorites:
fun with resistors
sometimes math is useless
pair tactics

Thanks Robert!!
More aboutxkcd

Blueberry Cream Cheese Tart

Diposting oleh good reading


When I saw a picture of this very delicious looking blueberry tart from a Chinese cookbook (甜心小妙厨), I thought I should give it a try. I like the way the tart is decorated, and it will be a good chance for me to practice my piping skill. The recipe looks simple, as it is quite similar to the no-bake oreo cheesecake I have done before. I have came across a low-fat cheesecake recipe, where cream cheese is mixed with yogurt. Hence, instead of the fresh cream called for in the recipe, I replaced it with non-fat plain yogurt. I was glad with what I did as the taste is really awesome, and it is a much healthier version.


The recipe in the cookbook didn't give any instructions on how to decorate the tart. I tried to follow by studying the picture. It turned out that my "stars" were too big, as such, after lining the blueberries in 2 circles, there was little room for the blueberry jam! I should have used a smaller piping tip. The tart was really out of proportion, as the "stars" were bigger than the blueberries :(

The cream cheese mixture was a little soft to handle when I tried to do the piping. In the end, some stars were big, some were small. It didn't help when my younger boy came over to have a hand in squeezing the piping bag. He found it rather interesting. We had fun placing the blueberries as we tried to look for those which were of the same size...he happily finished up the remaining "unwanted" blueberries.

My elder boy couldn't wait to eat the tart when he saw the finished product in the fridge. He missed out the fun as he was busy catching up with his holiday homework...poor fellow! He finally got this slice after dinner. He likes it very much and the slice was gone within seconds!



Ingredients:
(makes one 18cm tart)

for the base:
125g digestive biscuits, crushed into fine crumbs
60g butter, melted

for filling:
1 tablespoon gelatin powder
40ml boiling water
250g cream cheese
50g icing sugar
1 cup non-fat plain yogurt
1/2 teaspoon vanilla essence
1/2 cup blueberries
3 tablespoon blueberry jam

Method:
  1. Mix biscuit crumbs & melted butter together and press firmly with the help of a spoon onto the base and side of a 18cm tart pan. Chill for 30 minutes.
  2. Place gelatin powder and boiling water in a bowl. Heat a pot filled with some water until just simmering and place the bowl inside the pot. Dissolve gelatin and boiling water in the bowl. Keep warm.
  3. With an electric mixer, beat cream cheese , icing sugar and vanilla essence until smooth and creamy.
  4. Add in yogurt and continue to beat till smooth. Blend in gelatin solution and mix well.
  5. Pour and spread the cheese mixture evenly on the biscuit base. With the remaining cheese mixture, pipe two rings of stars. Then, place two rings of blueberries and fill the centre with blueberry jam. Chill for 3 to 4 hours before serving.
More aboutBlueberry Cream Cheese Tart

Continuous Integration, revisited...

Diposting oleh good reading on Senin, 12 Maret 2007

Sorry for the delay... I was sick with a broken dev machine, and without our source tree for reference, my knowledge on the subject is, well, not quite there...

Oxygen was setup for continuous integration before I started, so I know the "how" it works, but not the "why."

Before I started, I never had continuous integration setup (wow, I didn't know what I was missing!), so I don't know if my previous organizing methods would have worked so well... (even if I did really like them)

On to the point...

We use subversion for source control and have a build server running CruiseControl. We try to keep the build machine clean, so we're confident we have the project dependencies under control. The build machine does not even have Visual Studio installed -- just the .NET SDK so our projects can be built on the command line.

As for the development tree, its pretty simple:

1. Project Root
a. lib (Oxygen libraries)
b. tools (3rd party libraries) -- references like mbunit or rhinomocks and tools needed to build (like nant, msbuild...)
c. src (project source code)

There are some other folders in the root, but they are specific to the project, like documents or media... All references are to assemblies in lib or tools, never the GAC, this minimizes dependencies that need to be installed on the build server.

The only other file of note in the project root is our build file, which is a NAnt script. This script has several targets, like compile, unit-test, setup-dev-environment, install, cruiseconrol, etc (such a pain to write, but well worth the effort!) The cruisecontrol target, compiles, runs tests, builds installers, deploys installers, runs metrics, sends us result emails and has our bunny tell us updates.

So, "D", I hope this satisfies your curiosity about our development tree! If you have more specific questions, please let me know :)
More aboutContinuous Integration, revisited...

Chocolate Chips Brownie Muffins

Diposting oleh good reading on Jumat, 09 Maret 2007

Woke up early this morning to make these brownie muffins for breakfast.

This is the second time I have made these rich muffins...they are brownies actually. I adapted the recipe...Pecan and Chocolate Brownies, from one of the Australia Woman's Weekly Cookbook series. I didn't regret getting up slightly earlier than my usual Saturday mornings. I am quite happy with the result of the above photo. This is one of the better photos I have taken so far. The early morning sun gives enough lighting for this shot, which I took in our study room. Most of my photos are too dark because of the poor lighting condition in my kitchen.

These brownie muffins or muffin brownies, were neither brownie-like or muffin-like!

They were less fudgy that brownies...slightly more cake-like. They didn't taste exactly like muffins either, as they were kind of dense as compared to the fluffy texture of the usual muffins I made. I would say they were a "cross" between the two. In terms of taste, they were really good! "Yummy! Very good but not very sweet." my younger boy was nodding his head off with approval. I have cut down on the sugar this time as they were too sweet when I first made them. If you have a sweet tooth, do feel free to add in extra sugar ;)

Ingredients:
(makes 6 muffins, with diameter 2.5" by height 1.5" muffin cups)

80g butter, chopped into chunks
150g dark eating chocolate, chopped
100g sugar (the original recipe calls for 165g brown sugar)
2 eggs, lightly beaten
1 teaspoon vanilla extract
100g plain flour
1 tablespoon cocoa powder
A handful of chocolate chips

Method:

  1. Preheat oven to 200 degC. Line muffin pan with paper liners.
  2. Sift together flour and cocoa powder, set aside.
  3. Place butter in a saucepan, melt over low heat. Once the butter starts to melt, add in the sugar. Stir to prevent sugar from getting burnt. Add in the chocolate and stir still smooth.
  4. Transfer chocolate mixture to a mixing bowl. Stir in the eggs gradually, followed by the vanilla extract, then the sifted flour & cocoa powder mixture. Stir till just incorporated.
  5. Divide batter into muffin cups. Sprinkle with chocolate chips and bake for 20 mins or until skewer inserted in the centre comes out clean. Do not over bake as the muffins may get dry.
More aboutChocolate Chips Brownie Muffins

Japanese Curry Rice

Diposting oleh good reading on Kamis, 08 Maret 2007

One of the first few simple dishes which I have learnt after I picked up cooking, is the Japanese Curry Rice. My son fell in love with this dish after having tasted it at a foodcourt. I was very glad when I came across this ready mix sauce at the Cold Storage. It is one of the few Japanese products that have instructions printed in English. I followed the recipe and was able to get it right the first time. There are 3 different types of flavours available, Mild, Medium and Hot. I use the mild one as my younger boy still can't take spicy food. This sauce is in a curry block form, there is another type which is in liquid form, which I have not tried.

It's really a very simple dish where you just stir fry some onions, meat (be it chicken, seafood or beef) with some carrots and potato chunks. Add water to simmer till the vegetables are done (about 10~15 mins) then add in the curry blocks. Continue to simmer for another few more mins till the sauce is thicken. I cook this with only a saucepan, so cleaning up is especially easy. Serve the curry with Japanese rice...long-grain rice is just fine as well.

One thing to note though...your kitchen will be filled with this thick curry aroma (almost like authentic Indian curry)...and it lingers for a long while before the smell diffuses.

More aboutJapanese Curry Rice

Sprint Planning

Diposting oleh good reading on Rabu, 07 Maret 2007

At the end of every sprint review, we have our sprint planning meeting... This is our most painful meeting. We've done a lot to mitigate the suffering and the pain has lessened in return. However, our process, like any, is not without flaws and some planning sessions just plain suck.

During sprint planning we review the user stories in our backlog. For our enterprise projects, Salim, our SCRUM master, keeps track of the stories and priorities and the rest of the developers usually know whats going on too. For the new product development our client proxy, Ilio, manages the backlog, which is always well thought out and organized.

Before the review, the developer's knowledge of the stories is anywhere from nothing to very familiar. The more unfamiliar we are with the stories, the more painful our meeting.

Makes sense, because unfamiliarity and uncertainty go very well together, and uncertainty, while unavoidable, makes for long conversations and design talk. Too many unknowns during one sprint review makes us desperate to end the meeting.

The meeting is suppose to go like this:
1. Salim reads a story card
2. On the count of 3 we hold up an estimation card (very easy, easy, medium, hard, very hard and unknown)
3. Salim writes down the estimation
4. repeat

This process repeats until we've estimated more than an iteration of work.

Seems pretty simple, right?

Except, it only happens that smoothly when:
1. The story and solutions are well known
2. Everyone is focused

Sometimes the process is more like this:
1. Salim reads the story card
2. Ilio is asked to explain what it means
3. Ilio explains the story
4. Someone disagrees with Ilio about some behavior on the card
5. Ilio explains the logic again (he's so calm its amazing) and if necessary goes to Bob, our user interaction guru
6. Salim asks if people are ready to estimate
7. Someone answers, "what story are we doing?"
8. The card is re-read
9. On the count of 3 we hold up an estimation card
10. There are only 2 estimations that match, the others range from easy to question
11. The highest estimation explains their reasoning
12. The lowest estimation explains theirs (unless they changed their minds)
13. Salim asks if we want to re-estimate
14. On the count of 3 we hold up an estimation card
15. Kris or Luke make a final decision if we don't agree
16. Salim writes down the estimation
17. repeat

That took a lot longer to read, no? Believe me it makes the meeting take a lot longer too!

Does this make you think we're disfunctional? I think we'd be disfuctional if it always went perfectly... That may sound odd, but its conversations like these that bring interesting design discussions, find issues we missed, discuss user interactions we don't like, etc. These are important conversations to have.

When planning gets filled with unknown stories, we'll have 15 minute meetings each day to discuss stories for the next sprint. This helps, but is difficult too, because its another meeting to fit in during non-war room hours and there is very little time as it is...

I think we all decided that we'd rather have one long day of meetings (which we're having anyway) and a slightly more painful sprint planning than think about sprint planning every day of the week.

At the end of it all, we just want to code :)
More aboutSprint Planning

Heng Hwa Noodles

Diposting oleh good reading on Selasa, 06 Maret 2007


I cooked this noodles or mee sua for dinner last night. It's my own "lazy" version of our traditional dish.

When he was still a child, my dad sailed from Putian City in Fujian province in the Southern China to Singapore. Our dialect is Putian Hwa, or more commonly known as Heng Hwa here in Singapore. It has been a tradition that we eat this mee sua dish early in the morning on the first day of lunar new year, every year. It's meant for longevity, the noodles are really very long! These noodles are much thicker than the usual mee sua. It's kind of difficult to get this type of noodles here. My dad usually bought them through his Heng Hwa contacts. As such, we would only be able to cook this dish during the lunar new year period. This dish is very well-liked by the adults and children in my extended family, including my husband and brothers/sisters-in-laws who are from different dialect groups. They look forward to it every lunar new year and all of them asked for 2nd servings without fail.

The other type of Heng Hwa noodles, which we call "pah mee" in our dialect, or the Chinese translation (打面) is commonly available at the wet markets here. Some locals here who have tried Heng Hwa cuisines will know that the dish is also called Heng Hwa Lor Mee. I will probably feature that dish in my later post.

Coming back to this mee sua...it consists of 3 parts...the soup, the noodles and the toppings. The soup is usually clear chicken soup, but for a change, I made pork rib soup instead. The noodles are boiled and drained and mixed in a bowl with some oil and chicken soup, almost like preparing pasta. The noodles will become very sticky if they are not mixed with some oil. The toppings are usually stir-fried assorted mushrooms with green beans. Besides that, deep-fried seaweeds and peanuts are a must to top off the dish. As I was too lazy to stir-fry the mushrooms, I cooked them in the pork rib soup, and simply blanch the green beans. Mine came out to be a less oily version, but the taste was still as good :))
More aboutHeng Hwa Noodles

Development tress and continuous integration...

Diposting oleh good reading

Oksana, who doesn't have a blog to answer this on her own, is very disappointed I have not responded to the comment asking how we setup our development tree for continuous integration...

Well, its war room hours and I haven't had a chance to respond, so this post serves as a reminder, that yes Oksana, I will respond... back to coding :)
More aboutDevelopment tress and continuous integration...

InternalsVisibleTo

Diposting oleh good reading

At the chat on mocks, I mentioned you can test "internal" methods in your test fixture even if it isn't in the same assembly as the class under test (CUT). I used the wrong terminology (of course) and called it making the assembly friends, so if you spent the last few days googling that, my appologies :P

Testing internal methods comes in handy quite a bit:
1. Testing things that you don't want other assemblies accessing
2. Testing state machines or some other context of a class that you wouldn't otherwise expose
3. Using partial mocks

So, how do you let your test assembly access you internal methods?

Its quite easy, first you'll need your test assembly to have a strong name. Once thats done, you need to add one line to your CUT's AssemblyInfo.cs file.

[assembly: InternalsVisibleTo("TestAssembly, PublicKey=yourpublickey")]

For those of you used to 2003, you give your assemblies key files in the properties of the project and not in the assembly info :)
More aboutInternalsVisibleTo

Just a loaf of bread

Diposting oleh good reading on Senin, 05 Maret 2007

It's been quite a while since I last made a bread. I've wanted to try making one last week, but due to the rainy weather, I didn't attempt. I doubt the dough would rise properly when the weather was so cooling. My friend has told me that I could leave the dough in the oven (turn to a low temperature) to proof, but I was afraid that I might "kill" the yeast. Not that I am afraid of failure, but I didn't want my energy spent on 25mins of continuous kneading gone to waste ;p

I bought a loaf pan last week just so that I could make a loaf of bread. So far this is my 3rd attempt in bread-making. I made buns previously. This is my first try on loaf making. I was very happy with the result. The loaf looks so "traditional", like those bread made by traditional bakery shops.

I saw a toast bread recipe from this site and thought what a wonderful idea to have wolf berries (枸杞子) in the bread as they are supposed to be good for vision. I didn't follow the bread recipe as it didn't state how the texture of the bread will be like. I used the sweet buns dough instead, as my kids prefer breads that are soft and fluffy.

The effort spent on kneading the dough was really worth it. After popping the loaf into the oven, in no time, my kitchen was filled with a familiar aroma of fresh bread baking...just like the alluring aroma coming from a bakery. The bread is soft and fluffy, but somehow, I couldn't achieve the same kind of "swirl" inside the loaf as shown by this photo. Nevertheless, I thoroughly enjoyed the entire bread-making session this morning. This little success really gives me the boost to try more challenging bread next time.

More aboutJust a loaf of bread

Marsha Marsha Monkey

Diposting oleh good reading on Sabtu, 03 Maret 2007


This is meant to be a valentine's day cake. I know, it's way too belated. But both my boys were down with 40degC fever on valentine's day...so I didn't have the energy to bake this. It's no joke having to wake up every other hour in the middle of the night to check both their temperatures, and it was like that for a few nights in a row! Then, my better half was away for overseas work and didn't return until last night. Anyway, since today is the 15th day of the Chinese New Year, it's also the Chinese version of the valentine's day. So I merrily set off to bake this Chocolate Banana Cake with marshmallow toppings.

I really have to brush up on my cake frosting/decorating skills. As you can see, in terms of how it looks, this cake "really cannot make it!" :'(


Since I can't really make any piped decorations, I used heart-shaped marshmallows to dress-up the cake a little. In fact, it was my elder boy who helpped me with the decoration.


The only thing that I was satisfied with was how the sponge cake turned out. This time round, I sifted the cocoa with flour three times...as demonstrated in Alice Medrich's video clip. (The video clip shows her making a Chocolate Genoise Cake with Julia Child.) There were tiny undissolved cocoa lumps in my previous chocolate sponge. This didn't happen this time round. I was also delighted that I could cut the cake into 3 layers. Again, thanks to the video clip by Alice Medrich.

I used a chocolate ganache made with just pouring cream and dark chocolate. As for the filling, I didn't like the idea of buttercream (too much fat), so I used the same chocolate ganache, but added in a 2 teaspoon of instant coffee and 2 teaspoon of sugar as I thought it would be a little bitter for my boys.

Despite its look, the cake is really yummy. It's rich, but not too rich (hope you understand what I mean), and the banana really goes very well with the chocolate filling. As for the recipe, I borrowed ideas here and there, and came up with the following version.

Ingredients:
(make one 20cm round cake)

for sponge cake:
4 eggs, bring to room temperature
100g sugar
100g cake flour
20g cocoa powder
60g butter, melted

for chocolate frosting:
4 fl oz pouring cream (I used nestle's)
4 oz dark chocolate

for filling:
4 fl oz pouring cream
4 oz dark chocolate
2 tsp instant coffee
2 tsp sugar
3 ~ 4 bananas, cut into slices

Method:

For sponge cake:
1. Triple sift the cocoa powder and cake flour, set aside. Grease and line a 20cm round pan, set aside. Melt butter and set aside. Pre-heat oven to 180degC.

2. With an electric mixer, whisk eggs and sugar on HIGH speed for about 5 to 7mins, until the batter double in volume and is ribbon-like (the beater should leave a ribbon-like texture when the batter is lifted up). Turn to LOW speed and whisk for another 1 to 2 mins. Whisking at low speed helps to stablise the air bubbles in the batter.

3. Sift over the cocoa and cake flour mixture into the batter. With a spatula, gently fold in the flour mixture until well blended.

4. With a spatula, mix about 1/3 of the batter with the melted butter in a bowl. Fold in this mixture into the remaining batter. This method will help to ensure the butter will be fully blended and at the same time will not deflate the batter.

5. Pour the batter into the pan and bake for 20 to 25mins, or until a skewer inserted in the centre comes out clean. Remove from pan and cool completely.

For the frosting:
Place pouring cream and chocolate in a saucepan over low heat. Stir until melted and smooth. Set aside for 10mins before frosting the cake.

For the filling:
Slice bananas into pieces and squeeze some lemon juice over them. This helps to prevent the bananas from turning brown.

Place pouring cream, instant coffee, sugar and dark chocolate in a saucepan over low heat. Stir until melted and smooth. Set aside to cool before filling the cake.

Assemble the cake
Cut the cake into 3 layers. Place one of the cake layers cut-side down on a cake plate. Spread the coffee chocolate filling over the layer. Arrange rings of banana slices to cover the whole layer. Top with another cake layer. Repeat the same for the second layer. Top with the 3rd layer, cut-side up. Spread the chocolate ganache over the top and side of the cake. Decorate as desired.


More aboutMarsha Marsha Monkey

Failing at TDD

Diposting oleh good reading

Someone asked for more clarification about how I failed at TDD... I gave reasons why I failed, but no measurement of success. In the class, I had said that I failed until I finally changed my way of thinking and actually got what test driving is all about...

But I was thinking about this statement on the way home and this isn't true. Even after I understood how to test, my classes under test would outgrow their test fixtures because I wasn't in the habit of writing tests first or the tests were too rigid to change or I just wanted to get something to work really quick without having to write a test... a little extra code here and there eventually leads to a lot of failing tests, ignored tests, ignored assemblies and then total failure...

A few years ago I was lucky enough to have lunch with Bob Martin and we had a long talk about discipline. I would argue that this is the most important attribute for test development (he really knew what he was talking about, how little I knew then).

I finally considered myself successful in TDD when I had several projects that were test driven, and continued to evolve test driven as well... i.e. I was finally successful when my tests were refactored with the rest of my code, my tests continued to drive change and it wasn't painful.
More aboutFailing at TDD

Hope you had fun at code camp

Diposting oleh good reading



For everyone who sat in on our talks at code camp, thanks for being a great audience. I'll post some notes, answers to questions and code samples in the near future.

We hope you had fun and maybe learned a thing or two :)
More aboutHope you had fun at code camp

Killswitch Engaged tonight!

Diposting oleh good reading on Kamis, 01 Maret 2007

I've been looking forward to this for the past two months! I haven't been excited for a concert in a while, so its nice to have the teenage excitement of seeing one of your favorite bands :)

The show comes during a tough week because I'm still adjusting to my training schedule for team in training and Oksana and I have been working late for our Code Camp presentations. I'm still looking forward to it though!
More aboutKillswitch Engaged tonight!