<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2247246257923129702</id><updated>2011-12-13T09:52:15.209Z</updated><category term='users'/><category term='education'/><category term='teeth'/><category term='futurology'/><category term='Question engine'/><category term='weird analogy'/><category term='refactoring'/><category term='education technology'/><category term='patterns'/><category term='Statistics'/><category term='music'/><category term='Open University'/><category term='Students'/><category term='conductors'/><category term='Mathematica'/><category term='software development'/><category term='contentEditable'/><category term='GSOC'/><category term='bug tracker'/><category term='Plagiarism'/><category term='git'/><category term='Wolfram'/><category term='family'/><category term='strange hobbies'/><category term='OU'/><category term='marketing'/><category term='unit testing'/><category term='NHS'/><category term='dentist'/><category term='Quizzes'/><category term='project management'/><category term='Moodle'/><category term='version control'/><category term='JavaScript'/><category term='empathy'/><category term='Computation'/><category term='busses'/><category term='FLOSS'/><title type='text'>Tim's blog</title><subtitle type='html'>Occasional musings about Moodle, Music, Go and whatever else comes to mind.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-79651631671186635</id><published>2011-09-27T00:10:00.000+01:00</published><updated>2011-09-27T00:10:05.612+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='Quizzes'/><category scheme='http://www.blogger.com/atom/ns#' term='Question engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='education technology'/><title type='text'>What I want to build next</title><content type='html'>&lt;p&gt;Earlier this summer I finally finished the new Moodle question engine, which was released as part of Moodle 2.1. As you might expect with such a large change, a number of minor bugs were not spotted until after the release, but I (and others) have fixed quite a lot of them, and we will continue to fix more. I want to say "thank you" to everyone who has taken the time to report the problems they encountered. Pleasingly, some people, including Henning Bostelmann, Tony Levi, Pierre Pichet, Jamie Pratt, Joseph Rézeau and Jean-Michel Vedrine have not only been sending in bug reports, but also submitting bug fixes. I would like to thank them in particular. I don't know whether this means that the new &lt;a href="http://docs.moodle.org/dev/Process"&gt;Moodle development processes&lt;/a&gt; are working well and encouraging more contributors, or that I released the new question engine full of trivial bugs.&lt;/p&gt;&lt;p&gt;At the moment, apart from fixing bugs, we are about two months away from the end of the OU's one-year project to move from Moodle 1.9 to 2.x and implement a lot of new features at the same time. In the eAssessment area, we had about 30 work-packages to do, of which finishing the question engine was by far the biggest, and we have about 6 left to go. Most of the remaining tasks are at least started, but finishing them is what I, and the developers on my team, will be doing in the near future.&lt;/p&gt;&lt;p&gt;I have, however, been thinking ahead a bit, and I have an idea for what I would like to build, should I be given the opportunity. Honesty compels me to say these are not my ideas. I stole them from other people, and there are proper acknowledgements at the end of this post. I wanted to post about this because: 1. in my experience, if you post about your half-baked ideas, people will be able to suggest ways to make them better; and 2. I am hoping that at least one course-team at the OU will see this and say "we would love to use this in our teaching" because that might persuade the powers that be to let me build this.&lt;/p&gt;&lt;h4&gt;Rationale&lt;/h4&gt;&lt;p&gt;&lt;img border="0" width="320" style="margin-left: 1em; float: right; clear: right;" src="http://2.bp.blogspot.com/-xpV90YvLTKQ/ToDs3NMvpxI/AAAAAAAAGdU/tN6MlhIJxhk/s1600/view.png" /&gt;The Moodle quiz is a highly structured, teacher-controlled tool for building activities where students attempt questions. What I want to create is a more open activity where students can take charge of their learning using a bank of questions to practice some skill where the computer can mark their efforts and give feedback. For the sake of argument, I have been calling this the "Question practice" activity module.&lt;/p&gt;&lt;h4&gt;The entry page&lt;/h4&gt;&lt;p&gt;When a student goes into a Question practice activity, they see a front screen that lists all the categories in the question bank for this activity.&lt;/p&gt;&lt;p&gt;Next to each category, there are statistics for how the student has performed on that category so far. For example, it might say "recently you scored 19/21 (90%); all time you scored 66/77 (86%).” The categories are nested, and there is a subtotal for each category.&lt;/p&gt;&lt;p&gt;At the bottom of the page is an &lt;b&gt;Attempt some questions…&lt;/b&gt; button. This takes the student to the …&lt;/p&gt;&lt;h4&gt;Start a session form&lt;/h4&gt;&lt;p&gt;&lt;img border="0" width="320" style="margin-left: 1em; float: right; clear: right;" src="http://4.bp.blogspot.com/-8nU7pUJ8PU4/ToDtCOHtJDI/AAAAAAAAGdY/reGmetTju8E/s1600/start.png" /&gt;… where they set up what practice they would like to do. Students can select which categories they want to attempt questions from. They may also be able to choose how many questions they want. For example "Give me 10 questions", "As many as possible in 20 minutes", or "Keep going until I say stop". The teacher will probably be able to constrain the range of options available here.&lt;/p&gt;&lt;p&gt;Once they are satisfied, the they clicks the "Start session" button. This takes them to the …&lt;/p&gt;&lt;h4&gt;Attempt page&lt;/h4&gt;&lt;p&gt;&lt;img border="0" width="320" style="margin-left: 1em; float: right; clear: right;" src="http://4.bp.blogspot.com/-avQ_viZK0Rw/ToDtJlk47uI/AAAAAAAAGdc/qcVRQkWFZeg/s1600/attempt.png" /&gt;… which shows the student the first question, chosen according to the criteria they set. There will probably be a display of running statistics "In this session you have attempted 0 questions so far". The question will contain the controls necessary for attempting the question. There will also probably be a "Please stop, I'm bored" button, so the student can leave at any time.&lt;/p&gt;&lt;p&gt;When they get back to the front page, the statistics will have been updated.&lt;/p&gt;&lt;p&gt;If the student crashes out of a session, then when they go back in, the front page will have a "Continue current session" button.&lt;/p&gt;&lt;h4&gt;Overall activity log&lt;/h4&gt;&lt;p&gt;One batch of attempting questions will be called a 'practice session'. The system will keep track of all the sessions that the student has done, and what they achieved during each session.&lt;/p&gt;&lt;p&gt;The front page will have a link to a page that lists all of the student's sessions, showing what they achieved in each. This provides more detail than is visible on the front page.&lt;/p&gt;&lt;h4&gt;Possible extensions&lt;/h4&gt;&lt;p&gt;That is the key idea. Here are some further things that could be added to the basic concept.&lt;/p&gt;&lt;h4&gt;Milestones&lt;/h4&gt;&lt;p&gt;The system could recognise targets, goal, or achievement (I'm not sure of the best name). That would be something like "Attempt more than 10 questions from the Hard category, and score more than 90%". If the student achieves that target at any time, they system would notice, and the achievement would be recorded on the front page and in the session log in an ego-boosting way (e.g. a medal icon).&lt;/p&gt;&lt;p&gt;The whole point of this activity is to be as student-driven as possible, so should students be able to define their own targets or goals? Should students be able to set goals for each other?&lt;/p&gt;&lt;h4&gt;Locks / Conditional access&lt;/h4&gt;&lt;p&gt;The activity could also have locks, so that the student cannot access the questions in the Multiplication category until after they have scored more than 80% in the Hard addition category. Of course, unlocking a new category could be an achievement. We appear to be flirting with the gamification buzz-word here, so I will stop.&lt;/p&gt;&lt;h4&gt;Performance comparison&lt;/h4&gt;&lt;p&gt;Should there by any way for students to compare their performance, or achievements, with their peers? We are definitely getting to features that should be left until version 2.0. Let's get a basic system working first, but make sure it is extensible.&lt;/p&gt;&lt;h4&gt;How hard would this be to build&lt;/h4&gt;&lt;p&gt;I think this would not require too much work because a lot of the necessary building blocks already exist in Moodle. The question bank already handles questions organised into categories, and we would just use that. Similarly, the attempt page and practice sessions are very easy to manage with the new question engine.&lt;/p&gt;&lt;p&gt;The real work is in two places. First, building the start attempt form, and then writing the code that randomly selects questions based on the options chosen. Second, deciding what statistics to compute, and then writing the code to compute them.&lt;/p&gt;&lt;p&gt;Of course, before we can start writing any code, there are still a lot of details of the design to decide. Also one most not forget things like backup and restore, creating the database, and all the usual Moodle plumbing.&lt;/p&gt;&lt;p&gt;Overall, I think it would take a few months work to get a really useful activity built.&lt;/p&gt;&lt;h4&gt;Credit where credit is due&lt;/h4&gt;&lt;p&gt;I said earlier that I got most of these ideas from other people. To start with, things like this have been mooted in the &lt;a href="http://moodle.org/mod/forum/view.php?id=737"&gt;Moodle quiz forum&lt;/a&gt; over the years. The discussions there usually start from Computerised Adaptive Testing, whereas this idea is about student-driven use of questions. I think the latter is more interesting. (As a mathematician, I think CAT is an interesting concept. I just don't think it would make a useful Moodle activity.)&lt;/p&gt;&lt;p&gt;The real inspiration for this came at a meeting in London at the start of 2011. That meeting was at UCL with Tony Gardiner-Medwin who has already &lt;a href="http://www.ucl.ac.uk/lapt/"&gt;built a system something like this&lt;/a&gt;, but stand-alone, not in Moodle; and David Emmett from University of Queensland, Brisbane (who was &lt;a href="http://blogs.ucl.ac.uk/ltss/tag/david-emmett/"&gt;giving a seminar&lt;/a&gt;). David had been hoping to get a grant to build something like this proposal (in Moodle) but that did not pan out. We did, however, have a very interesting discussion, and that is where I got the key idea that this sort of question practice was most interesting if you could give the student control of their own learning as much as possible.&lt;/p&gt;&lt;p&gt;We have also discussed ideas like this on-and-off for a long time at the OU. There has, however, been a lot of other things we needed to deal with first. We had to do a lot of work getting the quiz system working to our satisfaction (a strand of work that eventually lead to the new question engine). We had to sort out the reporting of grades, including working with &lt;a href="http://moodle.com/hq/"&gt;Moodle HQ&lt;/a&gt; on the new gradebook in Moodle 1.9, and integrating Moodle with our student information system. We had to make a new question types that our users wanted. Only now can we start to think seriously about the last piece of the jigsaw: more activities that use all the question infrastructure we have built. I hope this post is a useful starting point for discussing what one of those activities might be.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-79651631671186635?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/79651631671186635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/09/what-i-want-to-build-next.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/79651631671186635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/79651631671186635'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/09/what-i-want-to-build-next.html' title='What I want to build next'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-xpV90YvLTKQ/ToDs3NMvpxI/AAAAAAAAGdU/tN6MlhIJxhk/s72-c/view.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-8806063551948626931</id><published>2011-08-06T14:37:00.001+01:00</published><updated>2011-08-08T17:06:55.035+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='contentEditable'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><title type='text'>The Good, the Bad and the Ugly</title><content type='html'>&lt;p&gt;It was the best of times, it was the worst of times, ... It has certainly been a mixed week.&lt;/p&gt;&lt;h4&gt;The good&lt;/h4&gt;&lt;p&gt;... was that I helped three OU developers submit their first bug fix through the new &lt;a href="http://docs.moodle.org/dev/Process"&gt;Moodle development process&lt;/a&gt;: &lt;a href="http://tracker.moodle.org/browse/MDL-27631"&gt;MDL-27631&lt;/a&gt;, &lt;a href="http://tracker.moodle.org/browse/MDL-28517"&gt;MDL-28517&lt;/a&gt; and &lt;a href="http://tracker.moodle.org/browse/MDL-28620"&gt;MDL-28620&lt;/a&gt;. Hopefully those fixes all get through integration review next week.&lt;/p&gt;&lt;h4&gt;The Bad&lt;/h4&gt;&lt;p&gt;... was that the time had finally come to deal with a hot potato that we have been tossing around for some months; and, to mix metaphors, when the buck stopped, I was in the the wrong place at the wrong time.&lt;/p&gt;&lt;p&gt;As part of some new question types we are developing, we want students to be able to type responses that include superscripts and subscripts. For example &lt;b&gt;3×10&lt;sup&gt;8&lt;/sup&gt; ms&lt;sup&gt;-1&lt;/sup&gt;&lt;/b&gt; or &lt;b&gt;SO&lt;sub&gt;4&lt;/sub&gt;&lt;sup&gt;2-&lt;/sup&gt;&lt;/b&gt;. We have an old implementation of this, done six years ago for OpenMark (for example &lt;a href="http://www.open.ac.uk/openmarkexamples/p2_4.shtml"&gt;this&lt;/a&gt; or &lt;a href="http://www.open.ac.uk/openmarkexamples/p3_3.shtml"&gt;this&lt;/a&gt;), but that never worked in Safari, and is a bit dodgy generally. We want a new, reliable implementation that works in IE, Firefox, Chrome and Safari.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Plan A&lt;/b&gt;: back near the start of spring, I quickly knocked up a partial solution using the &lt;a href="http://developer.yahoo.com/yui/2/"&gt;YUI 2&lt;/a&gt; Rich Text Editor library. It mostly worked, but there were issues. It did not work consistently across browsers, and it lets you nest superscripts inside subscripts inside superscripts which just gets confusing, so we want to prevent that.&lt;/p&gt;&lt;p&gt;I had a sneaking suspicion how hard it would be to get from my quick partial solution to a robust implementation. Therefore I moved on to other things, and tried to unload this job onto three other people in turn. There were plenty of other more urgent tasks on our todo list.&lt;/p&gt;&lt;p&gt;Time passed, and many of the other things got done, so at the start of the week I realised that creating this input widget could not be put off any longer. I also felt it was unfair to expect other developers to deal with a crappy job that I was not prepared to do myself, so I decided to have another go.&lt;/p&gt;&lt;p&gt;The other thing that had changed is that while attempting to implement this, &lt;a href="http://colchambers.blogspot.com/"&gt;Colin&lt;/a&gt; and Wale had both eliminated some blind alleys, and suggested some promising ideas. Therefore, I was continuing from a far better place than where I left off. Even so, it was a long week.&lt;/p&gt;&lt;h4&gt;The Ugly&lt;/h4&gt;&lt;p&gt;&lt;b&gt;Plan B&lt;/b&gt;: Although we had a partial implementation in YUI 2, I did not want to continue with that. Moodle is trying to move away from YUI 2 and to YUI 3 as soon as possible. So, my first attempt was to use the &lt;a href="http://developer.yahoo.com/yui/3/editor/"&gt;YUI 3(.3) Rich Text Editor&lt;/a&gt;. As the docs make clear. That is not finished yet. It is also not terribly well documented. With hindsight, I now realise that it provides only a very thin rapper around the native editing facilities provided by web browsers. Therefore it does not really help with browser inconsistencies.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Plan C&lt;/b&gt;: Since the Rich Text Editor is only beta, I decided to have a look at what was new in YUI 3.4, which is due for release soon. The answer is that they have made quite a lot of progress - in the sense that if you are trying to walk from London to Edinburgh, you have made quite at lot of progress &lt;a href="http://maps.google.com/maps?q=from:London+to:Milton+Keynes+to:Leeds+to:Brampton,+UK+to:Edinburgh&amp;saddr=London&amp;daddr=Milton+Keynes+to:Leeds+to:Brampton,+UK+to:Edinburgh&amp;hl=en&amp;ll=53.566414,-1.647949&amp;spn=7.39018,14.282227&amp;sll=54.908988,-2.647018&amp;sspn=0.213552,0.44632&amp;geocode=FXjUEQMd5BL-_yl13iGvC6DYRzGZKtXdWjqWUg%3BFdgZGgMdRD_1_ymFhiOC-Ex2SDEUfrlM950aFg%3BFUZ9NQMdG4np_ymZvWTaSj55SDGp3BMC_bqtUQ%3BFZFZRgMd8TfW_yltrGVMSAF9SDE1WU8_nC9tSw%3BFWC7VQMdsFzP_ykjJpilALiHSDEnF-d8exTyZA&amp;dirflg=w&amp;doflg=ptk&amp;t=h&amp;z=6"&gt;by the time you reach Milton Keynes&lt;/a&gt;. Compounded with the fact that it is hard to find any documentation for pre-release version of YUI, this approach also failed.&lt;/p&gt;&lt;p&gt;At this point, I decided to do a bit of reading. I found &lt;a href="http://dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-1/"&gt;two excellent&lt;/a&gt; &lt;a href="http://dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-2/"&gt;articles from Opera&lt;/a&gt; that explained exactly how &lt;tt&gt;contentEditable&lt;/tt&gt; works in web browsers. I also found a good &lt;a href="http://www.quirksmode.org/dom/execCommand.html"&gt;cross-browser compatibility table&lt;/a&gt;. That made me realise that YUI was hardly doing anything to help with cross-browser differences.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Plan D&lt;/b&gt;: Now that I knew roughly what the browsers were doing, I briefly toyed with the idea of implementing the widget entirely myself in plain JavaScript. Once again, getting something basic working was not too hard, but I had not even started to tackle the cross-browser differences.&lt;/p&gt;&lt;p&gt;Then I realised that &lt;a href="http://www.tinymce.com/"&gt;TinyMCE&lt;/a&gt;, which Moodle uses, tends to work really well across browsers. It is a bit slow to load, because it is a huge mass of code, but perhaps all that code is there for a reason. A quick play with superscript and subscript in the Moodle HTML editor in various browsers confirmed that TinyMCE must be working around most of the problems. So I dived into the TinyMCE code with the original idea of stealing the bits I needed to make Plan D work. It did not take much looking for me to develop a new-found respect for how hard TinyMCE is working to keep different web browsers in line. I did not want to have to replicate all that.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Plan E&lt;/b&gt;: So I finally concluded I should just use TinyMCE directly. That is using a very large sledge-hammer to crack a nut, but at least it should work. Indeed, it was mostly just a matter of setting the right configuration options. What made it particularly good is that there is &lt;a href="http://www.tinymce.com/wiki.php/Configuration:valid_children"&gt;an option to limit which tags can be nested inside other tags&lt;/a&gt;. That robustly prevents people from nesting superscript inside subscript, etc.&lt;/p&gt;&lt;p&gt;I was very nearly there, but there were two more requirements. We did not want pressing enter to insert a line-break, and because we were only dealing with a single line of input, we wanted to use the up and down arrow keys as shortcuts for superscript and subscript. The only way I could find to do that was to write a simple TinyMCE plugin. Fortunately, &lt;a href="http://www.tinymce.com/wiki.php/Creating_a_plugin"&gt;that is well documented&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;The end&lt;/h4&gt;&lt;p&gt;I got there eventually. &lt;a href="https://github.com/timhunt/moodle-editor_supsub"&gt;The code&lt;/a&gt; needs to be cleaned up, tested some more, and integrated into the question types we are building, but I don't foresee any problems doing that.&lt;/p&gt;&lt;p&gt;I would like to thank the &lt;a href="http://www.moxiecode.com/"&gt;Moxie Code&lt;/a&gt;, who make TinyMCE, even though they have completely ignored &lt;a href="http://www.tinymce.com/develop/bugtracker_view.php?id=3789"&gt;the patch I sent them&lt;/a&gt; some time ago in relation to &lt;a href="http://tracker.moodle.org/browse/MDL-27890"&gt;MDL-27890&lt;/a&gt;. I would also like to thank Olav Junker Kjær, who wrote the Oracle blog posts, which were the most useful thing I read. Also, the team behind &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt;. I can't imagine doing JavaScript development without that debugging tool. Finally Colin, Wale and Jamie, who I tried to dump this on, and who in return gave me helpful ideas.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-8806063551948626931?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/8806063551948626931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/08/good-bad-and-ugly.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8806063551948626931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8806063551948626931'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/08/good-bad-and-ugly.html' title='The Good, the Bad and the Ugly'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-7965443711752024310</id><published>2011-07-07T00:31:00.000+01:00</published><updated>2011-07-07T00:31:04.527+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='OU'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><title type='text'>Keeping the discipline of not changing Moodle core</title><content type='html'>&lt;p&gt;&lt;a href="http://learn.open.ac.uk/mod/oublog/viewpost.php?post=51014"&gt;We have said in the past&lt;/a&gt; that at the OU we made too many changes to core code in our Moodle 1.9 system, and that as we moved to Moodle 2, we would make far fewer. The release of Moodle 2.1 provides a good opportunity to stop and reflect on how we are doing.&lt;/p&gt;&lt;p&gt;Exactly how many core changes we had made in 1.9 seems to depend on who you ask. It was something of the order of one or two thousand depending on how you count. As a result, every time there is a new Moodle 1.9.x release, someone (Derek) has to do a couple of days painstaking merging to upgrade to the new version.&lt;/p&gt;&lt;p&gt;Moodle 2.1 was released on Friday. On Monday afternoon we decided to try upgrading our development branch to it. The merge (literally &lt;tt&gt;git merge MOODLE_21_STABLE&lt;/tt&gt;) only took a few hours, and that was most mostly a matter of thinking before typing &lt;tt&gt;git checkout --theirs&lt;/tt&gt; to resolve most of the conflicts in favour of the Moodle 2.1 code. Then we had to test test install, upgrade, and basic functionality before pushing the merge to our central repository.&lt;/p&gt;&lt;p&gt;But, how many OU-specific changes do we have in core code right now? Well, the answer appears to be eight. Let me explain that number.&lt;/p&gt;&lt;p&gt;To control the core code changes, we use a simple approval procedure. Each change must be proposed by one of the leading developers. They do this by opening a special sort of ticket in our issue tracking system. That serves as a permanent record of the change, and is also a place to log any discussion. The other leading developers then review the proposal. For the change to be approved, at least one other leading developer must endorse it with a +1 vote, and there must not be any -1 votes. Votes are normally accompanied by an explanation of why that developer is voting that way.&lt;/p&gt;&lt;p&gt;After a suitable time for votes, the issue is declared either accepted or rejected. OU-specific changes can be rejected for two reasons.We may decide that it is not acceptable to change core to implement this feature, so we drop the feature; or we think of some devious way to achieve the feature without changing core code.&lt;/p&gt;&lt;p&gt;If a change is approved, then the code is written. Well, in some cases the code will already have been written, because you can have a much more informed debate about whether a certain change is a good idea if you can see exactly what the proposed change is. Once the code is written and approved, it is committed to out git repository and the issue moves into state 'Code committed'. Finally, we may find a way to get rid of the OU-specific change in future. The most common way that happens is if we contribute the change upstream to moodle.org. For example the new Moodle question engine was an ou-specific change as long as we were using it in Moodle 2.0, but now we have upgraded to Moodle 2.1, it is standard code. Therefore, that issue has now changed status to 'No longer required'.&lt;/p&gt;&lt;p&gt;Overall, our we, have 22 ou-specific change issues in our bug tracker. The break-down is:&lt;/p&gt;&lt;p&gt;Rejected: 2&lt;br /&gt;New (under discussion): 4&lt;br /&gt;Approved (but not yet implemented): 1&lt;br /&gt;Code committed: 8&lt;br /&gt;No longer required: 7&lt;/p&gt;&lt;p&gt;Most of the 'Code committed' changes are pretty boring. For example three of them are bug-fixes to the questionnaire module that we have submitted upstream, but which have not been reviewed and accepted by the questionnaire maintainers yet. Therefore, those three will almost certainly end up as 'No longer required' in due course. Another example is that we want to customise the "Database connection failed / It is possible that the database is overloaded or otherwise not running properly" page that you get when Moodle fails to connect to the database. If Moodle can't connect to the database, then it cannot load the configuration, and so cannot determine which theme to use to display the error. Therefore, the only way customise that page is to edit lib/setup.php.&lt;/p&gt;&lt;p&gt;The one 'serious' ou-specific change we have is some hacking around in course/lib.php to support one of our custom modules called 'subpage' (not released yet, but we hope to share it eventually). Given more time, we might be able to find a more elegant way to handle these changes, but we don't have that sort of time at the moment.&lt;/p&gt;&lt;p&gt;While we have controlled the core code changes, we do have written a lot of custom plugins. Those range from big things like forumng and ouwiki, to small things like a local plugin that just implements a single web-service function. I'm afraid I don't have a complete list, but we must have more than 50 plugins by now. As far as I am aware, the upgrade from 2.0 to 2.1 did not break any of them.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-7965443711752024310?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/7965443711752024310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/07/keeping-discipline-of-not-changing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7965443711752024310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7965443711752024310'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/07/keeping-discipline-of-not-changing.html' title='Keeping the discipline of not changing Moodle core'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-7470310591228442503</id><published>2011-04-12T09:25:00.001+01:00</published><updated>2011-04-12T09:25:47.827+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Question engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='weird analogy'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><title type='text'>Performance and Scalability</title><content type='html'>&lt;p&gt;When you set up a web application, often you will start small with everything running on one server. Everything, in this case, typically means the application and the database and data files. That is nice and simple. It has the advantage that everything it fast because it is all one the one server.&lt;/p&gt;&lt;p&gt;The capacity is, however, limited. Suppose the load on your application increases. You can get some way just by upgrading the one server, adding more memory and faster processors, but that will only get you so far.&lt;/p&gt;&lt;p&gt;Eventually, you will have to scale out. You will get a number of separate web servers, with a load-balancer to distribute the incoming requests between them. All the web servers will connect to a shared database sever, or cluster of database servers. The files will probably go on a separate file server.&lt;/p&gt;&lt;p&gt;While this increases the total load that the whole system can support, it means, paradoxically, that processing a single request is slower. For example, if you switch from one server to three servers (application server, database and files) your site will not support three times as many users. The scalability will not be linear. That is because every connection to the database or to get a file now has to travel over the network. Accessing something across a network tends to be an order of magnitude slower than accessing something on the same server.&lt;/p&gt;&lt;p&gt;The above is all standard knowledge about scaling web applications. I have been thinking about about it recently because it explains the way my working life has been evolving. Just over six months ago I was working essentially on my own, &lt;a href="http://docs.moodle.org/en/Development:Question_Engine_2"&gt;re-developing the Moodle question engine&lt;/a&gt;. I had been working away like that for a year, and I had got a lot done.&lt;/p&gt;&lt;p&gt;Since then, things have changed, and I am now managing a team including three other developers, and two out-sourced development contracts. It has been particularly 'bad' this last couple of weeks as one development period of the project came to an end and I had to review a lot of code, and then I had to sort out everything we were supposed to be doing for the next three months. I am starting to wonder if I will every get any of my own development work done at all!&lt;/p&gt;&lt;p&gt;That is, however, just some exasperation showing. I know really that this has just been a brief spell with an excessive amount of administration. Overall I am happy that the OU is investing so much in its eAssessment systems (and the other parts of its VLE); as a team we are achieving more than I could on my own; but right now my inner geek would really like to go and hide in a cave for a while and just write code undisturbed.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-7470310591228442503?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/7470310591228442503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/04/performance-and-scalability.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7470310591228442503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7470310591228442503'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/04/performance-and-scalability.html' title='Performance and Scalability'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-5061382580783288985</id><published>2011-03-09T23:26:00.000Z</published><updated>2011-03-09T23:26:18.739Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='bug tracker'/><category scheme='http://www.blogger.com/atom/ns#' term='Quizzes'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><title type='text'>Moodle bug tracker</title><content type='html'>&lt;p&gt;Today, between fixing bugs and reviewing code, I spent a bit of time tinkering with my dashboard in the Moodle bug tracker. I was trying to make it as clear as possible which issues need my attention. I am quite pleased with the result:&lt;/p&gt;&lt;p&gt;&lt;img src="https://lh5.googleusercontent.com/-5R_2dhm2sAY/TXgAdAboBsI/AAAAAAAAFoI/-CmCHfEsQL8/s1600/tracker.png" alt="tracker screen grab"/&gt;&lt;/p&gt;&lt;p&gt;The issue statistics widget does not just show you the pretty graphs, it also makes it easy to get at those issues. For example, if I click on &lt;b&gt;1.9.12&lt;/b&gt; in the &lt;b&gt;My targetted issues&lt;/b&gt; box, then I am taken to a list of those 11 issues. That particular widget I have used for a while, the new parts are the boxes just under there.&lt;/p&gt;&lt;p&gt;&lt;b&gt;My: Ongoing pull requests&lt;/b&gt; I added to make it easy to find the things I have submitted for inclusion in next week's weekly build (hopefully). Thanks to Eloy, that filter is now available to everyone in the jira-developers group.&lt;/p&gt;&lt;p&gt;The next two boxes let me quickly get to issues with patches attached. There is an emerging convention of adding the label &lt;b&gt;patch&lt;/b&gt; to such issues, where the attached code needs to be reviewed. This makes finding such issues very much easier. The whole point of the new &lt;a href="http://docs.moodle.org/en/Development:Process"&gt;development processes&lt;/a&gt; is to encourage more people to contribute patches, and then ensure those patches get looked at, rather than just sitting there for years. (Here is an example I found yesterday of what used to happen: &lt;a href="http://tracker.moodle.org/browse/MDL-13983"&gt;MDL-13983&lt;/a&gt;). Therefore, as quiz maintainer, I need to be able to see easily if anyone has submitted any relevant patches. I also want easy access to bugs with patches that I created or commented on.&lt;/p&gt;&lt;p&gt;Having brought it up, can I say that I am quite happy with how the new processes are working so far. My impression is that since they were introduced, I have received more usable bug fixes for the quiz that in the past. I am not sure how much causality one can claim there, however, since as well as the new processes, we also had the Moodle 2.0 release. Moodle 2.0 has plenty of minor bugs that are ripe for fixing. So, it may just be that we are seeing lots of bug fixes because there are lots of bugs.&lt;/p&gt;&lt;p&gt;At the other end, it has made it a bit easier to get my code reviewed. Well, finished code where I have created a PULL request certainly gets is reviewed. It is still sometimes a problem to get comments on work-in-progress, because everyone is so busy.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-5061382580783288985?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/5061382580783288985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/03/moodle-bug-tracker.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/5061382580783288985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/5061382580783288985'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/03/moodle-bug-tracker.html' title='Moodle bug tracker'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-5R_2dhm2sAY/TXgAdAboBsI/AAAAAAAAFoI/-CmCHfEsQL8/s72-c/tracker.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-5145563549951578405</id><published>2011-02-23T01:31:00.001Z</published><updated>2011-02-23T10:30:48.941Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='OU'/><category scheme='http://www.blogger.com/atom/ns#' term='Question engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='education technology'/><title type='text'>Etiquette for questions</title><content type='html'>&lt;p&gt;I have been working hard at converting the &lt;a href="http://tjhunt.blogspot.com/2010/10/introducing-new-moodle-question-engine.html"&gt;new Moodle question engine&lt;/a&gt; to work in Moodle 2.0, aiming at a deadline this Friday (25th February). On Friday we should have a first OU version of Moodle 2.0 with all the key features so that we can start testing, even though students won't get onto the new system before July. I have have basically finished the question engine, give or take a few features that are not needed for testing, and this week I am just doing some final tidying up of the code.&lt;/p&gt;&lt;p&gt;Hopefully, next week I can start the process of getting it reviewed for inclusion in Moodle 2.1. As I say, there are some gaps in the functionality that will need to be filled in before it can actually be committed, but there is a lot of code to be reviewed (lucky Eloy!) and so I hope we can kick off the process.&lt;/p&gt;&lt;p&gt;So, my excuse for not blogging about the new question engine recently is that I have been too busy working on it to write about it. In the last few days, however, I encountered a couple of nice ideas that would be easy to implement using the flexibility the new question engine gives, and I want to describe them. First, I need to remind you of one key point about the new system:&lt;/p&gt;&lt;h4&gt;Question behaviours&lt;/h4&gt;&lt;p&gt;&lt;img src="http://3.bp.blogspot.com/-QwAf_ZgvnKE/TWRhWlwqTZI/AAAAAAAAFnY/69P4GbRdsTE/s1600/behaviour.png" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"/&gt;As &lt;a href="http://tjhunt.blogspot.com/2010/10/new-question-engine-how-it-works.html"&gt;I explained before&lt;/a&gt; a key idea in the new question engine is that of question behaviours. Whereas a question type lets you have either a multiple-choice, a drag and drop, or a short-answer question, a behaviour controls how the student interact with the questions, of whatever type. For example, the student may have to type in answers to each question in the quiz, then submit everything, and only then are the questions marked. This is known as the "Deferred feedback" behaviour. Alternatively, the student may answer one question, have their answer marked immediately. If they are wrong, they get a hint and can then immediately have another go. If they get it right on the second or third try, they get fewer marks. This is called the "Interactive with multiple tries" behaviour.&lt;/p&gt;&lt;p&gt;When I was first working on this, I did wonder whether it was perhaps over-kill to make behaviours fully-fledged Moodle plugins. It seemed to me that I had already implemented all the types of behaviour anyone was likely to want. It turns out I was wrong. Here are three ideas for new behaviours have I have come across since had that naive thought.&lt;/p&gt;&lt;h4&gt;Explain your thinking behaviour&lt;/h4&gt;&lt;p&gt;The concept here is that, in addition to presenting the question to the student for them to answer in the usual way, you also give them a text-area with the prompt "Explain your answer". When the submit the question is graded as usual. Moodle does not do anything with the explanation, other than to store it, and re-display it later when the student or their teacher reviews their attempt. The point is that the student should reflect upon and articulate their thought processes, and the teacher can then see what they wrote, which might be useful for diagnosing what problems the students are having.&lt;/p&gt;&lt;p&gt;I'm not sure that this would really work. Would the students really bother to write thoughtful comments if there were no marks to be had? However, this would be relatively easy to implement, so we should build it and see what happens in practice. The teacher could always manually adjust the marks based on the quality of the reflection, if that was necessary to incentivise students.&lt;/p&gt;&lt;p&gt;I'm afraid I cannot remember who suggested this idea. It was a post in the &lt;a href="http://moodle.org/mod/forum/view.php?id=737"&gt;Moodle quiz forum&lt;/a&gt; some time ago, just after I had implemented the behaviour concept and was thinking that my initial list of behaviours was all anyone could possibly want.&lt;/p&gt;&lt;h4&gt;gnikram desab-ytniatreC&lt;/h4&gt;&lt;p&gt;This idea I only came across yesterday evening, in &lt;a href="http://www.open.ac.uk/blogs/terg/?p=400"&gt;a blog post from people in the OU's technology faculty&lt;/a&gt;. It is a slightly strange twist on &lt;a href="http://www.ucl.ac.uk/lapt/"&gt;certainty-based marking&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;With classic CBM, the students answers the questions, and also says how certain they are they got it right (for example, on a three-point scale). The student will only get full marks if they get the question right, and are very certain that they were right. If, however, they express high certainty and are wrong, they are penalised heavily with a big negative mark. To maximise their score, the student must accurately gauge their level of knowledge. This hopefully promotes reflection, and self awareness by the student of their level of knowledge.&lt;/p&gt;&lt;p&gt;The idea from the OU technology faculty is to do this backwards, for multiple choice questions. Rather than getting the student to answer the question and then select a certainty, you first show them just the question stem without the choices, and get them to express a certainty. Only then do you show them the choices and let them chose what they think is the right answer.&lt;/p&gt;&lt;p&gt;Again, I am not sure if this would work, but it is sufficiently easy to do by creating a new behaviour plug-ing (and a some change to the multiple-choice question type so that you can output just the question, without the choices) that it has to be worth a try.&lt;/p&gt;&lt;h4&gt;Free text responses with a chance to act on feedback&lt;/h4&gt;&lt;p&gt;This last idea I only heard about this morning. There was a session of the OU's "eLearning community" all about eAssessment, which naturally I attended. This is a monthly gathering with a number of different presentations on some eLearning topic. The first three talks were about specific courses that have recently adopted eAssessment, and how students had engaged with that, what effect the effect had been on retention and pass rates, and so on. That was interesting, but not what I want to talk about here. The final talk was by &lt;a href="http://iet.open.ac.uk/people/d.m.whitelock"&gt;Denise Whitelock&lt;/a&gt; from the OU's Institute of Educational Technology who has just completed a review of recent research into technology-enhance assessment for &lt;a href="http://www.heacademy.ac.uk/"&gt;HEA&lt;/a&gt; that should be published soon. Here, I just want to pick up on one specific idea from her talk.&lt;/p&gt;&lt;p&gt;I'm afraid that again, I don't recall who deserves credit for this idea. (Once Denise's review is published, I will have a proper reference, but I did not take notes this morning.) It was another UK university that had done this. It was in the context of language teaching. The student had to type a sentence in answer to the question, then the computer graded that attempt and gave some feedback. Then, the student was immediately allowed to revise their sentence in light of the feedback, and get it re-marked. The final grade for the question is then a weighed sum of the first mark and the second mark. You need to get the weights right. The weight for the first try has to be big enough that the student tries hard to get the question right on their own before seeing the hints, and the weight for the second try, though smaller, also has to be big enough so that the student bothers to revise their response.&lt;/p&gt;&lt;p&gt;Now, the OU is currently creating a Moodle question type that can automatically grade sentence length answers using &lt;a href="http://docs.moodle.org/en/The_OU_PMatch_algorithm"&gt;an algorithm&lt;/a&gt; that my colleague Phil Butcher implemented the first version of in 1978! (When I say we are creating this, what I actually mean is that we have contracted &lt;a href="http://jamiep.org/"&gt;Jamie Pratt&lt;/a&gt; a free-lance Moodle developer to implement it to our specification.) Anyway, once you have that, the idea of allowing two tries, with feedback after the first try, and a final grade that is a weighted sum  of the marks for the two tries, is just another behaviour.&lt;/p&gt;&lt;p&gt;So, my initial thought that people would not have many ideas for interesting new behaviours seems to have been wrong. The flexibility I built into the system is worth having.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-5145563549951578405?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/5145563549951578405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/02/etiquette-for-questions.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/5145563549951578405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/5145563549951578405'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/02/etiquette-for-questions.html' title='Etiquette for questions'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-QwAf_ZgvnKE/TWRhWlwqTZI/AAAAAAAAFnY/69P4GbRdsTE/s72-c/behaviour.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-3315734571566448300</id><published>2011-02-09T14:00:00.003Z</published><updated>2011-02-09T14:07:01.920Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='education technology'/><category scheme='http://www.blogger.com/atom/ns#' term='futurology'/><title type='text'>Should you listen to futurologists?</title><content type='html'>Educause just published their &lt;a href="http://www.educause.edu/ELI/PressReleases/2011HorizonReportonEmergingTec/223140"&gt;annual survey describing "six areas of emerging technology that will have significant impact on higher education and creative expression over the next one to five years"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This got circulated round the team at work and I rather cynically asked "so, what did they predict last year then?" My colleague Pete Mitton took that question and ran with it to produce the following analysis:&lt;br /&gt;&lt;blockquote&gt;OK, as I have a full set of Horizon Reports on my hard disk, here's a summary of their predictions for the years 2004-11.&lt;br /&gt;&lt;br /&gt;I've pushed some titles together where the wording is different but the intent is the same (for example they've used mobile computing/mobiles/mobile phones in the past with the same meaning).&lt;br /&gt;&lt;br /&gt;The numbers in the table are the time-to-adoption horizon in years.&lt;/blockquote&gt;&lt;table border="1" style="border-collapse:collapse;"&gt;&lt;thead&gt;&lt;tr&gt;  &lt;th&gt;&lt;/th&gt;  &lt;th scope="col"&gt;2004&lt;/th&gt;  &lt;th scope="col"&gt;2005&lt;/th&gt;  &lt;th scope="col"&gt;2006&lt;/th&gt;  &lt;th scope="col"&gt;2007&lt;/th&gt;  &lt;th scope="col"&gt;2008&lt;/th&gt;  &lt;th scope="col"&gt;2009&lt;/th&gt;  &lt;th scope="col"&gt;2010&lt;/th&gt;  &lt;th scope="col"&gt;2011&lt;/th&gt; &lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;User-created content&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Social Networking&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Mobiles&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Virtual Worlds&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;New Scholarship and Emerging forms of publication&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Massively Multiplayer Educational Gaming&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Collaboration Webs&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Mobile Broadband&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Data Mashups&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Collective Intelligence&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Social Operating Systems&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Cloud Computing&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;The Personal Web&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Semantic-Aware Applications&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Smart Objects&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Open Content&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Electronic Books&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Simple Augmented Reality&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Gesture-based computing&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Visual Data Analysis&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Game-based learning&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Learning analytics&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Learning Objects&lt;/th&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Scaleable Vector Graphics&lt;/th&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Rapid Prototyping&lt;/th&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Multimodal Interfaces&lt;/th&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Context Aware Computing aka Geostuff&lt;/th&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Knowledge Webs&lt;/th&gt;  &lt;td&gt;4-5&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Extended Learning&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Ubiquitous Wireless&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;1&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;  &lt;th scope="row" style="text-align: left;"&gt;Intelligent Searching&lt;/th&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;2-3&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt;  &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Of course, the purpose of a report like this is not to accurately predict the future. The aim is rather to stimulate informed debate about the technologies that are coming up. Within our team, at least, they seem to have succeeded.&lt;br /&gt;&lt;br /&gt;I thought, however, that this analysis was interesting enough to share. It provides some context for year's predictions. More generally it shows how difficult it is predict future technology trends.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-3315734571566448300?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/3315734571566448300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2011/02/should-you-listen-to-futurologists.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/3315734571566448300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/3315734571566448300'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2011/02/should-you-listen-to-futurologists.html' title='Should you listen to futurologists?'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-8196137787738661985</id><published>2010-11-02T17:39:00.001Z</published><updated>2010-11-02T17:58:22.334Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='FLOSS'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='marketing'/><title type='text'>How (not) to sell your open source development services</title><content type='html'>&lt;p&gt;It must be terrible trying to sell software development services if you work in Open Source. The restrictions of the GPL appear to make it almost impossible to demonstrate your previous work to prospective clients. I would like to offer the following advice, which is my attempt to distil what appears to be current best practice in dealing with this tricky situation.&lt;/p&gt;&lt;p&gt;Do not make it possible for your potential client to find any examples of code you have written. If you cannot avoid it completely, make it as difficult for them as possible. For example, if you have created a certain sort of plugin, just say "We have created a new Moodle block." Do not give any clues as to which block that might be. If the open source project provides &lt;a href="http://moodle.org/mod/data/view.php?id=6009"&gt;a convenient place&lt;/a&gt; to &lt;a href="http://cvs.moodle.org/"&gt;upload and share your contributions&lt;/a&gt;, try to avoid making any code you have produced easy to find there. Even if you have been forced to share your code in these places, do not on any account provide your potential client with a link to the example of work that you are most proud of. It is fairer to let them search and find a representative sample of your work, if they are clever and patient enough to do so.&lt;/p&gt;&lt;p&gt;Your development staff are, or course, all faceless drones who are nothing to be proud of. Your potential client does not care who will actually be doing the work they are requesting. This is particularly important when the open source project has a strong community. It must not be possible to identify your staff in the &lt;a href="http://moodle.org/mod/cvsadmin/view.php"&gt;recognised list of project contributors&lt;/a&gt;; nor should it be easy to discover how they have contributed to the on-going development of the project's code by looking in the project's &lt;a href="http://tracker.moodle.org/secure/Dashboard.jspa"&gt;issue tracker&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It is important is to dress your proposal up in meaningless marketing-speak. If your client cannot complete their buzzword bingo card while reading your document, they just won't hire you. Including a PowerPoint presentation with impressive diagrams and more platitudes about your company can create a particularly strong impression.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-8196137787738661985?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/8196137787738661985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/11/how-not-to-sell-your-open-source.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8196137787738661985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8196137787738661985'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/11/how-not-to-sell-your-open-source.html' title='How (not) to sell your open source development services'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-1077058727367941023</id><published>2010-10-20T23:31:00.000+01:00</published><updated>2010-10-20T23:31:45.513+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Quizzes'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Question engine'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><title type='text'>The new question engine - how it works</title><content type='html'>&lt;p&gt;In &lt;a href="http://tjhunt.blogspot.com/2010/10/introducing-new-moodle-question-engine.html"&gt;my last blog post&lt;/a&gt; I promised more details of the new question engine "in a week or so". Unfortunately, things like work (mainly fixing minor bugs in the aforementioned question engine); rehearsing for &lt;a href="http://www.open.ac.uk/wikis/ouocmc/Orchestra_concerts"&gt;a rather good concert that will take place this Friday&lt;/a&gt;; and buying curtains for my new flat, have been rather getting in the way. Now is the time to remedy that.&lt;/p&gt;&lt;p&gt;Last time I explained roughly what a question engine was, and that I had made big changes to the one in Moodle. I now want to say more about what the question engine has to do, and how the new one does it.&lt;/p&gt;&lt;h4&gt;The key processes&lt;/h4&gt;&lt;p&gt;There are three key code-paths:&lt;/p&gt;&lt;p&gt;To display a page of the quiz:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;i&gt;Load the outline data about the student's attempt.&lt;/i&gt; &lt;/li&gt;&lt;li&gt;&lt;i&gt;Hence work out which questions are on this page.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Load the details of this student's attempt at those questions within this quiz attempt.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Get the display settings to use (should the marks, feedback, and so on be visible to this user).&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Taking note of the state of each question (from Step 3) update the display options. For example, if the student has not answered the question yet, we don't want to display the feedback now, even if we will later.&lt;/li&gt;&lt;li&gt;Using the details of the current state of each question, and the relevant display options, output the HTML for the question.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The bits in &lt;i&gt;italic&lt;/i&gt; are the bits done by the quiz. The rest is done by the question engine.&lt;/p&gt;&lt;p&gt;To start a new attempt at the quiz:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;i&gt;From the list of questions in the quiz, work out the layout for this attempt. (This is only really interesting if you are shuffling the order of the questions, or selecting questions randomly.)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Create an initial state for&amp;nbsp;each question in the quiz attempt. (This is when things like the order of multiple choice options are randomised.)&lt;/li&gt;&lt;li&gt;Write the initial states to the database.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To process a student's responses to a page of the quiz.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;From the submitted data, work out which attempt and questions are affected.&lt;/li&gt;&lt;li&gt;Load the details of the current state of those question attempts.&lt;/li&gt;&lt;li&gt;Sort all the submitted data, into the bits belonging to each question. (The bits of data have names like 'q188:1_answer'. The prefix before the '_' identifies this as data belonging to the first question in attempt 188, and the bit after the '_' identifies this as the answer to that question.)&lt;/li&gt;&lt;li&gt;For each question, process its data to work out whether the state has changed and, if so, what the new state is. This is really the most important procedure, and I will talk more about it in the next section.&lt;/li&gt;&lt;li&gt;Write any updated states to the database.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Update the overall score for the attempt, if appropriate, and store it in the database.&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These outlines are, of course, oversimplifications. If you really want to know what happens, you will have to read the code.&lt;/p&gt;&lt;p&gt;There are other processes which I will not cover in detail. These include finishing a quiz attempt, re-grading an attempt, fetching data in bulk for the quiz reports, and deleting attempts.&lt;/p&gt;&lt;h4&gt;The most important procedure&lt;/h4&gt;&lt;p&gt;This is the step where we take the data submitted by the student for one particular question and use it to update the state of that question.&lt;/p&gt;&lt;p&gt;Moodle has long had the concept of different questions types. It can handle short-answer questions, multiple-choices questions, matching questions, and so on. Naturally, what happens when updating the state of the question depends on the question type. That is true for both the old and new code.&lt;/p&gt;&lt;p&gt;Now, however, there is a new concept in addition to question types. The concept of 'question behaviours'.&lt;/p&gt;&lt;p&gt;In previous versions of Moodle, there was a rather cryptic setting for the quiz: Adaptive mode, Yes/No. That affected what happened as the student attempted the quiz. When adaptive mode was off, the student would go through the quiz entering their response to each question. Those responses were saved. At the end, they would submit the quiz and everything would be marked, all at once. Then the student could review their attempt (either immediately, or later, depending on the quiz settings) to see their marks and the feedback. When adaptive mode was on, the student could submit each question individually during the attempt. If they were right first time, they got full marks. If they were wrong, the got some feedback and could try again for reduced marks.&lt;/p&gt;&lt;p&gt;The problem with the previous version of Moodle was the way this was implemented. There was a single process_responses function that was full of code like "if adaptive mode, do this, else do that". It was a real tangle. It was very common to change the code to fix a bug in adaptive mode (for example), only to find that you had broken non-adaptive mode. Another problem was the essay question type, which has to be graded manually by the teacher. It did not really follow either adaptive or non-adaptive mode, but was still processed by the same code. That lead to &lt;a href="http://docs.moodle.org/en/Development:Question_Engine_2:Rationale#Correctness_issues"&gt;bugs&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;A very important realisations in the design of the new question engine was identifying this concept of a 'question behaviour' as something that could be isolated. There is now a behaviour called 'Deferred feedback' that works like the old non-adaptive mode; there is an 'Adaptive' behaviour; and there is a 'Manually graded' behaviour specially for the essay question type. Since these are now separate, you can alter one without risking breaking the others. Of course, the separate behaviours still share common functions like 'save responses' or 'grade responses'. We now also have a clean way to add new behaviours. I made a '&lt;a href="http://www.ucl.ac.uk/lapt/"&gt;certainly-based marking&lt;/a&gt;' behaviour, and a behaviour called 'Interactive', which is a bit like the old Adaptive mode but modified to work exactly how the Open University wants.&lt;/p&gt;&lt;h4&gt;It takes two to tango, and three to process a question&lt;/h4&gt;&lt;p&gt;In order to do anything, there now has to be a three-way dance between the core of the question engine, the behaviour and the question type. Does this just replace the old tangle with a new tangle (of feet)? Fortunately there is a consistent logic. The request arrives at the question engine. The question engine inspects it, and passes it on to the appropriate behaviour. The behaviour inspects it in more detail, to work out exactly what need to be done. For example is the student just saving a response, or are they submitting something for grading. The behaviour then asks the question type to do that specific thing. All this leads to a new state that is passed back to the question engine.&lt;/p&gt;&lt;p&gt;So, the flow of control is question engine -&gt; behaviour -&gt; question type except, critically, in one place. When we start a new attempt, we have to choose which behaviour to use for each question. At this point the question engine directly asks the question type to decide. Normally, the question type will just say "use whatever behaviour the quiz settings ask for", but certain question types, like the essay, can instead say "I don't care about the quiz settings, I demand the manual grading behaviour."&lt;/p&gt;&lt;p&gt;If you like software design patterns, you can think of this as a double application of the strategy pattern. The question engine uses a behaviour strategy, which uses a question type strategy (with the subtlety that the choice of behaviour strategy is made by the question type).&lt;/p&gt;&lt;h4&gt;Summary&lt;/h4&gt;&lt;p&gt;So that is roughly how it works. A clear separation of responsibility between three separate components. Each component focussing on doing one aspect of the processing accurately, which makes the system highly extensible, robust and maintainable. Of course, everyone says that about the software they design, but based on my experiences over the last year, first of building all the parts of the system, and then of fixing the bugs that were found during testing, I say it with some confidence.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-1077058727367941023?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/1077058727367941023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/10/new-question-engine-how-it-works.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/1077058727367941023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/1077058727367941023'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/10/new-question-engine-how-it-works.html' title='The new question engine - how it works'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-4427702828289642412</id><published>2010-10-05T23:24:00.003+01:00</published><updated>2010-10-06T14:53:42.161+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='Quizzes'/><category scheme='http://www.blogger.com/atom/ns#' term='OU'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><title type='text'>Introducing the new Moodle question engine</title><content type='html'>The rest of the (Moodle) world is eagerly anticipating &lt;a href="http://docs.moodle.org/en/Moodle_2.0_release_notes"&gt;Moodle 2.0&lt;/a&gt;, but I would like to tell you about what I have been doing for most of the last year, but which you won't be able to have until Moodle 2.1 - unless, that is, you are a student or teacher with the Open University, in which case you will be using it from this December.&lt;br /&gt;&lt;br /&gt;What I have done is to rewrite a large chunk of the Moodle quiz system. What chunk is that? Well, first you can split a quiz system into two main parts. There is the quiz part, which says, "This quiz comprises these questions, and will be open to students between these dates". It tracks the student and they attempt the quiz, and stores their total score. Then there is the part that deals with the details of the individual questions within each quiz.&lt;br /&gt;&lt;br /&gt;The question part can again be split in two. There is the question bank which lets the teacher create and store questions. For example "This is a multiple choice question where the student must select one of these three options, and it is an 'Elementary maths' question." Then there is the code that controls what happens when a student attempts a question "The student sees three radio buttons and a Submit button, and when they click the button we compute a score as follows and show this feedback." That second bit is what I call the question engine, and that is what I have rewritten.&lt;br /&gt;&lt;br /&gt;However, you cannot just change the question engine in isolation. There are knock-on effects. For example, the quiz module still maintains overall control of things, even though it delegates a lot of the details to the question engine. So there are places where the quiz says things like "Dear question engine, please display this question now", or "Dear question engine, the student submitted this data, please process it", or "Dear question engine, the teacher wants to see all students responses to all questions in this quiz, give me the data to display." All those places have to change when the question engine changes. &lt;br /&gt;&lt;br /&gt;There were also small changes required to the question bank. mainly because the new question engine has some new features that need some extra options stored with each question. So, the question bank needs to store the new options; let teachers edit them; back them up and restore them; import them and export them; and so on.&lt;br /&gt;&lt;br /&gt;Altogether, my year's work added about 52,000 lines of new code and removed about 25,000 lines of old code (or, if you prefer, added 27,000 lines and altered 25,000 lines). At least that is the size of the change that I committed to the OU's CVS server last Friday, just in time to make the feature-freeze for the December update of our VLE. For comparison, the whole of Moodle 2.0 is &lt;a href="https://www.ohloh.net/p/moodle/analyses/latest"&gt;about 1,600,000 lines of code&lt;/a&gt;, although that includes several large third-party libraries.&lt;br /&gt;&lt;br /&gt;I am sure that there will be some minor bugs still to be found and fixed, but this new code has already had extensive testing from my colleagues Phil Butcher and Paul Johnson, so I am confident that the remaining bug-fixes will be minor.&lt;br /&gt;&lt;br /&gt;There is much more I want to write about the new question engine, but I think this introductory post is already long enough. Therefore, I will split the remainder of what I want to say into separate posts which I hope to publish over the next week or so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-4427702828289642412?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/4427702828289642412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/10/introducing-new-moodle-question-engine.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/4427702828289642412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/4427702828289642412'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/10/introducing-new-moodle-question-engine.html' title='Introducing the new Moodle question engine'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-143657014551245410</id><published>2010-09-14T23:11:00.000+01:00</published><updated>2010-09-14T23:11:01.804+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teeth'/><category scheme='http://www.blogger.com/atom/ns#' term='users'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='empathy'/><category scheme='http://www.blogger.com/atom/ns#' term='dentist'/><category scheme='http://www.blogger.com/atom/ns#' term='NHS'/><title type='text'>On the other side of the fence</title><content type='html'>&lt;p&gt;I've been having problems with my teeth recently. Fortunately, none of it has been painful, but cycling home from yet another dentist's appointment this afternoon, I suddenly had a thought that the experience I was having with my dentist might be a bit like the experience of a non-developer who encounters a bug in the Moodle quiz. Allow me to explain.&lt;/p&gt;&lt;p&gt;I think it has been a total of four trips to the dentist over the summer. First I went for  a regular check-up. That revealed that one of my fillings was cracked, so there was another appointment to drill it out and redo it. Then a filling in another tooth fell out one Friday evening, so I could not get anything done about it until the following week, and over the weekend a bit of the tooth next to the hole broke off, which was really worrying. (Luckily, as I said above, it was not painful.) So anyway, that required a big filling to fill the resulting hole. Then part of the new filling broke off, so today's appointment was to re-do the missing bit. Hopefully that remedial fix will work. If the new bit breaks off again, I will have to go back to have the whole filling drilled out and redone.&lt;/p&gt;&lt;p&gt;With all this going on, I fear I have been starting to have unkind thoughts like: "Is my dentist competent?" "Should so many things go wrong over a few months?" "How do I know if this is normal?". This is exacerbated by what appears to me to be a slightly casual attitude on her part. I expect that these really are routine problems, and rather boring to her. I, however, am worried, so I would have appreciated a more concerned-seeming bedside manner.&lt;/p&gt;&lt;p&gt;As I say, it was just after I had climbed on my bike to go back to work this afternoon, that I had the epiphany that this is probably how someone feels when they come to the Quiz forum after encountering a problem in one of their Moodle quizzes. To them it seems like some terrible problem that has them really concerned. They describe their symptoms, and I read it and think "oh yes, the problem is probably in that bit of code, let me do a quick fix." And then maybe I screw up and introduce a regression, but when that is pointed out, it too is easily fixed. To me it seems like some routine and minor matter, but I have never really thought how the process of fixing bugs feels to someone who is not a software developer, and who does not really understand what is going on. Will they still trust Moodle?&lt;/p&gt;&lt;p&gt;Now that I have thought about it, will I do anything? I fear I am unlikely to change my 'bedside manner'. My time seems to be more than taken up with actually doing the bug fixes, and other development, to spend too much time being nice to people. Still, I will try to make a bit more effort in future know I now how it feels to be on the other side of the situation.&lt;/p&gt;&lt;p&gt;Before finishing, allow me to point out (particularly to American readers) that all these trips to the dentist have cost me very little or nothing. In particular, the two recent appointments to replace the filling that had (partly) fallen out cost me nothing. Thank you NHS. I hope the new government does not cut you to death.&lt;/p&gt;&lt;p&gt;While I am writing, I will also share the news that I finally bought an apartment of my own over the summer, after years of renting. It is very nice, and worth the hassles of dealing with solicitors. Hopefully now that the stresses of dealing with the move are behind me I can concentrate more on Moodle development, although there are still a few minor things to deal with like getting some more furniture. Over the weekend I ordered some new sofas, including some bright orange cushions. I can't think where I got the idea for such a daring colour ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-143657014551245410?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/143657014551245410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/09/on-other-side-of-fence.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/143657014551245410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/143657014551245410'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/09/on-other-side-of-fence.html' title='On the other side of the fence'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-15717185789483152</id><published>2010-07-09T22:33:00.001+01:00</published><updated>2010-08-02T10:59:09.092+01:00</updated><title type='text'>Book review: Moodle 1.9 Extension Development</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://moodle.org/file.php/1/moddata/data/55/259/3796/4244_MockupCover_1.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://moodle.org/file.php/1/moddata/data/55/259/3796/4244_MockupCover_1.jpg" width="259" /&gt;&lt;/a&gt;&lt;/div&gt;It is a book that the community has needed for a long time, &lt;a href="http://moodle.org/mod/data/view.php?d=55&amp;amp;rid=3796"&gt;a book that tells you how to write Moodle code&lt;/a&gt;. Now it is finally here. Does it live up to expectations?&lt;br /&gt;&lt;br /&gt;Yes, I think it does. The authors, Mike Churchward and Jonathan Moore, are two experienced Moodle developers (they both work for Canadian Moodle Partner &lt;a href="http://www.remote-learner.net/leadership"&gt;Remote Learner&lt;/a&gt;) so they can write authoritatively on the subject.&lt;br /&gt;&lt;br /&gt;One issue with a book like this is that the examples given are, necessarily, fairly basic. To illustrate key techniques and ideas, a book must explain using the simplest example that makes the point. The question is, when you come to solving real problems, will the techniques you have learned expand to cope? Well, this is where the experience of the authors counts. They are telling you the right way to do things that works for real applications, even if they are only using simple examples to illustrate them.&lt;br /&gt;&lt;br /&gt;The book does a thorough job of covering just about every type of Moodle plugin there is. Of course, some plugin types get more space than others, with the two most important, blocks and activity modules getting the most space. Therefore, some other plugin types, like question types, and gradebook plugins, are covered rather briefly.&amp;nbsp;Between the chapters on the different types of plugins are chapters on more general topics like security, accessing the database, and so on.&lt;br /&gt;&lt;br /&gt;Anyone who has had code reviewed by me will know that I get really pedantic when I review something. As I was reading the book I made a list of minor errors, or points where I disagreed with the authors. From the 300 pages of the book, I only found 22 things to put on my list, and none of them are interesting enough to mention here. (I did send the list to Jonathan.) So, I think this book has a very high standard of accuracy.&lt;br /&gt;&lt;br /&gt;This book does assume you already know how to program in PHP, and write HTML and CSS. I think that was the right decision. There are plenty of excellent books out there that will teach you to write general web application in PHP, and it would be silly to duplicate those in a book that is uniquely about writing code for Moodle.&lt;br /&gt;&lt;br /&gt;It is unfortunate timing that this book was released only a few months before Moodle 2.0. Moodle 2.0 does change quite a lot of the rules for how to do Moodle development, and so a lot of the details in the book will soon be out of date. However, don't let that stop you from getting this book. We have just talked about how this book helps you make the jump from being a general PHP developer to being specifically a Moodle (1.9) developer. Well, from there to being a Moodle 2.0 developer is just another small step. You won't be wasting much time if you learn about Moodle 1.9 first, and anyway, some people will still be running Moodle 1.9 for some time to come, and it will be a while before there is a book about Moodle 2.0 development on sale.&lt;br /&gt;&lt;br /&gt;This should go without saying, but programming is an activity that you actually need to do to understand. You won't become an expert Moodle programmer just be reading a book. You will become a Moodle programmer by actually trying to write Moodle code, and learning from your own mistakes, and from the code other people have written in the past. What a book like this will do for you is that it will help you avoid a lot of the really basic mistakes, and it will set you off on the right path. So it will make your own learning-by-doing much more efficient, but I cannot replace the doing. Also, I would like to point out that while this is the only &lt;b&gt;book&lt;/b&gt; about Moodle development, it is certainly not the only resource to help you learn Moodle development. If you are interested in this book, you should also look at the &lt;a href="http://docs.moodle.org/en/Development:Developer_documentation"&gt;Developer documentation on Moodle Docs&lt;/a&gt;&amp;nbsp;and the&amp;nbsp;&lt;a href="http://dev.moodle.org/"&gt;Introduction to Moodle Programming course on&amp;nbsp;http://dev.moodle.org/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Overall, if you want to learn Moodle development, this is a good book to help you attain your goal. Sure, you can get a lot of the information for free online, but in this book the authors set it out clearly and in a logical order. The information in this book has been written by expert Moodle developers and then carefully reviewed, so you can read the book without being on your guard for misinformation. You would have to be more careful just using the information Google finds for you online. So, as I say, this book lives up to expectations. If you want a book on Moodle development, get this one, and don't worry too much about Moodle 2.0 making it out-of-date.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-15717185789483152?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/15717185789483152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/07/book-review-moodle-19-extension.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/15717185789483152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/15717185789483152'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/07/book-review-moodle-19-extension.html' title='Book review: Moodle 1.9 Extension Development'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-5729267637281333536</id><published>2010-06-09T23:59:00.011+01:00</published><updated>2010-06-10T10:46:26.759+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='Wolfram'/><category scheme='http://www.blogger.com/atom/ns#' term='Computation'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='Statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='Mathematica'/><title type='text'>Computational Knowledge</title><content type='html'>I spent today at the &lt;a href="http://www.computationalknowledge.org.uk/"&gt;London Computational Knowledge Summit&lt;/a&gt;. A rather pretentious name for a meeting organised by Wolfram about &lt;a href="http://www.wolframalpha.com/"&gt;Wolfram|Alpha&lt;/a&gt;, Mathematica, and what these sorts of tools can do. They way they see it is that if &lt;a href="http://www.google.co.uk/"&gt;Google&lt;/a&gt; is a means to retrieve facts, Wolfram|Alpha aspires to be a way to use information. For example, &lt;a href="http://data.gov.uk/"&gt;governments have started dumping a lot of data into the public domain&lt;/a&gt;, but how easy is it for a citizen to extract meaningful information from that data?&lt;br /&gt;&lt;br /&gt;For someone used to &lt;a href="http://moodle.org/"&gt;Moodle&lt;/a&gt; and open source, I was deeply struck by how &lt;a href="http://catb.org/esr/writings/homesteading/cathedral-bazaar/index.html#catbmain"&gt;Cathedral (as opposed to Bazaar)&lt;/a&gt; the whole Wolfram/Mathematica world is. That may be, in part, a natural consequence of when they started. Wolfram has been working on Mathematica for twenty years. That is an impressive achievement, and it means they have been working on it since before Linux was a gleam in Linus Torvald's eye. They started at a time when the commercial model was how most software was written, and they are clearly still an American commercial software development business at heart.&lt;br /&gt;&lt;br /&gt;It is interesting to ask what would have happened of Mathematica had been GPL. Would it have developed more or less than it has as a commercial project? Wolfram would not have been able to pour as much money into it, but would a community have done as much, or more? I am not sure. Clearly the commercial model has been highly successful for driving the development of Mathematica. It is a very cool, and very sophisticated tool. On the other hand, one can dream about a world where the Mathematica engine is free, and as a result shipped on every OLPC XO. What effect would that have on the world over the next twenty years? (Quiz, can you name Mathematica's closes open source rival? I can, but only because it is used in &lt;a href="http://stack.bham.ac.uk/"&gt;STACK&lt;/a&gt;. Speaking of which, it was nice to renew my acquaintance with &lt;a href="http://web.mat.bham.ac.uk/C.J.Sangwin/"&gt;Chris Sangwin&lt;/a&gt; today.)&lt;br /&gt;&lt;br /&gt;Another things that struck me about the Wolfram world is how insular it is. Some of the speakers we heard clearly spend all their time thinking about&amp;nbsp;Mathematica. They have a really amazing tool, and, having what they hope is the ultimate sledge-hammer, they seem to view most problems as nuts to be cracked. It made me worry about whether the Moodle community seems that insular from the outside.&lt;br /&gt;&lt;br /&gt;However, the day was not just about Maths and Mathematica, but more about the democratisation of knowledge. How can a concerned citizen reach meaningful conclusions about the world using the data that is now available? Conrad Wolfram set the scene by talking about this mission. He started with two slides, one showing a page from Principia Mathematica, and then a page from a modern mathematical paper. They both comprised text, diagrams and equation. Certainly, modern type-setting is better, and the diagrams are now in colour, but that is not much to show for 350 years progress. Is this the best way to publish scientific knowledge in the 21st Century? No, it isn't. For instance, it is silly to show a static graph. It should be a graph that the reader can manipulate, and the raw data should be hidden behind it in a form that you can extract to perform you own analyses on if you choose. Is the paper about a model? If so the model should be embedded there, and you should be able to experiment with varying the inputs and the assumptions to see what happens. If you are interested, you should be able to get at the source code to see exactly what was implemented. So, rather than a document being a static, one-way, low-bandwidth form of information transmission, it should be an interactive things that allows the "reader" to engage in a two-way dialogue.&lt;br /&gt;&lt;br /&gt;Of course, Mathematica is the perfect tool for authoring such documents, or so Wolfram would like you to think. To encourage this, they are talking about a CDF - computational document format - which would be an 'open' standard based on a subset of Mathematica's capabilities, with a 'free' player for all common platforms. Think PDF and Adobe. Will it take off? Well, does the rest of the world trust Wolfram enough to adopt their format? Can the offer enough more than HTML5? I am not sure.&lt;br /&gt;&lt;br /&gt;The next talk was by Andrew Dilnot from Oxford University. He talked very engagingly about the difficulty with statistics and gave some nice topical examples of the need to interpret numbers in context. Presented with a numerical fact, you need to ask some basic questions: is this big or small? going up or down? where did it come from? For example, &lt;a href="http://news.bbc.co.uk/1/hi/health/10266997.stm"&gt;the smoking ban has saved the NHS £8million&lt;/a&gt;. Well, that is small. &lt;a href="http://www.nhs.uk/NHSEngland/thenhs/about/Pages/overview.aspx"&gt;The NHS annual budget is £100billion&lt;/a&gt;. Why are the media making such a big deal of the story? His talk could be summarised as: All numbers are wrong, but using numbers is still much better than not using numbers.&lt;br /&gt;&lt;br /&gt;There were a couple of talks about that were more pretty than interesting. John Barrow from Cambridge talked about the &lt;a href="http://www.absoluteastronomy.com/topics/William_Parsons,_3rd_Earl_of_Rosse"&gt;history&lt;/a&gt; of &lt;a href="http://www.space-images.com/wallpapers/apollo/11-earthrise/apollo11_earthrise_1920x1200.jpg"&gt;scientific&lt;/a&gt; &lt;a href="http://www.nasa.gov/multimedia/imagegallery/image_feature_228_prt.htm"&gt;images&lt;/a&gt;, and Alan Joyce showed some of the cool things you can do with Mathematical. There were also some glimpses behind the scenes of Wolfram|Alpha. As I say, very Cathedral. There is no web spidering or crowd-sourcing here. At one end it is about Wolfram people going out and finding the most authoritative data sources they can get, and loading them into a format their Mathematica code can use. At they other end they are training the Alpha system to take natural language queries, decide which methods to apply to what date, and select visualisation to display the results, in order to automatically give the best possible answer to that question. They gave an interesting parallel for this. In the past, all actors had to appear on stage to whatever live audience could fit into the theatre. Today, film and television allow most people to see the best actors in the world. Can the expertise of the best thinkers in different fields be made accessible in a similar way? Well, that is their goal. The initial results are impressive, but these are only the very early stages of a highly ambitious project and there is a lot more to do.&lt;br /&gt;&lt;br /&gt;In the afternoon, Conrad Wolfram talked about his thoughts on maths education. This has traditionally been focussed on teaching students how to perform computations by hand. But, said Conrad, this is only one part of what you need to know to be a mathematician. The full steps are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Ask an interesting question about the world.&lt;/li&gt;&lt;li&gt;Translate that real world question into mathematics.&lt;/li&gt;&lt;li&gt;Compute the solution.&lt;/li&gt;&lt;li&gt;Translate that solution back into real-world terms, and find some way to validate whether your answer makes sense.&lt;/li&gt;&lt;/ol&gt;(OU Maths students, note the similarities to the Modelling cycle as taught in &lt;a href="http://www3.open.ac.uk/study/undergraduate/mathematics-and-statistics/index.htm"&gt;OU courses&lt;/a&gt;.) Historically, maths education has focussed on Step 3. However, these days computers are just better than humans at that. At the same time, there has never been a greater demand for people who are good at the other three steps (in business, to guide public policy, and so on). So we need to rethink the maths curriculum. To put it another way, is it cheating if you use Wolfram|Alpha to do your maths homework? Well, if it is, then we are probably assessing the wrong things.&lt;br /&gt;&lt;br /&gt;At the end, Stephen Wolfram gave a presentation by video link summarising some of the themes of the day.&lt;br /&gt;&lt;br /&gt;Overall, it was a very interesting day. While I don't think it quite lived up to its pretentious title, it was certainly more than just a Wolfram marketing exercise. I would like to thank the Open University for sending me. I can see myself using Wolfram|Alpha in future for certain sorts of queries, but it will not replace Google as my day-to-day search engine. (I don't think it aspires too.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-5729267637281333536?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/5729267637281333536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/06/i-spent-today-at-london-computational.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/5729267637281333536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/5729267637281333536'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/06/i-spent-today-at-london-computational.html' title='Computational Knowledge'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-2772516214039548793</id><published>2010-03-25T12:17:00.000Z</published><updated>2010-03-25T12:17:13.383Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Open University'/><category scheme='http://www.blogger.com/atom/ns#' term='Quizzes'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='Students'/><title type='text'>When do students submit their online tests?</title><content type='html'>I am currently studying an Open University course (&lt;a href="http://www3.open.ac.uk/study/postgraduate/course/m888.htm"&gt;M888 Databases in Enterprise systems&lt;/a&gt;. There was an assignment due today, and like many students, I submitted only an hour before the deadline.&lt;br /&gt;&lt;br /&gt;That got me thinking, are all students really like that? Well, I don't have access to our assessment submission system, but I do work on our Moodle-based VLE, so I can give you the data from there.&lt;br /&gt;&lt;br /&gt;This graph shows how many hours before the deadline students submit their Moodle quizzes (iCMAs in OU-speak)&lt;br /&gt;&lt;br /&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_EEdbgam-elg/S6tRPzEiQcI/AAAAAAAADYU/_ScQtYki8DA/s1600/quiz+submissions+before+deadline.png" /&gt;&lt;br /&gt;&lt;br /&gt;That is not exactly what I was expecting. Certainly, there is a bit of a peak in the last few hours, but there is another peak almost exactly 24 hours before that, with lesser peaks two and three days before.&lt;br /&gt;&lt;br /&gt;Note that all our deadlines are at noon (it used to be midnight, but that changed a few months ago). The graph above is consistent with our general pattern of usage. The following graph shows what time of day students submitted their quiz attempts. It is same shape as our general load graph for most OU online systems.&lt;br /&gt;&lt;br /&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_EEdbgam-elg/S6tSH0_FNJI/AAAAAAAADYc/mQOTzn9---A/s1600/quiz+submissions+by+time+of+day.png" /&gt;&lt;br /&gt;&lt;br /&gt;I don't know what, if anything, this means, but I thought it was interesting enough to share.&lt;br /&gt;&lt;br /&gt;By the way, if you want to compute these graphs for your own Moodle, here are the database queries I used:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;-- Number of quiz submissions by hour before deadline&lt;br /&gt;SELECT &lt;br /&gt;    (quiz.timeclose - qa.timefinish) / 3600 AS hoursbefore,&lt;br /&gt;    COUNT(1)&lt;br /&gt;&lt;br /&gt;FROM mdl_quiz_attempts qa&lt;br /&gt;JOIN mdl_quiz quiz ON quiz.id = qa.quiz&lt;br /&gt;&lt;br /&gt;WHERE&lt;br /&gt;    qa.preview = 0 AND&lt;br /&gt;    quiz.timeclose &lt;&gt; 0 AND&lt;br /&gt;    qa.timefinish &lt;&gt; 0&lt;br /&gt;&lt;br /&gt;GROUP BY&lt;br /&gt;    (quiz.timeclose - qa.timefinish) / 3600&lt;br /&gt;&lt;br /&gt;HAVING (quiz.timeclose - qa.timefinish) / 3600 &lt; 24 * 7&lt;br /&gt;&lt;br /&gt;ORDER BY&lt;br /&gt;    hoursbefore&lt;br /&gt;&lt;br /&gt;-- Number of quiz submissions by hour of day&lt;br /&gt;SELECT &lt;br /&gt;    DATE_PART('hour', TIMESTAMP WITH TIME ZONE 'epoch' + timefinish * INTERVAL '1 second') AS hour,&lt;br /&gt;    COUNT(1)&lt;br /&gt;&lt;br /&gt;FROM mdl_quiz_attempts qa&lt;br /&gt;&lt;br /&gt;WHERE&lt;br /&gt;    qa.preview = 0 AND&lt;br /&gt;    qa.timefinish &lt;&gt; 0&lt;br /&gt;&lt;br /&gt;GROUP BY&lt;br /&gt;    DATE_PART('hour', TIMESTAMP WITH TIME ZONE 'epoch' + timefinish * INTERVAL '1 second')&lt;br /&gt;&lt;br /&gt;ORDER BY&lt;br /&gt;    hour&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-2772516214039548793?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/2772516214039548793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2010/03/when-do-students-submit-their-online.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/2772516214039548793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/2772516214039548793'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2010/03/when-do-students-submit-their-online.html' title='When do students submit their online tests?'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_EEdbgam-elg/S6tRPzEiQcI/AAAAAAAADYU/_ScQtYki8DA/s72-c/quiz+submissions+before+deadline.png' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-8606641099392128291</id><published>2009-10-15T19:54:00.005+01:00</published><updated>2009-10-15T20:04:31.560+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OU'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='Plagiarism'/><title type='text'>The Open University's approach to plagiarism</title><content type='html'>I spent the day at an OU internal conference on plagiarism. Until now, most of my engagement with this subject has been people coming to the &lt;a href="http://moodle.org/mod/forum/view.php?id=737"&gt;Moodle Quiz Forum&lt;/a&gt; expecting technological magic bullets. There seems to be a depressing assumption in some quarters that preventing students from copying or pasting during a quiz attempt, or from using a spell checker, in some way helps the validity of an assessment. And using Google during a quiz attempt is surely cheating, it couldn't possibly be a valuable study skill for the 21st century?&lt;br /&gt;&lt;br /&gt;Anyway, it is just not possible to enforce these kinds of restrictions from a web server application like Moodle. Image, for a moment, what would happen to the web if any advertiser could stop you leaving their horrible web site and going to Google to find something better. If you really want to set up a restricted environment (akin to the traditional invigilated/proctored exam hall) you need client-side software installed on the computer the student will be using. If you are looking for something like this, take a look at &lt;a href="http://www.safeexambrowser.org/"&gt;Safe Exam Browser&lt;/a&gt;, and open-source effort built on Firefox, which is now integrated into Moodle 1.9.6 (due for release soon). See &lt;a href="http://tracker.moodle.org/browse/MDL-19145"&gt;MDL-19145&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I am pleased to say that the OU approach is diametrically opposed to this wishful chasing after technological magic bullets. The conference today started with two keynotes by &lt;a href="http://www.brookes.ac.uk/services/ocsd/5_research/jude.html"&gt;Jude Carroll&lt;/a&gt; from Oxford Brookes University, who has been thinking about these issues for the last nine years, and who is an excellent speaker. She has the very clear summary of the issue: Universities have the responsibility/duty/privileged to accredit student's learning. They give the student a bit of paper saying that they have learned something, and in our society that bit of paper has a certain amount of value. So universities need to measure learning, and that is where assessment comes in. The real problem with plagiarism is that it breaks the link between what the student submits for assessment, what they have learned. If a student writes something in their own words, then that writing is good evidence of the extent to which they have taken in the ideas of a course. If they have just copied and pasted someone else's words, you cannot assess what they have learned. Also, teachers do not set assessment tasks just to measure students. We hope that performing the tasks helps the student to learn.&lt;br /&gt;&lt;br /&gt;Jude also made the point that exactly is plagiarism does depend on the context. For example the level of experience of the student, the learning that is being assessed, what you are allowed to assume as common knowledge. Also, not all plagiarism is cheating, and not all cheating is plagiarism. Dealing with plagiarism must be done in an appropriate and proportionate way. To start with, understanding issues of academic honesty is an important learning outcome from a degree course, but it needs to be taught, it is not innate. It cannot be taught as an optional add-on ("the plagiarism lecture") but instead it must be embedded in the context of the subject early in a degree program. (By and large the OU does this in its introductory course.) When plagiarism happens, the response has to be proportionate. Early in a program of study, students need to be given feedback to help develop good academic practices. Later on, students should be expected to understand these issues, and plagiarism becomes a disciplinary issue, but still their need to be a range of fair and proportionate penalties.&lt;br /&gt;&lt;br /&gt;The OU has clearly had a group of people thinking hard about this over the last few years, and that has resulted in a new plagiarism policy that was adopted last June. This conference was part of disseminating that policy more widely. There are now a range of penalties for various types of plagiarism, and a new role, 'Academic Conduct Officers' who can deal with most issues of plagiarism that go beyond what the student's individual tutors can deal with. This lets many cases be dealt with quickly, so that only the most serious cases have to be referred to the Central Disciplinary Committee. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_EEdbgam-elg/StdxrVYjAcI/AAAAAAAACfQ/_4eL-_0dqgY/s1600-h/dgap2.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_EEdbgam-elg/StdxrVYjAcI/AAAAAAAACfQ/_4eL-_0dqgY/s400/dgap2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Another part of the OU's response to this issue is a new web site &lt;a href="http://learn.open.ac.uk/site/dgap001"&gt;Developing good academic practices&lt;/a&gt;, which I am afraid you will only be able to see if you have some sort of OU login, student or staff. That is a Moodle site in our VLE. It is a mixture of text to read, with a few audio clips, with a quiz at the end of each section. There is also a summary quiz at the end which draws questions randomly from all the other quizzes. The estimated study time for the whole site is 2 hours. It seems to be well done, and for me it is pleasing to see the quiz module used well, even if it is only multiple-choice and matching questions. The course has about 2300 quiz attempts at the moment.&lt;br /&gt;&lt;br /&gt;Finally, the OU does use two technological means to detect plagiarism, &lt;a href="http://cflsoftware.com/?page_id=57"&gt;CopyCatch&lt;/a&gt; and &lt;a href="http://turnitin.com/static/index.html"&gt;Turnitin&lt;/a&gt;, on a proportion of submitted work. However, this is only used to flag up possible cases that are then reviewed by a human. The third form of detection is that tutors marking the students' work can often spot problems. However, overall, the amount of plagiarism detected at the OU seems to be lower than that reported elsewhere. It is interesting to speculate why that might be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-8606641099392128291?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/8606641099392128291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/10/open-universitys-approach-to-plagiarism.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8606641099392128291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8606641099392128291'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/10/open-universitys-approach-to-plagiarism.html' title='The Open University&apos;s approach to plagiarism'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_EEdbgam-elg/StdxrVYjAcI/AAAAAAAACfQ/_4eL-_0dqgY/s72-c/dgap2.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-6819609457641987834</id><published>2009-10-14T22:22:00.001+01:00</published><updated>2009-10-26T14:32:51.251Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>What I'm working on</title><content type='html'>I've been meaning to post here for a while about what I am working on, but I keep posting in the &lt;a href="http://moodle.org/mod/forum/view.php?id=737"&gt;Moodle Quiz Forum&lt;/a&gt; instead, because what I have to say seems more relevant there.&lt;br /&gt;&lt;br /&gt;Anyway, the short answer is that I am &lt;a href="http://docs.moodle.org/en/Development:Question_Engine_2"&gt;rewriting the Moodle Question Engine&lt;/a&gt;. That document explains the what and the why. I want to post here about the how.&lt;br /&gt;&lt;br /&gt;The question engine is the part of Moodle that processes what happens as a student attempts questions as part of a quiz (or other activity). What makes this a relatively difficult problem is that there are two independent degrees of variation. A question may be one of many different question types (multiple choice, short-answer, essay, ...) and there are various ways that a student may interact with it (adaptive mode, non-adaptive mode, manually graded, ...). Plus, people seem to think that when quizzes are used for summative assessments, it is quite important that there are no bugs and that performance is good ;-).&lt;br /&gt;&lt;br /&gt;The complexity of the problem, and my natural bias, means that I am taking a very object-oriented approach. More so than is normally used in Moodle. Separate objects, with clearly defined responsibilities, helps me understand the problem and have confidence that what I am doing will work.&lt;br /&gt;&lt;br /&gt;If you read the document linked to above, you will learn that I have been dissatisfied with this part of the quiz code for years, however it is really only within the last year that I have worked out the overall approach to solving this problem nicely. The key realisation is that you need to apply the &lt;a href="http://c2.com/cgi/wiki?StrategyPattern"&gt;strategy pattern&lt;/a&gt; twice, once for the bits that vary with the question type, and once for the bits that vary with the interaction model. The other important part of the plan is a cleaner database structure that more closely maps to data we need to store.&lt;br /&gt;&lt;br /&gt;However, to implement all that requires quite a lot of code. I need to build the core system that can support all the different interactions and question types. Then I need to create all the interactions to replicate Moodle's existing functionality and the new features we want to add (Certainty Based Marking, and what we are calling the Interactive mode). Then I need to modify all the existing Moodle question types to fit into the new system. And I need to do all this with robust bug-free code that we can confidently use for summative assessment.&lt;br /&gt;&lt;br /&gt;Over the last year I become increasing coverted to test-driven development. Certainly I wrote a lots of tests while &lt;a href="http://tjhunt.blogspot.com/2009/04/how-do-you-eat-elephant.html"&gt;eating my elephant&lt;/a&gt;, and this time round I am being very thorough with testing, although I must admit I still don't always write the tests first.&lt;br /&gt;&lt;br /&gt;I am also proceeding very iteratively. I started with a test that took a single true-false question through being attempted according to the simplest of the interactions, and wrote some code that used roughly the right classes to make that test pass. Then for about a week I did little more than refactor that code.&lt;br /&gt;&lt;br /&gt;It turned out that most of my variables and classes had the wrong name. For example, at one point I had classes called question_state and question_states, which was clearly a recipe for confusion. It was only after I had working code that I was able to think of the name question_attempt_step (one step in a question_attempt) for one of those. I also came to realise that grades were stored in three separate ways in different places, and so I ought to make sure I was using &lt;a href="http://docs.moodle.org/en/Development:Question_Engine_2:Design#Words_related_to_grades"&gt;a consistent naming scheme&lt;/a&gt; for my variables. Then I did a bit of moving methods between classes as the exact boundaries of responsibility of different classes became clearer. Should I have been able to get all that right first time? Well I think that would be impossible.&lt;br /&gt;&lt;br /&gt;I also started gradually removing simplifying assumptions that worked for my initial test true-false question, but not more generally. That was the point at which I started extending my code to other question types and interactions. For example I wrote a test case a walking an essay question through the manual grading interaction, and exposed some new issues that had to be accounted for; and just today I introduced multiple-choice questions, which randomise the order of the choices when you start an attempt, but then you have to store that random order somewhere so it can be used throughout the attempt. I have also already implemented the &lt;a href="http://www.ucl.ac.uk/lapt/"&gt;certainty based marking&lt;/a&gt; interaction.&lt;br /&gt;&lt;br /&gt;There is still much to do. My code that outputs the HTML for a question is still a rough hack of the current code that lets the tests pass. I need several rounds of refactoring before that will be cleaned to my satisfaction. There are sill five more interactions to write, although each one is getting quicker than the one before. Then I have to convert all the existing question types. I need code that stores the current state of everything in the database and later reads it back. Finally, the nasty bits, which are upgrading from the current database structure to the new one, and re-implementing backup and restore, including restore of old backups.&lt;br /&gt;&lt;br /&gt;If you were paying attention in that last paragraph, you will have deduced that my code does not yet store anything in the database! I am taking an approach with the domain objects completely unaware of the database (which makes testing very easy) and I am planning to use the &lt;a href="http://martinfowler.com/eaaCatalog/dataMapper.html"&gt;data mapper pattern&lt;/a&gt; to coordinate loading and saving the necessary data efficiently. I am pretty sure I know how to do that, however, I have not tried to write it yet because I want to re-read the relevant chapters of &lt;a href="http://martinfowler.com/books.html#eaa"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt;, and my copy only recently got back from Australia, and I won't be able to retrieve it from my parents' house until this weekend.&lt;br /&gt;&lt;br /&gt;In terms of time-scales, I am really hoping to get this done by about Christmas, and in time to go into Moodle 2.0, since it breaks a number of APIs. However, I first have to implement this in the OU's Moodle 1.9 code-base and then port it to Moodle 2.0, so no promises. This may have to wait until Moodle 2.1.&lt;br /&gt;&lt;br /&gt;Anyway, that is what I have been doing, and so far it has been very enjoyable. Write tests, make them pass, then refactor aggressively with the tests as a safety net is an approach that is working really well for me. These are quite big scary changes, but right now I am feeling confident that it will all work out, and we will end up with a really solid question engine upon which to base an enhanced quiz and other Moodle activities.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-6819609457641987834?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/6819609457641987834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/10/what-im-working-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/6819609457641987834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/6819609457641987834'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/10/what-im-working-on.html' title='What I&apos;m working on'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-7263877148648418270</id><published>2009-08-24T11:47:00.000+01:00</published><updated>2009-08-24T11:50:46.727+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FLOSS'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><title type='text'>Herding cats</title><content type='html'>Just before I left Perth, Martin &lt;a href="http://moodle.org/mod/data/view.php?d=54&amp;rid=2568"&gt;advertised for a Project Manager for Moodle HQ&lt;/a&gt;. I think this is probably a good thing, if a good person applies and is appointed. However, I also think it will be a very difficult job to do.&lt;br /&gt;&lt;br /&gt;Martin always has too much to do, and any time he can identify some tasks that can be delegated, it is a good thing. Early in the history of Moodle HQ he found Mike and Darlene who run a lot of the commercial side of the Partners network. More recently he appointed Helen to act as community co-ordinator, and Jordan as system admin. All those were successful appointments, and having watched form the sidelines I have seen that Martin will not recruit someone unless he is sure they are right for the job (important when you are running a small business) and Martin is a good judge of people.&lt;br /&gt;&lt;br /&gt;The other reason a project manager would be a good idea is clear to anyone who had been following the Moodle 2.0 development, which still has a long way to go until it is finished. Someone with more time than Martin has to ride herd on the process can only help us get 2.0 out of the door.&lt;br /&gt;&lt;br /&gt;However, it is not quite that simple. On the one hand, I have studied the &lt;a href="http://www3.open.ac.uk/courses/bin/p12.dll?C01M865"&gt;Open University Project Management course&lt;/a&gt; from their Postgraduate Computing program. That is an excellent course, and as a result I know a bit about and am interested in what project managers do. On the other hand, I also know the fairly independent way that I and other core developers like to work. That is why I chose the title of this blog post. (Not because of some people's user profile pictures!)&lt;br /&gt;&lt;br /&gt;To start with, the Moodle project is not even a project in the sense that Project Managers use the word. A typical definition is "&lt;a href="http://en.wikipedia.org/wiki/Project_management"&gt;A project is a temporary endeavor, having a defined beginning and end&lt;/a&gt;," but Moodle itself will not end (we hope). Still, some of the things we do, for example, the Moodle 2.0 release, are projects in this sense. However, we know there will also be another project called the Moodle 2.1 release later. Therefore, if we contemplate a short-cut that would let us release Moodle 2.0 sooner, we have to balance the short-term benefits with the long-term costs of cleaning things up in a later release. Classic project management tends to think about one project at a time.&lt;br /&gt;&lt;br /&gt;That ties in with Moodle's choice of feature-driven, not date-driven releases. We will pick a set of features to be included in a release, and we will release when they are done, tested and bug-fixed, however long that takes. Well that is the general policy, but a certain amount of pragmatism is applied when interpreting it. This is a fairly unusual way to run a project. For example, with the Open University's Moodle-based VLE we operate the other way. We have date-based releases, with the dates announced a long way in advance, but we do not guarantee what features will be an any given release very far in advance.&lt;br /&gt;&lt;br /&gt;Then there is the the nature of the work. One area where project management is generally successful is in construction projects. The cliché old maths problem "If it takes 2 men 7 hours to dig a trench 6 metres long ..." has at least some relevance to reality there. There is even the &lt;a href="http://www.bluebook.net/products/cost-guide/"&gt;Bluebook cost guide&lt;/a&gt; that has established estimates for certain types of construction work.&lt;br /&gt;&lt;br /&gt;In contrast, as that classic of software project management "The Mythical Man Month" says, "adding manpower to a late software project makes it later." What software developers do is much closer to an architect drawing the plans than to a builder laying bricks. The compiler (or PHP interpreter) is the builder. This is hardly new, and is why agile software-development methodologies were invented. If Moodle's new project manager is going to adopt a Methodology, I hope the choose an agile one.&lt;br /&gt;&lt;br /&gt;Another difficulty is that software developers are not fungible. If there is some tricky job involving security you probably want Petr to do it. If it is to do with the quiz, it would be best if I did it. If it is related to backup and restore, no one wants to do it, and so it ends up with Eloy ;-). If those people do the job, it will be quicker. On the other hand, sometimes you want to give the job to someone else, to increase the &lt;a href="http://www.c2.com/cgi/wiki?BusNumber"&gt;bus number&lt;/a&gt; of the project. While this sort of think makes the project harder to manage, it is the sort of thing that a good project manager knows how to deal with - once they get to know the people involved.&lt;br /&gt;&lt;br /&gt;Another consideration is that developers are highly distractible. That is, while they are working on one thing, they may suddenly notice that something is a bit messy, and decide to rewrite it or refactor it, even if that was not part of the original plan. When considering the long-term health of the moodle, that might be the right thing to do, even if, in the short term it delays the next release. At other times, it might just be self-indulgance and cause bugs. Would a project manager be able to tell the difference? Anyway, as some-time tiddlywinks world champion Andy Purvis once told my, after thrashing me soundly, "Strategy should be a mixture of planning and opportunism."&lt;br /&gt;&lt;br /&gt;A final potential problem is that the Moodle core developers are a highly motivated group of people. We care a lot about Moodle, and have demonstrated that over the years. We don't need to be told what to do, and a project manager who tried could piss a lot of people off very rapidly and do a lot of harm to the project. Fortunately, I think the chance of Martin appointing someone like that is tiny. However, I think is an important point to make, that the Moodle Project Manager should be a colleague and peer of the developers (with a particular set of skills). That is, they should manage the project, not the developers.&lt;br /&gt;&lt;br /&gt;So, I have said that I think a Moodle Project Manager is a good idea, but I have also said why I think it would be a very difficult job to do. So what do I think the Moodle Project Manager can usefully contribute (that I, as a developer, would not object to ;-)).&lt;br /&gt;&lt;br /&gt;A good project manager is always a good communicator, and in multiple directions. The Moodle Project Manager will need to communicate with the developers to track as clearly as possible what development is going on, and what still needs to be completed before the next release. They then need to communicate that picture of where we are to all the Moodle administrators waiting for the next release, including the Moodle Parters. They also need to communicate it back to the developers to help them see what progress is being made and what the priorities. Naturally they will be working closely with Martin. They also need to communicate progress to Translators and third-party plugin authors, to help translators have their translations ready as soon to the main release as possible.&lt;br /&gt;&lt;br /&gt;A project manager is also good at extracting clarity from a confusing situation, which is really another part of what I just wrote. They can take reports from a lot of people, and a more-or-less vague list of outstanding tasks, and combine that into a picture of where we are now, and where we are going that other people can understand.&lt;br /&gt;&lt;br /&gt;Once you can communicate well, and as a result derive a clear picture of where we are and where we are going, then the actually project planning - getting the right people to work on the right tasks next - is relatively easy, but still requires some knowledge of the people and the tasks. Then there are the people skills to help keep people motivated and focussed on the next release without trying to over-manage them.&lt;br /&gt;&lt;br /&gt;Finally, and particular around the release time, a project manager can improve the processes. For example, does Moodle need string and user-interface freezes in the run up to the release, to help translators and theme designers? (The answer needs to be a consensus of all involved, so more communication.)&lt;br /&gt;&lt;br /&gt;The project manager will also be one of the people in a position to hear what new features people are most desperate to have next, and so will be able to contribute to planning the scope of future releases.&lt;br /&gt;&lt;br /&gt;So, it is a challenging job, but I think someone is needed to do it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-7263877148648418270?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/7263877148648418270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/08/herding-cats.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7263877148648418270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7263877148648418270'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/08/herding-cats.html' title='Herding cats'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-7234053926657973945</id><published>2009-08-13T10:09:00.002+01:00</published><updated>2009-08-13T10:22:53.000+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='strange hobbies'/><category scheme='http://www.blogger.com/atom/ns#' term='busses'/><category scheme='http://www.blogger.com/atom/ns#' term='family'/><title type='text'>On the busses</title><content type='html'>On Monday I was privileged to to accompany Jo, Linda and Mary on two of &lt;a href="http://londonbusesonebusatatime.blogspot.com/"&gt;their busses&lt;/a&gt;. Jo and I made our way to  the middle of a street by the Thames in Pimlico, just opposite the old Battersea Power station, meeting Mary at one end of Vauxhall bridge, and Linda at &lt;a href="http://londonbusesonebusatatime.blogspot.com/2009/08/number-24-route.html"&gt;the 24&lt;/a&gt; head stop. Apparently that is the proper name for the bus stop at the end of a bus route.&lt;br /&gt;&lt;br /&gt;The plan had been to get the 24 all the way to the other end at Hampstead Heath, and then get the 168 back all the way south to Old Kent Road. However, it turned out due to an accident in Tottenham Court Road, the 24s were not going beyond Victoria. We got kicked off there, and were faced with a potential rules crises. Jo, displaying a frightening knowledge of the London bus network, almost immediately suggested that we could get the C2 from Victoria to the other side of the Heath, and then walk across to the 168 head stop and so salvage some of the day.&lt;br /&gt;&lt;br /&gt;Speaking of the rules of their busses odyssey, they can do other busses out of order, but are only allowed to add them to the blog in order. So, since the C busses will only appear after all the numbered busses, and the As and the Bs, that bit of the trip will probably get blogged in about 5 years time. Who know what the rules say if the route if modified in the mean time?&lt;br /&gt;&lt;br /&gt;Having walked across the park, we found not only 168 busses, but also plenty of 24s, and the news that the route was now clear. (Actually, the busses going south use Gower street, not Tottenham Court Road.) So, in the event we were able to complete the rest of the 24 route in reverse, finishing at Victoria, from where Jo and I went to Oxford Circus for a very nice Curry at the &lt;a href="http://www.london-eating.co.uk/3601.htm"&gt;Kerala&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's a strange hobby, but it keeps my mother out of mischief of a Monday and it was nice to be able to share it with her. Being a geek, I hope I can be there when they do the 42 route. And I am pleased I persuaded my mother to blog. Now that I have added a hit counter to their site (thanks to &lt;a href="http://www.statcounter.com/"&gt;http://www.statcounter.com/&lt;/a&gt;) we will be able to see whether anyone is interested, or whether the only visitors are friends and family, or &lt;a href="http://my6.statcounter.com/project/standard2/keyword.php?project_id=4984753"&gt;people trying to find travel information&lt;/a&gt;. I have now also added a little search form to let people easily find TfL bus route maps from the blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-7234053926657973945?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/7234053926657973945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/08/on-busses.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7234053926657973945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7234053926657973945'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/08/on-busses.html' title='On the busses'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-7256192595477531109</id><published>2009-07-14T03:09:00.004+01:00</published><updated>2009-07-14T03:41:46.536+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FLOSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='GSOC'/><title type='text'>One step at a time</title><content type='html'>An important thing to realise about Open Source development is that nothing is ever finished and nothing is ever perfect. (If it was, we would all be out of a job ;-)). Open source is never a project &lt;a href="#note1"&gt;[1]&lt;/a&gt;, but an eternal quest, and the relevant questions for planning are only ever: "What should we do next?" "What are the biggest problems now?" with the focus on next and now. The quest can only proceed one step at a time, and you know there will be more steps in the future.&lt;br /&gt;&lt;br /&gt;Of course, you must have a bold vision of where you are all heading, so everyone is moving in roughly the same direction, but that should not involve details. The details of what you will work on next year are better left until next year. You will be a year older and wiser then, and the state of the art will have moved on.&lt;br /&gt;&lt;br /&gt;An important aspect of "what should we do next?" is that it must be somewhere you can get to in one step from where you are now. (Some of the steps in Moodle 2.0 have been quite large.) Open Source proceeds best by accumulating incremental change. That is my belief anyway.&lt;br /&gt;&lt;br /&gt;&lt;a name="note1"&gt;1.&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Project_management"&gt;A project is a temporary endeavor, having a defined beginning and end ...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(This evolved out of a message I was writing to my &lt;a href="http://code.google.com/soc/"&gt;Google Summer of Code&lt;/a&gt; mentee &lt;a href="http://www.pilpi.net/"&gt;Olli Savolainen&lt;/a&gt;. Thanks Olli.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-7256192595477531109?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/7256192595477531109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/07/one-step-at-time.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7256192595477531109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7256192595477531109'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/07/one-step-at-time.html' title='One step at a time'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-8586114438411217280</id><published>2009-06-22T06:02:00.009+01:00</published><updated>2009-06-23T05:45:04.140+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='users'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><title type='text'>The geeks don't really matter</title><content type='html'>&lt;p&gt;I was just reading &lt;a href="http://btopro.wordpress.com/2009/06/18/moodlemoot/"&gt;this criticism of Moodle&lt;/a&gt;, and the thing that strikes me about Bryan Ollendyke's criticisms are the reactions of a software geek. They are also very familiar. I had a similarly horrified reaction the first time I saw the Moodle code (and got into trouble with my boss at the time for speaking my mind at an inopportune moment ;-)) and three and a half years later the same criticisms still apply.&lt;/p&gt;&lt;p&gt;But what I have come to learn over the last three and a half years is that it does not really matter. That is somewhat humbling. I am a professional software developer. I have worked hard to learn to write good code; to build and appreciate elegant and powerful software architectures; to design usable interfaces with modern UI idioms; and so on. However, as I say, that seems not to be very important. Teachers all over the world use Moodle to create great (and ordinary) learning experiences; teachers who move from other learning management systems tend to like Moodle better than whatever they were using before; and all sorts of people from all over the place seem to be able to write plugins. All that, despite Moodle not being a text-book example of software design.&lt;/p&gt;&lt;p&gt;So, are Bryan and I and others with similar opinions just software engineering snobs? Well, probably yes, up to a point, but it is our job to care about these things. Other things being equal, we should do things the right way. The point is that some of the other things are much more important than the cool (or not) technical things going on behind the scenes. The most important thing is &lt;b&gt;education&lt;/b&gt;. Moodle's genesis was in Martin Dougiamas's postgraduate studies of online education; but more important is that the Moodle project, led by Martin, has always focussed on engaging &lt;a href="http://moodle.org/mod/choice/view.php?id=343"&gt;teachers, as well as developers&lt;/a&gt;, in the Moodle community. To use the &lt;a href="http://en.wikipedia.org/wiki/Human-computer_interaction"&gt;HCI&lt;/a&gt; jargon, Moodle has always practiced user-centred design.&lt;/p&gt;&lt;p&gt;&lt;img style="float:right; margin:0 0 10px 10px; width: 223px; height: 608px;" src="http://2.bp.blogspot.com/_EEdbgam-elg/Sj9TzZzfx9I/AAAAAAAACIw/0ykEhgYfwbU/s1600/quizsettings.png" border="0" alt="Screenshot of the Moodle quiz settings form." /&gt;&lt;br /&gt;Now, if you are an expert in HCI design, and you have seen parts of Moodle like the quiz settings form (screen-shot right), then that last sentence might make you laugh. That form is a typical long Moodle form with a million fields you can fill in. In the technical details it does not follow recent user interface best practice. However, suppose you really want to simplify it. The best approach would be to find some options that nobody really needs, and remove them. Well, believe me, I have tried on several occasions. I have convinced myself that some feature is pointless and posted in the quiz forum. Of course, I quickly get a lot typical 'How dare you! I love it that feature. I'll throw my toys out of the pram if you remove it.' responses. Then, invariably, someone will make a well reasoned post that explains a compelling educational situation where that feature really makes a difference, and I will realise why that feature was added in the first place, and why it would be a mistake to remove it.&lt;/p&gt;&lt;p&gt;That is the thing. All those features that bloat the interface are there because someone wanted them badly enough to implement them. Even if they were not a professional developer, and even if their code is not first rate. On the whole, it is probably better for Moodle to have those features than not, even if that means that the interface is not great. We are not here primarily to build beautiful interfaces. We are here to let teachers build beautiful learning experiences. Of course, that is not an excuse to just ignore defects in the interface. We should, and do, go back and apply HCI know-how to improve the interfaces of existing features; and these days we do try to think about UI design for new features before we implement them. We are learning.&lt;/p&gt;&lt;p&gt;To reiterate my main points in summary: While we developers should strive to do the best job we can, technically, we should not be snobbish about it. We must remember that the most important people for Moodle are the teachers and learners, and it is our job to serve them. We should not reject contributions from people who know lots about education, even if they do not write code as well as we do.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-8586114438411217280?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/8586114438411217280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/06/geeks-dont-really-matter.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8586114438411217280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/8586114438411217280'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/06/geeks-dont-really-matter.html' title='The geeks don&apos;t really matter'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_EEdbgam-elg/Sj9TzZzfx9I/AAAAAAAACIw/0ykEhgYfwbU/s72-c/quizsettings.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-2108275053971258450</id><published>2009-04-17T15:31:00.006+01:00</published><updated>2009-04-17T17:26:03.307+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><title type='text'>PHP global variables are not necessarily evil</title><content type='html'>Global variables in software are generally a bad idea. They serve to magically teleport information from one place in a program to another in a way that is very hard to follow. Thus they cause subtle bugs, make maintenance difficult, and kill kittens.&lt;br /&gt;&lt;br /&gt;In a simple program, it is normally easy to avoid global variables. When you call a function or method to get it to do something for you, you can probably just pass all the necessary inputs to the function as parameters, and get all the results back in the return statement. The flow of data is easy to follow.&lt;br /&gt;&lt;br /&gt;However, in a large, complex system, that may become untenable. For example many, but not all functions in Moodle need a database connection to get information or update it. Does that mean all functions in Moodle end up taking a &lt;code&gt;$db&lt;/code&gt; parameter, whether they need them or not, just so they can pass it on to any functions they in turn call? Well, we don't do that, because that way lies madness. Instead we have a 'global' &lt;code&gt;$DB&lt;/code&gt; object, and that is not all. We also have &lt;a href="http://cvs.moodle.org/moodle/lib/setup.php?view=markup"&gt;&lt;code&gt;$CFG&lt;/code&gt;, &lt;code&gt;$COURSE&lt;/code&gt;, and so on.&lt;/a&gt; Imaging if you needed many of those inside your function. Calling it with all those parameters would be a pain.&lt;br /&gt;&lt;br /&gt;Now, I just put the word 'global' in quotes, why was that? Well, Moodle is a web application, so the process that is running is a web server, probably with multiple threads executing simultaneously. A true global variable would be accessible from all threads, and last forever. Something you declare in PHP as a global is only accessible for the duration of one server request, and not accessible from any other thread. In Java, that would be called a ThreadLocal, not a global.&lt;br /&gt;&lt;br /&gt;So, a PHP global is not truly a global. However, if abused, it can still be a way to teleport data from one place to another during the processing of a single request. The point I want to make is that there are non-evil ways to use it. In &lt;a href="http://www.martinfowler.com/books.html#eaa"&gt;&lt;i&gt;Patterns of Enterprise Application Architecture&lt;/i&gt;&lt;/a&gt; Martin Fowler describes the &lt;a href="http://www.martinfowler.com/eaaCatalog/registry.html"&gt;Registry pattern&lt;/a&gt; (sorry, that online summary is inadequate). That is an object in your program which all the other parts can get hold of, and from which they can get the service objects, like the database connection, that they must depend on. In web applications, you often want dependancies with thread local scope. My argument is that the PHP global keyword is a language feature that implements a thread-local registry for you with no effort. Thus it is a good thing if used properly.&lt;br /&gt;&lt;br /&gt;What is using it properly? Well it all depends on the kind of things you store there. Are you making common dependancies easy to find, or are you magically teleporting information. I think that Moodle does mostly use this feature properly. Our global variables like &lt;code&gt;$DB&lt;/code&gt;, &lt;code&gt;$CFG&lt;/code&gt; and &lt;code&gt;$COURSE&lt;/code&gt; are things that can legitimately be stored in and accessed from a Registry. However, we have some horrors, like &lt;code&gt;$CFG-&gt;pagepath&lt;/code&gt; and &lt;code&gt;$CFG-&gt;stylesheets&lt;/code&gt;, which I am currently trying to exorcise from Moodle 2.0.&lt;br /&gt;&lt;br /&gt;One advantage of storing your dependencies in a Registry, as opposed to, say, making them singletons, is that it makes them substitutable. This becomes important when you try to write unit tests. When unit testing, you often need to switch in a &lt;a href="http://xunitpatterns.com/Test%20Double.html"&gt;test double&lt;/a&gt; in place of one of the dependencies. Well, with a Registry you can swap one in during test set up, and switch it back out during tear down. I have been doing that a lot recently in Moodle, and it works. (You could not do it, for example, when you accessing the database in Moodle 1.9. There, the database connection was hidden in functions like &lt;code&gt;get_records&lt;/code&gt;, and could not be substituted. Now we have &lt;code&gt;$DB-&gt;get_records&lt;/code&gt; with &lt;code&gt;$DB&lt;/code&gt; in the 'global' registry where it can be substituted.) Some other global-like mechanisms, like static methods or singletons are not substitutable, and so make testing much harder, if not impossible.&lt;br /&gt;&lt;br /&gt;Of course, some people would argue that you still should not use the global keyword, that instead you should implement your own Registry class (&lt;a href="http://www.phppatterns.com/docs/design/the_registry"&gt;an example&lt;/a&gt;). I disagree. Appropriate use of language features tends to create more idiomatic code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-2108275053971258450?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/2108275053971258450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/04/php-global-variables-are-not.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/2108275053971258450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/2108275053971258450'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/04/php-global-variables-are-not.html' title='PHP global variables are not necessarily evil'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-4477805286747449579</id><published>2009-04-08T15:40:00.000+01:00</published><updated>2009-04-08T15:40:00.919+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='conductors'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>How do you eat an elephant?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_EEdbgam-elg/Sdy0ZwfAEcI/AAAAAAAABjg/vBNF_iOrCl0/s1600-h/elephant.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 255px;" src="http://2.bp.blogspot.com/_EEdbgam-elg/Sdy0ZwfAEcI/AAAAAAAABjg/vBNF_iOrCl0/s320/elephant.png" alt="" id="BLOGGER_PHOTO_ID_5322327214249742786" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Conductors say the funniest things some times. &lt;a href="http://hso.org.au/biographies.htm"&gt;Shaun&lt;/a&gt; uttered the above gem at a rehearsal recently, seemingly apropos nothing. The answer is, of course, one bite at a time. It turned out that he was trying to tell us that we &lt;b&gt;would&lt;/b&gt; one day get to grips with the first movement of the César Franck symphony in D minor, if we rehearsed it a bit at a time - yes, even the cellos.&lt;br /&gt;&lt;br /&gt;The symphony I think I can cope with. (Those bits I can't play properly, I will be able to fake ;-)) Instead, my personal elephant is currently the &lt;a href="http://docs.moodle.org/en/Development:Navigation_2.0"&gt;Navigation changes for Moodle 2.0&lt;/a&gt;. Although it is described as Navigation changes, it is much, much more than that. Blocks / themes / filters / rendering / pagelib / navigation changes would be more apt, and that is at least an African elephant, if not a &lt;a href="http://en.wikipedia.org/wiki/Mammuthus_sungari"&gt;mammuthus sungari&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Fortunately, I have Shaun's advice to guide me, so I sharpened my metaphorical butcher's knife and started trying to &lt;a href="http://docs.moodle.org/en/Development:Navigation_2.0_implementation_plan"&gt;dissect it into manageable chunks&lt;/a&gt;. Unfortunately I only got part way, because I started thinking about the filters bit of it, which I had &lt;a href="http://docs.moodle.org/en/Development:Filter_enable/disable_by_context"&gt;previously designed in detail&lt;/a&gt;. Since it is more fun to write code than to write documentation, and because I had been reading &lt;a href="http://xunitpatterns.com/"&gt;a book about unit testing and test driven development&lt;/a&gt;, and wanted to try some, I got seduced. Still, it is a worthwhile feature and the implementation is going well. You can follow the development in &lt;a href="http://tracker.moodle.org/browse/MDL-7336"&gt;MDL-7336&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Of course, once that is done, I must get back and finish the breakdown of all the Navigation work, especially as some of it needs funding, and so we need some estimates. That summarises what I have been working on in Moodle land recently.&lt;br /&gt;&lt;br /&gt;By the way, the book I mentioned (&lt;i&gt;xUnit Test Patterns&lt;/i&gt;) is excellent, if you want to read an 800 page book about unit testing. If you want a lighter introduction to the topic, &lt;a href="http://www.pragprog.com/titles/utj/pragmatic-unit-testing-in-java-with-junit"&gt;Pragmatic Unit Testing&lt;/a&gt;, or the Unit Testing chapter of &lt;a href="http://www.manning.com/reiersol/"&gt;PHP in Action&lt;/a&gt;, are probably better bets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-4477805286747449579?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/4477805286747449579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/04/how-do-you-eat-elephant.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/4477805286747449579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/4477805286747449579'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/04/how-do-you-eat-elephant.html' title='How do you eat an elephant?'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy0ZwfAEcI/AAAAAAAABjg/vBNF_iOrCl0/s72-c/elephant.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2247246257923129702.post-7395663850930479067</id><published>2009-02-18T13:13:00.004Z</published><updated>2009-02-18T13:47:55.405Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='Moodle'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Avoiding duplication and increasing flexibility in software: what about version control?</title><content type='html'>These thoughts were catalysed by Section 4.2.4 "Once and only once" of PHP in Action where they preach the evils of duplicated code. This is something I strongly believe in. (My best exorcism to date is &lt;a href="http://paste.dollyfish.net.nz/36088b"&gt;this Moodle commit&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;Unfortunately, the example they pick to illustrate their point utterly fails. Their example of what not to do is making a custom version of an application in a hurry by copying the whole thing and editing a few lines. Well, duh! Put the code in git and make a branch for the custom version. And, of course, when you do have time, come back and refactor, at which point git diff/merge/rebase ... will probably be a big help.&lt;br /&gt;&lt;br /&gt;Now, this is a form of software engineering that open source developers do all the time (while having wild flame wars about which version control system is best). But, when computer scientists dream about paradigms like object orientation, design patters, refactoring, and so on, as ways to reduce the need for code duplication and increase the flexibility of software designs, do they consider the role of version control systems? I don't recall reading anything.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The point about flexibility is particularly interesting in the context of opens source software written in in an interpreted language. Given my background, I am of course thinking about Moodle, which is a PHP web application. Suppose, by way of example, you want to change some part of the processing that occurs when a student submits a quiz, and Moodle works out what score they deserve. The 'proper' design patterns way to do this is:&lt;br /&gt;1. Check: Is the processing algorithm factored into a separate class, as recommended by the Strategy pattern? If not, refactor.&lt;br /&gt;2. Subclass the default Strategy to implement your customisations.&lt;br /&gt;3. Configure things so the factory methods instantiate your Strategy class, rather than the default one.&lt;br /&gt;&lt;br /&gt;Alternatively, you could just hack the code. Preferably as a custom branch in your version control system. When a new Moodle version is released, just upgrade and merge (or pull and rebase). One could even try to claim that this way is better, because if the code you hacked changes between releases, the merge may fail, helping you realise that you need to rework your customisation. If you don't notice the problem until you get to testing (which may happen anyway) it will be much harder to find and diagnose.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another example is &lt;a href="http://moodle.org/mod/forum/discuss.php?d=81641#p361586"&gt;this post in the Moodle quiz forum&lt;/a&gt;. Someone wanted to tweak something in Moodle, they were told to change the definition of a constant in a library file. Note that because there is no duplication of magic numbers throughout the code, it was only necessary to change the number in one place, so there is some proper design going on here.&lt;br /&gt;&lt;br /&gt;One could, of course, have a separate configuration file for all the settings like this in Moodle, but does that really make anyone's life easier? If you think of all the things people might want to tweak, that would be one big file. Also, it would move the constant definition further from where it is used, reducing the cohesion in the code. You could also handle this by making this number an admin setting, stored in the database, and editable through the web interface. In this case, I would argue that that is bad UI design. 3 is a perfectly good default for almost everyone, and Moodle already has more than enough configuration settings. Sufficiently few people need to adjust this, that telling those that do to edit the code is an adequate interface.&lt;br /&gt;&lt;br /&gt;You could call this approach "The whole code is a configuration file". In the abstract, you would not say it was good design, but for obscure configuration options like this, it may be the best way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, in a world with version control and interpreted languages, what is flexible and easy-to-modify software?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(To head off the obvious comments, I had better re-enforce that I do like nice clean software design, and design patterns, and so on; but I also spend most of my life working on Moodle where parts of the code are not like that; and somehow, most of the time, it just does not seem to matter. Millions of people around the world happily use and customise Moodle despite the lack of design patterns in the code. Should I be sad, or happy?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2247246257923129702-7395663850930479067?l=tjhunt.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tjhunt.blogspot.com/feeds/7395663850930479067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tjhunt.blogspot.com/2009/02/avoiding-duplication-and-increasing.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7395663850930479067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2247246257923129702/posts/default/7395663850930479067'/><link rel='alternate' type='text/html' href='http://tjhunt.blogspot.com/2009/02/avoiding-duplication-and-increasing.html' title='Avoiding duplication and increasing flexibility in software: what about version control?'/><author><name>Tim Hunt</name><uri>http://www.blogger.com/profile/01349724348368316287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://2.bp.blogspot.com/_EEdbgam-elg/Sdy8FLOrX7I/AAAAAAAABjs/9BpqGreLGt4/S220/tim.jpeg'/></author><thr:total>4</thr:total></entry></feed>
