<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Tue, 29 May 2012 11:16:32 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><title>Journal</title><subtitle>Journal</subtitle><id>http://jamieonsoftware.com/journal/</id><link rel="alternate" type="application/xhtml+xml" href="http://jamieonsoftware.com/journal/"/><link rel="self" type="application/atom+xml" href="http://jamieonsoftware.com/journal/atom.xml"/><updated>2012-05-22T21:21:32Z</updated><generator uri="http://www.squarespace.com/" version="Squarespace Site Server v5.11.81 (http://www.squarespace.com/)">Squarespace</generator><entry><title>Peru - May 16</title><category term="peru"/><id>http://jamieonsoftware.com/journal/2012/5/22/peru-may-16.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/5/22/peru-may-16.html"/><author><name>Jamie Rumbelow</name></author><published>2012-05-22T21:20:24Z</published><updated>2012-05-22T21:20:24Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p class="p1"><strong>Background: This month I'm in Cusco, seeing the city and volunteering at a school project for underprivileged, impoverished&nbsp;kids. This is an almost verbatim entry from the diary I'm keeping while I'm out here.</strong></p>
<p class="p1"><span class="s1">I wake up at 5:15 this morning, shower, get dressed and walk up to <em>Recoleta</em> where Katrina is staying. The lady at the travel agency (a massive Pink Floyd fan, incidentally) tells me to be at Katrina&rsquo;s for 6:10 to be picked up. I get there about 5:50. 6:10 rolls around and no sign of the annoying American or our escort, so I ring the doorbell. Within a minute a disgruntled Katrina pops her head out of the window. We get picked up and make our way to the bus terminal in Cusco.</span></p>
<p class="p1"><span class="s1">The bus journey to Puno is long, but is broken up by stops along the way. We find ourselves visiting a church, a small village, a restaurant and a plateau overlooking the mountains. The views are spectacular and the sights interesting, if a little touristy.</span></p>
<p class="p1"><span class="s1">We arrive in Puno at around 4 in the afternoon. We drop our bags off at the hotel we&rsquo;re staying in, and wonder out into the town for a spot of dinner.</span></p>
<p class="p1"><span class="s1">The next morning is another early start, and we&rsquo;re on the boat with the other tourists by 9:30. Our tour guide, a Quechan bloke called Angel, has this habit of inflecting upward at the end of his sentences, like everything he&rsquo;s saying is a question. It&rsquo;s very annoying.</span></p>
<p class="p1"><span class="s1">We arrive on the floating islands of Uros; an expansive, man-made structure of houses sitting on constructed islands of earth beds and reeds. The islands are extremely impressive, but very touristy. I get the impression our entire trip will be like this.</span></p>
<p class="p1"><span class="s1">After we leave the floating islands we begin the three hour boat ride out of the bay of Puno into the main Lake Titicaca itself. We get along well with a couple from Chicago; both physiotherapy students and both delightful company.</span></p>
<p class="p1"><span class="s1">We arrive on another island. I can&rsquo;t remember it&rsquo;s name exactly, but it was something like Isla Manta&ntilde;a. Unfortunately, the relationship with our host family is totally disparate and connecting with them at all is an impossible task. They give us a bizarre, heavily potato based lunch.</span></p>
<p class="p1"><span class="s1">Katrina and I trek, with the other tourists, up to the top of the island. The altitude up here is nearly 4,000m, and hiking up a steep slope is very strenuous.</span></p>
<p class="p1"><span class="s1">Upon reaching the top, the entire purpose of our trip is clear. The view is utterly remarkable. Lake stretches out into the distance, with the silhouettes of mountains carving a dark outline into the sky, as the sun sets and casts an orange glow onto the landscape.&nbsp;</span></p>
<p class="p1"><span class="s1">The only thing more beautiful than the view are the stars that night. No electricity means no light pollution, and no light pollution means a stunning view of the night&rsquo;s sky.</span></p>
<p class="p1"><span class="s1">K and I gaze at the stars, and, exhausted, sleep.</span></p>
<p class="p1"><span class="s1">The next morning we visit another island where we eat some fantastic trout in a restaurant with yet another brilliant <em>vista</em>.</span></p>
<p class="p1"><span class="s1">We head back by boat to Puno. I get cocky - &ldquo;Ahh I never get sunburnt!&rdquo; - and promptly get sunburnt. Quiet coach journey home in the dead of night.</span></p>
<p class="p1"><span class="s1">Lovely lunch with K the next day before she leaves back to New York. Leave her at her house. Back into Cusco.</span></p>
<p class="p1"><span class="s1">What a wonderful few days.</span></p>]]></content></entry><entry><title>Peru - May 12</title><category term="peru"/><id>http://jamieonsoftware.com/journal/2012/5/18/peru-may-12-1.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/5/18/peru-may-12-1.html"/><author><name>Jamie Rumbelow</name></author><published>2012-05-18T17:17:29Z</published><updated>2012-05-18T17:17:29Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p class="p1"><strong>Background: This month I'm in Cusco, seeing the city and volunteering at a school project for underprivileged, impoverished&nbsp;kids. This is an almost verbatim entry from the diary I'm keeping while I'm out here.</strong></p>
<p class="p1"><span class="s1">The past few days have been regular. I say regular, but this is Peru, so there isn&rsquo;t anything regular about it. I suppose I mean predictable, but even then...</span></p>
<p class="p1"><span class="s1">I spend my days learning Spanish and working with the kids and my nights out. K and I are&nbsp; getting along even better and spend three consecutive nights together; good food, good drinks and great company. She&rsquo;s complex and mature, and I sincerely like that. I wonder how much of my attraction to her is intellectual and how much of it is physical. I&rsquo;m not a physical being (as anyone who has witnessed me trying to play football will know), but she is conventionally beautiful, at the same time as being intriguingly intricate.</span></p>
<p class="p1"><span class="s1">Things are going really well at the project. I really enjoy working with the kids, the other volunteers are supportive and it&rsquo;s been really rewarding so far.</span></p>
<p class="p1"><span class="s1">I decide to try and engage the kids in programming. A seemingly impossible task, considering I don&rsquo;t speak technical Spanish, they don&rsquo;t have computers and none of the other <em>profesores </em>have any programming experience. I set about trying to teach the concept of input through to output, which lies at the core of programming a computer.</span></p>
<p class="p1"><span class="s1">As far as I&rsquo;m aware, the only real way to engage young kids in fundamentally dull concepts is to simplify them and make them exciting. Input through to output, in this context, equates to code through to result. Commands through to actions. The most accessible computer with the most immediately &lsquo;viewable&rsquo; results, conceptually, is a robot. Everyone knows what a robot is, so I began trying to design a game to allow the kids to control a robot.</span></p>
<p class="p1"><span class="s1">To give the activity a sense of community, I make <em>los profesores</em> the robots, and the kids divide into teams to control them.</span></p>
<p class="p1"><span class="s1">The idea is, they write a series of commands on a piece of paper, which is then given to the robot, who then executes the commands. The program must guide the robot through an obstacle course, pick up a bag of sweets and drop the sweets off in a box at the other end of the course.</span></p>
<p class="p1"><span class="s1">Within moments the kids grasp the concept and start writing programs. The first round goes terribly, but once they&rsquo;ve had a chance to see their programs in action, they&rsquo;re much more confident with the idea and they really start to have fun. This is problem solving at its core, and they take to it incredibly well. They&rsquo;re pacing across the room, shouting numbers out to team members,&nbsp;</span></p>
<p class="p1"><span class="s1">Everybody&rsquo;s laughing, everybody&rsquo;s working and everybody&rsquo;s thinking. It&rsquo;s moments like this that make me really excited about the future. Understanding these basic concepts are, and will be, fundamental to the future of businesses and the fact that I get to play a tiny role in this is so fulfilling.</span></p>
<p class="p1"><span class="s1">Moved my Lake Titicaca trip forward so K isn&rsquo;t alone (and I won&rsquo;t be alone either). Looking forward to seeing nature. Looking forward to seeing the stars. Looking forward to eating the food and doing some hiking in the mountains of the islands.</span></p>
<p class="p1"><span class="s1">Fingers crossed it won&rsquo;t disappoint.</span></p>]]></content></entry><entry><title>Peru - May 8th</title><category term="peru"/><id>http://jamieonsoftware.com/journal/2012/5/12/peru-may-8th.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/5/12/peru-may-8th.html"/><author><name>Jamie Rumbelow</name></author><published>2012-05-12T14:05:52Z</published><updated>2012-05-12T14:05:52Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p class="p1"><strong>Background: This month I'm in Cusco, seeing the city and volunteering at a school project for underprivileged, impoverished&nbsp;kids. This is an almost verbatim entry from the diary I'm keeping while I'm out here.</strong></p>
<p class="p1"><span class="s1">I begin my project today. After breakfast, Spanish lessons, a walk around Cusco and more leisurely loitering, I get to the Spanish school and meet Niko, who is taking me to the project. We go via another project - Caitlin, one of the Americans, works at United Planet, the volunteering network, and is looking around the various projects - an orphanage. So, the six of us cram into a taxi and make our way.</span></p>
<p class="p1"><span class="s1">Seeing such poverty is totally sobering.</span></p>
<p class="p1"><span class="s1">There are six houses and each house contains twelve kids. There&rsquo;s mold on the ceiling, the walls are damp and the bedsheets and mattresses are old and dirty.&nbsp;</span></p>
<p class="p1"><span class="s1">Our visit is well received by the kids. They swarm to us, tug our clothes and hug us. We take lots of photos, they dance around, play with each other and ask to use my camera (what&rsquo;s Spanish for &ldquo;For the love of God please be careful!&rdquo;?).</span></p>
<p class="p1"><span class="s1">The kids know Niko; he volunteered there when he first arrived in Peru. Shouts of &ldquo;&iexcl;Hola Niko!&rdquo; echo around the block.</span></p>
<p class="p1"><span class="s1">Outside there&rsquo;s a walkway, if you could call it that. It&rsquo;s more like a construction site. There are open drains, nails and big, wide cracks in the concrete.</span></p>
<p class="p1"><span class="s1">The path leads to a modest play area. There are some swings, a slide and a makeshift castle made from wooden crates, old bins and plastic piping. I spot a plank of wood with a nail sticking out of it, lying, exposed in the grass. I bend the nail into the wood and throw the plank far away from the play area.</span></p>
<p class="p1"><span class="s1">Like I said. Sobering.</span></p>
<p class="p1"><span class="s1">What fascinates me, and I don&rsquo;t wish to sound trite here, is how happy the kids are in the midst of all this poverty. Their smiles, laughter and innocence really does put your problems into perspective. My redhead dilemma is now totally insiginificant.</span></p>
<p class="p1"><span class="s1">According to Niko, when the kids reach the age of eighteen they have to leave. They most likely go into a life of crime; unemployment is rife in Peru and stealing or drug trafficking is a lot of people&rsquo;s only possible financial recourse.&nbsp;</span></p>
<p class="p1"><span class="s1">I hope things will change in the next ten years so that these kids have a better future. Until then they&rsquo;re left in a poor, difficult, but thankfully loving, home.</span></p>
<p class="p1"><span class="s1">They&rsquo;re also fanatical about Justin Beiber. Bizarrely.</span></p>
<p class="p1"><span class="s1">We pile back into a taxi and head for my project. Source travel is initially difficult; apparently my project is in a really dangerous area, or at least dangerous enough to deter taxi drivers. This bodes well.</span></p>
<p class="p1"><span class="s1">The journey is quick. Up an extraordinarily steep hill - think San Francisco - and through a rainbow-painted door lies the Asociacion Civil Giordana Liva de Cusco, or &lsquo;my project&rsquo; as it will be henceforth known.</span></p>
<p class="p1"><span class="s1">The project was started by an Italian guy called Perci in 2002. Since then it&rsquo;s blossomed into a humble but pleasant programme for homework help and after school activities. The district, Santiago, is poor, and many of the kids come from families of unemployment and alcoholism.</span></p>
<p class="p1"><span class="s1">The kids are a fantastic bunch and they work hard at their homework. The project runs activities too: music time with recorders and basic reading from staffs, creative drawing, arts and crafts and reading. <em>Los ni&ntilde;os </em>seem to enjoy doing it all, even if they are a bit restless sometimes.</span></p>
<p class="p1"><span class="s1">There are roughly ten volunteers (the kids call us <em>los profesores</em>, I&rsquo;m &lsquo;Profesor Jamie&rsquo;, so use that if you&rsquo;re writing any fan mail to me). Most of them are Italian, but they all speak a little bit of English and my Spanish is starting to get a lot better.</span></p>
<p class="p1"><span class="s1">I dive straight in and start helping the kids with their maths homework. They&rsquo;re very bright; long division seems to be easy for them. I don&rsquo;t know why, it&rsquo;s bloody hard.</span></p>
<p class="p1"><span class="s1">They&rsquo;re re-doing the garden area outside, and need help, so, after a cement mixing crash course in Spanish, I spend the rest of the afternoon doing manly building stuff.</span></p>
<p class="p1"><span class="s1">We&rsquo;d planned to meet back at the school and go out for a few drinks. I get to the school, but it&rsquo;s locked and closed, so I walk down to the bar we&rsquo;d been discussing.</span></p>
<p class="p1"><span class="s1">Lo and behold, I bump into Katrina, one of the Americans. She&rsquo;s quite short, totally antagonistic and really, <em>really</em> good looking. Painfully good looking. We end up spending the entire evening together, arguing with each other, and although we don&rsquo;t see eye to eye on pretty much anything we get along very well. Opposites attract, I suppose.</span></p>
<p class="p1"><span class="s1">We pop to the aforementioned Irish pub. We sit opposite an Irish couple (whose names we&rsquo;ve both forgotten, sorry!). They were going to get a mortgage, get married and have a family, but in their words: &ldquo;Feck that, getting pissed and seeing the world is much more fun&rdquo;.</span></p>
<p class="p1"><span class="s1">We have a blast. I introduce Katrina to proper British ale, I eat a fantastic steak sandwich and we thoroughly make the most of happy hour. The Irish couple are bollixed, but they carry on regardless and we make our merry way over to Frogs at about 10:30PM. I bump into Marko, one of the Italians at my project, and we drink <em>muchas bebidas</em>. I walk Katrina home.</span></p>
<p class="p1"><span class="s1">All in all a very interesting day.</span></p>]]></content></entry><entry><title>Peru - 7th May</title><category term="peru"/><id>http://jamieonsoftware.com/journal/2012/5/9/peru-7th-may.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/5/9/peru-7th-may.html"/><author><name>Jamie Rumbelow</name></author><published>2012-05-09T17:01:12Z</published><updated>2012-05-09T17:01:12Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p class="p1"><strong>Background: This month I'm in Cusco, seeing the city and volunteering at a school project for underprivileged, impoverished&nbsp;kids. This is an almost verbatim entry from the diary I'm keeping while I'm out here.</strong></p>
<p class="p1"><span class="s1">It&rsquo;s 5:30AM and this is the earliest I&rsquo;ve been up in a very long time. The difference of -6 hours is just enough to cause considerable jet lag, but I should be okay in a couple of days.</span></p>
<p class="p1"><span class="s1">Last night was lovely. Doris walked me to the Spanish school (not to be confused with the after school programme I&rsquo;m volunteering with, the San Blas Spanish School is a basecamp for a whole host of volunteering projects). I met Niko, a funny, charming and charismatic Austrian who works at the school. He told me we were going for dinner soon but needed to wait for a few others. The others turned out to be six Americans; five girls and a guy. They were all absolutely delightful and I very much look forward to getting to know them better. They all seem to be in their mid-Twenties.</span></p>
<p class="p1"><span class="s1">We ate at a funky little cocktail bistro called &lsquo;The Frogs&rsquo;. The food was superb and the Pisco sours plentiful; to top it off, my newly acquired volunteer card gives me 15% off food and happy hour all night long. It&rsquo;s also pretty cheap, at s/.15 per drink, which is about $4, or &pound;2.50 for the sterling-inclined.</span></p>
<p class="p1"><span class="s1">Niko distributed a bunch of welcome packs. My pack contains a map of Cusco, the discount card, a few coupons, a bunch of useful numbers and addresses and most importantly, the schedule. I&rsquo;ve got a busy few weeks ahead of me but it seems to be rather flexible too. I think it&rsquo;s the Peruvian attitude: a pervasive culture of &lsquo;why do it now when you can do it later?&rsquo; The Spanish translation of this is <em>ma&ntilde;ana</em>, I believe.</span></p>
<p class="p1"><span class="s1">I&rsquo;ve got Spanish lessons Mon-Thu 11-1 this week. I&rsquo;m on an after school programme so my volunteering doesn&rsquo;t begin until 3, which means I&rsquo;m busy this week but I will have plenty of exploring time next week when the Spanish classes aren&rsquo;t so intensive.</span></p>
<p class="p1"><span class="s1">Wednesday and Thursday nights host some great activities at San Blas: this week it&rsquo;s Salsa lessons, the following week cooking. Niko tells us on Thursday night we can go to <em>The Frogs</em> for a cocktail class.</span></p>
<p class="p1"><span class="s1">I&rsquo;m very much looking forward to my Spanish lessons: my patchy Spanish is already improving but a one-to-one class is going to be extremely valuable. I feel very limited at the moment. Those of you who know me know how much I like to express myself and not being able to articulate myself properly is proving to be a major barrier to, say, winning arguments.</span></p>
<p class="p1"><span class="s1">I eat some potato skins with sour cream and salsa, followed by a Peruvian dish with big chunks of beef cooked up with a load of veg in soy sauce. They&rsquo;re big on their carbohydrates here; most meals are served with rice AND potatoes or chips.</span></p>
<p class="p1"><span class="s1">For breakfast today it&rsquo;s fresh bread with butter and jam, as well as freshly squeezed and pulped pineapple juice. Pineapple is quite clearly the king of the juices.</span></p>
<p class="p1"><span class="s1">I chat to a fellow lodger over breakfast; Gabrielle is a 50-year-old Swiss woman who speaks fluent Spanish and has just quit her job as the HR director of a large Swiss firm in order to travel full time with her husband. Stories like hers are utterly inspiring and it&rsquo;d be amazing to have the courage and audacity to do that. Her kids have grown up so she has no attachments, which is hugely freeing, but I wonder if in a few years she&rsquo;ll yearn for a home, for a base, for stability.</span></p>
<p class="p1"><span class="s1">I walk up to the Spanish school and take a wander around town. I buy an SD card reader, but it doesn&rsquo;t work in my laptop or the school&rsquo;s computer, so I&rsquo;ll return it tomorrow.</span></p>
<p class="p1"><span class="s1">I&rsquo;ve taken some great photos today and can&rsquo;t wait to share them. There are so many interesting scenes and people here in Cusco and they make for some excellent photography.</span></p>
<p class="p1"><span class="s1">On a walk through an old Incan sidestreet I come across this small sign with a guitar and an arrow pointing to an open doorway. Walking through the doorway brings you into a yard; a chicken pecks at some corn and a dog chills in the shade. Another sign points to the direction of a arrow store corridor. I walk through, turn the corner and cross the threshold into a small, but bright workshop.</span></p>
<p class="p1"><span class="s1">Wooden chippings make up a carpet, and a man stands with a chisel, hunched over a small wooden instrument. It&rsquo;s got the build of a ukelele but the bridge and head of a guitar, so it must be a Peruvian instrument I&rsquo;m not aware of. I make the worker aware of my presence with a simple &ldquo;&iexcl;Hola!&rdquo; and instantly he switches from focused craftsmen to scatty amigo. I ask him about his instruments and he begins animately describing the process, the tools and the business he runs.</span></p>
<p class="p1"><span class="s1">Of course, it&rsquo;s all in speedy technical Spanish and I understand close to none of it. I take a few photos, nod along, smile, say &ldquo;gracias se&ntilde;or&rdquo; a lot and leave. I&rsquo;d like to revisit him in a couple of weeks to see the instrument when it&rsquo;s complete. I think he also appreciated the visit. I don&rsquo;t think he gets a lot of company <em>normalmente</em>.</span></p>
<p class="p1"><span class="s1">It&rsquo;s time for my first Spanish lesson. I arrive back at the school to find a bunch of confused foreigners sitting in chairs and eating avocado. I get chatting with a dutch girl called Anuk. She&rsquo;s an art historian and yoga instructor. People are interesting.</span></p>
<p class="p1"><span class="s1">Franklin, my soon-to-be Spanish teacher, pops his head round the door and yells my name. He says &ldquo;&iexcl;Arriba!&rdquo; and marches up the stairs. Thankfully, I knew <em>arriba</em> means upstairs rather than the &ldquo;let&rsquo;s get drunk, take our clothes off and party all night&rdquo; that it&rsquo;s synonymous with in British culture. That could have been embarrassing.</span></p>
<p class="p1"><span class="s1">The lesson is entertaining and rewarding, and I already feel a lot more confident with my Spanish. Give it a few more weeks and I&rsquo;ll be talking no ends of bullshit. It&rsquo;ll be fantastic. The equilibrium will be restored. I don&rsquo;t like not being able to express myself.</span></p>
<p class="p1"><span class="s1">I have another look round the city, sit in a caf&eacute; and type up yesterday&rsquo;s entry. Just as I&rsquo;m about to leave, the Dutch girl from earlier sidles up to me and says hello. I initially don&rsquo;t recognise her - she&rsquo;s not wearing her glasses - but after a couple of seconds it comes to me and we start chatting.</span></p>
<p class="p1"><span class="s1">She mentions getting a coffee. I come clean and sheepishly admit to having no more money on me (lunch was more pricey than I was expecting), but she says it&rsquo;s okay and offers to buy me a latte. We grab our coffees and sit by the fountain in Plaza de Ramas, chatting about everything and anything and watching the tourists pass by. We walk back to the school and go our separate ways.</span></p>
<p class="p1"><span class="s1">This is what I love most about traveling. Because I&rsquo;m on my own I have to make an effort to chat and make friends, and I&rsquo;m meeting so many interesting people.</span></p>
<p class="p1"><span class="s1">I spend the rest of the evening tucked up in bed reading, writing and sleeping. The combination of jet lag and altitude has left me thoroughly exhausted. Just remembered I have <em>Office Space</em> on my laptop so I might watch that. I&rsquo;m tempted to go out and abuse my discount at Frogs but I decide against it in favour of an early night and the thrilling final chapters of <em>Boris</em>.</span></p>
<p class="p1"><span class="s1">I begin at the after school programme tomorrow, as well as the two hour Spanish class, so I ought to be rested up. I&rsquo;m also starting to run out of my initial $100. I&rsquo;ve spent about $50 so far and I want this to last me until Thursday or so.&nbsp;</span></p>
<p class="p1"><span class="s1">An early night it is.</span></p>]]></content></entry><entry><title>Peru - 5/6th May</title><category term="peru"/><id>http://jamieonsoftware.com/journal/2012/5/7/peru-56th-may.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/5/7/peru-56th-may.html"/><author><name>Jamie Rumbelow</name></author><published>2012-05-07T19:17:46Z</published><updated>2012-05-07T19:17:46Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p class="p1"><strong>Background: This month I'm in Cusco, seeing the city and volunteering at a school project for underprivileged, impoverished&nbsp;kids. This is an almost verbatim entry from the diary I'm keeping while I'm out here.</strong></p>
<p class="p1"><span class="s1">Spent the plane flight absent minded. Bought a beer in the hope of enticing sleep but to little avail; three hours of shuteye achieved and the rest of the trip spent engrossed in <em>Boris: The Rise of Boris Johnson</em>. I suppose I&rsquo;ve had worse flights.</span></p>
<p class="p1"><span class="s1">Arrived in Lima with a few hours to kill before connection and walked into airport food court. Ahh, globalisation, you really want me to have an Egg McMuffin, don&rsquo;t you? I resist my Western urges and approach the most Peruvian counter I can find. I ask for &lsquo;un desayuno tradicional&rsquo; - a traditional breakfast - and get given a sandwich containing onions, an unidentifiable root vegetable and some very questionable beef. And a beer. For 5:30AM I&rsquo;m doing rather well. I think I&rsquo;m going to like this country.</span></p>
<p class="p1"><span class="s1">From glimpses through plane windows and the vast, low panorama of the departure lounge, Lima seems to be a very industrial city. I can see towering mechanical structures off in the distance, reminiscent of Rockerfeller&rsquo;s Standard Oil nodding donkeys. I don&rsquo;t think it&rsquo;s oil here in Peru but the structures are certainly significant; they&rsquo;re essentially the only thing visible in the otherwise flat Lima skyline.</span></p>
<p class="p1"><span class="s1">The airport itself offers no intrigue or cultural significance; it&rsquo;s very much a normal airport, which I suppose is exactly what you want from an institution created to shuttle you across continents at 500mph and 30,000ft up. Still, it&rsquo;d be nice to see some llamas or something.</span></p>
<p class="p1"><span class="s1">It&rsquo;s a balmy 19&deg;C, which is keeping me happy. I won&rsquo;t dwell on Lima or its airports any more. After all, it&rsquo;s Cusco I&rsquo;ve come here to see and Cusco I shall write more about. Back to <em>Boris </em>I go while I await the 09:20 to CUZ.</span></p>
<p class="p1"><span class="s1">My flight to Lima lands in the early hours, while it&rsquo;s still dark, so my first real glimpse of Peru while airborne is from the LIM -&gt; CUZ flight. As the plan ascends into the clouds I see glimpses of an unimpressive city. It feels totally European, which is really not what I came here hoping to see. An hour later the plane descends, breaking through the thick cloud, and suddenly all my previous skepticism is put to rest.</span></p>
<p class="p1"><span class="s1">We glide over mountains. It&rsquo;s a totally unpredictable landscape: soaring rockfaces jutting out of the Earth, deep, dark canyons and dense forest covering a plateau, stretching out into the distance. The variety of terrain really is a remarkable sight. I can see a hundreds of tiny little <em>pueblos </em>dotted across the countryside.</span></p>
<p class="p1"><span class="s1">It&rsquo;s an experience like this that makes me think Peru was meant to be viewed by air. It is akin to the Grand Canyon with its heterogeneous landscape; while it looks amazing now, I&rsquo;m sure from a helicopter it&rsquo;d look fucking phenomenal.</span></p>
<p class="p1"><span class="s1">As the plane draws closer to my destination the little <em>pueblos</em> out in the country begin to grow in number and increase in density until they morph into the unbroken urban sprawl of Cusco. It&rsquo;s much bigger than Google Maps has lea me to believe. The airport is old, dusty and archaic (yes!). There is something disingenuous about overly modern and Westernised facilities in poor cities. I suppose it&rsquo;s to attract tourism, but still, it saddens me to think of where that money could be put to much better use.</span></p>
<p class="p1"><span class="s1">I&rsquo;m picked up by the Mother of my host family, Doris, a delightful 57-year-old that speaks absolutely no English (or refuses to... I&rsquo;ve not sussed her out properly yet). I rely on my poor Spanish to make it through several conversations, including one about how &ldquo;las chicas de Cusco&rdquo; are lovely and bountiful, but they may just want me for my money. Fantastic Doris, thanks.</span></p>
<p class="p1"><span class="s1">After lunch - a potato soup followed by <em>pollo</em> with rice and marinaded-in-something veg - I decide to take a stroll around the town.</span></p>
<p class="p1"><span class="s1">As far as I&rsquo;m aware, Peru is a country in (what is known by pretentious middle-class white boys like me) the &lsquo;developing world&rsquo;. Whatever the ethics of the terminology, Peru definitely deserves to have its present tense nomenclature.&nbsp;</span></p>
<p class="p1"><span class="s1">The entire city of Cusco feels like one giant work in progress. Street after street of empty concrete buildings, dozens of abandoned roadworks and unclosed sewers. The whole place screams unfinished. The road on which I&rsquo;m staying, <em>Avenue de la Cultura</em>, is partitioned on the left (facing downhill) by tens of pieces of corrugated aluminium, bolted onto planks of wood to form a fence. A cycle bridge crosses over the busy road to a new roundabout, circling a fountain, while straight opposite is a new block of offices. It&rsquo;s a fascinating juxtaposition, from the makeshift, shantytown fencing on my left to the modern, clean, contemporary design of the workspace to my right.</span></p>
<p class="p1"><span class="s1">Poverty is not overtly apparent, but neither is wealth. <em>Cultura </em>is joined with its parallel road through a series of mini-markets. These bazaars are deceptively extensive, forming a labarinthine maze full of independent retailers trying to sell rip-off bags, boots and clothing, pirated CDs and DVDs, cheap plastic toys and local foods and drinks. I&rsquo;ve been warned by various people, including my Mother, not to get food from street stalls lest I suffer from diarrhea. It&rsquo;s very good advice, but the adventurer and rebel in me is tempted to try some of it out. I think I&rsquo;ll play that one by ear.</span></p>
<p class="p1"><span class="s1">I walk up to the more touristy area - a typical tourism scene, and fundamentally nothing too interesting to report - and sit myself in a posh bar overlooking a little piazza. I order a pisco sour (what else?!) and enjoy the last of the sub before the clouds consume it again. I pay the s/.25 (approximately $9, which isn&rsquo;t that bad but still seems overpriced) and walk back down the hill to the house.</span></p>
<p class="p1"><span class="s1">One thing I notice very quickly is the altitude and what effect it&rsquo;s having on my body. I&rsquo;m not exceptionally fit, but I&rsquo;m not in terrible shape either, and after five minutes of walking up a slight fradient I am quite severly out of breath. It feels like adifferent out of breath, not the panting, sweaty faced out-of-breathness, such as one Eric Pickles might get after walking up the stairs, no, it&rsquo;s an altogether different sensation, one of clawing at the oxygen in front of you, begging for it to enter your lungs. I&rsquo;ve never experienced this kind of altitude before so I had no idea what it would be like. I assume my body will adjust to it.</span></p>
<p class="p1"><span class="s1">I&rsquo;m back at the house now. After a 23 hour trip, plus walking around, I really want a shower, but alas, the hot water is off until tomorrow morning. I&rsquo;ll have to wait &lsquo;till then. I&rsquo;ve more or less unpacked, set up a desk with my laptop, notepad and camera, as well as the pile of books I hope to get through. There&rsquo;s one power socket in my room and in order for any of my appliances to work I have to prop the plug up with my camera&rsquo;s tripod. It&rsquo;s hilarious.</span></p>
<p class="p1"><span class="s1">Slightly annoyed I&rsquo;ve forgotten my camera cable, but it&rsquo;s not a huge worry as it&rsquo;s a standard microUSB and I&rsquo;m bound to find one in one of the phone shops I saw on my walk. Other than that, the room is homely and the family are hospitable. It&rsquo;ll be dinner soon and I&rsquo;m going to try to catch some sleep before I head off to the volunteering project welcome thing this evening. It would be nice if there are some younger people working with me. It&rsquo;ll be even nicer if they speak English.</span></p>
<p class="p1"><span class="s1">I suppose the perfect candidate would be a 5&rsquo;5 redhead girl who&rsquo;s into books, has strong political opinions and loves Pink Floyd. A guy can dream, right? Knowing me I&rsquo;ll get a smelly, angry, perspiring, bulimic Czech with a bronchial infection and a habit of breaking down in tears of hysteria at the word &ldquo;and&rdquo;. I&rsquo;ll report back as to the team members as the situation develops.</span></p>
<p class="p1"><span class="s1">Now, it&rsquo;s time for a 30 minute kip under the watchful eye of a Jesus Christ clock suspended over my bed. At least Jesus loves me, even if fate and cute redheads don&rsquo;t.</span></p>
<hr />
<p class="p1"><span class="s1">Dinner was lovely. It&rsquo;s 4AM English time so will write more in next entry.</span></p>
<p class="p1"><span class="s1">No redhead.</span></p>
<p class="p1"><em>P.S. I've not been able to get any photos onto my laptop yet, but I'll update this post with the pics when I can.</em></p>]]></content></entry><entry><title>How I Test</title><category term="php"/><category term="testing"/><id>http://jamieonsoftware.com/journal/2012/5/2/how-i-test.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/5/2/how-i-test.html"/><author><name>Jamie Rumbelow</name></author><published>2012-05-02T16:07:51Z</published><updated>2012-05-02T16:07:51Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>It's been over a year since I've wrote the libellous words <a href="http://jamieonsoftware.com/journal/2011/1/2/high-level-testing-php-applications-with-cucumber.html">"One of the things the PHP community has always been crap about is testing"</a>; an annum on and change is really starting to gain momentum. Personally, I'm now programatically testing pretty much every line of code I ship, in some way or another, and I've learnt a lot over the past year about the <em>best ways to test</em>. Others are starting to really see the value of unit testing.</p>

<p>One of the things I've discovered by talking to other developers is that a lot of people lack direction in what to test and how to make it a part of their process. They get the basics, but they struggle to get into the mindset of someone who writes tests. If you don't <strong>get it</strong> chances are <a href="http://www.imgftw.net/img/579399366.png">you're doing it wrong</a>.</p>

<p>Learning the tools is easy. Grabbing <a href="https://github.com/sebastianbergmann/phpunit">PHPUnit</a> off PEAR is a piece of cake, as is setting up a couple of files and running <code>phpunit</code> at your command line. Nowadays, the basic steps of setting up an environment for testing are so few and so effortless, it's child's play. For that reason I don't believe there's much more value in writing another introductory article.</p>

<p>This piece is about the process of testing. It's about test-driven development, how I work when I'm writing code and how writing unit tests gives me smarter, more stable and more refactorable code.</p>

<hr />

<p>Get <a href="https://github.com/sebastianbergmann/phpunit">PHPUnit</a> installed. We're going to write a small PHP class that takes an email request body and parses a bunch of info about it.</p>

<p>Create two new files, <em>email_parser_test.php</em> and <em>email_parser.php</em>. I like to work with these files side by side, so in <a href="http://www.sublimetext.com/2">Sublime Text 2</a> - a great text editor which you should all be using, incidentally - I'll hit Command + Alt + 2 to open my editor up into two columns. This means I can have my tests on the left and my implementation on the right.</p>

<p>Inside our test file, create a new class and a basic test method:</p>

<pre><code>class Email_parser_test extends PHPUnit_Framework_TestCase
{
    public function test_something()
    {
        $this-&gt;assertTrue(true);
    }
}
</code></pre>

<p>Jump into Terminal and give it a run:</p>

<pre><code>$ phpunit --colors email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 2.25Mb

OK (1 test, 1 assertion)
</code></pre>

<p>That <code>--colors</code> flag is going to get annoying, so we'll dump this in a <code>phpunit.xml</code> file:</p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;phpunit colors="true"&gt;&lt;/phpunit&gt;
</code></pre>

<p>There's one tiny little bit more of setup we need to do before we can begin writing proper code. We'll need some test data to work with; an email we know the format of and can reproduce every time. Tests are only valuable if they're consistent. We want two emails to work with; and you'll see why in a moment. I'll use an email I got from good friend <a href="http://httpster.org/">Alex Bilbie</a> about his excellent <a href="https://github.com/alexbilbie/codeigniter-mongodb-library">CodeIgniter MongoDB Library</a>. Save this in a file <em>email.eml</em>:</p>

<pre><code>Delivered-To: jamie@jamierumbelow.net
Return-Path: &lt;alex.bilbie@gmail.com&gt;
Date: Wed, 2 May 2012 01:06:01 +0100
From: Alex Bilbie &lt;alex.bilbie@gmail.com&gt;
To: jamie@jamierumbelow.net
Message-ID: &lt;586B7E1735704A1CB388F4434B4EAA9B@gmail.com&gt;
Subject: =?utf8?Q?Update_to_my_Mongo_library?=
X-Mailer: sparrow 1.5 (build 1043.1)
Content-Type: text/html
MIME-Version: 1.0

I've updated my CodeIgniter MongoDB library to version 0.5.1. It mostly contains bug fixes and optimisations.

Version 2.0 of the library is almost finished – check it out at &lt;a href="https://github.com/alexbilbie/codeigniter-mongodb-library/tree/v2"&gt;https://github.com/alexbilbie/codeigniter-mongodb-library/tree/v2&lt;/a&gt;. I'm currently working out how PHP Unit works so that the library can be tested on Travis CI each time a new commit is made.
</code></pre>

<p>And another one (<em>email2.eml</em>):</p>

<pre><code>Delivered-To: jamie@jamierumbelow.net
Return-Path: &lt;me@jeremygimbel.net&gt;
Date: Wed, 3 May 2012 09:25:55 +0100
From: Jeremy Gimbel &lt;me@jeremygimbel.net&gt;
To: praise@jamierumbelow.net
Message-ID: &lt;109A8F7538567P7VD675E7990N8NDS7T@gmail.com&gt;
Subject: =?utf8?Q?A_quick_note!?=
Content-Type: text/html
MIME-Version: 1.0

Jamie, I love what you're doing with &lt;a href="https://github.com/jamierumbelow/codeigniter-base-model"&gt;MY_Model&lt;/a&gt; and &lt;a href="https://github.com/jamierumbelow/codeigniter-base-controller"&gt;MY_Controller&lt;/a&gt;!
</code></pre>

<p>Now we know everything's working a okay and we've got our test data, we'll waste no more time and get straight on with writing our first test.</p>

<p>Actually, that was a lie. I just want to make three points before we begin:</p>

<ol>
<li>Remember that we should always write the smallest amount of code possible to get the test to pass. That'll become clearer shortly.</li>
<li>We're writing unit tests, so we're testing the input -> output flow of a unit of code (and any side effects)</li>
<li>Your tests should never negatively affect the API. If a parameter is only necessary for the tests, you're doing it wrong.</li>
</ol>

<p>We'll start off by simply parsing the headers out and grabbing them. This is good place to start because we'll need to parse the headers anyway; it's therefore worth our while to test that core functionality first.</p>

<pre><code>public function test_parses_headers()
{
    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email);
    $this-&gt;assertEquals(10, count($parsed['headers']));
}
</code></pre>

<p>The test might be simple, and it certainly doesn't test all the functionality we need to, but that is exactly what we want.</p>

<p>When I test, I find it valuable to write the smallest amount of code to test and the smallest possible amount to get the test past. It doesn't matter what the system needs to do in the future, it's just about <strong>getting the test to past</strong>.</p>

<p>You'll spot that we're accessing <code>$this-&gt;parser</code> and <code>$this-&gt;email</code>. Let's define them:</p>

<pre><code>public function setUp()
{
    $this-&gt;parser = new Email_parser();
    $this-&gt;email = file_get_contents('email.eml');
}
</code></pre>

<p>Run our tests:</p>

<pre><code>$ phpunit email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/jamierumbelow/Sites/email_parser/phpunit.xml

PHP Fatal error:  Class 'Email_parser' not found in /Users/jamierumbelow/Sites/email_parser/Email_parser_test.php on line 7

Fatal error: Class 'Email_parser' not found in /Users/jamierumbelow/Sites/email_parser/Email_parser_test.php on line 7
</code></pre>

<p>What's the smallest amount of code that can fix this error? In our <em>Email</em>parser.php_ file:</p>

<pre><code>class Email_parser { }
</code></pre>

<p>...and require it at the top of our test file:</p>

<pre><code>require_once 'email_parser.php';
</code></pre>

<p>Run again and we get an error about missing <code>parse()</code> method. Define it:</p>

<pre><code>public function parse($email) { }
</code></pre>

<p>Run again and we get an assertion error:</p>

<pre><code>$ phpunit email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/jamierumbelow/Sites/email_parser/phpunit.xml

F

Time: 0 seconds, Memory: 2.75Mb

There was 1 failure:

1) Email_parser_test::test_parses_headers
Failed asserting that 0 matches expected 10.

/Users/jamierumbelow/Sites/email_parser/email_parser_test.php:17

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
</code></pre>

<p>What's the smallest amount of code that we can write to make this test pass?</p>

<pre><code>return array( 'headers' =&gt; array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) );
</code></pre>

<p>You're probably shouting at the screen and telling me I'm an idiot right now, and honestly, I wouldn't blame you. This might seem like a total waste of time. You'll have to bare with me here; you'll soon see why this can become valuable.</p>

<p>Now we've got our test passing, let's add another assertion to it:</p>

<pre><code>public function test_parses_headers()
{
    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email);

    $this-&gt;assertEquals(10, count($parsed['headers']));
    $this-&gt;assertEquals('jamie@jamierumbelow.net', $parsed['headers']['To']);
}
</code></pre>

<p>Got it yet? Nope? Okay, I'll carry on.</p>

<pre><code>$ phpunit email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/jamierumbelow/Sites/email_parser/phpunit.xml

E

Time: 0 seconds, Memory: 2.50Mb

There was 1 error:

1) Email_parser_test::test_parses_headers
Undefined index: To

/Users/jamierumbelow/Sites/email_parser/email_parser_test.php:18

FAILURES!
Tests: 1, Assertions: 1, Errors: 1.
</code></pre>

<p>What's the smallest possible amount of code to fix it? We'll actually cheat a little bit here since we KNOW that once the <code>To</code> index is in the array, it'll ask for the value of <code>jamie@jamierumbelow.net</code>, so we might as well kill two birds with one stone.</p>

<pre><code>return array( 'headers' =&gt; array( 'To' =&gt; 'jamie@jamierumbelow.net', 2, 3, 4, 5, 6, 7, 8, 9, 10 ) );
</code></pre>

<p>Good good. Let's add one more just to ensure we're being thorough:</p>

<pre><code>$this-&gt;assertEquals('&lt;586B7E1735704A1CB388F4434B4EAA9B@gmail.com&gt;', $parsed['headers']['Message-ID']);
</code></pre>

<p>The failure:</p>

<pre><code>1) Email_parser_test::test_parses_headers
Undefined index: Message-ID
</code></pre>

<p>Again, killing two birds with one stone:</p>

<pre><code>return array( 
        'headers' =&gt; array( 'To' =&gt; 'jamie@jamierumbelow.net', 
                            'Message-ID' =&gt; '&lt;586B7E1735704A1CB388F4434B4EAA9B@gmail.com&gt;',
                            3, 4, 5, 6, 7, 8, 9, 10 ) );
</code></pre>

<p>So <strong>WHAT IS THE POINT OF ALL THIS?</strong></p>

<p>What happens when we copy + paste our assertions and run the same test on <em>email2.eml</em> as well?</p>

<p>Update the assertions so that we're checking for the appropriate number of headers and the appropriate values:</p>

<pre><code>public function test_parses_headers()
{
    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email);

    $this-&gt;assertEquals(10, count($parsed['headers']));
    $this-&gt;assertEquals('jamie@jamierumbelow.net', $parsed['headers']['To']);
    $this-&gt;assertEquals('&lt;586B7E1735704A1CB388F4434B4EAA9B@gmail.com&gt;', $parsed['headers']['Message-ID']);

    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email2);

    $this-&gt;assertEquals(9, count($parsed['headers']));
    $this-&gt;assertEquals('praise@jamierumbelow.net', $parsed['headers']['To']);
    $this-&gt;assertEquals('&lt;109A8F7538567P7VD675E7990N8NDS7T@gmail.com&gt;', $parsed['headers']['Message-ID']);
}
</code></pre>

<p>And load our email in our tests' <code>setUp()</code>:</p>

<pre><code>$this-&gt;email2 = file_get_contents('email2.eml');
</code></pre>

<p>Run it:</p>

<pre><code>$ phpunit email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/jamierumbelow/Sites/email_parser/phpunit.xml

F

Time: 0 seconds, Memory: 2.75Mb

There was 1 failure:

1) Email_parser_test::test_parses_headers
Failed asserting that 10 matches expected 9.

/Users/jamierumbelow/Sites/email_parser/email_parser_test.php:24

FAILURES!
Tests: 1, Assertions: 4, Failures: 1.
</code></pre>

<p>Understand the logic yet?</p>

<p>Ahhhhhh. There we go.</p>

<p>Suddenly, we're now in the position where in order to get this test to pass, we're forced to parse the email. In order to get the test passing, we need to implement our test appropriately. Adding in some weird switch as a parameter, although would require less code, detracts from our API (that is to say, it would be pointless in production/implementation code). So the only thing we can really do is actually parse the email.</p>

<pre><code>public function parse($email)
{
    list($headers_list, $body) = explode(PHP_EOL . PHP_EOL, $email, 2);
    $headers_list = explode(PHP_EOL, $headers_list);

    $headers = array();
    foreach ($headers_list as $h)
    {
        list($key, $value) = explode(':', $h, 2);
        $headers[$key] = trim($value);
    }

    return array( 'headers' =&gt; $headers );
}
</code></pre>

<p>This does two great things. It makes our tests pass:</p>

<pre><code>$ phpunit email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/jamierumbelow/Sites/email_parser/phpunit.xml

.

Time: 0 seconds, Memory: 2.50Mb

OK (1 test, 6 assertions)
</code></pre>

<p>...and it has the fortunate side effect of providing us with the body, parsed and separated out nice and easily!</p>

<p>While it's good that that's already done for us, it's currently untested, so let's fix that posthaste:</p>

<pre><code>public function test_parses_body()
{
    $expected_body_email = "I've updated my CodeIgniter MongoDB library to version 0.5.1. It mostly contains bug fixes and optimisations.\n\nVersion 2.0 of the library is almost finished – check it out at &lt;a href=\"https://github.com/alexbilbie/codeigniter-mongodb-library/tree/v2\"&gt;https://github.com/alexbilbie/codeigniter-mongodb-library/tree/v2&lt;/a&gt;. I'm currently working out how PHP Unit works so that the library can be tested on Travis CI each time a new commit is made.";
    $expected_body_email2 = 'Jamie, I love what you\'re doing with &lt;a href="https://github.com/jamierumbelow/codeigniter-base-model"&gt;MY_Model&lt;/a&gt; and &lt;a href="https://github.com/jamierumbelow/codeigniter-base-controller"&gt;MY_Controller&lt;/a&gt;!';

    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email);
    $this-&gt;assertEquals($expected_body_email, $parsed['body']);

    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email2);
    $this-&gt;assertEquals($expected_body_email2, $parsed['body']);
}
</code></pre>

<p>And making this pass is now just a matter of adding the <code>$body</code> variable to the return line:</p>

<pre><code>return array( 'headers' =&gt; $headers, 'body' =&gt; $body );
</code></pre>

<p>So. We have our headers and we have our body. While cool, it's not very useful. Let's try to extract the subject.</p>

<p>For those of you who know the MIME protocol, you'll know that the subject field is usually encoded in some way. This is conventionally <a href="http://en.wikipedia.org/wiki/MIME#Encoded-Word">Q-encoding or Base64</a>. PHP's <em>iconv</em> extension provides a great little function for decoding MIME headers: <code>iconv_mime_decode</code>.</p>

<p>Let's write a test:</p>

<pre><code>public function test_subject()
{
    $parsed = $this-&gt;parser-&gt;parse($this-&gt;email);
    $this-&gt;assertEquals('Update to my Mongo library', $parsed['subject']);
}
</code></pre>

<p>To get it passing:</p>

<pre><code>return array( 'headers' =&gt; $headers, 'body' =&gt; $body, 'subject' =&gt; 'Update to my Mongo library' );
</code></pre>

<p>Expand the tests:</p>

<pre><code>$parsed = $this-&gt;parser-&gt;parse($this-&gt;email2);
$this-&gt;assertEquals('A quick note!', $parsed['subject']);
</code></pre>

<p>And we can implement the function to get the tests to pass:</p>

<pre><code>$subject = iconv_mime_decode($headers['Subject']);

return array( 'headers' =&gt; $headers, 'body' =&gt; $body, 'subject' =&gt; $subject );
</code></pre>

<p>And there we have it!</p>

<pre><code>$ phpunit email_parser_test.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /Users/jamierumbelow/Sites/email_parser/phpunit.xml

...

Time: 0 seconds, Memory: 2.50Mb

OK (3 tests, 10 assertions)
</code></pre>

<p>It's a simple piece of code and a simple test suite, but hopefully this article has clarified <em>how</em> I test and why I believe this process to be truly valuable.</p>
]]></content></entry><entry><title>Open source (pour over pasta)</title><category term="addons"/><category term="codeigniter"/><category term="ellislab"/><category term="elsewhere"/><category term="expressionengine"/><category term="mojoblog"/><category term="programming"/><id>http://jamieonsoftware.com/journal/2012/4/30/open-source-pour-over-pasta.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/4/30/open-source-pour-over-pasta.html"/><author><name>Jamie Rumbelow</name></author><published>2012-04-30T20:46:49Z</published><updated>2012-04-30T20:46:49Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I've been making a real effort to tidy up my open source portfolio recently; getting issues closed, code tidied up, unit test suites written and on the fantastic <a href="http://travis-ci.org">Travis</a>&nbsp;and people happier!</p>
<p>As part of this transition, I've decided to retire Sparkplugs and open source the code.&nbsp;Big changes are happening in my professional and personal life over the next few months and I feel it would be disingenuous to pretend that I could carry on supporting and developing my formerly commercial add-ons. After all, there haven&rsquo;t been any updates to my add-ons for a while now, and support has been flakey.&nbsp;The honest truth is I lost my passion.</p>
<p>But onto bigger and better things!</p>
<p>Exciting things are going on over at my GitHub page (<a href="http://getsparkplugs.com/?URL=https%3A%2F%2Fgithub.com%2Fjamierumbelow">https://github.com/jamierumbelow</a>). You&rsquo;ll find my two most popular CodeIgniter libraries, <a href="https://github.com/jamierumbelow/codeigniter-base-model">MY_Model</a> and <a href="https://github.com/jamierumbelow/codeigniter-base-controller">MY_Controller</a>. You'll find a recent experiment with node.js, <a href="https://github.com/jamierumbelow/postmaster">Postmaster</a>, an SMTP testing server I'm remarkably proud of.&nbsp;</p>
<p>Also, you'll find the source to Sparkplugs' two commercial add-ons, <a href="https://github.com/jamierumbelow/taggable">Taggable</a>&nbsp;and <a href="https://github.com/jamierumbelow/mojoblog">MojoBlog</a>.&nbsp;I&rsquo;m sure I&rsquo;ll still be involved and am happy to answer any support questions through the issue trackers on the GitHub repositories.</p>
<p>It's an exciting time to be in open source and I've realised that I enjoy the atmosphere so much more than the pressures of a commercial add-on retailer.</p>
<p><a href="https://github.com/jamierumbelow">So go on. Check out my GitHub profile :)</a></p>]]></content></entry><entry><title>The CodeIgniter Handbook - Volume 1 - Available!</title><category term="books"/><category term="codeigniter"/><category term="php"/><category term="ruby"/><id>http://jamieonsoftware.com/journal/2012/2/23/the-codeigniter-handbook-volume-1-available.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/2/23/the-codeigniter-handbook-volume-1-available.html"/><author><name>Jamie Rumbelow</name></author><published>2012-02-23T02:48:18Z</published><updated>2012-02-23T02:48:18Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><a href="http://codeigniterhandbook.com">I am utterly thrilled to announce that my new book, The CodeIgniter Handbook Volume 1, is now available for order!</a></p>

<p>Volume 1, Who Needs Ruby? is a pragmatic, succinct guide to improving your efficiency and the cleanness of your code. Attractive to amateurs and professionals alike, The CodeIgniter Handbook isn't your usual programming book. It's short, useful and easy to read, and covers how to improve the quality of your code and the speed of your development time.</p>

<p>It's available to buy as a print book or an eBook. It's also much cheaper than most programming books, at only £12 (roughly $18) for the print book and £6 ($10) for the eBook.</p>

<p>I've had some great feedback already -- everyone appears to be enjoying it! Thanks for your support.</p>

<p><a href="http://codeigniterhandbook.com">Purchase the CodeIgniter Handbook today!</a></p>
]]></content></entry><entry><title>Happier Shelling</title><category term="unix"/><id>http://jamieonsoftware.com/journal/2012/2/6/happier-shelling.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/2/6/happier-shelling.html"/><author><name>Jamie Rumbelow</name></author><published>2012-02-06T15:26:52Z</published><updated>2012-02-06T15:26:52Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I've just added something to my <strong>~/.profile</strong> file that has made me much happier when moving around in Terminal / the UNIX shell. If you're anything like me, you forget where you put things and what directories look like.</p>

<p>In order to cure this ailment, I re-defined the <code>cd</code> command and got it to list the contents of a directory every time I change directories. It's nice to have a constant reminder of how unorganised I am.</p>

<p>If you'd like to have this sweetness, add this to your <strong>~/.profile</strong>:</p>

<pre><code>cd () {
  builtin cd "$*"
  ls -al
}
</code></pre>

<p>Then, either re-open your Terminal window or run <code>$ source ~/.profile</code> to load it into the shell. Happy cding!</p>
]]></content></entry><entry><title>Syntax Sugar #5 - A Quick CodeIgniter Caching Helper Function</title><category term="codeigniter"/><category term="memcached"/><category term="syntax sugar"/><id>http://jamieonsoftware.com/journal/2012/1/7/syntax-sugar-5-a-quick-codeigniter-caching-helper-function.html</id><link rel="alternate" type="text/html" href="http://jamieonsoftware.com/journal/2012/1/7/syntax-sugar-5-a-quick-codeigniter-caching-helper-function.html"/><author><name>Jamie Rumbelow</name></author><published>2012-01-07T17:45:31Z</published><updated>2012-01-07T17:45:31Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Caching your data in CodeIgniter? Good. You should be.</p>

<p>I use <a href="http://memcached.org/">memcached</a> lots. CI has <a href="http://codeigniter.com/user_guide/libraries/caching.html">a fantastic caching driver</a> built in (as of 2.0). Normally, the code you'll write looks like this:</p>

<pre><code>$accounts = $this-&gt;cache-&gt;memcached-&gt;get('user.' . $user_id . '.accounts');

if (!$accounts)
{
    $accounts = $this-&gt;db-&gt;where('user_id', $user_id)-&gt;get('accounts')-&gt;results();
    $this-&gt;cache-&gt;memcached-&gt;save('user.' . $user_id . '.accounts', $accounts);
}

$this-&gt;load-&gt;view('accounts/index', array( 'accounts' =&gt; $accounts ));
</code></pre>

<p>However this quickly becomes repetitive, boring and cluttering. With a bit of PHP5.3 magic, we can create a really nice little caching helper function that cleans this code up in no time:</p>

<pre><code>function cache($key, $data) {
    $CI =&amp; get_instance();
    $cache = $CI-&gt;cache-&gt;memcached-&gt;get($key);

    if (!$cache) {
        // There's been a miss, so run our data function and store it
        $cache = $data($CI);
        $CI-&gt;cache-&gt;memcached-&gt;save($key, $cache);
    }

    return $cache;
}
</code></pre>

<p>Now, our cluttered caching code becomes a commendable concoction of coding culinary craft:</p>

<pre><code>$accounts = cache('user.' . $user_id . '.accounts', function(&amp;$ci){
    return $ci-&gt;db-&gt;where('user_id', $user_id)-&gt;get('accounts')-&gt;results();
});
</code></pre>

<p>The anonymous method you pass through will only be executed if the cache misses (i.e. there's no data under that key, or it has expired). It will be saved into the cache and return. Delicious.</p>
]]></content></entry></feed>
