May 2010

Thinking about what people remember

May 1, 2010 - Categories: braindump, life, reflection, sketches

While thinking about identities, personal brands, and what people remember, I thought it might be useful to think about what people probably remember about me:


Presentations are probably the clearest time I present a “brand” or a slice of myself, because I focus on a single topic and I write a bio that highlights relevant aspects. At work, on my blog, and in life, I can bring out more complexity.

I started thinking about this when someone asked me how one makes the shift to talking about identity when people ask about their brand. When I thought about the question, I realized people don’t really ask me about my “brand”, they just figure it out.

People find happiness and energy remarkable. One of the tags people added to my profile at work is “howcomeshesalwayscheerful”. <laugh> Ditto with energy – people are surprised by that. It seems like being passionate about your work is a rare thing. I’m going to work and live as if these things aren’t rare, assuming instead that everyone can be happy and energized and passionate about what they do. =)

Happiness, energy, and passion don’t fit neatly into the idea of consciously building personal brand. Happiness doesn’t work well when you’re being happy just because you’re the happy person. You don’t say, “Hey, happiness would be a good brand for me, so I’m going to be happy.” You just are. You can focus on the bright side of life, but that’s more about you and less about what you want people to think of you. And happiness doesn’t mean that you need to hide the sad parts of your life, because those challenges help you grow too.

The cross-over between different parts of my life (such as Emacs people sharing their insights into my hobbies) is totally awesome, which is why I like sharing the complexities of who I am instead of boxing myself in with a brand.

I like working this way. I like being myself, seeing what people find valuable, and then building on those strengths so that I can use them to help more people. Instead of thinking of this as one-way, like personal branding is often seen, I think of the conversational development of identity. It doesn’t spring full-formed from my solitary thoughts, like the way someone might deliberately develop personal branding. It emerges as I interact with people and the world, and as I reflect on what I’ve learned.

Thanks to @saradelekta for prompting me to think about this, and to Bernie Michalik for the comparison between identities and personal brands!

Braindump: What I learned from our virtual leadership conversation

May 2, 2010 - Categories: braindump, kaizen, leadership

Around 20 people joined us for a conversation about Smarter Leaders, which was organized by Jack Mason in the IBM Virtual Analytics Center. Rawn Shah and I gave introductory remarks, and then we facilitated small-group discussions. I focused on the need for smarter leaders at every level and what we could do to help people develop as leaders.

What did I learn?

We know what can help: identifying characteristics of effective leaders, focusing on leadership instead of technology, collecting and sharing success stories, compiling a cookbook that focuses on needs instead of tools… That part is just a matter of doing it, and there are lots of programs already underway.

Is it going to be enough, or are there other things we can do to break through? If it took e-mail ten or so years to become part of the corporate culture and enable all sorts of opportunities, can we wait that long for connected leadership to become part of the way we work?

We tend to have a culture of waiting for permission instead of experimenting (and asking for forgiveness if needed). This means that lots of people are waiting for their managers and executives to participate in this.

Me, I’m all for people taking responsibility for leadership at any level. We might not make big decisions, but we can still make a difference.

What am I going to do based on what I learned?

I’m going to take a look at the characteristics that describe IBMers at their best. I’m going to figure out how to develop those characteristics myself, and how other people can develop them.

I’m passionate about helping individual contributors build and demonstrate leadership. I’m neither a manager nor an executive, and I don’t want to wait for everyone at the top to “get it” before the benefits can trickle down to everyone else. So I’m going to keep poking this idea of leadership until more people can identify with it and ask themselves, “How can I be a smarter leader?”.

What are you going to do to spread be the word about smarter leaders? =)

What worked well? What could we improve further?

  • I really liked being able to help bring together all these interesting people. It was like going to a real-life conference.
  • I finished my part in time (short talk!). =) I forgot some of the points I wanted to make, but it was okay because I’d already shared them in my blog post.
  • I did a good job of picking on people to get the ball rolling, and the conversation can get even better if I can figure out how to bring more people into the conversation.

  • Small-group virtual facilitation needs to be tweaked further. I felt conscious about people being outside my vision, so I turned my avatar around, but it still felt strange to have my back to a speaker. We didn’t organize ourselves into a circle because it would’ve taken time to position people, and the spatial audio might’ve been weak. I like the way that our Second Life meeting environments sometimes have auto-expanding chairs.
  • My audio was clipping because the sound was set too loud. I should definitely do more audio tests before the sessions.
  • My sketches turned out pretty well on the screen of the Virtual Analytics Center. =) Simple and easy to see from any part of the auditorium.
  • The auditorium turned out to be too small to accommodate breakout groups. One of the breakout rooms had audio running, and we couldn’t figure out how to turn it off. The big gathering area was a good place to have a discussion, though. Teleporting buttons would be a great way to get people from one place to the other without wasting time navigating. (Ooh, teleporting buttons with visual feedback for intuitive load-balancing…)
  • The indicators for who was currently speaking made large conversations so much easier. I want that on all of my teleconferences. =)
  • Text chat still beats speaking in turn when it comes to getting lots of stuff out. It’s odd to mix it in, though. It feels a little weirder than having an active backchannel during a phone conference. I think it’s because you can see people, so you feel more of an urge to talk to them instead of typing.
  • The web.alive folks definitely need to add a way to save the text chat!
  • The virtual environment can capture all sorts of interesting data. I wonder what kind of research can come out of this…

Lots of good stuff!

Bread of salt and taste of home

May 3, 2010 - Categories: cooking, cookordie, philippines, sketches


Pandesal. Brown paper bags of crunchy-yet-soft buns at breakfast and merienda, often accompanied by hot chocolate—or chocolate porridge, if I was really lucky.

If there is a type of bread in my heart, it is this. Not white bread or whole wheat or rye or flax. Not the focaccia we dipped into balsamic vinegar and olive oil at the Italian restaurant my family often went to. Not the banana breads or cornbreads W- and I have made.

Pan de sal. Bread of salt. 

Perhaps Laura Esquivel was on to something in Like Water for Chocolate. Food really is a language powerful beyond words.

I made pandesal for the first time. Fresh from the oven, they tasted of home.

I offered W- a piece. He had pandesal during our trips to the Philippines. I was glad he could relate to my memories.

There are places that sell pandesal in Toronto. I’ve never been to them. It’s different. Going out of my way to buy Filipino food? That’s something I might do if I get really homesick. Learning how to make the food of my memories? That fits. That helps me grow.

Now I can have pandesal any time I want. =) When we finish the 14 rolls I stashed in the freezer, I’m going to try this other recipe.


Picture by W-

Weekly review: Week ending May 2, 2010

May 4, 2010 - Categories: sketches, weekly

lettuce That was a busy week. Lots of work, lots of accomplishments, and lots of new things learned!

From last week’s plans:


  • [X] Discuss virtual leadership
  • [X] Finalize preparations for Idea Lab
  • [-] Revise my “Remote Presentations That Rock”
  • [X] Flesh out more parts of the wiki
  • [X] Follow up on expertise location pilot – export lists of experts
  • [X] Track Idea Lab interest
  • [-] Update invitation template
  • Also: Listened to Debbie Landers talk about being a remote executive (“All executives are remote, in a way”)
  • Chatted with Laurie Friedman about leadership
  • Blogged about facilitation tips
  • Drafted newsletter
  • Set up training community
  • Posted visual essay on smarter leaders
  • Updated and reorganized part of the wiki
  • Talked to extended team members
  • Helped Camille Nichols track down resources
  • Sent list of experts for expertise location pilot


  • [X] Meet with lawyer regarding the marriage contract
  • [-] Add another freezable meal to our repertoire (chicken-based?)
  • [X] Plant more herbs in the back box
  • Also: Attended Tania’s tea party
  • Built garden box frame with W-. Lots of work and lots of fun.
  • Planted asparagus, whee! Also picked up more strawberries and a cherry tomato plant
  • Turned the compost
  • Made large batch of spaghetti sauce
  • Made cream puffs
  • Attended J-’s school musical (Dear Edwina) – that was fun! Why don’t we have beginners’ musicals that grownups can sing in? =)
  • Scanned paperwork for my mom


  • [-] Get started on skirts
  • [-] Post five drawings
  • [X] Figure out how to blog or journal small, quick notes
  • Also: Drew more cats
  • Planned how to simplify life, remember better, and fight clutter

Plans for next week:


  • [  ] TOP: Facilitate Idea Lab and summarize results
  • [  ] Revise “Remote Presentations That Rock”
  • [  ] Follow up on expertise location pilot
  • [  ] Reflect on IBMers at their best – map competencies to how I currently practice them and how I want to grow
  • [  ] Post more thoughts on career growth


  • [  ] Work on garden frame
  • [  ] Send some more information that my mom needs for her visa application
  • [  ] Plant the rest of the herbs
  • [  ] Send additional information to lawyer


  • [  ] Spring cleaning: wardrobe, bedside table, living room, etc.
  • [  ] More organization: try belt pouch + bag system

Monthly review: April 2010

May 5, 2010 - Categories: monthly

The world is an explosion of colour. It’s gardening season, and I can’t wait to explore herbs, vegetables, and fruits. It’s biking season, and I’m lovin’ the exercise. As for sewing, I’ve swapped out my fleeces and started sewing linen. Spring has sprung!

I’ve been slowly working on improving little things in life. For example, I picked up a few more porcelain saucers from Goodwill so that I’m not always scrambling to find clean saucers for guests during my tea parties. I’ve also been doing lots and lots of gardening, and the plants are starting to poke up. Lots of drawing, too.

Monthly goal review: One of my goals for April was to figure out how to free up a weekend instead of doing batch cooking all the time. Now we’ve got the roast-chicken-for-frozen-lunches extravaganza down pat, and have a month of frozen goodies ready to go. Yay! I’ve been doing a bit of sewing, too, and have made a few tops I enjoy wearing. I haven’t been doing a lot of Emacs tweaking, though. That’s okay – I’ve been busy doing other things.

What’s up for May? I’m going to focus on slowing down and being mindful. I want to focus on the moment and giving myself time to tidy up, double-check, and reflect. I occasionally misplace or forget things, and I can get better at remembering. So May is spring-cleaning month. I’m going to get the hang of this!

April recap:

After preparing my personal business commitments in March, I spent some time thinking a lot about career growth. I thought I’d figured out my dreams of wild success, but I suspect there’s still a lot missing from that picture. Here are some thoughts on work:

I’ve been exploring leadership, collaboration, presentations, and creativity:

I’ve been thinking about life, too:

And writing about other stuff!

Weekly reviews:

Squirrels, shop class and drafting: making my peace with high school

May 6, 2010 - Categories: gardening, learning, life, love, sketches

The squirrels had messed with the wrong seedlings.

To entertain cats and people alike, we’d fed the squirrels throughout winter. Now we were paying for it with the consequences of population explosion: ravaged seedling beds, munched-on sprouts, and dug-up and discarded onion bulbs.

The stench of bloodmeal didn’t stop the marauding rodents from plundering our vegetable patches. We didn’t want to use hot pepper flakes and other painful irritants. We needed a plan.

We stapled chicken wire on our raised beds, which kept the scallions and other bulbs safe for the moment. When the strawberry plants grew tall enough to poke white and pink flowers through the mesh, we knew we needed something bigger.

I was about to experiment with circles of chicken wire held together with duct tape and string. But W- had an engineering decree, and he wasn’t afraid to use it.

After days of discussing diagrams on scratch paper, we decided to build a semi-permanent frame. We picked up spruce and hardware from Home Depot, and then set to work. W- taught me how to use a circular saw to cut the lumber. I told him that it felt a lot like sewing: marking my seams and following the lines. We sanded, measured, marked, leveled, measured, and fastened. We finished the frame just as the sky darkened.

This is what it will probably look like:

 garden-frame (… minus the text, of course, and liberally covered with chicken wire.)

We’ve finished the vertical and horizontal supports, and we’ll work on the chicken-wire doors this week. I’m looking forward to it.

I’m making my peace with subjects I detested in school. Now that sewing and cooking have become enjoyable hobbies, I’ve set my sights on shop class and drafting.

Working on shelves and other small projects in high school shop/tech class, I had felt awkward and clumsy. I struggled to wrap my mind around the spatial puzzles of carpentry. The classroom was full of sweat and sawdust, and the lab coats we wore did nothing for either.

Drafting classes in fourth year were more refined, but not more enjoyable. My classmates drew neat lines that intersected at just the right places. My papers were full of smudges, distortions, and impossibilities.

Now, without the pressure of a classroom and with more developed spatial skills (thank you, sewing and drawing), I can find these long-forsaken subjects relaxing, even enjoyable. Working with wood, I found myself thinking of other things I’d like to build. Drawing the structure, I though

Helps to have the right tools, too. Axonometric grids in Inkscape for drawing isometric images? Yes! So much easier than erasing and redrawing segments.

It’s great to challenge my memories. I’m learning that sometimes things are better learned the second time around. It’s great to know it wasn’t me, it was then. Who knows? I may yet revisit the Love Song of J. Alfred Prufrock and learn how to look at fiction and poetry with a critical eye.

But first, I have some squirrels to chase off the lawn.

Holy cow, that was a lot of mail. So sorry!

May 6, 2010 - Categories: blogging, sad, wordpress

I was checking out a few things on my blog today, and I came across my WordPress Post Notification administration page. “Hmm,” I said. “I seem to have misconfigured this.” No e-mail had been sent out since August 2009. I figured out that the configuration directory didn’t have write permissions, enabled it, and went on with the rest of my day.

In the evening, I checked my personal mail on my iPod Touch. Inbox…

323 unread messages. That wasn’t right. I read the e-mail subjects. Holy cow, my blog had sent out every single one of my posts in the past half-year.

Granted, the only people on the list had double-opted-in, but still. I’d be annoyed if that many messages showed up in my inbox too, instead of one at a time.


First step: Control the damage. I moved post-notification out of the way, automatically disabling the plugin.

Second: Figure out the impact. 50 e-mail addresses left. Two nasty-notes.

Third: Gingerly re-enable the plugin after removing the locking directory.

Fourth: E-mail everyone an apology.

Fifth: Write about what happened. Tradeoff: Personal embarrassment versus possibility of saving other people from doing this kind of stuff. Worth it.

Looking at the bright side (because there always is a bright side)… At least I’m learning this now instead of later. And with my blog instead of a customer site. And with a smaller list instead of a megafan community. And… umm… it’s e-mail instead of text messages. Which has happened before. I was writing a Perl script that sent messages, and I had a bug, and there was an infinite loop, and poof! there went the balance on my prepaid card.


I’m sorry.

A letter to my 8-year-old self

May 7, 2010 - Categories: life

Dear 8-year-old Sacha,

You might not believe me, but your interest in computers will lead to making lots of good friends. So go ahead, enjoy it, and don’t mind the people who tease you about being a geek. When you grow up, this will be a very good thing.

I don’t know which experiences I’d want to steer you towards or away from. Even the tough decisions and seeming mistakes turn out to be all right. The boy whose heart you’ll break in second year high school will turn out to be a good friend later on. The writer you’ll have a crush on (although you’ll eventually find conversation awkward because you aren’t immersed enough in fiction) will end up telling you about a scholarship that will take you halfway around the world. The big fight you have with a friend at school will make it easier to leave for Japan, where you’ll meet the research supervisor who’ll convince the department to accept your application. Things work out.

There are a few minor things you might do differently, but don’t worry, life works out to be pretty awesome anyway. These suggestions will probably make life better without messing up the space-time continuum too much:

  • People will tease you for reading your pocket dictionary and for using unusual words. That’s okay. Later in life, you will meet someone who browsed through dictionaries too, and you will get to make all sorts of obscure puns.
  • Get into open source earlier. Not only will you learn a lot and meet many interesting people, you’ll get nudged into writing and presenting.
  • If you go to a high school where everyone’s talented, don’t let people’s skills in drawing, writing, acting, or other things intimidate you from trying.
  • Remember that people are human and have to sort out their own issues. Get better at figuring out what’s really you and what are issues other people are projecting onto you, what you want and whether that’s different from what other people want you to want, and who you are versus who other people think you are.
  • People pass in and out of your life. You pass in and out of people’s lives. This is okay.
  • In university, convince your teachers to put you in the regular English class instead of the merit English class. All the other computer science students will be in the regular classes. They’ll be bonding on food trips while you and a dozen other people sit in a circle in a classroom, discussing the irony in the Love Song of J. Alfred Prufrock.
  • If you end up in that English class anyway, try to enjoy it, and don’t let it convince you that writing is boring. School essays and book reports may be a pain, but you can write for fun. Keep your writing on your computer, though. It’s easier to organize (and protect), and you’ll thank me in university. (Say hi to your teachers for me – they were great, even if you weren’t the best of students at the time.)
  • People like your sisters will try to convince you that you’re boring. You’re not. You’re just different. Take a notebook along on those family trips, and write or draw while they surf.
  • Get into the university dorm earlier. Yes, you live in Metro Manila and there’s a long waiting list, but the network team will bump you up in priority thanks to your tech skills. You will learn a lot, and you’ll have lots of fun.
  • Future paperwork will require a list of trips you’ve made. It may help to keep good records when you travel, although they’ll let you submit a partial list anyway.
  • You will have to memorize things at some point, and developing that skill early will help you in calculus and chemistry. Make it more fun by turning it into a game. Flashcards are good.
  • Practice being organized. Fold-back clips can help you keep those endless photocopies tidy. Multi-colour ballpens are handy.
  • Go ahead and wear your glasses during presentations. (Yes, you will end up giving lots of presentations.) Contact lenses are a pain, and you can make a connection even with glasses on.
  • Pay more attention in sewing and shop class. While most of your classmates may never own a sewing machine or pick up a drill again, you will. And you’ll enjoy it, so don’t be embarrassed about starting. Ask or save up for your own sewing machine if you need to. You might as well start early so that you can learn how to make cool things. And while you’re at it, build on that interest in gardening and take advantage of the space and the sun that you have.

Stick up for yourself, learn and share as much as you can, and enjoy. Life is going to be awesome.

26-year-old Sacha

May 8, 2012

P.S. Draw and doodle more. Ignore the frustration of not being able to draw as well as you want. You’ll appreciate having practised. – 28-year-old Sacha

May 2010: Remember and declutter

May 8, 2010 - Categories: kaizen, life

My project for May 2010 is to get better at remembering and decluttering. I want to reclaim the time and energy I spend looking for things. I don’t want to inconvenience W-. It feels good to remember and have things in the right place.

Key points:

  • Don’t just look, see.
  • Have a place for everything, and put everything in its place.
  • Slow down and give yourself time to tidy up.
  • Finish things before starting something new.

Things that often get misplaced

iPod and phone

  • Problem: I usually don’t have pockets, so I put them down when I need to use both hands, and then I forget where I put them down.
  • Approach: Wear a belt pouch. Put the iPod and phone into it.

Wallet, keys, badge, etc.

  • Problem: These get transferred from bag to bag. Sometimes I forget which bag these are in, so I have to check several bags before I find it.
  • Approach: Keep everything in a white mesh pouch, which I can leave in the cabinet near the door. When I’m about to go out, I can take the pouch from the cabinet and put it in my current bag. When I return home, I take the pouch out of the bag and put it back into the cabinet.

Bicycle lock

  • Problem: If I put it in a bag, I sometimes forget to take the bag if I’m rushing out the door.
  • Approach: Use a bungee cord to keep my lock on the rack.

Physical places that attract clutter

Top of dresser

  • Problem: Attracts scarves, clothes, books, etc.
  • Approach: Keep it clean except for the next day’s clothes.

Bedside table

  • Problem: Attracts notebooks and books
  • Approach:
    • Reserve the top for iPod base, chapstick, pencil, eyeglasses, mouthguard
    • The second shelf: At most one notebook, at most one book, phone charger, phone, and belt pouch

Kitchen table

  • Problem: Attracts dishes, electronics, papers, pens that don’t work
  • Approach: Clear everything when I get home, for a fresh start

Coffee table

  • Problem: Attracts bags, books, scarves, etc.
  • Approach: Bags should be emptied and hung up. Books go on shelves. Scarves, gloves, etc. should go into a box.

Entry shelf

  • Problem: Bags pile up.
  • Approach: Once a week, tidy this up.


  • Problem: Accumulates paper, coins, books, and other things
  • Approach: Once a week, empty my purse and plan it from scratch.

Sewing desk

  • Problem: Accumulates scraps, paper, unfinished ideas
  • Approach:
    • Make a small scrap catcher and put it near my sewing machine.
    • Focus on sewing projects with clear instructions.
    • Tidy everything up after each phase.

Library bookshelf

  • Problem: Read books mingle with unread books, so I spend more time scanning. Sometimes I have too many books checked out, so the shelf gets untidy.
  • Approach:
    • Set up a last-in-first-out queue, perhaps going from left to right
    • Annex another shelf for overflow. Give away old books to free up space.

Digital clutter


  • Problem: My blog posts aren’t copied into my personal reference system. I don’t have an overview/knowledge-map of how everything ties together.
  • Approach:
    • Extract titles and links and put them into an Org-format file so that I can organize them.
    • Review my Learning map and intentionally write blog posts along those topics.


  • Problem: I’m taking lots of notes, but I don’t share them because I’ve limited myself to publishing one blog post a day.
  • Approach: Publish them as future posts, and keep a local copy for ease of searching.


  • Problem: Digital notes get scattered all over the place: iPod, blog, Twitter, etc. I try to keep both hierarchical notes and chronological notes, which doesn’t work too well with my outline.
  • Approach:
    • Have a master date-stamped file, then copy information out of it.
    • Develop and use a consistent indexing scheme.
    • Use the iPod as an inbox and set aside time to transfer info from the inbox.
    • Use M-x remember to capture notes in sequence, then process the inbox of notes and put things into a categorized archive.
    • Get the hang of using Org hyperlinks.

To-do list

  • Problem: Toodledo list cluttered with items whose Due Dates aren’t really on that day. That’s because I’m using the due dates for prioritization, because the priorities aren’t enough. Org is better at this because of the distinction between Due Date and Scheduled.
  • Approach: Use priorities more, and use start dates as well. Don’t use due dates for scheduling. Get used to working from the context view.


  • Problem: Scans pile up in my inbox directory. I don’t have an index for referring to them.
  • Approach:
    • Review my batch OCR script and run that more regularly.
    • Use my file to keep track of everything.


  • Problem: I don’t regularly review and upload my pictures.
  • Approach: Set aside time each week to review all the pictures taken, select the ones I want to share, and share them. Format the card afterwards so that I don’t have to deal with duplicates.

Remote Presentations That Rock (revised)

May 9, 2010 - Categories: presentation, speaking

Notes for an upcoming presentation on “Remote Presentations That Rock”, for IBM’s “Best of the Technical Leadership Exchange” series. (Whee!) Compare this with the original.

I’ll be the first to confess: I’ve checked mail and surfed the web while “listening” to presentations. I hated not being able to pay attention, but it was hard to concentrate when the speaker was just reading the slides. Whose fault was it? Mine, for being easily distracted? Or the speaker’s, for wasting my time?

And sometimes I was the speaker trying to figure out how to be more interesting than e-mail. It’s hard!

Chances are, you’ve been in that situation too, both as listener and as speaker. I want to share with you the top tips I’ve picked up from years of doing and watching remote presentations. Little things can make such a big difference. I want to convince you to pick one of these tips and use them to make your next presentation rock. Here they are:

Don’t be a robot. Make your presentations real. Don’t be a recording. Interact. Don’t run over time. Make room for learning. Don’t do too much. Keep it simple. Don’t limit yourself. Practise everywhere. Don’t build suspense. Start strong and end strong. Don’t stop there. See the big picture of your presentation.

Don’t be a robot. Make it real.

Have you ever listened to speakers who found their own topics boring? Or droned on and on in a monotone? Or who just couldn’t keep you interested?

Why do speakers do this? Chances are, it’s because the presentation isn’t real enough to them. They can’t see people’s reactions. They can’t see people falling asleep. They’re trying to squeeze a talk into a busy day. They’re distracted by other priorities. They don’t have the time or energy to care.

Or sometimes, people are just plain too nervous to relax. They’re worried about making mistakes.

You might be thinking: “But Sacha, I have to sound serious! I can’t get away with sounding as excited as you!”

You don’t have to sound like a used-car salesman or a rabbit on a sugar rush, but you do need to sound alive. You need to really want to connect with people. You can sound serious as long as people know you care about helping them understand.

The basics: It’s hard to be energetic if your neck is sore and you can’t breathe well. That’s the position you often end up in if you don’t have a headset for your phone. Do yourself a favour and get yourself a phone headset.

Smile. People will hear that in your voice. Stand up if that helps. Use your hands to gesture, even if no one can see them. Wear your favourite suit if it will give you confidence.

Imagine the people you’re talking to, and pretend they’re in front of you. Pictures of people can make this easier.

Even better: instead of just sharing your slides, use a webcam to add video. That way, people can see your facial expressions and even your hand gestures.

Don’t be a robot. Be real. Make that connection.

Don’t be a recording. Interact.

Part of being real is interacting. Think about the last time you attended a presentation that didn’t have time for questions or interaction. Didn’t you wish you could just catch the replay?

Think about the last time you listened to someone reading a script. Didn’t you wish you could just get the e-mail instead?

Don’t waste people’s time. If people are attending your session, it isn’t so that they can read your slides – or listen to you reading your slides. They’re there because they’re interested, they want to ask questions, and they want to learn.

Build interaction into your presentation so that you can find out what’s important to people, what they’re interested in, what they want to learn more about. If not, you might find that you’ve just spent an hour talking about topics 1, 2, and 3, when people are still trying to understand topic 1.

How can you build more interaction into your talk? Explore your teleconferences’ tools for interaction. For example, I ask people to use the text chat to share their questions and ideas throughout the session. In fact, remote presentations can be more interactive than face-to-face ones, because people don’t have to wait for the microphone or a Q&A session.

Many webconferences will let you see how many people have raised their hands. Some even make it easy for people to answer multiple-choice questions or draw on a shared whiteboard. Experiment and explore.

Feel overwhelmed? Ask a buddy to watch the text chat, keep an eye out for raised hands, or set up the urveys for you so that you can focus on speaking.

When you build interaction into your talk, you help people learn, and you learn a lot along the way.

Don’t run over time. Make room for learning.

Imagine you’re giving a presentation for a lunch-and-learn. You think sixty minutes should be plenty of time. But you lose ten minutes waiting for everyone and dealing with technical troubles. Then someone asks a question, and you spend 5 minutes answering it. You try to get through the rest of the presentation, but you realize that it’s already 12:50 and you’re nowhere near the end. You flip through your slides quickly, and manage to make it to the end by 1:03. You ask: “Any questions?” but all you hear are the beeps of people dropping from the call so that they can make it to their next meeting.

Virtual conferences are worse, because speakers who take too much time mess up the schedule for everyone else.

This happens in face-to-face presentations, but remote presentations are even more challenging because people usually schedule other things right after your presentation. Back-to-back meetings mean that if you run late, people will miss your key points or the Q&A.

Here’s how you can make sure you always end on time: Plan for a much shorter time than you have. Don’t try to cram 80 minutes of speaking into 60 minutes. Get your key message across in 10 to 20 minutes, or even shorter. Then plan backup material so that you can take more time if needed.

For example, although this session is supposed to be sixty minutes long, I can give you an executive summary in less than three minutes. I recorded this talk as a 14-minute video. All the rest of the time is for questions and answers, which is where the real value is.

When you have a clear plan, you can make your session longer or shorter as needed. Do you need to keep talking because the next speaker is still missing? Tell more stories. Do you have to do your talk quickly because technical troubles stole twenty minutes? Don’t talk faster, just focus on the important points. Be flexible and respect people’s time.

Don’t do too much. Keep it simple.

What causes people to go over time? It’s because they’re trying to do too much.

Think about the last time you attended a presentation that tried to cover too many topics. Think about slides that had so much text on them that you couldn’t figure out where to start. It doesn’t work for you, and it doesn’t work for people listening to you.

“But Sacha, I need all those details,” you say. Yes, but people can’t listen to you, read your slides, and understand everything all at the same time. Make a simpler presentation, then share the details separately.

When I plan a presentation, I focus on one thing I want people to do. Then I think of three to seven things that support that key message. That’s it. It’s easier to keep things simple when you start small, instead of trying to shoehorn a large presentation into a limited space. If you need to summarize a big presentation, read through everything, then take a step back and say: “What do I want people to do or remember?” Start from there and figure that out before you make a single slide.

Keep it simple in terms of technology, too. Have a simple backup plan just in case. That way, you don’t panic when your fancy animations or your technology demo doesn’t work. No demo? Use slides. No slides? Talk about your key message. No teleconference? Send an e-mail or reschedule. Keep it simple.

Don’t limit yourself. Sneak practise into everyday life.

“But Sacha, it takes time to make things simple!” Yes. It takes time to figure out what you want to say and how you want to say it. It’s easier to tell people everything you know, instead of the one or two things they need. It’s easier to take someone else’s deck and hope you can talk your way through it, instead of customizing it to fit what you know.

At the very least, you should read through a deck before presenting it, and you should try out your conference tools before you use them with a real audience.

But you know that already. So here’s a useful, unconventional tip: even if you can’t spend a few hours working on your presentation, you can still practise while doing other things.

I spend more than eight hours a day working on my presentations. How? When I read or experiment, I learn things that might be useful for a talk. When I talk or write to people, I learn more about what I want to say and how I want to say it. When I watch other people, I take notes on what they’re saying AND how they’re presenting it. I learn from conversations and commercials. Before big presentations like this one, I even end up rehearsing in my dreams. As I keep talking about something, I figure out my key message and how I can share it.

You might not have time to go to presentation classes or public speaking clubs like Toastmasters, but you have plenty of opportunities to practise. Talk to yourself. Seriously. Your presentations will be much better when you don’t just write them, you listen to yourself saying them. For example, you will probably never use the word “utilize” again, because “use” feels much more natural.

Talk to other people about what you’re going to present. Write about what you’re going to present. Practice isn’t just about scripting your talk and re-reading it. You can practise any time, anywhere.

Stand-up comedians practise all the time so that they can figure out their punchlines, and they always keep an eye out for interesting things they can turn into jokes. If you practise, I can’t promise that you’ll be funny, but you will be much clearer and more confident.

Don’t build suspense. Start strong and end strong.

Speaking of stand-up comedians – this is where you shouldn’t be like them. When you’re telling a joke, it’s okay to build up the suspense. When you’re giving a remote presentation, don’t wait until the end of your talk to say your key message, because you’re not going to have the time to do that. Say what you want to say within the first five to ten minutes, then spend the rest of the time explaining the details and handling questions.

“But Sacha, if I do that, everyone’s going to leave right away!”

That’s terrific! You’ve just saved everyone time. If you say your key message at the beginning instead of at the end of your talk, then the people who are super-busy can get on with the rest of their day, while the people who need to find out more can stay for questions. Also, by getting your message in early, you’ll make it easy for people to remember.

What does this mean for you? Move your executive summary to the front. You can still talk about your agenda and how you’re going to talk about things, but put the important stuff first. Start strong.

End strong, too. Let’s say that you’ve made the most of tip #3 and planned for plenty of time for questions and answers. Don’t make your last slide show just “Q&A” or “Thank you!”. It’s a waste of time and space. Instead, make a one-slide summary of the key points and next actions from your talk. Include contact information and a link where people can find out more. Use that one-slide summary as your Q&A slide so that people can remember what they want to ask questions about. It’s simple, easy to do, and very effective.

Jumpstart questions and answers by preparing some questions that people usually ask you. If people have been using the text chat throughout your session, you probably have lots of questions to deal with already. Great! Go for it.

Then take back control at the end of the session. Save five minutes at the end so that you can give a quick summary of your talk, the key points from Q&A, and the next actions you want people to take. That way, people’s last impressions of your talk are the ones you want them to have.

People remember the beginning and the end more clearly than what’s in the middle. Take advantage of that by starting strong and ending strong.

Don’t stop there. See the big picture.

Many people have a hard time doing a strong ending because they don’t know what they want people to do next. Have you ever watched a presentation and thought, “Okay, now what do I do?”

When you speak, you need to understand the bigger picture of your presentation. Your presentation never stands by itself. It should lead into something. What do you want people to do? What do you want people to feel? What do you want people to remember? How do you want to change people’s minds? Your presentation is not the end. It’s the beginning.

For example, after this presentation, I want you to take one of these tips and use it to make your next presentation better. I want you to watch other remote presentations and learn about what they do well and what can be improved. I want you to download the slides and read my article, and I want you to share that with other people. Those are the next steps that this presentation must help you take. The bigger goal I have is to help people make more effective remote presentations (so that I don’t have to sit through boring ones!).

Next time you make a presentation, think: What do I want people to do after this? It doesn’t matter if you’re reporting utilization rates or talking about the technical details of a new product – you still want people to remember something, change something, do something. If you don’t, then there’s no reason to give a presentation – just send a document.

Seeing the big picture also means you can get a lot more ROI from the time and effort you invest into making a presentation. Using the same work you put into the presentation, you can share slides, handouts, videos, follow-up tips, and many other resources. For example, I gave a presentation to 90 people. When I put the slides up online, they were viewed 24,000 times. 24,000 more views for five minutes of additional work? Yes! It’s all part of the bigger picture of a presentation: the conversations that go on after your talk.

In fact, you can get that kind of return even before you make a presentation. For example, when I’m working on a presentation, I tell people I’m working on a presentation. I post my presentation outline on my blog, where people can see it and give suggestions. I post my presentation script as a blog entry. I post my slides. I talk to people about it. As a result, by the time I get to the actual presentation, I’ve had lots of practice. Remember tip 5 about practicing everyday? This is how you do it. And I also have lots of feedback and lots of connections, all because of these conversations before my talk.

You need to see the big picture of your presentation. Why does your talk matter? What do you want people to do after your talk? How can you keep the conversation going? How can you start the conversation earlier? How can you involve more people? How can you increase your ROI? Plan how, and build that into your presentation.


Don’t be a robot. Make your presentations real. Don’t be a recording. Interact. Don’t run over time. Make room for learning. Don’t do too much. Keep it simple. Don’t limit yourself. Practise everywhere. Don’t build suspense. Start strong and end strong. Don’t stop there. See the big picture of your presentation.

You’ve probably heard tips like these before, but there’s a big difference between hearing them and doing them. Focus on one of these tips and use it to make your next presentation better. Watch other remote presentations. Take notes on what they do well and what can be improved. Download these slides or read my notes, and share them with other people.

We spend so many hours in remote presentations, and little things can make such a big difference. Down with boring presentations, and ever onward to remote presentations that rock!

Quick guide to domain names

May 10, 2010 - Categories: geek

Having your own domain name means being able to use the same e-mail address or website URL for as long as you like.

Here’s how to register a domain name, get it set up for e-mail, and point it to another website. These instructions assume you’re using Namecheap; adjust them if you’re using something else.

  1. Pick a domain name register. I like NameCheap (affiliate link, 15% commission on first sale) because they’re reasonably priced and they aren’t a pain to work with. Open the domain name register’s site.
  2. Enter the domain you want, and click on Search.
  3. Pick which domains you’d like to register. Click on Add to Cart.
  4. Put in your coupon code. NameCheap’s always running one promotion or another, so search for coupons.
  5. Click on Express Checkout.
  6. Create an account, or log in if you don’t already have one.
  7. Choose your payment source, and go through the payment dialogs. You can skip anything you don’t understand. Use Namecheap’s DNS.

When you’re done with the registration process, sign in again if you need to.

Then you can set up e-mail forwarding and URL forwarding if you like.

If you use Gmail to send mail, you can send mail using your new e-mail address in the From: field. Check out these instructions: Adding a custom ‘From’ address.

You can do more with domain names than what I’ve described here, but that might require some geeking out. =)

Weekly review: Week ending May 9, 2010

May 11, 2010 - Categories: weekly

That was a very busy weekend. =)

From last week’s plans:


  • [X] TOP: Facilitate Idea Lab and summarize results
  • [X] Revise “Remote Presentations That Rock”
  • [X] Follow up on expertise location pilot
  • [-] Reflect on IBMers at their best – map competencies to how I currently practice them and how I want to grow
  • [-] Post more thoughts on career growth


  • [X] Work on garden frame
  • [X] Send some more information that my mom needs for her visa application
  • [X] Plant the rest of the herbs
  • [X] Send additional information to lawyer


  • [-] Spring cleaning: wardrobe, bedside table, living room, etc.
  • [X] More organization: try belt pouch + bag system – working well!

Plans for the week ending May 16, 2010:


  • [  ] Present social media / collaboration ideas at an executive briefing
  • [  ] Set up two simultaneous Idea Labs
  • [  ] Update SME note and send it to Julia
  • [  ] Follow up on IBM innovation journey – refine into presentation
  • [  ] Put together English summary for past Idea Lab


  • [  ] Cook another batch of food
  • [  ] Explore woodworking
  • [  ] Edit stuff – spring cleaning


  • [  ] Map past few years of blog posts
  • [  ] Draw more
  • [  ] Make organizer

Dear future Sacha,

May 12, 2010 - Categories: life, reflection

Remember these things as you go through life:

Happiness is a state of mind. It can’t be bought, given, or taken away, but it can be chosen.

Simple things can make it easier to be happy. Experiment.

Don’t forget that the reason you make a safety net is so that you can fly.

Tough experiences make good stories. Everything will work out.

It’s possible to have laugh lines, great stories, and lots of energy well into what most people would consider old age. Go for it.

On the different components of happiness: You can manage yourself. You can create opportunities for work. Relationships are different. You can’t control them, but you can invest in them.

Good parenting comes from a strong partnership. Don’t let kids or work distract you.

People will flow into and out of your life. Grief is the other face of love. It’s worth it. The holes in your life show you what people added and force you to grow.

The world is full of good people.

It’s never too late to learn something.

Always give yourself room to write, reflect, draw, and know yourself.

Other people can learn from you, even while you’re learning.

As you grow older, people will focus less on your “potential”. You won’t get as many lucky breaks practically handed to you, but you can keep creating opportunitites. This is good. It gives you the freedom to explore.

You don’t have to do everything. Eliminate, negotiate, and delegate.

You are not responsible for everything. Give people room to learn from their own experiments.

Don’t let nostalgia for the good old days blind you to the good new days.

Whether or not the world falls apart, life is what you make of it. Worry only so much as that helps you plan. Skip blame entirely. Look for the bright side, and share it with others. Life will be awesome.

26-year-old Sacha

Quick notes from a conversation about speaking and facilitation

May 13, 2010 - Categories: speaking

I’m working on revising my Remote Presentations That Rock presentation because it’s going to be featured in the “Best of the Technical Leadership Exchange 2009” series at work. (Whee!) Because the content’s already available via video recordings, slides, and blog posts, I’m trying to figure out how to add extra value to the talk so that it’s worth experiencing live.

Timothy Kelpsas reached out to me with a teaser about running multiple sub-plots to help with remote listeners. I finally got to ask him what he meant. Thirty minutes was far too short! =)

Tim thinks of presentations or facilitated sessions like a movie. Just as a director might plant clues about upcoming scenes (foreshadowing) or refer to previous events (flashbacks), Tim plans short forward-looking and backward-looking throughout the session. He establishes a rhythm. And just as a director mixes up action, comedy, romance, and other parts to appeal to different audiences, Tim tries to make sure that different kinds of people get engaged in a variety of activities. He shared how he thinks about introversion and extroversion, multiple intelligences, and other preferences that influence how people learn.

For remote audiences, he keeps a few tips in mind:

  • When Tim’s giving a presentation, he imagines the experience from the point of view of someone who’s far away and who’s watching the presentation through a replay. This helps him build empathy.
  • Tim works on actively engaging remote listeners by incorporating questions and self-reflection into his talk. For example, he might ask people to think about the worst leader they’ve had. A short while later, he might ask them to think about one thing they would change about that leader if they could. This gives people an opportunity to engage with the topic, even if they can’t interact with him directly.
  • Tim also deliberately builds rapport with replay audiences. He occasionally addresses people who are listening along on the replay. This acknowledgement helps build rapport, and it helps him remember their needs too.

How can I apply what I’m learning?

Instead of repeating the same presentation, I’m going to revise it thoroughly. I know the core ideas are sound. Not only did the content get me voted into the Best of the TLE series, but lots of people have reused it already, and people tell me that the tips are very useful. Now I get to experiment with more effective ways to present those tips. Taking Barclay Brown’s suggestion to use the basic fiction plots, I’m going to revise it to use a revenge plot. (Now I’m curious about how I might pull that off, and if I’m curious, chances are other people will be curious too!) I think that will be more fun than the quest plot, and the more vivid I can make things, the more people might remember.

Building on that subplot, I can weave reflection through more of the presentation. The original presentation had a little bit of reflection up front, but the revenge plot gives me plenty of opportunities to build reflection in.

Applying Tim’s tips, I’m going to prompt myself to  “break the fourth wall” and address people listening to the replay. I generally haven’t done this because I prepare blog posts, slides, and the occasional short standalone video for replay audiences, but people might come in through the web conference archives and miss out on the additional resources. Besides, it must be possible to do a good live/replay mix, and the practice will help me with in-person presentations as well.

Also awesome: The very first thing Tim did when we connected on the phone was to sing to me. He explained afterwards that he wanted to make sure I quickly got the sense of who he was. You bet that’s sticking in my memory! I told Tim how it reminded me of when Ethan McCarty sang me a song when I dropped by IBM NY. Ah, IBM and awesome people having fun… =)

Even more awesome LotusScript mail merge for Lotus Notes + Microsoft Excel

May 14, 2010 - Categories: geek, lotus
UPDATE: May 20, 2011 – David Turner has shared his excellent improvements. Check them out!

UPDATE: May 28, 2010 – fixed errors caused by default Option Declare. Thanks to Lisa Harnett for the feedback!
UPDATE: Oct 19, 2010 – fixed Quit(). Thanks to Vance for the feedback! Also, clarified tokens.

Based on the feedback on my Lotus Notes mail merge from a Microsoft Excel spreadsheet (2009), I’ve refined my merge script to make it more awesome. How is it more awesome?

  • Prompts you for drafting or sending
  • Saves sent messages
  • Allows you to customize the subject
  • Uses [ ] instead of < and > for built-in tokens ([to], [cc], [subject]) for less HTML confusion in blog posts and replies
  • Displays number of sent messages and errors
  • Closes the Microsoft Excel spreadsheet afterwards

The search-and-replace tokens are defined in the first row of your Microsoft Excel spreadsheet. The script searches for them in the message body, replaces them with the appropriate values from the current row, and either saves the message as the draft or sends the message. There are a few built-in tokens for this script ([to], [cc], [subject]) – these are case-sensitive, so enter them exactly like that. All the other tokens are up to you, so you could use FOO and BAR as search-and-replace tokens if you want.

Tokens are replaced only in the message body. If you want a variable subject line, use a formula to calculate the subject in a column with the [subject] header.

As always, test your mail merges with a small list before using it for your entire list. Create an agent and call it something like “Mail merge”. Edit the agent and set the type to LotusScript. In the (Declarations) section, add

%Include "lsconst.lss"

In the “Initialize” section, put in:

Sub Initialize
	'Mail merge script by Sacha Chua (

	Dim ws As NotesUIWorkspace
	Set ws = New NotesUIWorkspace
	Dim sendTypes(1) As String
	Dim sendValue As String
	Dim errorCount As Integer
	errorCount = 0
	sendTypes(0) = "Draft messages without sending"
	sendTypes(1) = "Send messages"
	sendValue = ws.Prompt(PROMPT_OKCANCELLIST, "Sending options", "What would you like to do?", "", sendTypes)
	If (sendValue = "") Then
		Exit Sub
	End If

	Dim fileName As String
	Dim strXLFilename As String
	'Prompt for the filename - should be a Microsoft Excel file with columns, where the first row of each column
	'is a token that will be used when replacing text in the body of the message
	'Special tokens: [to], [cc], [subject] set the appropriate fields
	'Make sure the first column does not have any blank cells
	fileName$ = ws.Prompt(12, "Select file", "3")
	If fileName$ = "" Then
		Exit Sub   'Cancel was pressed
	End If
	strXLFilename = fileName$
	Dim s As New NotesSession
	Dim uidoc As NotesUIDocument
	Dim partno As String
	Dim db As NotesDatabase
	Dim view As NotesView
	Dim doc As NotesDocument
	Dim collection As NotesDocumentCollection
	Dim memo As NotesDocument
	Dim body As NotesRichTextItem
	Dim newBody As NotesRichTextItem
	Dim range As NotesRichTextRange
	Dim count As Integer

	Set db = s.CurrentDatabase
	Set collection = db.UnprocessedDocuments
	Set memo = collection.getFirstDocument()

	Dim varXLFile As variant
	'Get data from the spreadsheet
	Set varXLFile = CreateObject("Excel.Application")
	varXLFile.Visible = False
	Dim varXLWorkbook As variant
	Set varXLWorkbook = Nothing
	varXLFile.Workbooks.Open strXLFilename
	Set varXLWorkbook = varXLFile.ActiveWorkbook
	Dim varXLSheet As variant
	Set varXLSheet = varXLWorkbook.ActiveSheet

	Dim lngRow As Integer
	Dim columnNo As Integer
	Dim token As String
	Dim value As string
	lngRow = 2
	Dim maildoc As NotesDocument
	While (Not (varXLSheet.Cells(lngRow, 1).Value = ""))
		'Fill in the template
		Dim subject As string
		subject = memo.Subject(0)
		Set body = memo.GetFirstItem("Body")

		'Compose message
		Set maildoc = New NotesDocument(db)
		Set maildoc= db.CreateDocument()
		maildoc.Form = "Memo"
		maildoc.Subject = subject
		Set newBody = maildoc.CreateRichTextItem("Body")
		Call newBody.appendRTItem(body)
		Set range = newBody.CreateRange			

		'Count the number of fields
		'Look up tokens from the column headings and replace them
		columnNo = 1
		While Not(varXLSheet.Cells(1, columnNo).Value = "")
			token = varXLSheet.Cells(1, columnNo).Value
			value = varXLSheet.Cells(lngRow, columnNo).Value
			count = range.FindAndReplace(token, value, 16)
			If (token = "[to]") Then
				maildoc.SendTo = value
			End If
			If (token = "[cc]") Then
				maildoc.CopyTo = value
			End If
			If (token = "[subject]") Then
				maildoc.Subject = value
			End If
			columnNo = columnNo + 1
		On Error GoTo save
		If (sendValue = sendTypes(0)) Then
			Call maildoc.Save(True, False)
			maildoc.SaveMessageOnSend = True
			maildoc.PostedDate = Now()
			Call maildoc.Send(False)
			Call maildoc.Save(True, True)
		End If
		GoTo nextrow
		MessageBox("Error processing " + maildoc.sendTo)
		errorCount = errorCount + 1
		Resume Next
		lngRow = lngRow + 1
	If (sendValue = sendTypes(0)) Then
		MsgBox "Drafted " & (lngRow - errorCount - 2) & " message(s). Errors: " & errorCount
		MsgBox "Sent " & (lngRow - errorCount - 2) & " message(s). Errors: " & errorCount
	End If
	Call varXLFile.Quit()
End Sub

Picking hobbies that fit together

May 15, 2010 - Categories: life, productivity, sketches

Some people have one hobby at a time. I tend to have several that shift over time, and I’ve gone through a lot of interests.

I started sketching my current hobbies to get a sense of how woodworking might fit in, and how it interacts with my other interests. I wanted to figure out if I could explore that interest enough to reach the point of being able to comfortably do it. In particular, woodworking tends to require blocks of unstructured time, which means it competes with sewing and cooking for those precious weekend blocks.


I got interested in woodworking  because of gardening, and there are a number of items we can build to make gardening easier. Now that we’ve set the garden up, it doesn’t take that much more time: ten minutes each day, and maybe an hour during weekends to turn the compost and take care of additional tasks.

Woodworking conflicts with cooking, though, because we use the kitchen and there’s no point in cooking when sawdust is floating around. That’s okay. We’re at a “good enough” level in cooking, and batch-cooking lets us free up weekends.

Drawing helps a lot with woodworking, and woodworking helps me develop spatial intelligence for better drawing.

Looking at my other hobbies, you can see that writing, drawing, and presentations all feed each other. I’m not making as good a use of photography as I could, so that’s something to develop. All the hobbies that I actively work on are well-connected. In contrast, something like music doesn’t connect well with my other interests, so I rarely end up practising on the piano.

Picking hobbies that fit together means that you get more value for the time and energy you put in. The more you develop skills in one area, the more effectively you can do connected areas.

Another related post: How to do a lot


May 16, 2010 - Categories: emacs, geek, org, productivity

I finally got around to asking my manager for permission to contribute org-toodledo as open source. Here it is. Enjoy!

;;; org-toodledo.el - Toodledo integration for Emacs Org mode
;; (c) 2010 Sacha Chua (
;; This file is not part of GNU Emacs.

;; This is free software; you can redistribute it and/or modify it under
;; the terms of the GNU General Public License as published by the Free
;; Software Foundation; either version 2, or (at your option) any later
;; version.
;; This is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
;; for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
;; MA 02111-1307, USA.

;; How to use:
;; 1. Customize org-toodledo-userid and org-toodledo-password
;; 2. Open a blank org file.
;; 3. Call org-toodledo-initialize-org
;; Call org-toodledo-update to bring in new/updated tasks (skips locally modified tasks newer than updated)
;; Call org-toodledo-sync-task to create or update the current task
;; Call org-toodledo-delete-current-task to delete the current task
;; Doesn't do lots of error trapping. Might be a good idea to version-control your Org file.
;; TOODLEDO ATTRIBUTES and how they are bi-directionally handled
;; Context: Handled by tags (ex:   :@work:  :@errands:)
;;   - will create new contexts if necessary
;; Task status: Mapped to TODO state.
;;   See org-toodledo-status-to-string and org-toodledo-parse-current-task for the mapping
;;   You will probably want something like this in your ~/.emacs:
;; (setq org-todo-keywords
;;      '((sequence
;;         "TODO(t)"  ; next action
;;         "PLAN(-)"
;;         "STARTED(s)"
;;         "WAITING(w@/!)"
;;         "POSTPONED(p)" "SOMEDAY(s@/!)" "|" "DONE(x!)" "CANCELLED(c@)")
;;      (type "DELEGATED(d@!)" "DONE(x)")))
;; Length: Mapped to effort
;; Priority: Mapped to [#A], [#B], or [#C]. (TODO: Change this to five levels of priority to match Toodledo)
;; Start date: Mapped to "SCHEDULED"
;; Due date: Mapped to "DEADLINE"
;; Tags: Mapped to tags
;; Note: Mapped to todo text. May get confused by asterisks, so don't use any starting asterisks in your body text.
;;   (or anything that looks like an Org headline).
;; Completed: Mapped to DONE todo state.
;; TODO:
;; - [ ] Double-check new/changed/deleted task updating, still seems buggy
;; - [ ] Test, test, test - maybe make test harness?
;; - [ ] Move status<->string mapping to a variable - lookups are better than logic
;; - [ ] Make sure sync timestamps aren't getting updated more often than needed
;; - [ ] Suggest some kind of hook to make it easier to mark a task as locally modified

(require 'org)
(require 'w3m)
(require 'xml)
(defcustom org-toodledo-userid ""
  "UserID from Toodledo:"
  :group 'org-toodledo
  :type 'string)

(defcustom org-toodledo-password ""
  "Password for Toodledo."
  :group 'org-toodledo
  :type 'string)

(defvar org-toodledo-token-expiry nil "Expiry time for authentication token.")
(defvar org-toodledo-token nil "Authentication token.")
(defvar org-toodledo-key nil "Authentication key.")

(require 'url)
(require 'url-http)

(defun org-toodledo-initialize-org ()
  "Replace buffer contents with Toodledo tasks."
  (delete-region (point-min) (point-max))
  (let ((account-info (org-toodledo-get-account-info))
        (server-info (org-toodledo-get-server-info))
        (tasks (org-toodledo-get-tasks '(("notcomp" . "1")))))
    (insert "* Toodledo\n"
            ":Last-modified: " (cdr (assoc "lastaddedit" account-info)) "\n"
            ":Last-deleted: " (cdr (assoc "lastdelete" account-info)) "\n"
            ":Last-sync: " (cdr (assoc "unixtime" server-info)) "\n"
    (insert (mapconcat 'org-toodledo-task-to-string tasks "\n"))))

(defun org-toodledo-get-token ()
  "Retrieve authentication token valid for four hours."
  (if (and org-toodledo-token
           (time-less-p (current-time) org-toodledo-token-expiry))
    ;; Else retrieve a new token
    (let ((response
                 (concat ";userid="
              (xml-parse-region (point-min) (point-max)))))
      (if (equal (car (car response)) 'error)
            (setq org-toodledo-token nil
                  org-toodledo-key nil
                  org-toodledo-token-expiry nil)
            (error "Could not log in to Toodledo: %s" (elt (car response) 2)))
        (setq org-toodledo-token
              (elt (car response) 2))
        (setq org-toodledo-key (org-toodledo-key)
              ;; Set the expiry time
               (+ (time-to-seconds (current-time))
                  (* 60 60 4)))))   ;; four hours

(defun org-toodledo-key ()
  "Return authentication key used for each request."
  (if (and org-toodledo-token
           (time-less-p (current-time) org-toodledo-token-expiry)
    (setq org-toodledo-key
          (md5 (concat (md5 org-toodledo-password)

(defun org-toodledo-get-url (method-name &optional params)
  "Return URL for METHOD-NAME and PARAMS."
  (concat ""
          (w3m-url-encode-string method-name)
          ";key=" (org-toodledo-key)
          (if params
               (mapconcat (lambda (x)
                             (w3m-url-encode-string (car x)) "="
                             (w3m-url-encode-string (cdr x))))

(defun org-toodledo-call-method (method-name &optional params)
  "Call METHOD-NAME with PARAMS and return the parsed XML."
  (setq params (cons (cons "unix" "1") params))
       (org-toodledo-get-url method-name params))
    (xml-parse-region (point-min) (point-max))))

(defmacro org-toodledo-defun (function-name api-name description)
  `(defun ,function-name (params)
     (org-toodledo-call-method ,api-name params)))

(defun org-toodledo-get-server-info ()
  "Return server information."
    (car (org-toodledo-call-method "getServerInfo"))))

(defun org-toodledo-get-account-info ()
  "Return server information."
   (car (org-toodledo-call-method "getAccountInfo"))))

(org-toodledo-defun org-toodledo-add-task "addTask" "Add task with PARAMS.")
(org-toodledo-defun org-toodledo-edit-task "editTask" "Edit task with PARAMS.")
(org-toodledo-defun org-toodledo-delete-task "deleteTask" "Delete task with PARAMS.")

;; (setq temp (org-toodledo-get-tasks '(("notcomp" . "1"))))
;; (setq server-info (org-toodledo-get-server-info))
;; (setq account-info (org-toodledo-get-account-info))
(defun org-toodledo-convert-xml-result-to-alist (info)
  "Convert INFO to an alist."
  (delq nil
         (lambda (item)
           (if (listp item)
               (cons (symbol-name (car item)) (elt item 2))))
         (xml-node-children (delete "\n\t" info)))))

(defun org-toodledo-get-tasks (&optional params)
  "Retrieve tasks using PARAMS.
Return a list of task alists."
    (car (org-toodledo-call-method "getTasks" params))

(defun org-toodledo-get-deleted (&optional params)
  "Retrieve deleted tasks using PARAMS.
Return a list of task alists."
    (car (org-toodledo-call-method "getDeleted" params))

(defun org-toodledo-entry-note ()
  "Extract the note for this entry."
    (when (looking-at org-complex-heading-regexp)
      (goto-char (match-end 0))
      (let ((text (buffer-substring-no-properties
                   (if (re-search-forward org-complex-heading-regexp nil t)
                       (match-beginning 0)
          (insert text)
          (goto-char (point-min))
          (when (re-search-forward
                 (concat "\\<"
                         (regexp-quote org-deadline-string) " +<[^>\n]+>[ \t]*") nil t)
            (replace-match ""))
          (goto-char (point-min))
          (when (re-search-forward
                 (concat "\\<"
                         (regexp-quote org-scheduled-string) " +<[^>\n]+>[ \t]*") nil t)
            (replace-match ""))
          (goto-char (point-min))
          (while (re-search-forward "\n\n+" nil t)
            (replace-match "\n"))
          (org-export-remove-or-extract-drawers org-drawers nil nil)
          (buffer-substring-no-properties (point-min)

(defun org-toodledo-parse-current-task ()
  "Extract the status and Toodledo ID of the current task."
    (org-back-to-heading t)
    (when (and (looking-at org-complex-heading-regexp)
               (match-string 2)) ;; TODO
      (let* (info
             (status (match-string-no-properties 2))
             (priority (match-string-no-properties 3))
             (title (match-string-no-properties 4))
             (tags (match-string-no-properties 5))
             (id (org-entry-get (point) "Toodledo-ID"))
             (contexts (org-toodledo-get-contexts))
        ;; (add-to-list 'info (cons "title" (match-string-no-properties 1)))
        (if id (add-to-list 'info (cons "id" id)))
        (when tags
          (setq tags
              (delq nil
                     (lambda (tag)
                       (if (> (length tag) 0)
                           (if (string-match (org-re "@\\([[:alnum:]_]+\\)") tag)
                                 ;; Not recognized context
                                 (if (null (assoc (match-string 1 tag) contexts))
                                     ;; Create it if it does not yet exist
                                     (let ((result
                                             (list (cons "title" (match-string 1 tag))))))
                                       (if (eq (caar result) 'added)
                                           (setq org-toodledo-contexts
                                                 (cons (cons (match-string 1 tag)
                                                             (elt (car result) 2))
                                                 contexts org-toodledo-contexts))))
                                   ;; Get the ID of the context
                                 (setq context
                                       (cdr (assoc (match-string 1 tag) contexts)))
                     (split-string tags ":")))))
        (setq info
               (cons "id" id)
               (cons "title" title)
               (cons "length" (org-entry-get (point) "Effort"))
               (cons "context" context) 
               (cons "tag" (mapconcat 'identity tags " "))
               (cons "completed" (if (equal status "DONE") "1" "0"))
               (cons "status"
                      ((equal status "STARTED") "2")
                      ((equal status "DELEGATED") "4")
                      ((equal status "SOMEDAY") "8")
                      ((equal status "CANCELLED") "9")
                      ((equal status "PLAN") "3")
                      ((equal status "WAITING") "5")                      
                      ((equal status "TODO") "1")))
               (cons "priority"
                      ((equal priority "[#A]") "2")
                      ((equal priority "[#B]") "1")
                      ((equal priority "[#C]") "0")))
               (cons "note"
        (when (org-entry-get nil "DEADLINE")
          (setq info (cons (cons "duedate"
                                 (substring (org-entry-get nil "DEADLINE")
                                            0 10)) info)))
        (when (org-entry-get nil "SCHEDULED")
          (setq info (cons (cons "startdate"
                                 (substring (org-entry-get nil "SCHEDULED")
                                            0 10)) info)))

(defun org-toodledo-sync ()
  "Synchronize all tasks."
  ;; Retrieve all tasks
  ;; For each task in the current buffer
  ;;   Synchronize an existing task that has changed
   (let ((regexp (concat "^\\*+[ \t]+\\(" org-todo-regexp "\\)")))
    (goto-char (point-min))
    (while (re-search-forward regexp nil t)

(defun org-toodledo-update ()
  "Insert new tasks and update previous tasks."
  (let* ((server-info (org-toodledo-get-server-info))
         (account-info (org-toodledo-get-account-info))
         (changed (org-toodledo-account-changed account-info))
         (last-deleted (string-to-number (or (org-entry-get-with-inheritance "Last-deleted") "0")))
         (last-modified (string-to-number (or (org-entry-get-with-inheritance "Last-modified") "0")))
         (last-update (string-to-number (or (org-entry-get-with-inheritance "Last-sync") "0")))
    ;; If tasks have been deleted or modified, then the Toodledo API
    ;; will give us the timestamps. We need to find out which tasks
    ;; have been deleted or modified since the last time we retrieved
    ;; the list of tasks that have been deleted or modified. We store
    ;; the last times in the properties of the root element.
    (if (and (assoc "deleted" changed) ;; Tasks have been deleted
             (>= (string-to-number (cdr (assoc "deleted" changed))) last-deleted))
        (setq processed
              (append (org-toodledo-process-deleted-tasks
    (if (and (assoc "modified" changed) ;; Tasks have been added or edited
             (>= (string-to-number (cdr (assoc "modified" changed)))
        ;; Retrieve added/modified tasks
        (setq processed (append
                         (org-toodledo-process-modified-tasks last-modified) processed)))
    ;; TODO Look for tasks that were modified locally since the last synchronization
    (org-toodledo-process-locally-modified-tasks last-update processed)
    ;; TODO Update timestamps here
    (goto-char (point-min))
    (when (re-search-forward (concat "^\\(" outline-regexp "\\)") nil t)
      (org-entry-put (point)
                     (cdr (assoc "unixtime" server-info)))
      (when (assoc "lastaddedit" account-info)
        (org-entry-put (point)
                        (assoc "lastaddedit" account-info))))
      (when (assoc "lastdelete" account-info)
        (org-entry-put (point)
                          (assoc "lastdelete" account-info)))))))

(defun org-toodledo-process-locally-modified-tasks (last-update processed)
  "Synchronize tasks that were locally modified after LAST-UPDATE.
Skip tasks with IDs in PROCESSED."
  (goto-char (point-min))
  (let ((start (float-time (current-time))))
    (while (re-search-forward org-complex-heading-regexp nil t)
      ;; Look for all tasks in this buffer
      (if (match-string 2)
          ;; Is it a new task, or has it been modified since the last update?
          (let ((id (org-entry-get (point) "Toodledo-ID"))
                (modified (string-to-number (or (org-entry-get (point) "Modified") "")))
                (last-sync (if (org-entry-get (point) "Sync")
                               (string-to-number (org-entry-get (point) "Sync"))
            (if (or (null id)
                    (and (> modified last-sync)
                         (< modified start)
                         (not (member id processed))))
                (save-excursion (org-toodledo-sync-task))))))))

(defun org-toodledo-touch ()
  "Update the current task."
  (org-entry-put (point) "Modified" (format "%d" (float-time (current-time)))))

(defvar org-toodledo-actually-delete t)
(defun org-toodledo-process-deleted-tasks (timestamp)
  "Remove tasks deleted after TIMESTAMP."
  (delq nil
         (lambda (task)
           (when (org-toodledo-find-task task)
             (if org-toodledo-actually-delete
                 (delete-region (org-back-to-heading)
                                (if (re-search-forward org-complex-heading-regexp nil t)
                                    (match-beginning 0)
               (org-entry-delete (point) "Toodledo-ID")
               (org-entry-put (point) "Toodledo-Deleted" (timestamp)))
             (org-toodledo-task-id task)))
          (list (cons "after" (number-to-string timestamp)))))))
(defun org-toodledo-process-modified-tasks (modified)
  "Handle all the tasks that have been modified since MODIFIED."
  (delq nil
         (lambda (task)
           (if (org-toodledo-find-task task)
               (if (null (org-toodledo-update-task task modified))
                   (org-toodledo-task-id task))
             (org-toodledo-create-task task)))
         (org-toodledo-get-tasks (list (cons "modafter" (number-to-string modified)))))))

(defun org-toodledo-create-task (task)
  "Create a task for TASK."
  (goto-char (point-max))
  (if (point-at-eol) (insert "\n"))
  (insert (org-toodledo-task-to-string task))
  (org-toodledo-task-id task))

(defun org-toodledo-find-task (task)
  "Find the task specified by TASK."
  (goto-char (point-min))
   (concat "^[ \t]*:Toodledo-ID:[ \t]+" (org-toodledo-task-id task) "$")
   nil t))
(defun org-toodledo-account-changed (account-info)
  "Return non-nil if the account has changed since the last check.
The result will be an alist of (\"modified\" . \"timestamp\") if tasks have
been added/edited and (\"deleted\" . \"timestamp\") if tasks have been deleted."
  (let ((last-modified (org-entry-get-with-inheritance "Last-modified"))
        (last-deleted (org-entry-get-with-inheritance "Last-deleted"))
    (if (> (string-to-number (or (cdr (assoc "lastaddedit" account-info)) "0"))
           (string-to-number (or last-modified "0")))
        (add-to-list 'result (cons "modified" last-modified)))
    (if (> (string-to-number (or (cdr (assoc "lastdelete" account-info)) ""))
           (string-to-number (or last-deleted "0")))
        (add-to-list 'result (cons "deleted" last-deleted)))
(defun org-toodledo-sync-task (&optional force)
  "Update my Toodledo for the current task."
  (interactive "P")
    (let ((task (org-toodledo-parse-current-task)))
      (if (null (org-toodledo-task-id task))
          ;; New task, create it
          (let ((result (org-toodledo-add-task task)))
            (when (eq (elt (car result) 0) 'added)
              (org-entry-put (point) "Toodledo-ID" (elt (car result) 2))
              (org-entry-put (point) "Sync"
                             (format "%d" (float-time (current-time)) 1000))))
        ;; Old task, update
        (when (org-toodledo-success-p (org-toodledo-edit-task task))
          (if (equal (org-toodledo-task-completed task) "1")
              (org-entry-put (point) "Completed" "1")
            (org-entry-put (point) "Status" (org-toodledo-task-status task)))
          (org-entry-put (point) "Sync"
                         (format "%d" (float-time (current-time)) 1000)))))))

;; (assert (equal (org-toodledo-format-date "2003-08-12") "<2003-08-12 Tue>"))
(defun org-toodledo-format-date (date &optional repeat)
  "Return yyyy-mm-dd day for DATE."
    "%Y-%m-%d %a"
     ((listp date) date)
     ((numberp date) (seconds-to-time date))
     ((and (stringp date)
           (string-match "^[0-9]+$" date))
      (seconds-to-time (string-to-number date)))
     (t (apply 'encode-time (org-parse-time-string date)))))
   (if repeat (concat " " repeat) "")

;; (mapconcat 'org-toodledo-task-to-string temp "\n")
;; (setq task (elt temp 2))
;; (org-toodledo-task-to-string task)
(defun org-toodledo-task-to-string (task &optional level)
  "Return an Org-formatted version of TASK."
  (let* ((repeat (string-to-number (org-toodledo-task-repeat task)))
         (rep-advanced (org-toodledo-task-repeat-advanced task))
         (repeat-string (org-toodledo-repeat-to-string repeat rep-advanced))
         (priority (org-toodledo-task-priority task)))
     (make-string (or level 2) ?*) " "
     (org-toodledo-status-to-string task) " "
      ((equal priority "-1") "")
      ((equal priority "0") "[#C] ")
      ((equal priority "1") "[#B] ")
      ((equal priority "2") "[#A] ")
      ((equal priority "3") "[#A] "))
     (org-toodledo-task-title task)
     (if (org-toodledo-task-context task)
         (concat " :@" (org-toodledo-task-context task) ":") 
     (if (and (org-toodledo-task-duedate task)
              (not (equal (org-toodledo-task-duedate task) ""))
              (not (< (string-to-number (org-toodledo-task-duedate task)) 0)))
         (concat org-deadline-string " "
                  (org-toodledo-task-duedate task)
     (or (org-toodledo-task-note task) "") "\n"
     ":Toodledo-ID: " (org-toodledo-task-id task) "\n"
     ":Modified: " (org-toodledo-task-modified task) "\n"
     ":Sync: " (format "%d" (float-time (current-time))) "\n"
     ":Effort: " (org-toodledo-task-length task) "\n"

;; (assert (equal (org-toodledo-repeat-to-string 0) ""))
;; (assert (equal (org-toodledo-repeat-to-string 1) "+1w"))
;; (assert (equal (org-toodledo-repeat-to-string 2) "+1m"))
;; (assert (equal (org-toodledo-repeat-to-string 3) "+1y"))
;; (assert (equal (org-toodledo-repeat-to-string 4) "+1d"))
;; (assert (equal (org-toodledo-repeat-to-string 5) "+2w"))
;; (assert (equal (org-toodledo-repeat-to-string 6) "+2m"))
;; (assert (equal (org-toodledo-repeat-to-string 7) "+6m"))
;; (assert (equal (org-toodledo-repeat-to-string 8) "+3m"))
;; (assert (equal (org-toodledo-repeat-to-string 108) ".+3m"))
;; (assert (equal (org-toodledo-repeat-to-string 101) ".+1w"))
;; (assert (equal (org-toodledo-repeat-to-string 0) ""))

(defconst org-toodledo-repeat-intervals '("" "+1w" "+1m" "+1y" "+1d" "+2w" "+2m" "+6m" "+3m"))
(defun org-toodledo-status-to-string (task)
  (let ((comp (org-toodledo-task-completed task))
        (status (string-to-number (org-toodledo-task-status task))))
     ((not (or (null comp) (equal comp "") (equal comp "0"))) "DONE")
     ((= status 0) "TODO")
     ((= status 1) "TODO")
     ((= status 2) "STARTED")
     ((= status 3) "PLAN")
     ((= status 4) "DELEGATED")
     ((= status 5) "WAITING")
     ((= status 6) "PLAN")  ; hold
     ((= status 7) "SOMEDAY")  ; postponed
     ((= status 8) "SOMEDAY")
     ((= status 9) "CANCELLED")

(defun org-toodledo-repeat-to-string (repeat &optional rep-advanced)
  "Turn TASK into a repeat sequence."
   ((= repeat 0) nil)
   ((> repeat 100) (concat "+" (org-toodledo-repeat-to-string (mod repeat 100) rep-advanced)))
   ((and (= repeat 50) rep-advanced)
     ((string-match "Every \\([0-9]+\\) week" rep-advanced)
      (concat "+" (match-string 1 rep-advanced) "w"))
     ((string-match "Every \\([0-9]+\\) month" rep-advanced)
      (concat "+" (match-string 1 rep-advanced) "m"))
     ((string-match "Every \\([0-9]+\\) year" rep-advanced)
      (concat "+" (match-string 1 rep-advanced) "y"))
     ((string-match "Every \\([0-9]+\\) day" rep-advanced)
      (concat "+" (match-string 1 rep-advanced) "d"))
     (t rep-advanced)))
   (t (elt org-toodledo-repeat-intervals repeat))))

(defun org-toodledo-delete-current-task ()
  "Delete the current task."
  (org-back-to-heading t)
  (let ((task (org-toodledo-parse-current-task)))
    (and (> (length (org-toodledo-task-id task)) 0)
         (org-toodledo-success-p (org-toodledo-delete-task task)))
     (if (and (end-of-line)
              (re-search-forward org-complex-heading-regexp nil t))
         (match-beginning 0)
       (org-end-of-subtree t t)

(defun org-toodledo-task-get-prop (task prop) (cdr (assoc prop task)))
(defmacro org-toodledo-task-prop-defun (field)
  `(defun ,(intern (concat "org-toodledo-task-" field)) (task)
     (cdr (assoc ,field task))))

(defun org-toodledo-success-p (result)
  "Return non-nil if RESULT indicates success."
  (eq (car (car result)) 'success))
(org-toodledo-task-prop-defun "id")
(org-toodledo-task-prop-defun "title")
(org-toodledo-task-prop-defun "status")
(org-toodledo-task-prop-defun "completed")
(org-toodledo-task-prop-defun "repeat")
(org-toodledo-task-prop-defun "context")
(org-toodledo-task-prop-defun "duedate")
(org-toodledo-task-prop-defun "modified")
(org-toodledo-task-prop-defun "priority")
(org-toodledo-task-prop-defun "note")
(org-toodledo-task-prop-defun "length")
;; defun'd separately because of the change in name
(defun org-toodledo-task-repeat-advanced (task)
  (cdr (assoc "rep_advanced" task)))

(defvar org-toodledo-contexts nil "An alist of (context . id).")
(defun org-toodledo-get-contexts (&optional force)
  "Store an alist of (context . id) in `org-toodledo-contexts'.
Reload if FORCE is non-nil."
  (if (or force (null org-toodledo-contexts))
      (setq org-toodledo-contexts
             (lambda (node)
              (car (xml-node-children node))
              (xml-get-attribute node 'id)))
             (xml-get-children (car
                                (org-toodledo-call-method "getContexts")) 'context)))

(defun org-toodledo-agenda-touch ()
  "Update the Modified timestamp for the current entry in the agenda."
  (org-agenda-check-type t 'agenda 'timeline)
  (let* ((marker (or (org-get-at-bol 'org-marker)
         (buffer (marker-buffer marker))
         (pos (marker-position marker)))
    (org-with-remote-undo buffer
     (with-current-buffer buffer
       (goto-char pos)
       (if (org-entry-get (point) "Modified")
           (org-entry-put (point) "Modified" (format "%d" (float-time (current-time)))))))))

(defun org-toodledo-update-task (task &optional last-update)
  (let* ((modified (string-to-number (or (org-entry-get (point) "Modified") "")))
         (last-sync (if (org-entry-get (point) "Sync")
                        (string-to-number (org-entry-get (point) "Sync"))
         (level (car (org-heading-components)))
         (locally-modified (> modified last-sync)))
    ;; Locally modified? keep
    (if locally-modified
      ;; Not locally modified? replace
      ;; Figure out what our level is
      (delete-region (org-back-to-heading)
                     (progn (goto-char (match-end 0))
                            (if (re-search-forward org-complex-heading-regexp nil t)
                                (goto-char (match-beginning 0))
      (insert (org-toodledo-task-to-string task level))

(provide 'org-toodledo)

Weekly review: Week ending May 16, 2010

May 17, 2010 - Categories: weekly

Plans from last week:


  • [X] Present social media / collaboration ideas at an executive briefing
  • [X] Set up two simultaneous Idea Labs
  • [X] Update SME note and send it to Julia
  • [X] Follow up on IBM innovation journey – refine into presentation
  • [X] Put together En glish summary for past Idea Lab – someone else contributed a translation, hooray!
  • Helped Cate Huston settle in
  • Met with mentors
  • Put together checklists/activity templates for post-engagement follow-up, Idea Labs
  • Launched expertise search pilot for our group


  • [X] Cook another batch of food  – arroz caldo, chicken curry, and lots of chicken soup
  • [X] Explore woodworking
  • [-] Edit stuff – spring cleaning


  • [-] Map past few years of blog posts
  • [X] Draw more
  • [-] Make organizer
  • Made wallet, Moleskine covers, zippered pouch, etc. – getting the hang of this sewing thing!
  • Planted parsley bed
  • Sawed top off shelf so that it fits into the greenhouse
  • Set up Nginx, PHP, and WordPress
  • Shared org-toodledo

Plans for next week


  • [  ] Launch and facilitate two Idea Labs
  • [  ] Give “Remote Presentations That Rock” v2 presentation
  • [  ] Have more mentoring meetings
  • [  ] Write newsletter tool and use it for EAD


  • [  ] Book bed-and-breakfast for my parents
  • [  ] Check out photographers
  • [  ] Coordinate
  • [  ] Edit stuff – spring cleaning
  • [  ] Plan tea party


  • [  ] Make a list of more craft ideas
  • [  ] Get through crunchy week

Custom fields in Lotus Notes / Domino? You may need to set the SUMMARY field flag

May 18, 2010 - Categories: geek, lotus

It took me a few hours to figure out that I needed the SUMMARY field flag, so I thought I’d save you the struggle if you ever need to create a view with custom columns.

I was trying to create a view that showed the custom fields I’d added to an RSVP message: RSVPCampaign, RSVPCode, and other details. I had created a Lotus Notes button that sent me an e-mail with the information in hidden fields. I successfully processed the extra fields using a LotusScript agent. I wanted to create a view that showed the results so that I didn’t have to keep clicking on the button and checking my mail. Using a view would make it easier for me to share these tools with other people, because I figured out how to create a button that creates a view.

I couldn’t figure out how to get my custom fields to display, though. They showed up in @DocFields, but @IsAvailable(RSVPCampaign) was always false.

I read about all of the functions in the Formula language. I experimented with @GetField, field names, and other ways to access data. I dug through documentation and websites (most of which assumed people already knew things like this). Frustrated, I opened the properties dialog and started systematically going through the fields on my RSVP messages.

It took me several passes to notice that the regular fields had “Field Flags: SUMMARY” and my custom fields didn’t.

After some quick searching, I realized that I needed to set the summary field flag. So I rewrote my RSVP mailing function to include lines like this:

Dim item As NotesItem
Set item = New NotesItem(doc, "RSVPCode", code) item.IsSummary = True

I tested my new RSVP mailing button, and my view worked!

So if you’re stumped because your custom fields don’t work in view selection formulas or in column formulas, set the summary flag on the field when you set the field, and you should be good to go.

I wonder how I could’ve learned that faster. Reading other people’s source code would help. Forums are useful, too. Part of it involves picking up the jargon so that I know how to phrase my searches. Anyway, I fixed it! =D

I want to learn how to make drawings/videos like this

May 19, 2010 - Categories: drawing, learning

How do I get there? Hmm. I know how to do simple timelapse videos. I can figure out lighting. I need to get the hang of drawing and cartooning. Hmm…

Thinking about the path ahead

May 20, 2010 - Categories: career, ibm, sketches


Yes, I know, I said I wasn’t going to overthink this career thing. During a bike ride to work, I thought it might be a good idea to graph the different things I’m considering in the medium/long-term, how they relate to my comfort zone, and what kind of growth I see ahead.

Development: I understand this path the most. I have a deep background in it, I know I love doing it, I can list some things I want to learn, and I’m already in a good position to work on projects like that. This path is mainly limited by the movement of development to lower-cost areas, but I have a lot of role models who are IT architects or senior developers, so I can imagine what growth looks like.

Consulting: I’ve done a bit of consulting in the past, and I can continue to develop industry knowledge and learn more about frameworks. I can find opportunities to do this, although it’s not as easy as finding development opportunities.

My current role in Innovation Discovery: I’ve gotten the hang of the routine things I need to do, and push outside my comfort zone by creating new tools and resources to help us work. It doesn’t feel as deep in terms of growth as the other paths do, though.

Supporting and leading workshops might be a good thing to grow into. It’s a relatively big jump from where I am and I may need to have a lot more experience (people who do this are several pay-levels above me!). It’s a subset of consulting. It will give me lighter cross-industry knowledge instead of the deeper industry knowledge that comes from extended engagements.

Communications: I know a little about communications, and I enjoy writing and presenting. I don’t know enough about full-time communications work to get a good sense of whether it would be a good fit, though.

Sales: I don’t have any sales experience. It’s a great life and business skill, though, so I’d love to explore it and learn more about client needs, our offerings, and how to match-make the two. What would I bring to the table? I’m good at finding resources/experts.

Management: I don’t have any management experience, although my experiments with virtual assistance helped me learn about delegation. I don’t know yet whether I’d like this a lot or not. One way to find out is to grow in development until I can become a project manager, and then use that project management experience to figure out if I like contributing primarily through a team (instead of as an individual contributor).

It’s good to have a Plan B, C, D, etc. In terms of flexibility and transferable skills, development, consulting, and sales are great. Communications and management are transferable, but more dependent on the organization. My current role is much more IBM-specific than the others, and the complex parts of workshop leading are also IBM-specific, although the facilitation skills are transferable.

I need to learn more about the other paths to see what they look like and what the opportunities are. It’s good to explore different areas, because that will help me bring the different parts together later on.

Presented Remote Presentations That Rock v2 for the Best of TLE 2009 series

May 21, 2010 - Categories: kaizen, presentation, speaking

I presented “Remote Presentations That Rock” as part of the IBM Best of Technical Leadership Exchange series.

What worked well? What can I improve next time?

  • The one-slide summary format gave me lots of flexibility.
  • I told a few more mini-stories. Yay! Next time, I can sprinkle more examples and anecdotes into my talk.
  • Apparently, people remember my hats. =)
  • The “Oak” room and some of the other meeting rooms at 120 Bloor are excellent for videos. Well-lit white wall for the win! All you need is to bring in one of the desk lights, and you’re good to go.
  • A whiteboard is not a bad place to keep notes so that you can refer to them during your talk. Write big.
  • Using the text chat for all questions worked out well. Apparently, people are starting to shift to that pattern instead of mixed voice Q&A and text. Good for handling and prioritizing long questions, too!
  • One of the organizers suggested puppets. I could do a good presenter – bad presenter thing for fun. <laugh> If I think of the pre-conference time like a silent movie and figure out what to do, that might give people an incentive to come early!
  • One of the participants suggested using partially-drawn slides and then drawing on top of them. That might be a great way to do the next version of this talk. Elluminate’s drawing tool feels a bit harsh, but maybe Inkscape or the Gimp might be fun to try. Must check whether screensharing introduces too much of a delay.
  • Another participant suggested clipping or taping the phone headset cable so that it doesn’t create a distracting visual line away. Isn’t it so cool that people think of these things?
  • I definitely need to keep the equivalent of two bottles of water around. My throat got a bit parched towards the end.
  • Lots of good stuff in the text chat. Will reflect on and re-answer questions soon.

Remote Presentations That Rock

The garden in May

May 22, 2010 - Categories: gardening

 dscf2076 dscf2081 

I’ve written a little bit about our garden, but I haven’t reflected on how the garden helps me write and vice versa. Does it?

The usual benefits: Weeding and watering provide meditative breaks from the buzz of daily life.  The garden teaches me patience and anticipation. It keeps me in better tune with the seasons.

What can I write that hasn’t been written before?

I tell people to never let  the fear of clichés stop them from starting. After all, writing what has already been written is part of the process of discovering what is your own.

So: Why do I garden?

The mundane: I don’t want to pay the premium for cherry tomatoes at the supermarket, but I’ll happily invest in the seeds, soil, and screens to grow my own (even if it comes out to be more expensive).

I want to experience the taste of peas picked fresh from the vine, the glint of strawberries in a matted patch, the scent of rosemary lingering as I brush past. dscf2075

The stubbornness of weeds inspires me, as does the revival of the sage that I’d given up for dead.

Composting fascinates me. It’s good exercise, too.

I love the everyday miracles of seeds growing into plants ever so slowly and quickly all at once. Every day is a game of spot-the-difference.

What do I like about gardening? Turning lawn and patio stones into lettuce and tomatoes, putting down roots, and reaching for the sky (perhaps with a little help).

Braindump: On face-to-face and online social networking (xpost)

May 23, 2010 - Categories: braindump, connecting

An author wants to set up an interview with me because she’s working on a paper on what can be done through face-to-face networking that can’t be done online.

Here’s what I think:

Most people strongly feel that face-to-face networking is much better than online social networking. A paper that focuses on what can be done through face-to-face networking that can’t be done with on-line social networking will find it hard to say anything that hasn’t been discussed before. If you want to get attention and create value, you can teach people how to effectively blend on-line social networking with their offline social networking.

How can people use online social networking tools to make it easy to identify people they want to get to know, make the initial contact, find common ground, keep in touch, maintain their network, and make introductions?

People have heard a lot about how online social networks are limited and often a waste of time. What they need is guidance on how to use these tools effectively, and how to make it worth the investment of time. As more companies explore telecommuting as a way to cut expenses and reach more globally-distributed talent, people need to learn how to connect and stay connected at work and in life.

Hmm. Let me explore that, because I get a whole lot more done with online social networking than with offline ones, and I find virtual networking to give me better results – and surprisingly good serendipity – than offline networking events.

Why I like online networking investments (blogs, presentations, etc.) more than offline networking investments (networking events, lunch, coffee):

  • Works for you even when you’re sleeping
  • Can start with other people getting value from you right away (people finding answers on your blog through search engines, etc.) – jumpstarts reciprocity
  • Reaches a much wider network with little additional effort
  • Allows people to efficiently get a sense of your depth and breadth (often more than you can pack into a five-minute conversation)
  • Makes it easy to stay connected (asymmetric connections possible; not dependent on both people’s time and inclination)
  • Supports greater value capture (it’s easier to copy and share an answer sent through e-mail than to remember what you discussed, type that up, and then share it)

Where offline networking is still useful: hearing from people who don’t share online

What I would recommend to people who are starting out:

  • Ditch the mindset that online social networking is much less effective than offline. Don’t be limited by your preconceptions.
  • Share what you know. Give as much knowledge away as you can. Create as much value as you can.
  • Be real. Don’t let the fear of imperfections stop you from sharing.
  • Build bridges. Make it easy for people who meet you offline to discover your online self. Make it easy for people who come across one of your posts to discover the others.
  • Experiment. Stick with things for a while before you give up, because it takes time to form a habit. Focus on immediate personal benefits so that you don’t get discouraged if you’re not immediately popular. Figure out what works for you.
  • Learn from others. Find someone you admire and learn from them. Ask questions. Share what you learn from them.

Getting the hang of gardening

May 24, 2010 - Categories: gardening, kaizen

I’m starting to figure out what works for me in terms of gardening. I start seeds indoors on a seed tray, keeping them cat-proof by stashing them in an indoor greenhouse. I don’t get enough light indoors, so I move seedlings out to larger containers in a small outdoor greenhouse, or in the pots on the deck. As seedlings grow, I move them into the garden bed, where chickenwire keeps them safe from squirrels and birds.

How is this better than planting directly in the ground?

  • Because I start the seeds in sterile soil mix, I don’t have to figure out whether a seedling is one of my plants or a weed.
  • It’s easier to weed around larger transplants than in a seedling bed.
  • I make better use of the sunny garden areas because I don’t have to wait for seeds to start.
  • I can use a heating mat to germinate seeds that need warm temperatures (bitter melon, canteloupes).

Things that are doing well: cilantro, lettuce (many kinds), tomatoes, spinach

Exponential awesomeness

May 25, 2010 - Categories: education, teaching, web2.0


@smeech I recently built an entire workshop around Sacha Chua‘s Teacher’s Guide to Web 2.0: Watch/Do/Teach was our mantra

@sachac Sacha! Your presentation provided a perfect, low-stress, socratic & fun contextual frame for my day-long workshop. We had a ball!


kjarrett on Twitter

@sachac LOVE your stuff! I use a couple of your slideshares for an online Web 2.0 class I facilitate. GR8 job! Keep em coming!

jdornberg on Twitter

This is why sharing is so cool. Even if I don’t have the time, ability, or network to explore the opportunities opened up by what I’ve learned, I can share those thoughts with other people, and they can go and do something awesome.

I put together the Teacher’s Guide to Web 2.0 at School because I needed to make a presentation to kick off the school year for 90 teachers. Since then, it’s been viewed over 20,000 times. More than 150 people have shared it on their blogs. I haven’t explored it further. I haven’t even posted any notes. In particular, slide #25 probably needs more explanation than the few keywords I put on there to help people remember after my talk. But it’s enough to tickle people’s imaginations, and the simplicity lets them fill in their own insights.

I like this. The more I share, the more awesome things I get to see, and the more inspired I am to share.

What can you share so that other people can build on it?

Weekly review: Week ending May 24, 2010 (Victoria Day long weekend)

May 26, 2010 - Categories: weekly

From the previous week’s plans:


  • [X] Launch and facilitate two Idea Labs
  • [X] Give “Remote Presentations That Rock” v2 presentation
  • [X] Have more mentoring meetings
  • [X] Write newsletter tool and use it for EAD
  • Reviewed Extreme Blue presentations and started planning June 23 preso
  • Chatted with David Singer about virtual presentations
  • Wrote feed widget interface script for Darrel Rader
  • Wrote a script to process Idea Lab RSVPs
  • Coached a developer on Drupal theming
  • Helped with Smarter Leaders virtual session
  • Had one-on-one chat with new manager
  • Blogged about new team structure
  • Contributed org-toodledo.el


  • [-] Book bed-and-breakfast for my parents  – sent two options
  • [  ] Check out photographers
  • [X] Coordinate
  • [X] Edit stuff – spring cleaning
  • [C] Plan tea party – postponed: incompatible with woodworking. Also, Luke’s shedding lots of cat hair, which makes entertaining hard ;)
  • Also: Built a bobbin box and a bread box, yay!
  • Finished orange paisley Moleskine cover, wallet, zippered pouch
  • Started making a price book. Still need a good way to refer to things easily and do unit cost comparisons
  • Picked up a router bit from Lee Valley Tools
  • Worked on the deck with W-
  • Clipped Neko’s claws
  • Checked out e-counseling – yes, they do premarital counseling too! Nifty. Picking their brains for best practices.


  • [X] Make a list of more craft ideas
  • [X] Get through crunchy week
  • Installed soaker hose irrigation system for front boxes and side garden
  • Reviewed new library books.

Plans for next week


  • [  ] Talk to people about expertise location and other new tools
  • [  ] Talk to Lynne Waymon about networking
  • [  ] Present “Remote Presentations That Rock” again on Friday?
  • [  ] Update Idea Lab guide
  • [  ] Add more to Lotus Connections API library – create/retrieve/update/delete discussion forum posts, blog posts, etc.
  • [  ] Catch up on other initiatives


  • [  ] Plan and build Adirondack chairs
  • [  ] Post pictures of projects
  • [  ] Batch-cook this weekend: ground beef, chicken, etc.
  • [  ] Check out photographers


  • [  ] Install soaker hose irrigation system for back box and street-facing garden
  • [  ] Make a Moleskine cover for myself; create other items
  • [  ] Set up my new webserver


May 27, 2010 - Categories: life

Russian birch plywood love © 2010 Sacha Chua – feel free to use it under the Creative Commons Attribution Licence

After Neko (our cat) joined our household, we discovered that we couldn’t leave bagels and other bread products outside without the risk of nibbles from a cat with the midnight munchies. We’d been looking for a wooden bread box for some time, but the stores we frequent have only plastic and stainless steel bread boxes. So I found a simple bread box plan and borrowed the basic ideas from it.

I modified the plan to use butt joints instead of lap joints because we haven’t figured out how to make proper joints yet. I also changed the plan to use 3/4″ plywood all around, because we might wall-mount the bread box and the back needs to be sturdy. I changed the height, width, and depth of the bread box too, so that it was as long as the microwave but shallow and short enough not to get in the way.

After drafting the plans on graphing paper, I marked the pieces on a sheet of 3/4″ Russian birch plywood, with 1/8″ gaps for the kerf removed by sawing. W- cut the pieces using the circular saw and his straight-cut jig. I glued and nailed the box top, back, bottom, and front rail. The nails gave me a bit of trouble, but I’m getting better at driving them in.

With the center assembled, it was easy to trace the outline on the two pieces of wood for the sides, adding 3/4″ near the top to account for the cover. I refined the lines with a ruler and W- cut them to size. While I attached the sides, he beveled the cover to fit.

All the bread box needs now are two hinges, a knob, and some kind of finish. It’s a substantial bread box with plenty of space for bread and other things we want to keep away from cats.

If I were to do this again, I’d probably make it out of a thinner wood. Russian birch plywood is stronger than regular birch plywood, so 1/2″ or thinner might do the trick. Russian birch is probably overkill for an everyday bread box, but (a) we had it, (b) I enjoyed working with it, and (c) the 13 layers of alternating dark and light wood look rather pretty on the front-facing edges. So maybe it would be regular plywood for the bottom and back (no exposed edges), and Russian birch for the sides, front, and top. =)

Oak bread boxes sell for ~$85 – 120 on The 3/4″ sheet of Russian birch was around twenty dollars. Sure, it’s not oak, and we spent a lot of time making things, but it was a great way to learn something new, create something useful, and enjoy a holiday with someone I love.

Getting the hang of big companies

May 28, 2010 - Categories: ibm, work

It occurred to me that many people don’t know what it’s like to enjoy working at a large company.

What is it like?

What I love the most about it is the ease and frequency with which I work with amazing people. No matter what the topic is, there’s bound to be someone who has thought long and hard about it and who’s passionate about it. If I’m lucky, there’s even a community of interest around it. It’s like the diversity of passions and interests you’d find on the Internet, except with a shared culture, clear identities, and ready access.

I like the fact that there’s always something happening. There are always new systems to explore, new tools to try, new ways to work.

I like the scale. I can share something that other people can build on, I can build on what other people have shared, and we can work on big things together.

I’m sure I’d love working in a smaller company or on my own as well. But hey, big-company life isn’t as bad as people sometimes think it is. Even in a company of more than four hundred thousand people, you can still find a way to rock. How?

Figure out what you do well and what you’re passionate about, and help people make the most of that. In a large company, there are plenty of opportunities, so find your way to something that fits you. For example, I enjoy helping people collaborate and I love building tools and systems, and my work has evolved to take advantage of those interests.

Get to know people in different parts of the organization. Take advantage of your organization’s size and scope by familiarizing yourself with what’s going on elsewhere, so that if you need to do something outside your area, you can get help from people who specialize in working on those things. I love using internal social networking tools to keep up with the exciting things going on in other departments.

Deal with the processes. A large company will have many standardized processes to keep things consistent. Don’t stress out about it. Adapt. If you have great ideas for making things better, figure out what and how you can influence, and be patient. Sometimes things are they way they are for good reasons beyond your experience, and sometimes things are ready for change. For example, our annual personal business commitments can seem like just another routine, but I use them to really think about what I want to do and how I want to measure success.

Take care of yourself. Take responsibility for your happiness and career growth. In a small company, it might be easier for people to relate personally, but you’re still responsible for your own growth. In a large company, it’s even more important that you realize that the best person who can look out for yourself is you. Me, I make sure I have the time and space to breathe so that I can keep bringing my passion and enthusiasm to work.

Empower yourself. Vision isn’t just the CEO’s job. Figure out your bigger picture. What’s your vision, and how can the company help you make things happen? The more your personal vision and the company vision are aligned, the easier it will be to work with the company to achieve big things.



May 29, 2010 - Categories: blogging, career, ibm, learning

During Laurie Miller’s presentation on digital eminence, she asked us to set an example for people by making sure all of our posts were relevant and meaningful.

That didn’t feel right, and I wanted to understand why.

I realized that I want people to see that they have permission to fail. To write boring things.

Blogs written by professional writers are inspiring. Tweets by stand-up comedians can be consistently amusing. But you can’t get to that point without slogging through the boring bits. Master photographers take thousands of pictures that will never see the light of day. The best baseball players still miss half of all their shots. You can’t be excellent if you’re terrified of imperfection.

You need to write badly in order to learn how to write well. That is, you need to give yourself permission to share, to make mistakes, to have errors and failed experiments.

So my contribution to helping people increase their digital eminence is this: I will be human, imperfect, and actively learning, and I hope that will help people see that it’s okay.

Exercising the senses

May 30, 2010 - Categories: learning, life

When I started writing, I discovered that it gave me ways to look at things I was learning and see if I could share them with other people.

When I tried drawing, I started seeing the structures and forms of things.

When I stumbled into giving my first presentations, I felt the dynamism of structure and conversation.

When I started exploring photography, I found myself looking at light and pattern and tone.

When I learned to sew, I couldn’t help but be entranced by the fabrics and seams of people’s clothes and accessories.

When I got into gardening, I became more aware of the seasons, sunshine, different kinds of plants, and different types of soil.

Now that I’m starting with woodworking, things around me are treasure-troves of lessons about woods, joints, and finishes. There is surprising beauty in a door when you think about how the panels float in a gap so that the wood can expand or contract. The smoothness of our shelves makes me smile.

I don’t expect much of my hobbies—just that they change my world.

How do your interests shape your experiences?

Travel kaizen and the meaning of life

May 31, 2010 - Categories: career, kaizen, purpose, reflection, travel

What do I want to do with my life? Is it worth the trade-offs? How can I make it more worthwhile?

If I’m clear about the meaning of my life and I know that it’s worth the challenges (like travel!) along the way, then relentless optimism will kick in and show me the silver lining to whatever happens. =)

So, what do I want to do with my life?

I want to share what I’m learning. This matters because it means other people can build on what I’ve figured out, and maybe they’ll be inspired to share what they’re learning, too. I don’t need travel in order to share, but travel helps me learn from other people.

I want to help figure out how people can connect and work together all around the world. This matters because I want people to be able to do their best wherever they are, not limited by the geographic lottery. Someday I’ll be able to do this without travel. Right now, sometimes I need to be there in person.

I want to live an awesome life. This matters because I can train people to do most of what I do at work, but I can’t delegate love or experiences. I worry that travel might get in the way of this, but if I learn how to do things better, maybe I can use travel to enrich life.

What can I do to make travel better for work, relationships and life?

  • I can lighten W-‘s load. This could include arranging for cat sitting or dropping the cats off at a cat hotel, doing extra chores before/after the trip to share the workload, taking transit or a cab, and so on.
  • I can meet up with more people and sit in more meetings, like the wonderful times I had in Cambridge and in London.
  • I can try different kinds of food each time, and make more of an effort to get to restaurants with great reviews.
  • I can take my gym clothes along and use the exercise facilities at the hotel. This might mean checking in, as my carry-on is often tightly packed with electronics and travel-ready business clothes. Who knows, maybe it would be great to bring along a folding bicycle. Mel Chua does that. =)
  • I can skip watching television or old movies. If I didn’t think it was worth finding and watching, then it’s probably not worth watching just because it’s there. I can spend the time writing or reading instead.
  • I can fill my iPod with interesting e-books and audiobooks. Time to go through the classics I haven’t read yet…
  • I can wake up earlier, since I don’t need to worry about disturbing anyone.
  • I can set up a calling card, or pay for the Net connection.

Hmm… I just need to figure out how to look at this, and then everything will move more smoothly.