At the team-building event the other day, I got to meet a number of other people who had been with IBM for a number of years. Several people told me stories about projects planned using at least 80-hour weeks, of high turnover and stressful environments, but also the increased responsibilities and career opportunities for people who stay with those projects. Other people talked about priorities and intentionally limiting the number of hours they worked in order to make time for other things, their happiness with their decisions, and the support they received from the company. It made me think about what work I love to do and how I want to live.
I'm getting a better idea of the work I enjoy doing. Here's a rough sketch:
I'd like to explore sales at some point, too. I want to find out if it might be a good fit for me, too, and I like the idea of helping people find the right solution for them.
So that's a general idea of my strengths. I love helping people be more effective, whether it's by sharing ideas or tips, connecting them with others, or building or tweaking tools for them. I enjoy software development and technical writing too, but mainly as a way of supporting my ability to help people be more effective. Those are the "whats," at least right now. What about the hows?
I don't see myself working on projects with unrealistic time expectations. I don't see myself sacrificing life for work or for career advancement. If I did, I'd be going up the ladder, yes, but it might be the wrong ladder for me.
The things I love doing and the things that make me special all require me to be happy and passionate about my work. I believe that I can be successful at them while living according to my values. I'm looking forward to seeing the kind of life I can build. =)
Have you thought about your whats and hows?
It's really quite odd. I've tried two USB mice (one wireless, one wired) on my Kubuntu system. They work well… once. The next time I try to use them, I'm lucky if I manage to get a minute of use out of them. Something is very wrong. =(
Anyway, that's enough time spent on mouse issues–one hour today, one hour yesterday! Pfft. I'll try it again later.
Here's a handy shortcut that toggles between the W3M web browser and other buffers you're working on. I use it to quickly switch between code and documentation (or your favorite timewasting site, as it also makes a handy boss key).
Define the function by adding the following code to your ~/.emacs:
(defun wicked/toggle-w3m () "Switch to a w3m buffer or return to the previous buffer." (interactive) (if (derived-mode-p 'w3m-mode) ;; Currently in a w3m buffer ;; Bury buffers until you reach a non-w3m one (while (derived-mode-p 'w3m-mode) (bury-buffer)) ;; Not in w3m ;; Find the first w3m buffer (let ((list (buffer-list))) (while list (if (with-current-buffer (car list) (derived-mode-p 'w3m-mode)) (progn (switch-to-buffer (car list)) (setq list nil)) (setq list (cdr list)))) (unless (derived-mode-p 'w3m-mode) (call-interactively 'w3m)))))Then bind it to a shortcut key sequence (F7 F7 in this example) by adding the following code to your ~/.emacs:
(global-set-key (kbd " ") 'wicked/toggle-w3m)You can then use F7 F7 to switch back and forth between your web browser and whatever else you're working on.
My second and last week in the Philippines was more relaxed, but it was just as enjoyable as the first week. I spent most of the time working, and I learned a lot about documentation. I helped kickstart the first BarCampManila. I also got to spend more time with my parents, have high tea with my godparents, and watch Blades of Glory with friends. Leaving the Philippines was difficult - it always is - and I found myself near tears as I walked through the airport with W-. But it was a very good trip, and I was happy to have gone.
Work: I put on my technical writer hat and rewrote most of the documentation for the administrator, bringing it up to date and adding plenty of screenshots. I still haven't quite figured out if I should document the system as it currently is (which means revising it often) or as it will be (which means inconsistent documentation for work in progress). My project manager suggested this compromise: I'll document the system assuming some critical bugs are fixed on the production server, but leave other enhancements out of the manual.
I'm learning how to use doxygen to extract source code comments, too. I'd prefer to keep low-level design documentation close to the source code so that I can keep it up to date, and I definitely don't want to reboot to Windows and start both Lotus Notes and Microsoft Word every time I need to make a change. Doxygen looks like a good tool for documenting not only the functions but also the design of the system, and I'm looking forward to learning how to make it dance. Even with what I learned after half a day of study, I was already much more comfortable with it than with the idea of keeping our developer documentation in Word. I've gotten permission from my project manager to use it for our low-level documentation, and I've promised him an archive of HTML documents by Wednesday.
That wasn't the only thing I did during the second week of my vacation, of course. I had a lot of fun at BarCampManila, a hastily-organized unconference that went really well. I gave a short speech on why geeks should blog, and I hope I convinced a few people to make it a habit. I've also posted other notes about the event. Check them out!
My parents spent a lot of time with us that week. My dad took us flying in an ultralight, and W- got this totally amazing shot of the blue sky and the volcano reflecting off the ricefields. We also snuck into a photo summit lecture on portrait photography, and we picked up lots of tips. We passed by the zoo to say hi to Maali, and we took some fun pictures with the zoo animals. Once we sort our vacation pictures, I'll post the pics on my blog.
My goals for next week (well, this week, now) are:
I've just ordered the Cintiq 12WX, a 12.1" pressure-sensitive tablet that also includes a screen so that you can see what you're working on. I think it's brilliant. It will probably be even more useful than the Lenovo X61 Tablet PC–the other gadget I was considering getting with the gadget fund I'd saved up.
I hope it will arrive in time for the four-day weekend we've got coming up. I'd love to use it to sketch my presentations, and W- will certainly enjoy using it to retouch photos.
I like this feeling. I knew I'd be in the market for some kind of drawing thing, so I started saving a few months ago. After I gave my Nintendo DS to my mom, I needed another drawing tool, and it was nice to know what I wanted AND know that I could freely get it.
More sketches to come!
BarCampManila drew over 80 people. There were 16 presentations ranging from 5 to 7 minutes each. What an amazing turnout!
Jerome Gotangco is my new hero. He organized everything (including getting a banner printed with the BarCampManila logo) less than two weeks after I e-mailed him saying that it would be fantastic to have a geek get-together on the 21st and could he please Make It Happen… Wow!
Highlights for me:
What would make this even better?
Catch the replay! I'm looking forward to hearing about the next one. I'm probably going to be in Canada, but that's what streaming is for… =)
Many people hate working during vacations. Others hate going on vacations with people who stay just as connected to the office in the country as they are in the cubicle. One of the things that I'm learning on this trip, though, is that work can actually make the trip more relaxing.
This isn't a forget-your-worries kind of vacation, but more about keeping my ties. I grew up in the Philippines, and most of my family and my friends live in Metro Manila. The short trips I take are the only time I get to catch up with them face-to-face. I remember one trip when I felt so distraught at the prospect of leaving that it was hard to enjoy the days before my flight back to Toronto. When departure looms, every moment gets thrown into hyperfocus, and there's such a temptation to pack every instant with activity. When I return to my quiet(er) Toronto life, the the sudden vacuum in my schedule gets filled with the pain of being between worlds.
So when I decided that I'd find a way to make it to the wedding of one of my best friends, I felt guilt over not being able to spend the whole time relaxing. My team members were counting on me to contribute to the project. I didn't feel comfortable taking an entire two weeks off, and it didn't make sense to fly halfway around the world for a trip of only a week. My compromise was to spend the first week on a proper vacation and the second week working remotely.
It turned out remarkably well. This week of work is what made everything feel more like home. It seems that the greatest leisure is the feeling of normalcy, of being part of the everyday routine, of following the rhythm of meals and work and some unwinding at the end of the day. Last week was hectic: lots of fun, hardly any time to breathe, hardly any time to reflect, hardly any time to slow down. This week, I feel more like I'm at home.
This trip to the Philippines feels much more relaxed than the others, as if we're not trying to cram too much in too little time. Yes, we're flying back to Toronto two days from now. Yes, two weeks is still too short a trip. Yes, I've run out of evenings for planning get-togethers. But it doesn't feel as jarring as the last time I traveled. I don't feel as misplaced, and I don't feel that I'm unraveling from the strain of being "on" all the time. I have space to be normal. I have time to breathe.
I've checked off some bugs, written some documentation, responded to some mail, and thought about some improvements. There's a sleepy cat on my lap. All is well with the world.
I'm flying back to Toronto in a couple of days. In the past two weeks, I learned that I can work anywhere, there are things I love about both worlds I live in, and that I can be fully present–here and now–even though I'm becoming a person of two worlds.
I just spent the last three days updating the administrator's guide and related documentation for the Transition2 project, making pretty screenshots and typing in clear, step-by-step instructions. Last time I checked, I had 80 pages or so. I don't know if anyone's going to read it, but at least it's there. =)
I actually had fun writing it. I do miss hacking on Drupal code, though.
So here's my current hierarchy of things I enjoy doing for work, going from most enjoyable to least enjoyable:
In an ideal world, you would never need to make your browser pretend to be a different browser. In reality, a number of websites check for specific browsers such as Mozilla or Internet Explorer, or even specific versions of those browsers. Other websites check for popular search engine crawlers such as the Googlebot in order to display content optimized for that search engine. You may want to change your user agent to work around such limitations, or you might want to change your user agent string just for fun.
The following code allows you to set your user agent (wicked/w3m-set-user-agent), reload the current page using a specified user agent (wicked/w3m-reload-this-page-with-user-agent), and define regular expression matches for URLs to control user agent strings (wicked/w3m-fake-user-agent-sites). To use this, add the following to your ~/.emacs:
(defvar wicked/w3m-fake-user-agents ;; (1) `(("w3m" . ,(concat "Emacs-w3m/" emacs-w3m-version " " w3m-version)) ("ie6" . "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)") ("ff3" . "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008070206 Firefox/3.0.1") ("ff2" . "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.13) Gecko/20080208 Firefox/2.0.0.13") ("ie7" . "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)") ("ie5.5" . "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)") ("iphone" . "Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_0 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5A347 Safari/525.20") ("safari" . "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_2; en-us) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13") ("google" . "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")) "*Associative list of user agent names and strings.") (defvar wicked/w3m-fake-user-agent-sites ;; (2) '(("^https?://www\\.useragentstring\\.com" . "ff2")) "*Associative list of regular expressions matching URLs and the agent keyword or value. The first matching entry will be used.") (defun wicked/w3m-set-user-agent (agent) "Set the user agent to AGENT based on `wicked/w3m-fake-user-agents'. If AGENT is not defined in `wicked/w3m-fake-user-agents', it is used as the user agent. If AGENT is empty, the default w3m user agent will be used." (interactive (list (completing-read "User-agent [w3m]: " (mapcar 'car wicked/w3m-fake-user-agents) nil nil nil nil "w3m"))) ;; (3) (if agent (progn (setq w3m-user-agent (or (and (string= agent "") (assoc "w3m" wicked/w3m-fake-user-agents)) ;; (4) (cdr (assoc agent wicked/w3m-fake-user-agents)) ;; (5) agent)) ;; (6) (setq w3m-add-user-agent t)) (setq w3m-add-user-agent nil))) (defun wicked/w3m-reload-this-page-with-user-agent (agent) "Browse this page using AGENT based on `wicked/w3m-fake-user-agents'. If AGENT is not defined in `wicked/w3m-fake-user-agents', it is used as the user agent. If AGENT is empty, the default w3m user agent will be used." (interactive (list (completing-read "User-agent [w3m]: " (mapcar 'car wicked/w3m-fake-user-agents) nil nil nil nil "w3m"))) (let ((w3m-user-agent w3m-user-agent) (w3m-add-user-agent w3m-add-user-agent)) (wicked/w3m-set-user-agent agent) ;; (7) (w3m-reload-this-page))) (defadvice w3m-header-arguments (around wicked activate) ;; (8) "Check `wicked/w3m-fake-user-agent-sites' for fake user agent definitions." (let ((w3m-user-agent w3m-user-agent) (w3m-add-user-agent w3m-add-user-agent) (sites wicked/w3m-fake-user-agent-sites)) (while sites (if (string-match (caar sites) (ad-get-arg 1)) (progn (wicked/w3m-set-user-agent (cdar sites)) (setq sites nil)) (setq sites (cdr sites)))) ad-do-it))
wicked/w3m-fake-user-agents sets up a number of common user agents(1) using examples from http://www.useragentstring.com. If you frequently use other user agents, add them to this associative list. wicked/w3m-fake-user-agent-sites sets up some rules for URLs so that you can work around specific websites(2). The first matching rule will be used.
wicked/w3m-set-user-agent can be called from a w3m browser session to set the user agent for all new pages visited. By default, it uses the w3m user agent(3). It will also use the w3m user agent if the agent is blank(4). If the user agent is one of the frequently-used agents defined in wicked/w3m-fake-user-agents, then the corresponding user agent string will be used(5). If not, the string will be used as-is(6). If the agent is nil, the user agent string will be disabled.(7)
You can check a single page using a different user agent by using M-x wicked/w3m-reload-this-page-with-user-agent. It temporarily sets the user agent and then reloads the current page.(7)
The last segment of code modifies the behavior of w3m-header-arguments(8), matching wicked/w3m-fake-user-agents against the URL. This temporarily sets the user agent for matching sites.
I've written about using drush to evaluate PHP statements in the Drupal context using the command line before, and it turns out that Drush is also quite useful for running Simpletest scripts. Drush comes with a module that allows you to display all the available tests with "drush test list", run all the tests with "drush test run", or run specified tests with "drush test run test1,test2".
'Course, I wanted to run groups of tests and tests matching regular expressions, so I defined two new commands:
Here's the patch to make it happen:
Index: drush_simpletest.module =================================================================== --- drush_simpletest.module (revision 884) +++ drush_simpletest.module (working copy) @@ -12,9 +12,13 @@ function drush_simpletest_help($section) { switch ($section) { case 'drush:test run': - return t("Usage drush [options] test run.\n\nRun the specified specified unit tests. If is omitted, all tests are run. should be a list of classes separated by a comma. For example: PageCreationTest,PageViewTest."); + return t("Usage drush [options] test run .\n\nRun the specified unit tests. If is omitted, all tests are run. should be a list of classes separated by a comma. For example: PageCreationTest,PageViewTest."); case 'drush:test list': return t("Usage drush [options] test list.\n\nList the available tests. Use drush test run command to run them. "); + case 'drush:test group': + return t("Usage drush [options] test group .\n\nRun all unit tests in the specified groups. For example: drush test group Group1,Group2"); + case 'drush:test re': + return t("Usage drush [options] test re .\n\nRun all unit tests matching this regular expression. For example: drush test re Page.*"); } } @@ -30,10 +34,18 @@ 'callback' => 'drush_test_list', 'description' => 'List the available Simpletest test classes.', ); + $items['test re'] = array( + 'callback' => 'drush_test_re', + 'description' => 'Run one or more Simpletest tests based on regular expressions.', + ); + $items['test group'] = array( + 'callback' => 'drush_test_group', + 'description' => 'Run one or more Simpletest test groups.', + ); return $items; } -function drush_test_list() { +function drush_test_get_list() { simpletest_load(); // TODO: Refactor simpletest.module so we don't copy code from DrupalUnitTests $files = array(); @@ -60,6 +72,11 @@ $rows[] = array($class, $info['name'], truncate_utf8($info['desc'], 30, TRUE, TRUE)); } } + return $rows; +} + +function drush_test_list() { + $rows = drush_test_get_list(); return drush_print_table($rows, 0, TRUE); } @@ -75,3 +92,31 @@ } return $result; } + +function drush_test_re($expression) { + if (!$expression) { + die('You must specify a regular expression.'); + } + $rows = drush_test_get_list(); + $tests = array(); + foreach ($rows as $row) { + if (ereg($expression, $row[0])) { + $tests[] = $row[0]; + } + } + simpletest_run_tests($tests, 'text'); + return $result; +} + +function drush_test_group($groups) { + $rows = drush_test_get_list(); + $tests = array(); + $groups = explode(',', $groups); + foreach ($rows as $row) { + if (in_array($row[1], $groups)) { + $tests[] = $row[0]; + } + } + simpletest_run_tests($tests, 'text'); + return $result; +}That makes running tests so much easier and more fun!
A number of browsers allow you to define quick searches so that you can type keywords into your address bar in order to search predetermined sites. With a little bit of code, you can do this in Emacs, too. In this project, you'll learn how to set up your own keywords to work with w3m and browse-url, so you can use your keywords for browsing both inside and outside Emacs.
First, set up keywords by adding the following lines to your ~/.emacs. We'll use an associative list of regular expressions and substitutions, like this:
(setq wicked/quick-search-alist '(("^g?:? +\\(.*\\)" . ;; Google Web "http://www.google.com/search?q=\\1") ("^g!:? +\\(.*\\)" . ;; Google Lucky "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&q=\\1") ("^dict:? +\\(.*\\)" . ;; Dictionary "http://dictionary.reference.com/search?q=\\1")))This will turn "g keyword1 keyword2" into a Google search for keyword1 and keyword2.
Next, define advice for the functions that open URLs. Before-type advice allows you to modify arguments before the function is run, and we'll use that to change the URLs. To modify the URL behavior of w3m, add the following to your ~/.emacs:
(require 'cl-seq) (defadvice w3m-goto-url (before wicked activate) "Use the quick searches defined in `wicked/quick-search-alist'." (let* ((my-url (replace-regexp-in-string "^ *\\| *$" "" (replace-regexp-in-string "[ \t\n]+" " " (ad-get-arg 0)))) (match (assoc-if (lambda (a) (string-match a my-url)) wicked/quick-search-alist))) (if match (ad-set-arg 0 (replace-regexp-in-string (car match) (cdr match) my-url)))))This sets up your quick searches for use within w3m. To set up quick searches for use with browse-url and external browsers, add the following to your ~/.emacs:
(defadvice browse-url (before wicked activate) "Use the quick searches defined in `wicked/quick-search-alist'." (let* ((my-url (replace-regexp-in-string "^ *\\| *$" "" (replace-regexp-in-string "[ \t\n]+" " " (ad-get-arg 0)))) (match (assoc-if (lambda (a) (string-match a my-url)) wicked/quick-search-alist))) (if match (ad-set-arg 0 (replace-regexp-in-string (car match) (cdr match) my-url)))))To try out your searches, use M-x browse-url RET g emacs RET to do a Google search for all things Emacs, and use M-x w3m-goto-url (usually bound to g) inside w3m to use the quick searches.
You can define more quick searches like this:
(add-to-list 'wicked/quick-search-alist '("^ew:? *?\\(.*\\)" . ;; Emacs Wiki Search "http://www.emacswiki.org/cgi-bin/wiki?search=\\1"))What a hectic and fun week!
It was the first week of my vacation in the Philippines, and every day was just packed with things to do with friends and family.
On August 11 (Monday), we arrived in Manila. The Philippine Airlines flight we arrived on was full of boisterous Filipinos who joked with the flight attendants, sang way off-key, and cheered as the plane touched the tarmac, but I didn't mind losing sleep on that red-eye flight. I was home! And I was awake enough to try the dress I was going to wear for Diane's wedding and make other arrangements…
On August 12, I celebrated my birthday with W- and my parents. My dad took W- and me to Raon (the electronics district) and R. Hidalgo (the street of photography shops), and he gave me a flash for my birthday. I look forward to using it to light stuff! In the afternoon, my mom took W- and me to Ateneo de Manila University and Philippine Science High School, so that W- could get an idea of what my campus years were like. We also passed by the University of Philippines, where my mom told W- stories about her campus years. In the evening, I snuck into the Benilde commencement ceremony and exhibit for the graduates of their photography diploma course, and I listened to my dad and my sister give the short commencement speech. Cool!
On August 13, my dad gave W- and me a few shooting lessons. We discovered that the flash I have can freeze water drops in action, and we also practiced lighting small objects. I took a picture of the Scrabble game that W- and I had played on the flight home. It was definitely worth recording. =) After our shooting lessons, my mom took us to Alabang, where we had a tea party with several of my godparents. We listened to hilarious stories about avoiding traffic tickets, taking pictures in restricted areas, and other hijinks that my parents and godparents had done.
Practically all of August 14 was taken up by Diane's wedding. She was the first of my best friends to get married, so we were all excited about that. I couldn't help going "squee!" every few minutes. I loved the video montage that Mario had put together: childhood pictures, high school pictures, all the way up to their engagement pictures. The wedding photographers delighted us by showing a video montage of Di's wedding pictures during the reception itself - that was fast work!
We spent most of August 15 working at home. I was aghast to find out that a bug in my code had resulted in the deletion of users on our production system ( =( !), and that the project manager and the IT architect had to recreate many accounts by hand. That further emphasized the importance of test-first development and well-written tests. Ouch. I've paid the tuition for that mistake, now I just have to collect the paycheck; I can't undo that mistake, but I can learn from it and become a better developer. To avoid that mistake in the future, I will write more tests using the Simpletest framework, and I'll ask someone else to review the tests with me.
I perked up a bit more in the afternoon, when my mom took W- and me to a yoga class taught by one of her friends. It was more challenging than the yoga classes we normally attend, and it was a good break. The yoga teacher was so impressed that both W- and I do yoga, and waxed lyrical about how beautiful it was to see couples practice yoga together.
On August 16, I hosted a get-together for my friends. We spent the entire afternoon laughing at the best of the Internet memes: a pastiche of websites and Youtube videos that we or the others had missed. In the evening, we watched Shaun of the Dead and Hot Fuzz, which both left us practically crying from laughter (and maybe a little grossed out). It was so nice to laugh with my friends again!
We spent most of August 17 at a photography summit, where we learned about taking pictures of people. I'm looking forward to applying those lessons. I'd like to learn how to take good pictures of my friends! My mom also showed W- the rows and rows of stalls selling pearls at Greenhills. It was all quite overwhelming, and I was glad to get back to the photography summit.
So that was what last week was like. I hope next week will be a little calmer. <b>I plan to work during most of the week</b>. I'm going to be on a team call this evening, so I napped this afternoon to make sure I can stay up later. A quieter schedule should mean more early-morning writing time, too, and I'm looking forward to <b>posting more notes on browsing the Web from Emacs</b>.
Lastly, I'm thrilled at how BarCampManila's turning out. I pinged a couple of people about having a geek get-together on Thursday, August 21, and gave them the responsibility for making it happen. And they did! So, if you're near Metro Manila and you want to hang out, check out:
<a href="http://www.barcamp.org/BarCampManila">BarCamp Manila</a> - August 21, 2008, 7:00 PM @ G2VC Innovation Center<br />
<a href="http://www.barcamp.org/BarCampManila">SIGN UP ON BARCAMP.ORG!</a>
So here's how to access Facebook from w3m, one of the web browsers in
Emacs:
1. Enable cookies by setting w3m-use-cookies to t.
2. Go to http://m.facebook.com .
3. Choose the HTTP login.
4. Log in with your username and password.
Hooray for mobile interfaces that don't require Javascript! =D
So far, it seems to work. I can update my status! Sweet!
Next step: Figure out how to set up shimbun for Facebook mail so that I can read my Facebook mail like a newsgroup…
"Are you browsing Slashdot in Emacs?", W- asked me after he glanced at my screen.
With Emacs' reputation for including everything _and_ the kitchen sink, you probably won't be surprised to hear that there's more than one way to surf the Internet using your text editor. With today's Javascript- and image-heavy websites, it can be hard to believe that anyone would use a text-based browser with limited support for many of the things we take for granted. Still, a Web browser in your text editor can be surprisingly useful. Here are some of the reasons why you might like it:
There's more than one way to browse the Web in Emacs, of course. Browse-url is a package that makes it easy to open URLs in your preferred browser or browsers. For example, you can use it to browse the Web in Mozilla Firefox, and (of course) you can use it to browse the Web within Emacs itself. For browsing within Emacs, you can use w3m.el, an interface to the external W3M browser, or w3, a Web browser written entirely in Emacs Lisp. Of the two, I prefer w3m.el, which is much faster and more featureful than w3. Both can display graphics, tables, and frames, and w3 supports stylesheets.
More about Emacs and browsing the Web soon! Planned projects for this chapter of Wicked Cool Emacs:
*** Project XXX: Browse the Web *** Project XXX: Open the current webpage in an external browser *** Project XXX: Different browsers for different pages *** Project XXX: Toggle between Web and work *** Project XXX: Quick search *** Project XXX: Customize your keymap *** Project XXX: Download files *** Project XXX: Add access keys *** Project XXX: Use social bookmarking *** Project XXX: Typeahead *** Project XXX: Preview HTML *** Project XXX: Read Web pages as newsLast night, I figured out how I wanted to celebrate my birthday.
I've never really been one for gifts, and my family's much the same way. One year, my mom said that for her birthday, she'd like to receive sturdy plants for her garden. Another time, she requested books. One year, I asked people for letters. On another birthday, I asked people for their two-year plans. (Seriously. I gave seatwork.)
This year, I wanted to celebrate my birthday by sharing stories. I realized that a large part of being homesick is missing the sense of being known, and I wanted to share both my Philippine stories with W- and my Canadian stories with my family.
I celebrated my 25th birthday with my parents, my middle sister Kathy, and my partner W-. In the morning, my dad took W- and me around the electronic shops at Raon, the combination of Catholicism and superstition around Quiapo, and the photography shops at R. Hidalgo. I'm looking forward to trying out the SB-800 flash my dad gave me as a birthday gift. =)
After our trip, my mom took us around Ateneo, UP, and Pisay. W- and I had watched "Philippine Science" at the Toronto International Film Festival, so it was nice for him to see where I'd gone to school. We told a lot of stories along the way.
In the evening, my dad and my sister gave the commencement speech at the graduation of the photography students at Benilde. It was a quick, informal affair accompanied by a photo exhibit, which inspired me to think about shooting more.
After the commencement reception, we went out to dinner at Chateau 1771 in Greenbelt. We told tons of stories over dinner, and W- got a better idea of the crazy adventures that my family finds ourselves in. =D It was just the way I wanted to spend my birthday. (Or, well, it would've been if I'd remembered to bring a way to record the stories…)
Tomorrow, my godparents are having a tea party at the house in Alabang. It'll be fun seeing them again. =) The day after that is Diane's wedding - hooray! I just finished sending a few of my high school pictures to Mario, who's putting together a slideshow. Can't wait to attend!
25 years. So far, so good. Next up - even better!
Building on the configuration management strategy I described last time, I wrote some scripts to make it easier for other developers to migrate the production database to the QA server or to get a copy of the production database for their local system. I needed to consider the following factors:
| Production | QA | Local |
|---|---|---|
| example.com | qa.example.com | local.example.com |
| foo.example.com | foo.qa.example.com | foo.local.example.com |
| bar.example.com | bar.qa.example.com | bar.local.example.com |
Here's how I did it:
$conf allows you to override Drupal variables returned by variable_get.
So now, I can click on a button to migrate a sanitized copy of the production database to the QA server or to my local system. Sweet!
I'm heading to the Philippines tomorrow, and to make life easer for the two other Windows-based PHP developers on my team, I updated the web-based deployment script I mentioned in
Development kaizen: deployment and testing. I added the ability to push a specified revision to the production server. It took me less time than I thought it would (I love it when things Just Work!), so I decided to spend time documenting it just in case I ever need to do it again (almost certainly) or just in case it breaks while I'm away (hope not).
Behind the scenes, there are a number of moving parts:
Luis Suarez has just realized that being a Web 2.0 evangelist doesn't mean getting into every new Web 2.0 tool, and he linked to Chris Brogan's post on doing what works for you.
This reminds me of a point I've been wanting to think about for a while. =)
When people look at the way new generations or new hires immerse themselves in learning, they often think that they themselves could never do that, could never find the time to try out and learn all these different things.
If you've ever told yourself that or heard someone say that, I'd like to help you remember what it was like to be on the other side of the fence, and I'd like to remind my future self what it's like to be here.
Yes, being new means I have no bad habits to unlearn. That's part of it. But it's also true that I don't have as many good habits as you do, or even "good enough" habits that can get me through. That's one of the things that drives me to go out there and experiment. Because I don't have a "good" way of dealing with so many things, I need to try lots of different ways and see which ways work for me.
In other areas, where I've found things that work for me, I stick with them and get deeper and deeper into them. Someday, my mind might have been so shaped by the tools I've used that I won't see any need or potential beyond them, and it might be someone else's turn to explore even further.
I think that the trick, then, is to keep "breaking" things, keep stepping out of my comfort zone, so that I always feel the urge to learn something. For example, even though I've used Emacs for years, I'm always pushing it to do something new, and I'm always tinkering with other editors and other systems to see if I can steal any good ideas.
Helping other people also stops me from becoming complacent, becoming too comfortable with my current toolkit. When I'm helping people brainstorm, answering their questions, customizing systems to fit their needs, I learn more about them, the system, and myself. I learn in the process of teaching.
I'm not going to adopt every single thing that comes along, especially when I've already got something that works out quite well. (Look at how old my text editor is!) That's okay. That kind of exploration will naturally fit other people. What I can do, though, is:
That's how I plan to mix being both new and experienced. =)
How do you keep yourself new?
What a creative way to make things concrete… <laugh>
Tangible Bug Tracking Using LEGO Bricks in Agile2008, Toronto view presentation (tags: buglego agile2008 lego tool)I've been paying attention to the preventive advice I picked up during my last session with a registered massage therapist, and I thought I'd post an update on how things are going with this life-hacking.
I switched to flat shoes. When the massage therapist mentioned that high-heeled shoes could be the reason why some of my muscles were tense, I said I'd switch to flat shoes. This was apparently not the way most women react. They're more likely to say, "Sure, when they make flat shoes that aren't ugly." Well, I found two pairs of shoes that look presentable enough for the office. =)
It turns out that you really do need to walk a mile in your own shoes before they're broken-in enough to be comfortable. Both of my new pairs of flat shoes are now comfy enough for extended walks. The fancy insoles I picked up to add arch support threw me off balance and induced enough pain to make me hobble, so I got rid of the insoles. Now I just use plain liners to keep the shoes relatively clean.
There's only one thing I'm having a hard time doing: leaning back. The massage therapist said that some of my back and neck muscles are tenser than they need to be because I lean forward instead of using the chair back. I'm not used to the idea of leaning back against the chair. It feels casual, and it sometimes means that I'm not in quite the right position to type.
Hmm…