Search Results: "rinni"

26 September 2022

Bits from Debian: New Debian Developers and Maintainers (July and August 2022)

The following contributors got their Debian Developer accounts in the last two months: The following contributors were added as Debian Maintainers in the last two months: Congratulations!

29 December 2021

Chris Lamb: Favourite books of 2021: Memoir/biography

Just as I did for 2020, I won't publically disclose exactly how many books I read in 2021, but they evidently provoked enough thoughts that felt it worth splitting my yearly writeup into separate posts. I will reveal, however, that I got through more books than the previous year, and, like before, I enjoyed the books I read this year even more in comparison as well. How much of this is due to refining my own preferences over time, and how much can be ascribed to feeling less pressure to read particular books? It s impossible to say, and the question is complicated further by the fact I found many of the classics I read well worth of their entry into the dreaded canon. But enough of the throat-clearing. In today's post I'll be looking at my favourite books filed under memoir and biography, in no particular order. Books that just missed the cut here include: Bernard Crick's celebrated 1980 biography of George Orwell, if nothing else because it was a pleasure to read; Hilary Mantel's exhilaratingly bitter early memoir, Giving up the Ghost (2003); and Patricia Lockwood's hilarious Priestdaddy (2017). I also had a soft spot for Tim Kreider's We Learn Nothing (2012) as well, despite not knowing anything about the author in advance, likely a sign of good writing. The strangest book in this category I read was definitely Michelle Zauner's Crying in H Mart. Based on a highly-recommended 2018 essay in the New Yorker, its rich broth of genuine yearning for a departed mother made my eyebrows raise numerous times when I encountered inadvertent extra details about Zauner's relationships.

Beethoven: A Life in Nine Pieces (2020) Laura Tunbridge Whilst it might immediately present itself as a clickbait conceit, organising an overarching narrative around just nine compositions by Beethoven turns out to be an elegant way of saying something fresh about this grizzled old bear. Some of Beethoven's most famous compositions are naturally included in the nine (eg. the Eroica and the Hammerklavier piano sonata), but the book raises itself above conventional Beethoven fare when it highlights, for instance, his Septet, Op. 20, an early work that is virtually nobody's favourite Beethoven piece today. The insight here is that it was widely popular in its time, played again and again around Vienna for the rest of his life. No doubt many contemporary authors can relate to this inability to escape being artistically haunted by an earlier runaway success. The easiest way to say something interesting about Beethoven in the twenty-first century is to talk about the myth of Beethoven instead. Or, as Tunbridge implies, perhaps that should really be 'Beethoven' in leaden quotation marks, given so much about what we think we know about the man is a quasi-fictional construction. Take Anton Schindler, Beethoven's first biographer and occasional amanuensis, who destroyed and fabricated details about Beethoven's life, casting himself in a favourable light and exaggerating his influence with the composer. Only a few decades later, the idea of a 'heroic' German was to be politically useful as well; the Anglosphere often need reminding that Germany did not exist as a nation-state prior to 1871, so it should be unsurprising to us that the late nineteenth-century saw a determined attempt to create a uniquely 'German' culture ex nihilo. (And the less we say about Immortal Beloved the better, even though I treasure that film.) Nevertheless, Tunbridge cuts through Beethoven's substantial legacy using surgical precision that not only avoids feeling like it is settling a score, but it also does so in a way that is unlikely to completely alienate anyone emotionally dedicated to some already-established idea of the man to bring forth the tediously predictable sentiment that Beethoven has 'gone woke'. With Alex Ross on the cult of Wagner, it seems that books about the 'myth of X' are somewhat in vogue right now. And this pattern within classical music might fit into some broader trend of deconstruction in popular non-fiction too, especially when we consider the numerous contemporary books on the long hangover of the Civil Rights era (Robin DiAngelo's White Fragility, etc.), the multifarious ghosts of Empire (Akala's Natives, Sathnam Sanghera's Empireland, etc.) or even the 'transmogrification' of George Orwell into myth. But regardless of its place in some wider canon, A Life in Nine Pieces is beautifully printed in hardback form (worth acquiring for that very reason alone), and it is one of the rare good books about classical music that can be recommended to both the connoisseur and the layperson alike.

Sea State (2021) Tabitha Lasley In her mid-30s and jerking herself out of a terrible relationship, Tabitha Lasley left London and put all her savings into a six-month lease on a flat within a questionable neighbourhood in Aberdeen, Scotland. She left to make good on a lukewarm idea for a book about oil rigs and the kinds of men who work on them: I wanted to see what men were like with no women around, she claims. The result is Sea State, a forthright examination of the life of North Sea oil riggers, and an unsparing portrayal of loneliness, masculinity, female desire and the decline of industry in Britain. (It might almost be said that Sea State is an update of a sort to George Orwell's visit to the mines in the North of England.) As bracing as the North Sea air, Sea State spoke to me on multiple levels but I found it additionally interesting to compare and contrast with Julian Barnes' The Man with Red Coat (see below). Women writers are rarely thought to be using fiction for higher purposes: it is assumed that, unlike men, whatever women commit to paper is confessional without any hint of artfulness. Indeed, it seems to me that the reaction against the decades-old genre of autofiction only really took hold when it became the domain of millennial women. (By contrast, as a 75-year-old male writer with a firmly established reputation in the literary establishment, Julian Barnes is allowed wide latitude in what he does with his sources and his writing can be imbued with supremely confident airs as a result.) Furthermore, women are rarely allowed metaphor or exaggeration for dramatic effect, and they certainly aren t permitted to emphasise darker parts in order to explore them... hence some of the transgressive gratification of reading Sea State. Sea State is admittedly not a work of autofiction, but the sense that you are reading about an author writing a book is pleasantly unavoidable throughout. It frequently returns to the topic of oil workers who live multiple lives, and Lasley admits to living two lives herself: she may be in love but she's also on assignment, and a lot of the pleasure in this candid and remarkably accessible book lies in the way these states become slowly inseparable.

Twilight of Democracy (2020) Anne Applebaum For the uninitiated, Anne Applebaum is a staff writer for The Atlantic magazine who won a Pulitzer-prize for her 2004 book on the Soviet Gulag system. Her latest book, however, Twilight of Democracy is part memoir and part political analysis and discusses the democratic decline and the rise of right-wing populism. This, according to Applebaum, displays distinctly authoritarian tendencies, and who am I to disagree? Applebaum does this through three main case studies (Poland, the United Kingdom and the United States), but the book also touches on Hungary as well. The strongest feature of this engaging book is that Appelbaum's analysis focuses on the intellectual classes and how they provide significant justification for a descent into authoritarianism. This is always an important point to be remembered, especially as much of the folk understanding of the rise of authoritarian regimes tends to place exaggerated responsibility on the ordinary and everyday citizen: the blame placed on the working-class in the Weimar Republic or the scorn heaped upon 'white trash' of the contemporary Rust Belt, for example. Applebaum is uniquely poised to discuss these intellectuals because, well, she actually knows a lot of them personally. Or at least, she used to know them. Indeed, the narrative of the book revolves around two parties she hosted, both in the same house in northwest Poland. The first party, on 31 December 1999, was attended by friends from around the Western world, but most of the guests were Poles from the broad anti-communist alliance. They all agreed about democracy, the rule of law and the route to prosperity whilst toasting in the new millennium. (I found it amusing to realise that War and Peace also starts with a party.) But nearly two decades later, many of the attendees have ended up as supporters of the problematic 'Law and Justice' party which currently governs the country. Applebaum would now cross the road to avoid them, and they would do the same to her, let alone behave themselves at a cordial reception. The result of this autobiographical detail is that by personalising the argument, Applebaum avoids the trap of making too much of high-minded abstract argument for 'democracy', and additionally makes her book compellingly spicy too. Yet the strongest part of this book is also its weakest. By individualising the argument, it often feels that Applebaum is settling a number of personal scores. She might be very well justified in doing this, but at times it feels like the reader has walked in halfway through some personal argument and is being asked to judge who is in the right. Furthermore, Applebaum's account of contemporary British politics sometimes deviates into the cartoonish: nothing was egregiously incorrect in any of her summations, but her explanation of the Brexit referendum result didn't read as completely sound. Nevertheless, this lively and entertaining book that can be read with profit, even if you disagree with significant portions of it, and its highly-personal approach makes it a refreshing change from similar contemporary political analysis (eg. David Runciman's How Democracy Ends) which reaches for that more 'objective' line.

The Man in the Red Coat (2019) Julian Barnes As rich as the eponymous red coat that adorns his cover, Julian Barnes quasi-biography of French gynaecologist Samuel-Jean Pozzi (1846 1918) is at once illuminating, perplexing and downright hilarious. Yet even that short description is rather misleading, for this book evades classification all manner number of ways. For instance, it is unclear that, with the biographer's narrative voice so obviously manifest, it is even a biography in the useful sense of the word. After all, doesn't the implied pact between author and reader require the biographer to at least pretend that they are hiding from the reader? Perhaps this is just what happens when an author of very fine fiction turns his hand to non-fiction history, and, if so, it represents a deeper incursion into enemy territory after his 1984 metafictional Flaubert's Parrot. Indeed, upon encountering an intriguing mystery in Pozzi's life crying out for a solution, Barnes baldly turns to the reader, winks and states: These matters could, of course, be solved in a novel. Well, quite. Perhaps Barnes' broader point is that, given that's impossible for the author to completely melt into air, why not simply put down your cards and have a bit of fun whilst you're at it? If there's any biography that makes the case for a rambling and lightly polemical treatment, then it is this one. Speaking of having fun, however, two qualities you do not expect in a typical biography is simply how witty they can be, as well as it having something of the whiff of the thriller about it. A bullet might be mentioned in an early chapter, but given the name and history of Monsieur Pozzi is not widely known, one is unlikely to learn how he lived his final years until the closing chapters. (Or what happened to that turtle.) Humour is primarily incorporated into the book in two main ways: first, by explicitly citing the various wits of the day ( What is a vice? Merely a taste you don t share. etc.), but perhaps more powerful is the gentle ironies, bon mots and observations in Barnes' entirely unflappable prose style, along with the satire implicit in him writing this moreish pseudo-biography to begin with. The opening page, with its steadfast refusal to even choose where to begin, is somewhat characteristic of Barnes' method, so if you don't enjoy the first few pages then you are unlikely to like the rest. (Indeed, the whole enterprise may be something of an acquired taste. Like Campari.) For me, though, I was left wryly grinning and often couldn't wait to turn the page. Indeed, at times it reminded me of a being at a dinner party with an extremely charming guest at the very peak of his form as a wit and raconteur, delighting the party with his rambling yet well-informed discursive on his topic de jour. A significant book, and a book of significance.

27 May 2020

Russ Allbery: Review: Middlegame

Review: Middlegame, by Seanan McGuire
Publisher: Tor
Copyright: May 2019
ISBN: 1-250-19551-9
Format: Kindle
Pages: 528
Roger and Dodger are cuckoo children, alchemical constructs created by other alchemical constructs masquerading as humans. They are halves of the primal force of the universe, the Doctrine of Ethos (which is not what the Doctrine of Ethos is, but that is one of my lesser problems with this book), divided into language and math and kept separate to properly mature. In this case, separate means being adopted by families on opposite coasts of the United States, ignorant of each other's existence and closely monitored by agents Reed controls. None of that prevents Roger and Dodger from becoming each other's invisible friends at the age of seven, effortlessly communicating psychically even though they've never met. That could have been the start of an enjoyable story that hearkened back to an earlier age of science fiction: the secret science experiments discover that they have more power than their creators expected, form a clandestine alliance, and fight back against the people who are trying to control them. I have fond memories of Escape to Witch Mountain and would have happily read that book. Unfortunately, that isn't the story McGuire wanted to tell. The story she told involves ripping Roger and Dodger apart, breaking Dodger, and turning Roger into an abusive asshole. Whooboy, where to start. This book made me very angry, in a way that I would not have been if it didn't contain the bones of a much better novel. Four of them, to be precise: four other books that would have felt less gratuitously cruel and less apparently oblivious to just how bad Roger's behavior is. There are some things to like. One of them is that the structure of this book is clever. I can't tell you how it's clever because the structure doesn't become clear until more than halfway through and it completely changes the story in a way that would be a massive spoiler. But it's an interesting spin on an old idea, one that gave Roger and Dodger a type of agency in the story that has far-ranging implications. I enjoyed thinking about it. That leads me to another element I liked: Erin. She makes only fleeting appearances until well into the story, but I thought she competed with Dodger for being the best character of the book. The second of the better novels I saw in the bones of Middlegame was the same story told from Erin's perspective. I found myself guessing at her motives and paying close attention to hints that led to a story with a much different emotional tone. Viewing the ending of the book through her eyes instead of Roger and Dodger's puts it in a different, more complicated, and more thought-provoking light. Unfortunately, she's not McGuire's protagonist. She instead is one of the monsters of this book, which leads to my first, although not my strongest, complaint. It felt like McGuire was trying too hard to write horror, packing Middlegame with the visuals of horror movies without the underlying structure required to make them effective. I'm not a fan of horror personally, so to some extent I'm grateful that the horrific elements were ineffective, but it makes for some frustratingly bad writing. For example, one of the longest horror scenes in the book features Erin, and should be a defining moment for the character. Unfortunately, it's so heavy on visuals and so focused on what McGuire wants the reader to be thinking that it doesn't show any of the psychology underlying Erin's decisions. The camera is pointed the wrong way; all the interesting storytelling work, moral complexity, and world-building darkness is happening in the character we don't get to see. And, on top of that, McGuire overuses foreshadowing so much that it robs the scene of suspense and terror. Again, I'm partly grateful, since I don't read books for suspense and terror, but it means the scene does only a fraction of the work it could. This problem of trying too hard extends to the writing. McGuire has a bit of a tendency in all of her books to overdo the descriptions, but is usually saved by narrative momentum. Unfortunately, that's not true here, and her prose often seems overwrought. She also resorts to this style of description, which never fails to irritate me:
The thought has barely formed when a different shape looms over him, grinning widely enough to show every tooth in its head. They are even, white, and perfect, and yet he somehow can't stop himself from thinking there's something wrong with them, that they're mismatched, that this assortment of teeth was never meant to share a single jaw, a single terrible smile.
This isn't effective. This is telling the reader how they're supposed to feel about the thing you're describing, without doing the work of writing a description that makes them feel that way. (Also, you may see what I mean by overwrought.) That leads me to my next complaint: the villains. My problem is not so much with Leigh, who I thought was an adequate monster, if a bit single-note. There's some thought and depth behind her arguments with Reed, a few hints of her own motives that were more convincing for not being fully shown. The descriptions of how dangerous she is were reasonably effective. She's a good villain for this type of dark fantasy story where the world is dangerous and full of terrors (and reminded me of some of the villains from McGuire's October Daye series). Reed, though, is a storytelling train wreck. The Big Bad of the novel is the least interesting character in it. He is a stuffed tailcoat full of malicious incompetence who is only dangerous because the author proclaims him to be. It only adds insult to injury that he kills off a far more nuanced and creative villain before the novel starts, replacing her ambiguous goals with Snidely Whiplash mustache-twirling. The reader has to suffer through extended scenes focused on him as he brags, monologues, and obsesses over his eventual victory without an ounce of nuance or subtlety. Worse is the dynamic between him and Leigh, which is only one symptom of the problem with Middlegame that made me the most angry: the degree to this book oozes patriarchy. Every man in this book, including the supposed hero, orders around the women, who are forced in various ways to obey. This is the most obvious between Leigh and Reed, but it's the most toxic, if generally more subtle, between Roger and Dodger. Dodger is great. I had absolutely no trouble identifying with and rooting for her as a character. The nasty things that McGuire does to her over the course of the book (and wow does that never let up) made me like her more when she tenaciously refuses to give up. Dodger is the math component of the Doctrine of Ethos, and early in the book I thought McGuire handled that well, particularly given how difficult it is to write a preternatural genius. Towards the end of this book, her math sadly turns into a very non-mathematical magic (more on this in a moment), but her character holds all the way through. It felt like she carved her personality out of this story through sheer force of will and clung to it despite the plot. I wanted to rescue her from this novel and put her into a better book, such as the one in which her college friends (who are great; McGuire is very good at female friendships when she writes them) stage an intervention, kick a few people out of her life, and convince her to trust them. Unfortunately, Dodger is, by authorial fiat, half of a bound pair, and the other half of that pair is Roger, who is the sort of nice guy everyone likes and thinks is sweet and charming until he turns into an emotional trap door right when you need him the most and dumps you into the ocean to drown. And then somehow makes you do all the work of helping him feel better about his betrayal. The most egregious (and most patriarchal) thing Roger does in this book is late in the book and a fairly substantial spoiler, so I can't rant about that properly. But even before that, Roger keeps doing the the same damn emotional abandonment trick, and the book is heavily invested into justifying it and making excuses for him. Excuses that, I should note, are not made for Dodger; her failings are due to her mistakes and weaknesses, whereas Roger's are natural reactions to outside forces. I got very, very tired of this, and I'm upset by how little awareness the narrative voice showed for how dysfunctional and abusive this relationship is. The solution is always for Dodger to reunite with Roger; it's built into the structure of the story. I have a weakness for the soul-bound pair, in part from reading a lot of Mercedes Lackey at an impressionable age, but one of the dangerous pitfalls of the concept is that the characters then have to have an almost flawless relationship. If not, it can turn abusive very quickly, since the characters by definition cannot leave each other. It's essentially coercive, so as soon as the relationship shows a dark side, the author needs to be extremely careful. McGuire was not. There is an attempted partial patch, late in the book, for the patriarchal structure. One of the characters complains about it, and another says that the gender of the language and math pairs is random and went either way in other pairs. Given that both of the pairs that we meet in this story have the same male-dominant gender dynamic, what I took from this is that McGuire realized there was a problem but wasn't able to fix it. (I'm also reminded of David R. Henry's old line that it's never a good sign when the characters start complaining about the plot.) The structural problems are all the more frustrating because I think there were ways out of them. Roger is supposedly the embodiment of language, not that you'd be able to tell from most scenes in this novel. For reasons that I do not understand, McGuire expressed that as a love of words: lexicography, translation, and synonyms. This makes no sense to me. Those are some of the more structured and rules-based (and hence mathematical) parts of language. If Roger had instead been focused on stories collecting them, telling them, and understanding why and how they're told he would have had a clearer contrast with Dodger. More importantly, it would have solved the plot problem that McGuire solved with a nasty bit of patriarchy. So much could have been done with Dodger building a structure of math around Roger's story-based expansion of the possible, and it would have grounded Dodger's mathematics in something more interesting than symbolic magic. To me, it's such an obvious lost opportunity. I'm still upset about this book. McGuire does a lovely bit of world-building with Asphodel Baker, what little we see of her. I found the hidden alchemical war against her work by L. Frank Baum delightful, and enjoyed every excerpt from the fictional Over the Woodward Wall scattered throughout Middlegame. But a problem with inventing a fictional book to excerpt in a real novel is that the reader may decide that the fictional book sounds a lot better than the book they're reading, and start wishing they could just read that book instead. That was certainly the case for me. I'm sad that Over the Woodward Wall doesn't exist, and am mostly infuriated by Middlegame. Dodger and Erin deserved to live in a better book. Should you want to read this anyway (and I do know people who liked it), serious content warning for self-harm. Rating: 4 out of 10

1 June 2017

Russ Allbery: Review: Migration

Review: Migration, by Julie E. Czerneda
Series: Species Imperative #2
Publisher: DAW
Copyright: 2005
ISBN: 0-7564-0260-3
Format: Hardcover
Pages: 453
Migration is the second book of the Species Imperative, and this is the old-fashioned type of trilogy that you very much want to read in order. Start with Survival. There is a (slightly awkward) recap of the previous book at the start, though, if it's been a bit since you read it. In my review of Survival, I praised Czerneda's ability to capture the feel of academic research and the sense of real scientists doing science. I thought I went out on a bit of a limb, not being a scientist myself (just someone who worked at a university for decades), but Czerneda was still holding back. I'm now completely convinced: whatever else this series is, and it contains a lot of politics and world-building and fascinating (if very human-like) aliens, it's some of the best science fiction about practicing scientists I've ever read. I cannot express how much I adore the fact that the center of this book is not space combat, not daring adventure across alien landscapes, but getting a bunch of really smart experts in their field together in a room with good equipment and good computers to chase an intellectual problem from their own individual perspectives. And if Mac is perhaps a bit *too* good at quickly overcoming interpersonal conflict and suspicion, I'll forgive that for the deft sense of politics. Mac's success may be a bit unrealistic, but the direction and thrust of her tactics are spot-on. This is how interactions between smart and curious people often work, at least if they're sufficiently motivated to put aside pettier political infighting. This is also how the dynamics of emergency war rooms work: if you can give people a focus and divide up the work, the results can be amazing. The second best part of the book is Oversight. The first book opened with the latest round of Mac's ongoing war with Charles Mudge III, the oversight board of the neighboring wilderness trust. He shows up again at the start of this book, acting completely consistent to his stubborn idealism shown in Survival, and then develops into one of the best characters in the book. Unexpected allies is one of the tropes I love most in fiction in general, but this one resonates so deeply with the way grudging respect and familiar patterns, even patterns of argument, work on people. Czerneda had me grinning. It's just perfectly in line with Mac's character, her single-minded focus on work that tended to miss a few points of human connection, and the sort of deepening respect that builds up even between adversaries when they know deep inside that they are following different interpretations of the same principles. I'm going to be rather sketchy on the plot, since Migration follows closely on from Survival and is concerned almost entirely with the aftermath of the climactic events at the end of that book. But as you can tell, this is more of Mac, and she's not managed to separate herself from Dhryn problems or from the Ministry of Extra-Solar Affairs. She does, however, get rather far away from Norcoast for a while, an interlude in the wild northern Canadian wilderness that once again proves Czerneda to be the type of writer who can make the quotidian as engrossing as alien dramatics. She's also suffering from nightmares, anxiety, and a lot of circular thinking, making this one of the series that shows the realistic toll of dramatic events on human psychology. There was a bit of a nascent love story in Survival; there's a lot more of that here. It's the one bit of the book that I have mixed feelings about, since it feels a touch unnecessary to me, and therefore a bit intrusive. It also involves a fair bit of love at, well, not first sight but surprisingly fast, which is something I know intellectually that other people think happens, but which always undermines my suspension of disbelief. That said, Czerneda gives Mac a clear tendency in how she forms emotional attachments and sticks with it throughout this series to date, which I do like, and she keeps the romance consistent with that. It thankfully does not get too much in the way of the plot, although I could have done with just a few fewer determined proclamations that the characters won't let love get in the way of doing what they need to do. That quibble aside, this is fantastic stuff that avoids most of the cliches of this sort of story of alien politics and possible war. The focus is firmly on analysis and understanding rather than guns and action, the portrayal of scientists, analysis, and problem-solving is spot on, the aliens are delightfully different (and different from each other within the same alien species, which is important depth), and Mac is a fantastic protagonist. She's vulnerable, wounded, and out of her depth, but she knows how to map new situations to her areas of competence and how to admit when she doesn't know something, and her effectiveness is well-grounded and believable. Oh, and there are some amazing descriptions of the Canadian wilderness that almost make me want to find a secluded cabin without Internet access. (At least if it had all of the convenient technology that Mac's future Earth has.) It's a rare middle book of a trilogy that's better than the first, but this one is. Much better. And I already liked the first book. Highly recommended; I think this is one of Czerneda's best. Followed by Regeneration. Rating: 9 out of 10

5 January 2015

Russ Allbery: Review: Ancillary Sword

Review: Ancillary Sword, by Ann Leckie
Series: Imperial Radch #2
Publisher: Orbit
Copyright: October 2014
ISBN: 0-316-24665-4
Format: Trade paperback
Pages: 354
This is the second book in the Imperial Radch series and a direct sequel to Ancillary Justice. You don't want to read this book out of order, since the previous book sets up the background of everything that happens here. Besides, Ancillary Justice is an amazing book. It's going to be challenging to review Ancillary Sword without spoiling the previous book. If you're planning on reading Ancillary Justice but haven't gotten to it, you may want to stop here and come back to this review after you've read it. Or, even better, just read both books. They're some of the best science fiction I've read. Ancillary Justice started small, with one person and their quixotic search for revenge, and grew large, to encompass conflicts and confrontations that would shake the Radch. Ancillary Sword returns to a smaller scale and stays there. This means that much of what was left unresolved at the end of the previous book is still unresolved; Leckie does not continue escalating into large-scale conflict. It also means that we see a lot more of Breq making personal choices and trying to work out her own sense of morality, plus semi-adopting a couple more injured people along the way. One of my favorite types of stories is where I get to watch someone who is very good at something do the thing that they're very good at. Breq's unique background and experience makes her a wildcard outsider with vast experience in her new role. (Not to mention the special advantages she has from her implants.) Her long experience with people, similarly from a unique perspective, lets her use her power to effectively navigate political situations while keeping people slightly off-balance. And now she has some real power, made more potent for being somewhat ill-defined. In short, this is a story of political agency, given to someone who hasn't had it before but who is very good at using it. It's immensely satisfying, in part because it's not a simple wish fulfillment. Breq can't just reshape the world to her preferences; in fact, she can't do much about one of the social conflicts she runs into, except treat the people involved with unexpected respect. But she can occasionally do something, and she can always upset existing power structures in subtle ways, and the way Leckie writes this makes it so much fun to read. I think one of the reasons why I enjoyed this so much is that Breq is not relentlessly introspective. She just acts. Usually this sort of book involves lots of soul-searching and analysis, and the lack is refreshing. The other people in the story analyze Breq much more than she analyzes herself, sometimes incorrectly, and Breq finds the whole thing faintly amusing. Not only does this keep the story from bogging down in too much internal drama, it means that Breq frequently surprises the reader, usually in ways that had me grinning. And, despite not mulling things over incessantly, she is growing and developing, finding her own sense of morality and and ethics in a way that's sometimes only apparent in retrospect. The one caveat I will mention is that this is a book that concerns itself a great deal with colonialism and racial slavery, but it's a fantasy of political agency focused on someone who's part of the dominant culture. While it's not quite accurate to say that Breq is this world's equivalent of white, she can pass, and she's Radchaai. I thought the book handles the issues reasonably well, but it is still using oppressed cultures to focus on the agency and power of someone who is, comparatively, privileged. This didn't bother me while I was reading the story, but it started to bother me a little afterwards once it was pointed out. There's nothing inherently wrong with that story, but it's a rather common pattern, and I'm afraid Ancillary Sword doesn't do much to broaden the pattern. That said, it's a caveat rather than a fatal flaw, at least for me. Ancillary Sword is obviously the middle book of a trilogy, and normally the lack of forward progress on the overarching story and the sense of filling in background and setting the scene would undermine the book. But Breq and the other characters in this world are so fascinating that I didn't mind. The ending was not quite what I expected, but worked better the more that I thought about it. I'm really looking forward to the next book. Followed by Ancillary Mercy. Rating: 9 out of 10

2 September 2011

Asheesh Laroia: Debian bug squashing party at SIPB, MIT


(Photo credit: Obey Arthur Liu; originally on Picasa, license.) Three weekends ago, I participated in a Debian bug squashing party. It was more fun than I had guessed! The event worked: we squashed bugs. Geoffrey Thomas (geofft) organized it as an event for MIT's student computing group, SIPB. In this post, I'll review the good parts and the bad. I'll conclude with beaming photos of my two mentees and talk about the bugs they fixed. So, the good:

The event was a success, but as always, there are some things that could have gone more smoothly. Here's that list: Still, it turned out well! I did three NMUs, corresponding to three patches submitted for release-critical bugs by my two mentees. Those mentees were: Jessica enjoying herself Jessica McKellar is a software engineer at Ksplice Oracle and a recent graduate of MIT's EECS program. She solved three release-critical bugs. This was her first direct contribution to Debian. In particular: Jessica has since gotten involved in the Twisted project's personal package archive. Toward the end of the sprint, she explained, "I like fixing bugs. I will totally come to the next bug squashing party." Noah grinning Noah Swartz is a recent graduate of Case Western Reserve University where he studied Mathematics and played Magic. He is an intern at the MIT Media Lab where he contributes to DoppelLab in Joe Paradiso's Responsive Environments group. This was definitely his first direct contribution to Debian. It was also one of the most intense command-line experiences he has had so far. Noah wasn't originally planning to come, but we were having lunch together before the hackathon, and I convinced him to join us. Noah fixed #625177, a fails-to-build-from-source (FTBFS) bug in nslint. The problem was that "-Wl" was instead written in all lowercase in the debian/rules file, as "-wl". Noah fixed that, making sure the package properly built in pbuilder, and then spent some quality time with lintian figuring out the right way to write a debian/changelog. That's a wrap! We'll hopefully have one again in a few months, and before that, I hope to write up a guide so that we run things even more smoothly next time.

6 June 2011

Steve McIntyre: Silly Cars!

Jo bought me a voucher last Christmas to spend some time on a race track, driving an Aston Martin and a Lamborghini. Finally we got around to using it last week. Jo is just as much a petrol-head as me, so I surprised her by buying the same experience voucher for her - call it a wedding present. Good call - she didn't stop grinning all day, even on the long drive home! The Aston Martin was a DB9 Volante (i.e. the convertible). Lovely car, but a little softer than I'd expected (maybe due to it being the convertible). I preferred the Lamborghini Gallardo, pictured here in a nice subtle colour. *grin* Lamborghini The nice folks doing the official photos at the track also took some extra photos of us sitting in another supercar - an Audi R8 V10 convertible. We've got those photos coming on CD in the post, and I'll post one when they land.

15 October 2010

Enrico Zini: Award winning code

Award winning code Me and Yuwei had a fun day at hhhmcr (#hhhmcr) and even managed to put together a prototype that won the first prize \o/ We played with the gmp24 dataset kindly extracted from Twitter by Michael Brunton-Spall of the Guardian into a convenient JSON dataset. The idea was to find ways of making it easier to look at the data and making sense of it. This is the story of what we did, including the code we wrote. The original dataset has several JSON files, so the first task was to put them all together:
#!/usr/bin/python
# Merge the JSON data
# (C) 2010 Enrico Zini <enrico@enricozini.org>
# License: WTFPL version 2 (http://sam.zoy.org/wtfpl/)
import simplejson
import os
res = []
for f in os.listdir("."):
    if not f.startswith("gmp24"): continue
    data = open(f).read().strip()
    if data == "[]": continue
    parsed = simplejson.loads(data)
    res.extend(parsed)
print simplejson.dumps(res)
The results however were not ordered by date, as GMP had to use several accounts to twit because Twitter was putting Greather Manchester Police into jail for generating too much traffic. There would be quite a bit to write about that, but let's stick to our work. Here is code to sort the JSON data by time:
#!/usr/bin/python
# Sort the JSON data
# (C) 2010 Enrico Zini <enrico@enricozini.org>
# License: WTFPL version 2 (http://sam.zoy.org/wtfpl/)
import simplejson
import sys
import datetime as dt
all_recs = simplejson.load(sys.stdin)
all_recs.sort(key=lambda x: dt.datetime.strptime(x["created_at"], "%a %b %d %H:%M:%S +0000 %Y"))
simplejson.dump(all_recs, sys.stdout)
I then wanted to play with Tf-idf for extracting the most important words of every tweet:
#!/usr/bin/python
# tfifd - Annotate JSON elements with Tf-idf extracted keywords
#
# Copyright (C) 2010  Enrico Zini <enrico@enricozini.org>
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
import sys, math
import simplejson
import re
# Read all the twits
records = simplejson.load(sys.stdin)
# All the twits by ID
byid = dict(((x["id"], x) for x in records))
# Stopwords we ignore
stopwords = set(["by", "it", "and", "of", "in", "a", "to"])
# Tokenising engine
re_num = re.compile(r"^\d+$")
re_word = re.compile(r"(\w+)")
def tokenise(tweet):
    "Extract tokens from a tweet"
    for tok in tweet["text"].split():
        tok = tok.strip().lower()
        if re_num.match(tok): continue
        mo = re_word.match(tok)
        if not mo: continue
        if mo.group(1) in stopwords: continue
        yield mo.group(1)
# Extract tokens from tweets
tokenised = dict(((x["id"], list(tokenise(x))) for x in records))
# Aggregate token counts
aggregated =  
for d in byid.iterkeys():
    for t in tokenised[d]:
        if t in aggregated:
            aggregated[t] += 1
        else:
            aggregated[t] = 1
def tfidf(doc, tok):
    "Compute TFIDF score of a token in a document"
    return doc.count(tok) * math.log(float(len(byid)) / aggregated[tok])
# Annotate tweets with keywords
res = []
for name, tweet in byid.iteritems():
    doc = tokenised[name]
    keywords = sorted(set(doc), key=lambda tok: tfidf(doc, tok), reverse=True)[:5]
    tweet["keywords"] = keywords
    res.append(tweet)
simplejson.dump(res, sys.stdout)
I thought this was producing a nice summary of every tweet but nobody was particularly interested, so we moved on to adding categories to tweet. Thanks to Yuwei who put together some useful keyword sets, we managed to annotate each tweet with a place name (i.e. "Stockport"), a social place name (i.e. "pub", "bank") and a social category (i.e. "man", "woman", "landlord"...) The code is simple; the biggest work in it was the dictionary of keywords:
#!/usr/bin/python
# categorise - Annotate JSON elements with categories
#
# Copyright (C) 2010  Enrico Zini <enrico@enricozini.org>
# Copyright (C) 2010  Yuwei Lin <yuwei@ylin.org>
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
import sys, math
import simplejson
import re
# Electoral wards from http://en.wikipedia.org/wiki/List_of_electoral_wards_in_Greater_Manchester
placenames = ["Altrincham", "Sale West",
"Altrincham", "Ashton upon Mersey", "Bowdon", "Broadheath", "Hale Barns", "Hale Central", "St Mary", "Timperley", "Village",
"Ashton-under-Lyne",
"Ashton Hurst", "Ashton St Michael", "Ashton Waterloo", "Droylsden East", "Droylsden West", "Failsworth East", "Failsworth West", "St Peter",
"Blackley", "Broughton",
"Broughton", "Charlestown", "Cheetham", "Crumpsall", "Harpurhey", "Higher Blackley", "Kersal",
"Bolton North East",
"Astley Bridge", "Bradshaw", "Breightmet", "Bromley Cross", "Crompton", "Halliwell", "Tonge with the Haulgh",
"Bolton South East",
"Farnworth", "Great Lever", "Harper Green", "Hulton", "Kearsley", "Little Lever", "Darcy Lever", "Rumworth",
"Bolton West",
"Atherton", "Heaton", "Lostock", "Horwich", "Blackrod", "Horwich North East", "Smithills", "Westhoughton North", "Chew Moor", "Westhoughton South",
"Bury North",
"Church", "East", "Elton", "Moorside", "North Manor", "Ramsbottom", "Redvales", "Tottington",
"Bury South",
"Besses", "Holyrood", "Pilkington Park", "Radcliffe East", "Radcliffe North", "Radcliffe West", "St Mary", "Sedgley", "Unsworth",
"Cheadle",
"Bramhall North", "Bramhall South", "Cheadle", "Gatley", "Cheadle Hulme North", "Cheadle Hulme South", "Heald Green", "Stepping Hill",
"Denton", "Reddish",
"Audenshaw", "Denton North East", "Denton South", "Denton West", "Dukinfield", "Reddish North", "Reddish South",
"Hazel Grove",
"Bredbury", "Woodley", "Bredbury Green", "Romiley", "Hazel Grove", "Marple North", "Marple South", "Offerton",
"Heywood", "Middleton",
"Bamford", "Castleton", "East Middleton", "Hopwood Hall", "Norden", "North Heywood", "North Middleton", "South Middleton", "West Heywood", "West Middleton",
"Leigh",
"Astley Mosley Common", "Atherleigh", "Golborne", "Lowton West", "Leigh East", "Leigh South", "Leigh West", "Lowton East", "Tyldesley",
"Makerfield",
"Abram", "Ashton", "Bryn", "Hindley", "Hindley Green", "Orrell", "Winstanley", "Worsley Mesnes",
"Manchester Central",
"Ancoats", "Clayton", "Ardwick", "Bradford", "City Centre", "Hulme", "Miles Platting", "Newton Heath", "Moss Side", "Moston",
"Manchester", "Gorton",
"Fallowfield", "Gorton North", "Gorton South", "Levenshulme", "Longsight", "Rusholme", "Whalley Range",
"Manchester", "Withington",
"Burnage", "Chorlton", "Chorlton Park", "Didsbury East", "Didsbury West", "Old Moat", "Withington",
"Oldham East", "Saddleworth",
"Alexandra", "Crompton", "Saddleworth North", "Saddleworth South", "Saddleworth West", "Lees", "St James", "St Mary", "Shaw", "Waterhead",
"Oldham West", "Royton",
"Chadderton Central", "Chadderton North", "Chadderton South", "Coldhurst", "Hollinwood", "Medlock Vale", "Royton North", "Royton South", "Werneth",
"Rochdale",
"Balderstone", "Kirkholt", "Central Rochdale", "Healey", "Kingsway", "Littleborough Lakeside", "Milkstone", "Deeplish", "Milnrow", "Newhey", "Smallbridge", "Firgrove", "Spotland", "Falinge", "Wardle", "West Littleborough",
"Salford", "Eccles",
"Claremont", "Eccles", "Irwell Riverside", "Langworthy", "Ordsall", "Pendlebury", "Swinton North", "Swinton South", "Weaste", "Seedley",
"Stalybridge", "Hyde",
"Dukinfield Stalybridge", "Hyde Godley", "Hyde Newton", "Hyde Werneth", "Longdendale", "Mossley", "Stalybridge North", "Stalybridge South",
"Stockport",
"Brinnington", "Central", "Davenport", "Cale Green", "Edgeley", "Cheadle Heath", "Heatons North", "Heatons South", "Manor",
"Stretford", "Urmston",
"Bucklow-St Martins", "Clifford", "Davyhulme East", "Davyhulme West", "Flixton", "Gorse Hill", "Longford", "Stretford", "Urmston",
"Wigan",
"Aspull New Springs Whelley", "Douglas", "Ince", "Pemberton", "Shevington with Lower Ground", "Standish with Langtree", "Wigan Central", "Wigan West",
"Worsley", "Eccles South",
"Barton", "Boothstown", "Ellenbrook", "Cadishead", "Irlam", "Little Hulton", "Walkden North", "Walkden South", "Winton", "Worsley",
"Wythenshawe", "Sale East",
"Baguley", "Brooklands", "Northenden", "Priory", "Sale Moor", "Sharston", "Woodhouse Park"]
# Manual coding from Yuwei
placenames.extend(["City centre", "Tameside", "Oldham", "Bury", "Bolton",
"Trafford", "Pendleton", "New Moston", "Denton", "Eccles", "Leigh", "Benchill",
"Prestwich", "Sale", "Kearsley", ])
placenames.extend(["Trafford", "Bolton", "Stockport", "Levenshulme", "Gorton",
"Tameside", "Blackley", "City centre", "Airport", "South Manchester",
"Rochdale", "Chorlton", "Uppermill", "Castleton", "Stalybridge", "Ashton",
"Chadderton", "Bury", "Ancoats", "Whalley Range", "West Yorkshire",
"Fallowfield", "New Moston", "Denton", "Stretford", "Eccles", "Pendleton",
"Leigh", "Altrincham", "Sale", "Prestwich", "Kearsley", "Hulme", "Withington",
"Moss Side", "Milnrow", "outskirt of Manchester City Centre", "Newton Heath",
"Wythenshawe", "Mancunian Way", "M60", "A6", "Droylesden", "M56", "Timperley",
"Higher Ince", "Clayton", "Higher Blackley", "Lowton", "Droylsden",
"Partington", "Cheetham Hill", "Benchill", "Longsight", "Didsbury",
"Westhoughton"])
# Social categories from Yuwei
soccat = ["man", "woman", "men", "women", "youth", "teenager", "elderly",
"patient", "taxi driver", "neighbour", "male", "tenant", "landlord", "child",
"children", "immigrant", "female", "workmen", "boy", "girl", "foster parents",
"next of kin"]
for i in range(100):
    soccat.append("%d-year-old" % i)
    soccat.append("%d-years-old" % i)
# Types of social locations from Yuwei
socloc = ["car park", "park", "pub", "club", "shop", "premises", "bus stop",
"property", "credit card", "supermarket", "garden", "phone box", "theatre",
"toilet", "building site", "Crown court", "hard shoulder", "telephone kiosk",
"hotel", "restaurant", "cafe", "petrol station", "bank", "school",
"university"]
extras =   "placename": placenames, "soccat": soccat, "socloc": socloc  
# Normalise keyword lists
for k, v in extras.iteritems():
    # Remove duplicates
    v = list(set(v))
    # Sort by length
    v.sort(key=lambda x:len(x), reverse=True)
# Add keywords
def add_categories(tweet):
    text = tweet["text"].lower()
    for field, categories in extras.iteritems():
        for cat in categories:
            if cat.lower() in text:
                tweet[field] = cat
                break
    return tweet
# Read all the twits
records = (add_categories(x) for x in simplejson.load(sys.stdin))
simplejson.dump(list(records), sys.stdout)
All these scripts form a nice processing chain: each script takes a list of JSON records, adds some bit and passes it on. In order to see what we have so far, here is a simple script to convert the JSON twits to CSV so they can be viewed in a spreadsheet:
#!/usr/bin/python
# Convert the JSON twits to CSV
# (C) 2010 Enrico Zini <enrico@enricozini.org>
# License: WTFPL version 2 (http://sam.zoy.org/wtfpl/)
import simplejson
import sys
import csv
rows = ["id", "created_at", "text", "keywords", "placename"]
writer = csv.writer(sys.stdout)
for rec in simplejson.load(sys.stdin):
    rec["keywords"] = " ".join(rec["keywords"])
    rec["placename"] = rec.get("placename", "")
    writer.writerow([rec[row] for row in rows])
At this point we were coming up with lots of questions: "were there more reports on women or men?", "which place had most incidents?", "what were the incidents involving animals?"... Time to bring Xapian into play. This script reads all the JSON tweets and builds a Xapian index with them:
#!/usr/bin/python
# toxapian - Index JSON tweets in Xapian
#
# Copyright (C) 2010  Enrico Zini <enrico@enricozini.org>
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
import simplejson
import sys
import os, os.path
import xapian
DBNAME = sys.argv[1]
db = xapian.WritableDatabase(DBNAME, xapian.DB_CREATE_OR_OPEN)
stemmer = xapian.Stem("english")
indexer = xapian.TermGenerator()
indexer.set_stemmer(stemmer)
indexer.set_database(db)
data = simplejson.load(sys.stdin)
for rec in data:
    doc = xapian.Document()
    doc.set_data(str(rec["id"]))
    indexer.set_document(doc)
    indexer.index_text_without_positions(rec["text"])
    # Index categories as categories
    if "placename" in rec:
        doc.add_boolean_term("XP" + rec["placename"].lower())
    if "soccat" in rec:
        doc.add_boolean_term("XS" + rec["soccat"].lower())
    if "socloc" in rec:
        doc.add_boolean_term("XL" + rec["socloc"].lower())
    db.add_document(doc)
db.flush()
# Also save the whole dataset so we know where to find it later if we want to
# show the details of an entry
simplejson.dump(data, open(os.path.join(DBNAME, "all.json"), "w"))
And this is a simple command line tool to query to the database:
#!/usr/bin/python
# xgrep - Command line tool to query the GMP24 tweet Xapian database
#
# Copyright (C) 2010  Enrico Zini <enrico@enricozini.org>
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
import simplejson
import sys
import os, os.path
import xapian
DBNAME = sys.argv[1]
db = xapian.Database(DBNAME)
stem = xapian.Stem("english")
qp = xapian.QueryParser()
qp.set_default_op(xapian.Query.OP_AND)
qp.set_database(db)
qp.set_stemmer(stem)
qp.set_stemming_strategy(xapian.QueryParser.STEM_SOME)
qp.add_boolean_prefix("place", "XP")
qp.add_boolean_prefix("soc", "XS")
qp.add_boolean_prefix("loc", "XL")
query = qp.parse_query(sys.argv[2],
    xapian.QueryParser.FLAG_BOOLEAN  
    xapian.QueryParser.FLAG_LOVEHATE  
    xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE  
    xapian.QueryParser.FLAG_WILDCARD  
    xapian.QueryParser.FLAG_PURE_NOT  
    xapian.QueryParser.FLAG_SPELLING_CORRECTION  
    xapian.QueryParser.FLAG_AUTO_SYNONYMS)
enquire = xapian.Enquire(db)
enquire.set_query(query)
count = 40
matches = enquire.get_mset(0, count)
estimated = matches.get_matches_estimated()
print "%d/%d results" % (matches.size(), estimated)
data = dict((str(x["id"]), x) for x in simplejson.load(open(os.path.join(DBNAME, "all.json"))))
for m in matches:
    rec = data[m.document.get_data()]
    print rec["text"]
print "%d/%d results" % (matches.size(), matches.get_matches_estimated())
total = db.get_doccount()
estimated = matches.get_matches_estimated()
print "%d results over %d documents, %d%%" % (estimated, total, estimated * 100 / total)
Neat! Now that we have a proper index that supports all sort of cool things, like stemming, tag clouds, full text search with complex queries, lookup of similar documents, suggest keywords and so on, it was just fair to put together a web service to share it with other people at the event. It helped that I had already written similar code for apt-xapian-index and dde before. Here is the server, quickly built on bottle. The very last line starts the server and it is where you can configure the listening interface and port.
#!/usr/bin/python
# xserve - Make the GMP24 tweet Xapian database available on the web
#
# Copyright (C) 2010  Enrico Zini <enrico@enricozini.org>
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
import bottle
from bottle import route, post
from cStringIO import StringIO
import cPickle as pickle
import simplejson
import sys
import os, os.path
import xapian
import urllib
import math
bottle.debug(True)
DBNAME = sys.argv[1]
QUERYLOG = os.path.join(DBNAME, "queries.txt")
data = dict((str(x["id"]), x) for x in simplejson.load(open(os.path.join(DBNAME, "all.json"))))
prefixes =   "place": "XP", "soc": "XS", "loc": "XL"  
prefix_desc =   "place": "Place name", "soc": "Social category", "loc": "Social location"  
db = xapian.Database(DBNAME)
stem = xapian.Stem("english")
qp = xapian.QueryParser()
qp.set_default_op(xapian.Query.OP_AND)
qp.set_database(db)
qp.set_stemmer(stem)
qp.set_stemming_strategy(xapian.QueryParser.STEM_SOME)
for k, v in prefixes.iteritems():
    qp.add_boolean_prefix(k, v)
def make_query(qstring):
    return qp.parse_query(qstring,
        xapian.QueryParser.FLAG_BOOLEAN  
        xapian.QueryParser.FLAG_LOVEHATE  
        xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE  
        xapian.QueryParser.FLAG_WILDCARD  
        xapian.QueryParser.FLAG_PURE_NOT  
        xapian.QueryParser.FLAG_SPELLING_CORRECTION  
        xapian.QueryParser.FLAG_AUTO_SYNONYMS)
@route("/")
def index():
    query = urllib.unquote_plus(bottle.request.GET.get("q", ""))
    out = StringIO()
    print >>out, '''
<html>
<head>
<title>Query</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() 
    $("#queryfield")[0].focus()
 )
</script>
</head>
<body>
<h1>Search</h1>
<form method="POST" action="/query">
Keywords: <input type="text" name="query" value="%s" id="queryfield">
<input type="submit">
<a href="http://xapian.org/docs/queryparser.html">Help</a>
</form>''' % query
    print >>out, '''
<p>Example: "car place:wigan"</p>

<p>Available prefixes:</p>

<ul>
'''
    for pfx in prefixes.keys():
        print >>out, "<li><a href='/catinfo/%s'>%s - %s</a></li>" % (pfx, pfx, prefix_desc[pfx])
    print >>out, '''
</ul>
'''
    oldqueries = []
    if os.path.exists(QUERYLOG):
        total = db.get_doccount()
        fd = open(QUERYLOG, "r")
        while True:
            try:
                q = pickle.load(fd)
            except EOFError:
                break
            oldqueries.append(q)
        fd.close()
        def print_query(q):
            count = q["count"]
            print >>out, "<li><a href='/query?query=%s'>%s (%d/%d %.2f%%)</a></li>" % (urllib.quote_plus(q["q"]), q["q"], count, total, count * 100.0 / total)
        print >>out, "<p>Last 10 queries:</p><ul>"
        for q in oldqueries[:-10:-1]:
            print_query(q)
        print >>out, "</ul>"
        # Remove duplicates
        oldqueries = dict(((x["q"], x) for x in oldqueries)).values()
        print >>out, "<table>"
        print >>out, "<tr><th>10 queries with most results</th><th>10 queries with least results</th></tr>"
        print >>out, "<tr><td>"
        print >>out, "<ul>"
        oldqueries.sort(key=lambda x:x["count"], reverse=True)
        for q in oldqueries[:10]:
            print_query(q)
        print >>out, "</ul>"
        print >>out, "</td><td>"
        print >>out, "<ul>"
        nonempty = [x for x in oldqueries if x["count"] > 0]
        nonempty.sort(key=lambda x:x["count"])
        for q in nonempty[:10]:
            print_query(q)
        print >>out, "</ul>"
        print >>out, "</td></tr>"
        print >>out, "</table>"
    print >>out, '''
</body>
</html>'''
    return out.getvalue()
@route("/query")
@route("/query/")
@post("/query")
@post("/query/")
def query():
    query = bottle.request.POST.get("query", bottle.request.GET.get("query", ""))
    enquire = xapian.Enquire(db)
    enquire.set_query(make_query(query))
    count = 40
    matches = enquire.get_mset(0, count)
    estimated = matches.get_matches_estimated()
    total = db.get_doccount()
    out = StringIO()
    print >>out, '''
<html>
<head><title>Results</title></head>
<body>
<h1>Results for "<b>%s</b>"</h1>
''' % query
    if estimated == 0:
        print >>out, "No results found."
    else:
        # Give as results the first 30 documents; also use them as the key
        # ones to use to compute relevant terms
        rset = xapian.RSet()
        for m in enquire.get_mset(0, 30):
            rset.add_document(m.document.get_docid())
        # Compute the tag cloud
        class NonTagFilter(xapian.ExpandDecider):
            def __call__(self, term):
                return not term[0].isupper() and not term[0].isdigit()
        cloud = []
        maxscore = None
        for res in enquire.get_eset(40, rset, NonTagFilter()):
            # Normalise the score in the interval [0, 1]
            weight = math.log(res.weight)
            if maxscore == None: maxscore = weight
            tag = res.term
            cloud.append([tag, float(weight) / maxscore])
        max_weight = cloud[0][1]
        min_weight = cloud[-1][1]
        cloud.sort(key=lambda x:x[0])
        def mklink(query, term):
            return "/query?query=%s" % urllib.quote_plus(query + " and " + term)
        print >>out, "<h2>Tag cloud</h2>"
        print >>out, "<blockquote>"
        for term, weight in cloud:
            size = 100 + 100.0 * (weight - min_weight) / (max_weight - min_weight)
            print >>out, "<a href='%s' style='font-size:%d%%; color:brown;'>%s</a>" % (mklink(query, term), size, term)
        print >>out, "</blockquote>"
        print >>out, "<h2>Results</h2>"
        print >>out, "<p><a href='/'>Search again</a></p>"
        print >>out, "<p>%d results over %d documents, %.2f%%</p>" % (estimated, total, estimated * 100.0 / total)
        print >>out, "<p>%d/%d results</p>" % (matches.size(), estimated)
        print >>out, "<ul>"
        for m in matches:
            rec = data[m.document.get_data()]
            print >>out, "<li><a href='/item/%s'>%s</a></li>" % (rec["id"], rec["text"])
        print >>out, "</ul>"
        fd = open(QUERYLOG, "a")
        qinfo = dict(q=query, count=estimated)
        pickle.dump(qinfo, fd)
        fd.close()
    print >>out, '''
<a href="/">Search again</a>

</body>
</html>'''
    return out.getvalue()
@route("/item/:id")
@route("/item/:id/")
def show(id):
    rec = data[id]
    out = StringIO()
    print >>out, '''
<html>
<head><title>Result %s</title></head>
<body>
<h1>Raw JSON record for twit %s</h1>
<pre>''' % (rec["id"], rec["id"])
    print >>out, simplejson.dumps(rec, indent=" ")
    print >>out, '''
</pre>
</body>
</html>'''
    return out.getvalue()
@route("/catinfo/:name")
@route("/catinfo/:name/")
def catinfo(name):
    prefix = prefixes[name]
    out = StringIO()
    print >>out, '''
<html>
<head><title>Values for %s</title></head>
<body>
''' % name
    terms = [(x.term[len(prefix):], db.get_termfreq(x.term)) for x in db.allterms(prefix)]
    terms.sort(key=lambda x:x[1], reverse=True)
    freq_min = terms[0][1]
    freq_max = terms[-1][1]
    def mklink(name, term):
        return "/query?query=%s" % urllib.quote_plus(name + ":" + term)
    # Build tag cloud
    print >>out, "<h1>Tag cloud</h1>"
    print >>out, "<blockquote>"
    for term, freq in sorted(terms[:20], key=lambda x:x[0]):
        size = 100 + 100.0 * (freq - freq_min) / (freq_max - freq_min)
        print >>out, "<a href='%s' style='font-size:%d%%; color:brown;'>%s</a>" % (mklink(name, term), size, term)
    print >>out, "</blockquote>"
    print >>out, "<h1>All terms</h1>"
    print >>out, "<table>"
    print >>out, "<tr><th>Occurrences</th><th>Name</th></tr>"
    for term, freq in terms:
        print >>out, "<tr><td>%d</td><td><a href='/query?query=%s'>%s</a></td></tr>" % (freq, urllib.quote_plus(name + ":" + term), term)
    print >>out, "</table>"
    print >>out, '''
</body>
</html>'''
    return out.getvalue()
# Change here for bind host and port
bottle.run(host="0.0.0.0", port=8024)
...and then we presented our work and ended up winning the contest. This was the story of how we wrote this set of award winning code.

13 March 2010

Joerg Jaspert: Vacation fun

As some people know, I had a vacation in February. Only very few knew that I was heading down to Taiwan. I was leaving Germany at the 8th and back here on the 24th of February. Yes, that neatly fit this years Chinese New Years parties. Was at home for four days (and at work for one), after which I went off to this years Cebit. Until the day I arrived in Taiwan it looked like we do not have a booth there, but then everything changed while I was having a nice vacation. I really have to thank Alex here. Cebit was actually my task, but he jumped in and did all the preparatory work that was needed right in the time I started my vacation. Without that either my vacation would have been much different and less nice or we wouldn t have had a booth. I am back home since some days now, without any travel plans for the next few weeks/months to come. Though I wish I had a job (and private life) that would allow me to just go off again, ie. something I could do everywhere where there is net. Meh. Of course I did take some pictures (more than 2500) and also some notes during the trip. And having a blog that one or two people read, I think I should bore you all with it. But hey, you can skip it if you want. :) Yes, I should really take some time and work a bit on the pictures I took. Right now I only selected around seven hundred which I show off to people (and to link to from here), but they are basically just copies. While some are great in itself, many can need a bit of work here and there (cut out unimportant, blurry, colors, the usual stuff). And I also prepared multiple shots for HDR processing or to make a panorama view from, but thats something that takes time and has to wait. Just for the record, I think that this, this and this are very nice ones.
This is a public version of this text, so names and also various events and days have been cut out. Yes, people who know those in my pictures will know names, but thats no reason to feed the evil $searchengine caches more with hits for their names. Flight down, 8 Feb. Flight down from Frankfurt, using KLM so it went via Amsterdam and Bangkok (short Transit stop) to Taipei. The days before we had lots of snow and cold and all that stuff which tends to get flights cancelled, but I was lucky, none of that for me. The only slightly annoying thing was in Taipei, where KLM demonstrated how much a Business class Priority luggage sign is worth for them sometimes. We came in half an hour before schedule, but then had to wait an hour for our luggage (while all of economy luggage passed by). I think the business class Priority sign actually meant Priority to wait . The food on the flight from AMS to BGK was good, having a No Lactose Meal actually tasting well. Can t remember what it was, but better than the fish I got from BGK to TPE. Catering from Thai Airways, they do not know anything besides Fish when preparing No lactose meal and then they also manage to prepare it in the most boring way possible. Sad thing, but happened four times now, all the times I had catering prepared by them. Other than those points, no trouble at all. Immigration was done in about 20 seconds, customs didn t want to look at me, just the asians in front and behind me, all fine. Met my Travel Companion outside and off we got. First to the Taipei Main Station, where we got some food. Some rice (with a bit of meat) and red sauce, together with a soup. And a glass of tea, but that had an oily surface. Umm. Guess the cup wasn t all that clean, we both skipped that. Then I tried to get money from an ATM. First had to find one that actually wants my european credit card. And then, as usual when I travel offroad, I managed to forget my pin. Bah. Well, found an HSBC somewhere that actually takes my Maestro card, so at some point I got money (a pretty helpful thing, that is).
Wednesday, 10 Feb. First night in a new Timezone which is 7 hours before my normal one. Makes my body think I should not be allowed to sleep much. So it only allowed me some two hours before I woke up again. It didn t listen to any argument and didn t care that it was all dark and night, so I couldn t sleep more. Wellwell, got up at the same time as $TC then, we got some breakfast, egg/ham sandwich and tea. From there I set off and juggled my way through Taipei MRT over to YuanShan Station.
Confucius Temple
It is good for a visit of the Confucius Temple and also the Dalongdong Baoan Temple which is right beside it. Later on I got told there are much more impressive Confucius temples elsewhere, but it is still a good place to start off. And it just means I have one more reason for another visit. After those two temples I moved over to the Taipei Fine Arts Museum. Took about an hour to go through that museum, which again made it pretty clear to me: Some people just have too much time and money. I do not even get the setup in the entry hall, even though it looks nice, and let s not start about the rest they show there. Definitely not my thing, Fine Arts , nothing worth to waste money on, at least for me.
Having fun
So I left there after just about an hour and fought the MRT again. This time it spit me out at the Taipei Zoo station and I went through that. Appearently the nice sunny weather let some animals have fun, and that all in public. Tssk. Won t someone please think of the children?! :) Otherwise it is a pretty big area with lots of animals. Not all of them seem to be in areas that (I think) are big enough for them, though I m no expert in that. But it looked small for them. Also, while I thought it pretty well visited, many people there, I bet for Taiwanese standards the zoo was nearly empty. At least looking at their preparations for queues, like in front of the koala house, they are used to deal with like 20 times the amount of people. I count me lucky that there haven t been that many, else I would have needed to wait everywhere, which I hate. Queues are bad, mmmmmkay? As I already mentioned, the weather that day was pretty nice. Mostly sunny, only few clouds and some 25 til 29 degrees. No rain. Now that s a nice winter day.
HotPot
Dinner was scheduled for 1800h, a Hot Pot session. 5 people in total. Appears you order the meat for the hot pots from the waiter and let them bring it, but all the additional stuff you get yourself. They have a big selection of vegetables, seafood, bread/cake like stuff and whatnot you can take. I first also went there and got a small dish with stuff. But stopped right then and let the Taiwanese do the rest. Better that way, they know it. And hey, we had been 5 and they got stuff for like 35 people. :) It was a nice 2 hour session, in which we had lots of different kinds of additions to the hotpot (two pots actually, one spicy and one not spicy). I know of some meats, some vegetables, but then there also was said to be duck bladder and some other organs which they couldn t (or didn t want to? :) ) name in english. Now, db sounds worse than it is, it doesn t have a special taste and is mostly boring, I think. Of course, not liking seafood, I skipped on that, but about all the rest was nice. I like Hot Pot :) After this session the other 3 left for various reasons and $TC and me had a nice walk around/through the University, before going back to $TCs place.
Thursday, 11 Feb Had another short night as I only got to bed around 2AM, just to get up around 9AM. Additional fun that my body again insisted in being elsewhere, not accustomed to the timezone in Taiwan yet, waking me up a few times during the night.
Fishermans Wharf
Got an easypass for the MRT as that is a little better than buying a chip for every single trip and battled with MRT again, finally emerging at Danshui station. Sat a bit at the beach eating breakfast before finally starting a walk out to the Fisherman s Wharf . It is some 4 kilometers to it, made out as a bicycle path, but I just walked. Visited Fort San Domingo on the way and then went all the way up in that Wharf area, another kilometer. Got me a nice peppermint ice tea, though it was a funny process to it. The salesperson didn t speak english and my chinese is - well, limited is a too soft word to describe it. But it worked pretty well, with us pointing around on the menu and then the salesman showing me various additions, if I would want them. Like showing a milk bottle Want milk in tea? , showing sugar,
Spongebob
At the bridge in that Wharf I was approached by some Asian people, asking me to take a picture of them in front of the bridge. Fine, did it, did it again in another setting and then, when done, they asked me where I am from. When I said Germany they thanked me in German which surprised me a little. :) That is something funny anyways. Wherever I go, people look. They aren t much used to someone my size. Kids are usually more direct with pointing, grinning and sometimes crossing my way on purpose, just saying hi (some kind of test of courage, I bet). Every now and then I also get asked if they can take a picture with me. Right now there are like 20 pictures of me (that I know of) all over Taiwan that I didn t take, nor have. :) Now, who here loves Spongebob? This is the country for you! The picture only shows one small table, you can find much much more. Same goes for Hello Kitty and other such stuff.
Food!
Dinner this day was initially planned to be at some place called Maokong, but then plans changed, as $TC and others that we should meet there needed to pack for the next day. So $TC and me just went to the Shilin Night Market. Right beside it is a big food plaza. Like a thousand square meters (or probably a few more, what do I know, I haven t measured it, but it wasn t all too big) having some hundred or more little kitchens where you can get a very broad mix of things. We had cold noodles with some slightly spicy sauce and then some fresh guava juice. Tasty tasty. Though noodles with chopsticks was something new, but it worked out well enough. Later I had a noodle soup, that was something more tricky, but in the end you just need to find the right trick.
Little crowded
After food we went through the night market. Well. Parts of it. It s big. And its crowded. About the most crowded place I ve been to. Heck, half of Taiwan was in that street area. :) Didn t buy anything. The only stuff I thought interesting was a T-Shirt with a Taiwan map on it, but do try getting some in my size. Ha. Small asians. They say they have big sizes, but then its XL only (or a totally ugly color, brrr). We finished early here, as the packing for the trip starting Friday right in the middle of the night still needed to be done, and getting up at 6AM you do not want to stay up too late. But it was nice there anyways.
Friday, 12 Feb Got up early. I mean, early. 6 AM. ARGS. Not really my favorite thing to do, but as our plan said we have to get the HighSpeedRail to Kaohsiung at 7:42AM there wasn t much else to do. Pretty nice train, lots of room to sit, even in second class. Don t know business, but probably even more. And it looks fast, if I can trust the display it had we where going near 300km/h. After arrival in Kaohsiung we went out to $TC s place to get our luggage away, as it is annoying to move around with all the stuff. I got another easypass here, this time a lent one from $TC s Mother. It s fun, there are two MRT systems in Taiwan using the same technics, basically the one in Kaohsiung is built like the one in Taipei, using the same style of RFID cards (and chips for single trips). But they made them incompatible. One can not use a pass from Taipei in Kaohsiung and vice versa, for whatever reason. It s not like the two cities are very far away from each other, it would actually make sense to be compatible, but that is probably what stops them doing it. We took this Friday and also the Saturday to get around Kaohsiung, visiting several places. As the MRT in Kaohsiung has a different station design at every of its stations we did look at some of those too. Especially Formosa Boulevard , a station that has two points describing it best:
one part of the dome of light
Right outside one of the exits is a funny little cosmetic surgery. I only remember it thanks to the english name of the Doc, but somehow I don t think it was chosen wisely: Dr. Luck . . Aiik, you need be lucky to get out there looking better? Dr. Unlucky might not be good for you taking a wrong cut? :) (Yes, I know, I m crazy, don t tell me. Ok, if you really want, queue up, you aren t the first.) At one point we went out to Sizihwan, where we walked to a ferry. Actually we tried renting bikes, but this little bike shop wasn t prepared for a small german like me, not having bikes my size. (And no safe way to get the saddle of the smaller ones into a height I could start using the bike). So walk it was, not nice bike trip. Still ok, got to the ferry, got over to the other side and had a nice walk there to the/along the coast.
one more temple
We bypassed multiple temples there, at one of which a great cite came up: Temples in Taiwan are something like 7-eleven. They are everywhere. I love it. And somehow it s true, you can find one around each other corner, a little like those churches in Puebla, Mexico. In the evening we had been out for a night market. The first one was pretty boring. While having been announced in the MRT station near it to be a night market for New Years things, we found it to be about empty and very boring, so we went over to another one nearby. Wasn t as crowded as the Shilin one, and not as large, but nice. At the end of it had been a small game stand, where one could shoot balloons to get some price. I ended up getting the biggest available, as this isn t really a challenge. How anyone can miss hitting a balloon there I don t know. They are only like 3m away, not moving, you have clear view, and if you really need it even get a laser pointer on your gun. Anyways, was fun enough, I repeated shooting enough times to get the biggest available Patrick doll they had (a meter). Hrhr. Who likes Spongebob, eh? Speak up! :) I got a few nice shots of the night skyline of Kaohsiung late one of those evenings, where we went to the Dream Mall and up into the big wheel . Also had some game spots there, but turns out I m not as good throwing things at a target than I am shooting at them. We also went out to a historical sugar refinery, looking around. Of course, this being Chinese New Years eve, there haven t been that much people moving around, it was pretty empty. And the people working there all just waiting for their shift to end. But still got some pretty nice pictures from and around it. Also tasted a new kind of icecream (new for me that is), which actually has a kind of sand like feel. I like it. Like I actually liked most of the food, pretty much all the time. Of course everyone has things one does not like, but in general the food is great. Especially the largely different style compared to the european way of cooking. I ate lots of things I won t ever touch here in Germany.
Sunday, 14 Feb; Monday 15 Feb A nice two days some way out of Kaohsiung. Found out I am pretty good at losing various things: I got a bag full of (Li n w ; Syzygium samarangense; wax apple, love apple, java apple, bellfruit, see the wikipedia page for more on it) and about an hour later I totally had lost track where it ended up. The same happened with a big bag of tissues I had bought. Somehow both of the bags got feet and ended up elsewhere without telling me.
ocean place
That one evening we went out for Dinner, a big party of people. Was a place right beside the ocean, so yes, seafood. Oh yay, I don t like that too much. Happy enough there must have been a conversation going on like Hey people, this silly german doesn t like seafood much, lets get one other option too . So we had a plate with some cold chicken on. But I tried various of the seafood dishes too and liked some of them. Actually some I had tried in Germany at some point where I learned to hate them and now I liked them as I got them in Taiwan. People also seemed to think I am good at using chopsticks, though I think I am just fiddling around and be lucky when I get my stuff. But maybe it just means Hey, it looks funny what you are doing. Keep going, we like to laugh. :) ). We actually had been around this place a little earlier that day, taking a walk around it, drinking some tea, that type of thing. And got a set of nice bottles of fresh coconut juice. My first time i got it fresh, I think. But I also managed to lose track of it. I bet somewhere there is a party consisting of tissues, (Li n w ) and a bottle of coconut juice, singing classic songs like Strike, we escaped the german Lunch the other day happened to be a big family meetup. Lots of people, lots of chatting, lots of fun (I think :) ). When we arrived it started out by about all of them trying to get me to sit down somewhere. And me bad impolite german not wanting to. But there was no way to escape, so finally they won and I sat, with a number of people around me, trying to chat with me. Which is actually hard work for both sides, but every now and then gets a good laugh. But my chinese is far far away from being useful for even a small meaningful sentence, so they had to activate their english knowledge, especially for the times $TC had been elsewhere and couldn t help out translating. Somehow the job got done, they asked their questions and I hope they mostly understood my replies. Bad me, speaking too fast english sometimes. We had a nice lunch there, with the most notable part being the way I got called to it. It s interesting how much you can say by just using body language and pointing. (Oh, of course food was very good too, but that fact is one you can take as a given, even if I don t mention it again). Later on a dice game started, and after a short explanation of the rules I joined in. Took only a little, but then I got the rules, its easy. I didn t get any of the chatting that happened during the whole game, but it was very much fun and really insane (so would also fit DebConf very well) and nearly no times you do need words to understand what is going on. I like this game and they gave me a set of dices, so I can train it and come back to play again. Ha. A bit after that dice game people unpacked some of the sweets I brought from Germany. One of them being spicy. Really nicely spicy, at least for the average Taiwanese. If you happen to have been at DebConf9 and also had the luck to be one of those I offered some chocolate or wine gum to, you know what I write about. The stuff here was slightly less spicy, but still more than enough to leave a nice impression. They had lots of - well - fun trying them out, gave a good set of laughter. And ordered more for next time. Uhoh, I already know which I will take with me, but then there have to be special preparations before testing. :) I ve also got invited to come back next year. Might be I haven t made the worst impression. Well, lets see if I can take this up and if they still want me in a years time. At least my chinese should be much better by then, given another year of training. (Even if I find it actually hard to learn. For some reason its not easy for me to memorize language things, at least not chinese. Oh my, one year, I should have some 3 words more, I hope :) ). In the evening, back in Kaohsiung, $TC also told me rules of a second dice game that I had seen some people playing. Also seems like fun if played with enough people.
Tuesday, 16th Feb
35mins delay
We started the trip by taking the train from Kaohsiung to Taitung. We had been a little late for it, had to run from the MRT to the train station. Silly me took that as an opportunity to fall down a set of stairs. Only to discover, when getting to the platform, that the Taiwan Railway wanted to give me a feeling of home, delaying the train. First by 31 minutes, later it got up to 43 minutes. Somehow felt like Deutsche Bahn, being late is also their best quality. When the train finally got in we saw that we had been lucky to have seats reserved, this train was full, lots of people moving around within Taiwan that day. We got to Taitung all fine and had the Hotel send someone to pick us up at the train station, as it is a long way from the train station over to the Hotel. Got our room and left it pretty soon again to look around.
Hello Kitty
Spotted a funny little Hello Kitty car and got some food for lunch followed by a walk along the beach. Found some sculptures made of wood, where one of it seems to have some bad stomach problems
Wooden figure with stomach problems
Later on we had a nice and long walk through Taitung Forest Park. Took some time, got some nice pictures. It was getting dark when we got back into town, time for Dinner already. Yay, food. Next day a train trip to Hualien was set, but only for the afternoon, so we had time to look around. We first went through the Peinan Cultural Park, but unfortunately
Park your dog
we had no dog to park there. After that we rented a scooter to get a little farther away from the train station. After getting some fuel for it we headed to National Museum of Prehistory (which was much more interesting than the Fine Arts one earlier) and later on just drove around some time. Just looking around, without a clear direction, simply for the look around. Was fun, but too short actually. But we had to head back at some point to catch our train over to Hualien. In Hualien we again got a Taxi to the Hotel. We left that soon after arriving, Hotel rooms are boring, and it was food time again anyways. Only a little annoying, one of the few days we had rain and I can imagine something nicer than rain when I am outside. But somehow this damn weather doesn t bother to stop raining when I go out.
Thursday, 18th Feb A full day stay in Hualien, no Hotel change. Just a trip over to the Taroko Gorge.
Taroko Gorge
Which is a very nice and impressive place to visit, sure too much for a single day, I definitely have to come back here. (Well, I have to come back for multiple other reasons, but this sure is one). We took the bus to the first stop in that park, somewhere around the Leader Village Taroko. Probably a nice place for a night or ten.
Nice place?
There was a short trail we followed, getting some more pictures and impressions, but it didn t take us long until we where back in a queue for a bus, this one going all the way up to the furthest away spot a bus goes to. There we had some lunch before we wanted to start walking around. Unfortunately (for my nose) we then passed by a place selling Stinking Tofu . Other customers there said that this is not the best available, but I got a taste of it. Don t really need that version more often, even though its not as bad as it smells or the name suggests. We walked a little there and I got some more pictures before we set off to climb the stairs to the Hsiang-Te Temple of Taroko .
Hsiang-Te Temple of Taroko
Looking down from there we saw a lot of buses which was our sign to get back to the bus station, as the last bus was scheduled to get off somewhere at 3 in the afternoon. And as we didn t have a Hotel place here it is pretty helpful to catch the bus. So we queued up once more and had a bus ride back to the train station. Next time there should definitely be a night or more in some Hotel somewhere there. On the way back we took a slight detour, having another time at the beach, not enjoying the weather which insisted on a little rain and lots of wind.
Friday, 19th Feb This day saw us moving to Luodong, another place with a day of rain. Still, my gps log tells me we where moving around a lot, even though I do not have a single picture from the whole day. And as pictures are the main source of my memory ups. Well, I remember the rain, of course. I also remember that I got a steak at some place and that we bought various kinds of food (and tea and juice! :) ) on one of those markets, eating it in our Hotel room. (Rain is bad, mmmmmmmkay?!). And there was some kind of park too, in which I got a funny little game. Oh well.
Saturday, 20th Feb
Way to go
There is nothing nicer than starting a day with a fun bus trip in the morning. Going high up into the mountains. On a day where the clouds reach down to some level underground, more or less. Using very narrow streets and the usual mountain like narrow curves. While not being able to see far. We got up to Taipingshan all fine but once there we had to wait for our room to be ready. So we took a walk around. Actually not a walk. More a climb. Being a mountain place, and those mountains never having heard of those nice invention called elevator or that other named escalator, people setup stairs. Millions of them.
atmosphere
Besides the stairs it is a very nice place to walk around. We took various of the trails through the area and besides me sometimes nearly falling down (damn slippery grounds) it was great. At some point in the afternoon we got our room and also ate some instant noodles before taking another trail, one that took us some 2 hours. You should really take a look at all the pictures I took, as the few I link directly sure do not present this area right. Taipingshan starts at Picture 434 and continues up to Picture 634, but a good number of them is from the second day too.
Sunday, 21st Feb Contrary to the day before there wasn t a single cloud to spot. Ok, ok, there have been some, pictures proof it, but it was a nice sunny day. Nice start of the end of the trip through Taiwan (still one and a half day in Taipei to follow, but the trip around country is over). Of course that meant taking a lot of pictures again,
a sunny morning
and soon after breakfast we took the BongBong Train over over to the Maosing station. There are again a few prepared trails, most of which we took. We only skipped on the one going to the waterfalls, as it wouldn t have fit into our schedule. Got compensated with a pretty adventurous track with lots of nice sights following the old train tracks. Thanks to a number of landslides there is no train going anymore and thus it is a nice way to walk.
rails
It is a 1500m long walk and sometimes you really have to be careful, but it provides many great views and is a really nice trail. Got a few hundred pictures, yay. Including a proof I ve really been there. I hate pictures with me, really, they are just shit by default (maybe I shouldn t be in them?), but in total I got 11 pictures that proof I was really there and not only sent a camera (four of those are included in that gallery I always link to). We got back to the main place around noon and after Lunch we took the Bus back down to Ylan. The bus was scheduled to go at 15:30h, so we went to it fifteen minutes earlier. While we had a sunny day, clouds had started coming in at 15:00h, and at the time the bus started it was all white and there wasn t much too see for the driver again.
me was there
But it turned out that this makes no difference. The driver must have a very prominent wish to die while taking his passengers with him. Or he is insane. Or has a very important appointment somewhere else. Whatever it is, he drove down, on narrow streets, very tight curves, not too much sight and all that with a speed thats incredible. Several times a part of our bus was out over the abyss. I found it pretty fun and all that, especially as it made for a set of very nice views all over the area, and appearently another passenger thought similar, but $TC did have quite the opposite of thoughts and did not feel all that great. We arrived in Ylan one hour before schedule, which, on a 70km trip through mountain area should give a hint how it was. Took a minute off to regenerate and then we wanted to look around a bit. Having our luggage with us that is annoying so we tried to leave that at the train stations baggage service counter. Turns out the personell there is a bunch of crackmonkeys not following their own advertised opening times. Probably wanted to go home early, those lazy dolts. Fortunately the people at the ticket counter were better and exchanged our tickets and we took the Train back to Taipei a little earlier than initially planned.
Monday, 22nd Feb Bad day for all those people who had a nice vacation during Chinese New Year, they had to get back to work. I didn t have that problem and so went around Taipei a bit. Initially I had plans of going to some tourist spots, like the National Palace Museum or others, but then just skipped them all and just took a walk through various spots of Taipei. Basically just Get out of MRT station XY, walk around . The GPS track later told me that I actually covered about 15 km that way, and my feet agreed to that. At some point I did bypass a German Cuisine restaurant, called Zum Fass . Don t ask me how the food is there, I wasn t in, but still had to grin a little when reading the menu. In the evening we went out to get me some Tea to bring back to Germany. Well, some is some kind of understatement, it was lots, as much as I could pack. But good stuff, some of it is steaming right now right besides the keyboard here. Yummy.
Tuesday, 23rd Feb
lantern
As always, the worst day of any vacation. The day you have to leave and go back home. My flight was scheduled for 20:00h, so I took another half a day just looking around Taipei. Which made me even more jealous of those not having to get away, as I happened to pass by some preparations for the Lantern festival. Which happened only a few days after I got away. Next year I have to plan better and stay longer, what I saw on preparations, and that only at the Sun Yat-sen Memorial Hall definitely makes it worth it. Timing in the afternoon was very tight, I actually got the last bus that was in time for my flight. Just one later would have created some trouble, my total time on the airport was something around 30 minutes before boarding started. Just enough to get the minimum needed amount of postcards written and off to boarding. The flight back was boring. Food from TPE to BGK was a pretty good variation on No lactose , some noodles with stuff. Of course from BGK over to AMS it was fish again, same boring Thai Catering as usual. I was unable to sleep well on the flight. Somehow I woke up very often despite earplugs and eye mask. With all that I turned out to be half asleep when we arrived in Amsterdam and so I accidently took an opened half litre bottle of water with me through security. Funny, they didn t spot it. Instead they decided to make a big fuss about my camera bag, asking me in detail what I have in there, supposedly trying to check if I know what I carry. And made an even bigger show of scanning it again. And that bad liquid that those idiotic stupid laws written by brainless monkeys from our governments forbid got no notice at all. Imagine what I could have done to air safety with it! Oh my. Back in Germany my luggage got out first, so no waiting at all. I passed by work to leave some weight there (Hello boss, want some tea?) and went back home. This was also my first trip where I had a noticable jetlag after coming back. For nearly a week my damn body insisted on being in Taiwans timezone, waking me up at times I should sleep, feeling tired when I should be awake. Tssk. Conclusion of this trip: I will be back in Taiwan for sure. I don t care if you take this as a promise or threat, but I will be back! :)

30 May 2009

Steve McIntyre: age++

On Thursday it was my birthday, and I fulfilled a promise I made to myself many years ago. I've always been a car nut, and when I was about 6 years old and had posters of Lamborghinis on my bedroom walls I promised myself that by the time I reached 35 I would have one. That would be long enough in the future that it might happen, but I'd still be young enough to still be able to appreciate it. Well, as it got to the beginning of this year I realised I was running out of time and my bank balance didn't quite look large enough to buy a Lamborghini. So, I cheated a little and I hired one for the day on Thursday. Toy! More pictures here. I had one car booked a few weeks ago, but unfortunately the company involved had to let me down as the car developed problems a couple of days before I was due to have it and needed to go away for repairs. I'm not going to complain too much about them, as it wasn't their fault and they did their level best to make things right: offering a different car, a refund or a later replacement hire. But dammit! I wanted the Lamborghini and I wanted it on my birthday! I quickly rang around on Wednesday to find somebody else, and thankfully the folks at Signature Car Hire were very helpful, sorting out a car with just a few hours' notice. Yay! When they guys turned up on Thursday morning to deliver the car to my office, I couldn't stop myself grinning like the 6-year old boy whose promise I was keeping. Here was a gorgeous car, and it was mine for the day!!! I planned a route for the day to take in some nice driving roads and, importantly, some tunnels. I've watched Top Gear on the TV and I read Autocar every week, and they had both said that taking a fast sports car through a tunnel with the roof down was a good thing to do. I now know that's an understatement! As a whole, the car was awesome: the acceleration, the handling, the brakes were all wonderful. But, as I found out on that day, the noise from the engine was just astonishing. I went through several tunnels that day, heading down past Baldock to Hatfield and back, and at full throttle I could not help but laugh out loud at the music coming from the 5-litre V10 orchestra just inches behind me. It's an experience I'm never going to forget. grin. I also gave short rides to quite a few of the people at work; oddly I had lots of friends that day... :-) I'd also planned other things for the day. I bought myself a new camera in advance to make sure I got some nice photos of the day. Then at the end of the day I went out to the pub with a huge group of friends and I was forced to drink lots of beer. It was horrible, horrible I tell you.

9 April 2009

Martin Meredith: My Boss, with a little help, starts the conversion to Linux

Ok, so at work, pretty much the whole company uses Windows, of some sort. The web team, however, are pretty adamant that they use the best tools available for them, and we use Ubuntu because of this (because it s the easiest option that we all have the same distro, and as long as it s Linux, we don t mind) Anyway, at the moment we re working through the process of moving all our internal business applications from Visual Basic.NET (urgh!) to PHP + a web based app. The Product Owner for this is one of the bosses, who currently uses Windows Vista. He has, however, seen us all using Ubuntu and it s got him interested in using it. He s said that he wants to try using Ubuntu, and see whether he can get his work done on that, and slowly transition to it, as obviously, he needs to be able to use Windows for the .NET stuff (which sadly, doesn t work well under WINE). So, we set him up a Virtual Machine, and he got to grips with what he was doing, great. Except for the fact that he had to allocate memory to it, switching back and forth between windows and Ubuntu was a pain. He eventually gave up on this idea, and got a spare machine, a spare monitor, and set it up next to his machine. Still, however, it was a bit of a pain, he d have to switch position on his desk, start using a different keyboard and mouse, and i was all a bit of hassle. Recently, we ve gotten a big screen (which isn t actually that big!) for the Web Team to monitor the servers, our order download service, etc etc. We were showing our manager some of the stuff we could do with it, and he asked the question So, how do you control it - to which my response was to move my mouse off of the edge of my screen, and onto the big screen. So is that a third monitor? he asked. No I replied, it s another machine. Enter Synergy So this is the point where I explained to our manager exactly what synergy is. Trying to explain it however, is a bit of a hassle, so I ll try my best here. Synergy is an application that allows you to control another machine s keyboard and mouse from your own PC. It s a bit of a mix between a KVM switch, and Remote Desktop, but it doesn t require extra hardware, and you dont have to relay the video across the network to show it on your screen too. At this point, our boss got a glint in his eye Does it work in Windows? he asked. At this point, I didn t realise that he had a seperate machine for Ubuntu. I told him it did anyway, but I wasn t too sure whether it worked with Vista Lets give it a go anyway So we went over to his machine, and I installed quicksynergy on his ubuntu box, while he downloaded the Windows installer for Synergy. 5 minutes later, he was grinning like a maniac as he moved his mouse from one machine to another. Now he s happily using Ubuntu without any hassle, it s just a third screen to him - with different stuff on it. I think the moral here is, there are different ways to get people to be able to use Linux, and Synergy is one of those great tools that enable people to use Linux without having all the hassle that comes with switching over. I think also, a quote from m manager sums it up.
This is one of the best things I ve seen all year. I thought it d take forever to setup, but it was so quick. I can be so much more productive now
I hope that this will be one of the turning points for my manager, and we ll have another convert by the end of the year

19 August 2006

Clint Adams: Whaling in Memphis

I was sitting in the airport, watching all the teenage Marines hitting on each woman they saw, and watching them get consistently rejected, when I may have had an auditory hallucination. By means of the public address system, some sort of airline employee had summoned a list of passengers to the gate, and none of those passengers were named Horselover Fat. Nevertheless, I sashayed up to the desk and inquired of the manchimp standing there, Did someone call my name? He looked at me, grinning smugly, and asserted his intellectual superiority by pointing out that he couldn't answer that question without knowing my name. Rather than explaining to him that he could have assimilated that little bit of knowledge by reading the boarding pass that I was holding in front of me, I told him that my name was Jarom Hennessey, for that was the name in the passport I was using. (Hi, Alana. Hi, Ophira. Die, Aliza.) Nope, he said, and as I began climbing over a pile of Marines, he continued, Oh, wait. She called your name and I didn't hear. So I climbed back, and waited for him to ask my name. Alas, he did not; he only said, You don't have any objection to sitting in Business class, do you? No, I lied, and so he printed me a new boarding pass. It turns out that this was the good sort of Business class not the foul sort you might get on British Midlands, where your seat is exactly 14 millimetres wider than those in Economy, and they still stab you with sharpened Yorkshire pudding and plead with you to do your part in lightening the load of the airplane, even though you are several thousand feet in the air and don't even want to be going to the UK in the first place, but the kind where the enormous seat reclines all the way back, has electronic adjustable lumbar support and all kinds of other gadgets, the food is pretty good, and you can even get snakes if you ask for them. First class on that flight looked even better, especially because there was a 55-year-old 4'7"-tall man giving people laypdances and begging them not to keep calling him a stewardess , because apparently he is some sort of flight attendant . Anyway, I sat next to some fratboy douchebag who eventually learned to mind his own goddamn business, and passed on the free Bellinis since it was only 6am. I did avail myself of other free stuff, and when the stewardess (not the guy from First class) took my breakfast order, she asked if I wanted a DVD player. In mimicry of Fratboy Douchebag, I grunted, Sure. She brought me a portable DVD player, which claimed to have a battery, but didn't work unless it was plugged in, and also claimed that it would not play any DVDs not provided by the airline. I did not have the opportunity to test this, since I had opted to not bring any DVDs with me. Instead, I perused the selection provided me. These DVDs were all labeled to indicate that they could be played only in the airline-provided DVD player. I have a funny story about that. I'm not going to tell it. I don the noise-cancelling headphones, and jack them into the DVD player, into which I have put Transamerica. For a little while, I think that the lack of speech is the movie being artsy. Then I begin to suspect that something is horribly wrong, so I start over, with subtitles on. It becomes clear that all the speech has been elided, as well as some of the sound effects. A bad burn? I swap the DVD out for Firewall, and experience similar problems. Summoning one of the stewardesses, I complain that there seems to be something wrong with something. I trade everything in for a new set. This time I don't get Transamerica, so I put in Firewall; having seen the first two minutes, I have to watch it to completion now. There's no sound at all. I discover that if I press down on the headphone plug, shifting the jack sideways, I can hear the audio portion of the presentation. What a pain in the ass. Here would be another good place to not tell the funny story. I switched to a better movie after that. In retrospect, I should have taken more advantage of the in-flight service, since my next leg was abysmal. This airline was one of my favorites a little over half a decade ago, and now I am plotting ways to never fly it again. I'll note that the seat was smaller than Greg Pomerantz's former toilet, that the radio controls were from the wrong century, and instead of having hot food included, the flight staff sold sandwiches and snack boxes . Matthew Garrett might say that this sort of flight gives one more freedom than the sort where you get a choice between two different meals or nothing at all, but I think that it is a travesty. There should be giant warning indications for such flights, so that one has ample time to purchase crappy, overpriced airport food to drag on board, as that is a better alternative. The third leg was rather unremarkable, except for the elderly Jewish man who kept fondling a stewardess and gesticulating some sort of claim that he had no command of English. Just prior to the descent, she gave him a loud scolding, repeating at the end, Yes, you understand me. I imagine that she could make quite a bit of money as a prostitute for the Chasidim; they like their hookers blonde. Now the fourth leg was pleasant for numerous reasons, most of which are boring. The guy across the aisle from me bore some disturbing similarities to Mr. Foxworthy, but was not nearly entertaining enough to hold either my interest or the interest of a blonde chick, who sat on the other side of him and probably wouldn't be all that popular with the Chasidim. One of the stewardesses was Latina, but spoke like a limp Swiss man. Her partner in comedy was not Latina, and did not speak like a limp Swiss man. I didn't catch their names, so I'll call the first one Marta and the second one Gladys. Marta and Gladys were having a work-related discussion about a complimentary beverage prior to it having been served to some fool behind me. There was a bit of a communication mixup, so Gladys leaned over to me and gestured a few allegations about Marta, concluding with So if you have to talk to her, just use sign language or somethin'. Hearing this, Marta shoved Gladys out of the way, leaned over to me, and said, You just wait. Later on, I'll tell you something really bad about her. Then I wrecked some guy's priceless painting. Oops. Isn't paint a liquid- or gel-like substance? If you ask me, all instances of art are terraist weapons. Oh, Gladys sighed happily, I don't know what I'd do if you weren't here. Later, at the deplaning, Gladys cried out, My friend! , and Marta nudged me and said, She's single!

4 July 2006

Clint Adams: Exploding moon pie

December came by, and the girl proceeded to remind everyone that her birthday was in a week. My birthday is in a week! she said. I like flowers and candy. I just love roses and chocolate, she said, and my birthday is next Tuesday. After making the rounds, the girl went to visit the boy. My birthday is in a week! she declared. Yes. Next Tuesday, he replied. I like flowers and candy. Do you like my shoes? she said. He looked down. You know I hate high heels, he sighed. She pouted and stormed off. He threw away the birthday card he had been making. He's so mean to me, she told everyone. I hate him! she announced. I hate him because he's so mean to me! Everyone mumbled supportive nothings, and soon she was pacified by a couple of passing rhinestones and a length of ratty yarn. Before long it was her birthday. The girl woke up to a plethora of Hallmark cards, flowers, and candies. She brushed her hair and went to see the boy. It is my birthday! she announced. I know, he said. I didn't see a present from you, she stated, puzzled. That's because your present is here, he retorted, grinning. She beamed while he went to fetch her gift. What the? she squeaked, her brow furrowed. I got you a new coat, he explained. It has reinforced thumb holes so you won't have to cut your own and repair them, and it has extra pockets for your herb bags. Do you like my shoes? He looked down. You know I hate high heels, he sighed. But they're shiny! Well, I like you. Then why didn't you get me flowers and candy she shrieked and stormed off. December came 'round again, and the girl proceeded to remind everyone that her birthday was in a week. My birthday is in a week! she said. I like flowers and candy. I just love roses and chocolate, she said, and my birthday is next Wednesday. After making the rounds, the girl went to visit the boy. My birthday is in a week! she declared. Is it? On Wednesday the boy bought her a box of chocolates and a dozen roses. Flowers and chocolate! she exclaimed, delighted. How thoughtful!

14 June 2006

Simon Richter: Remind me why I got up

Today is going to be interesting. A parcel arrived (good), I jumped out of the shower to answer the door, stepped into a piece of broken glass (bad), went to the post office to at least get the address my bank statements are sent to changed (again), and now I'm on my way to work (late). Tomorrow is a holiday, which means I won't get my parcel there either. And I'm not entirely sure whether to interpret the look the post office workers had as smiling (friendly) or grinning (not quite so)

11 December 2005

Matthew Palmer: FORTH: The One True Language

Just reading the comments associated with a post from the reddit.com people about a rewrite of their entire site from Common Lisp to Python. The Lispers are screaming "noooooo!", the Pythonistas are grinning smugly, and the Rubyolas are asking "why not us?". In the middle of it all, comes this gem (unfortunately, posted by "Anonymous", so no attribution):
Real men would design a custom ASIC and write a new FORTH system optimized for Reddit, complete with custom developent environment, web server, etc. It would multiply the development time-to-1.0 by about 2-4x, but the entire system would be smaller than the ethernet plug, would handle a saturated gigabit pipe with sub centisecond latency, never crash, and use less power than your toaster. Everyone would be too busy saying "WTF is FORTH?" to bitch about you not using Ruby on Rails. Then you'd lose to the guy who did it in PHP (*turn* *puke*), because it's not about the technology, stupid.